|
12 | 12 | using Microsoft.CST.OAT.Utils;
|
13 | 13 | using Microsoft.Extensions.Logging;
|
14 | 14 | using Microsoft.Extensions.Logging.Abstractions;
|
| 15 | +using Newtonsoft.Json; |
| 16 | +using Newtonsoft.Json.Linq; |
15 | 17 | using Location = Microsoft.CodeAnalysis.Sarif.Location;
|
16 | 18 | using Result = Microsoft.ApplicationInspector.Commands.Result;
|
17 | 19 |
|
@@ -241,18 +243,55 @@ public override void WriteResults(Result result, CLICommandOptions commandOption
|
241 | 243 | run.Results.Add(sarifResult);
|
242 | 244 | }
|
243 | 245 |
|
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) |
246 | 261 | {
|
247 |
| - log.Save(StreamWriter.BaseStream); |
| 262 | + resultWithoutLevel["level"] = "warning"; |
248 | 263 | }
|
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) |
250 | 270 | {
|
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" } }; |
255 | 272 | }
|
| 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(); |
256 | 295 | if (autoClose)
|
257 | 296 | {
|
258 | 297 | FlushAndClose();
|
|
0 commit comments