Skip to content

Commit 774ba64

Browse files
authored
Port DevSkim Sarif Output Workarounds to ApplicationInspector (#551)
1 parent b830cf9 commit 774ba64

File tree

1 file changed

+47
-8
lines changed

1 file changed

+47
-8
lines changed

AppInspector.CLI/Writers/AnalyzeSarifWriter.cs

Lines changed: 47 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,8 @@
1212
using Microsoft.CST.OAT.Utils;
1313
using Microsoft.Extensions.Logging;
1414
using Microsoft.Extensions.Logging.Abstractions;
15+
using Newtonsoft.Json;
16+
using Newtonsoft.Json.Linq;
1517
using Location = Microsoft.CodeAnalysis.Sarif.Location;
1618
using Result = Microsoft.ApplicationInspector.Commands.Result;
1719

@@ -241,18 +243,55 @@ public override void WriteResults(Result result, CLICommandOptions commandOption
241243
run.Results.Add(sarifResult);
242244
}
243245

244-
log.Runs.Add(run);
245-
try
246+
log.Runs.Add(run);
247+
248+
/* Sarif SDK workarounds */
249+
// Begin Workaround for https://github.com/microsoft/sarif-sdk/issues/2024 - results with level warning are not serialized
250+
// Save the sarif log to a stream
251+
var stream = new MemoryStream();
252+
log.Save(stream);
253+
stream.Position = 0;
254+
// Read the saved log back in
255+
var reReadLog = JObject.Parse(new StreamReader(stream).ReadToEnd());
256+
// Find results with levels that are not set
257+
var resultsWithoutLevels =
258+
reReadLog.SelectTokens("$.runs[*].results[*]").Where(t => t["level"] == null).ToList();
259+
// For each result with no level set its level to warning
260+
foreach (var resultWithoutLevel in resultsWithoutLevels)
246261
{
247-
log.Save(StreamWriter.BaseStream);
262+
resultWithoutLevel["level"] = "warning";
248263
}
249-
catch (Exception e)
264+
265+
// Rules which had a default configuration of Warning will also not have the field populated
266+
var rulesWithoutDefaultConfiguration = reReadLog.SelectTokens("$.runs[*].tool.driver.rules[*]")
267+
.Where(t => t["defaultConfiguration"] == null).ToList();
268+
// For each result with no default configuration option, add one with the level warning
269+
foreach (var rule in rulesWithoutDefaultConfiguration)
250270
{
251-
_logger.LogError(
252-
"Failed to serialize JSON representation of results in memory. {Type} : {Message}",
253-
e.GetType().Name, e.Message);
254-
throw;
271+
rule["defaultConfiguration"] = new JObject { { "level", "warning" } };
255272
}
273+
274+
// Rules with a DefaultConfiguration object, but where that object has no level also should be set
275+
// ApplicationInspector should always populate this object with a level, but potentially
276+
var rulesWithoutDefaultConfigurationLevel = reReadLog.SelectTokens("$.runs[*].tool.driver.rules[*].defaultConfiguration")
277+
.Where(t => t["level"] == null).ToList();
278+
// For each result with a default configuration object that has no level
279+
// add a level property equal to warning
280+
foreach (var rule in rulesWithoutDefaultConfigurationLevel)
281+
{
282+
rule["level"] = "warning";
283+
}
284+
285+
// Begin Workaround for https://github.com/microsoft/sarif-sdk/issues/2662
286+
// The provided schema (rtm.6) is 404, so replace it with a 2.1.0 that is available.
287+
reReadLog["$schema"] = "https://www.schemastore.org/schemas/json/sarif-2.1.0-rtm.5.json";
288+
using var jsonWriter = new JsonTextWriter(TextWriter);
289+
reReadLog.WriteTo(jsonWriter);
290+
// Add a newline at the end to make logging messages cleaner
291+
TextWriter.WriteLine();
292+
293+
// End Workarounds
294+
TextWriter.Flush();
256295
if (autoClose)
257296
{
258297
FlushAndClose();

0 commit comments

Comments
 (0)