public void SarifLogger_WritesFileDataWithUnrecognizedEncoding() { var sb = new StringBuilder(); string file; string fileText = "using System;"; using (var tempFile = new TempFile(".cs")) using (var textWriter = new StringWriter(sb)) { file = tempFile.Name; File.WriteAllText(file, fileText); using (var sarifLogger = new SarifLogger( textWriter, analysisTargets: new string[] { file }, dataToInsert: OptionallyEmittedData.TextFiles, invocationTokensToRedact: null, invocationPropertiesToLog: null, defaultFileEncoding: "ImaginaryEncoding")) { LogSimpleResult(sarifLogger); } } string logText = sb.ToString(); SarifLog sarifLog = JsonConvert.DeserializeObject <SarifLog>(logText); Artifact fileData = sarifLog.Runs[0].Artifacts[0]; fileData.Contents.Binary.Should().BeNull(); fileData.Contents.Text.Should().Be(fileText); }
// This helper is intended to validate a single enum member only // and not arbitrary combinations of bits. One defined member, // All, contains all bits. private void TestForLoggingOption(LoggingOptions loggingOption) { string fileName = Path.GetTempFileName(); try { SarifLogger logger; // Validates overload that accept a path argument. using (logger = new SarifLogger(fileName, loggingOption)) { ValidateLoggerForExclusiveOption(logger, loggingOption); }; // Validates overload that accepts any // TextWriter (for example, one instantiated over a // StringBuilder instance). var sb = new StringBuilder(); var stringWriter = new StringWriter(sb); using (logger = new SarifLogger(stringWriter, loggingOption)) { ValidateLoggerForExclusiveOption(logger, loggingOption); }; } finally { if (File.Exists(fileName)) { File.Delete(fileName); } } }
public void SarifLogger_LogsSpecifiedInvocationProperties() { var sb = new StringBuilder(); using (var textWriter = new StringWriter(sb)) { using (var sarifLogger = new SarifLogger( textWriter, analysisTargets: null, dataToInsert: OptionallyEmittedData.Hashes, invocationTokensToRedact: null, invocationPropertiesToLog: new[] { "WorkingDirectory", "ProcessId" })) { LogSimpleResult(sarifLogger); } } string logText = sb.ToString(); var sarifLog = JsonConvert.DeserializeObject <SarifLog>(logText); Invocation invocation = sarifLog.Runs[0].Invocations[0]; // StartTime and EndTime should still be logged. invocation.StartTimeUtc.Should().NotBe(DateTime.MinValue); invocation.EndTimeUtc.Should().NotBe(DateTime.MinValue); // Specified properties should be logged. invocation.WorkingDirectory.Should().NotBeNull(); invocation.ProcessId.Should().NotBe(0); // Other properties should be empty. invocation.CommandLine.Should().BeNull(); invocation.ExecutableLocation.Should().BeNull(); }
public static void AnalyzeDllAndWriteLog(string inputPath, string outputPath, ScopeMethodKind kind, bool useScopeFactory = true, bool interProc = false, StreamWriter outputStream = null) { var log = AnalyzeDll(inputPath, ScopeMethodKind.All, useScopeFactory, interProc, outputStream); SarifLogger.WriteSarifOutput(log, outputPath); }
private void InitializeOutputFile(TOptions analyzeOptions, TContext context, HashSet <string> targets) { string filePath = analyzeOptions.OutputFilePath; AggregatingLogger aggregatingLogger = (AggregatingLogger)context.Logger; if (!string.IsNullOrEmpty(filePath)) { InvokeCatchingRelevantIOExceptions ( () => { LoggingOptions loggingOptions; loggingOptions = analyzeOptions.ConvertToLoggingOptions(); var sarifLogger = new SarifLogger( analyzeOptions.OutputFilePath, loggingOptions, null, null, targets, Prerelease, invocationTokensToRedact: GenerateSensitiveTokensList(), invocationPropertiesToLog: analyzeOptions.InvocationPropertiesToLog); sarifLogger.AnalysisStarted(); aggregatingLogger.Loggers.Add(sarifLogger); }, (ex) => { Errors.LogExceptionCreatingLogFile(context, filePath, ex); ThrowExitApplicationException(context, ExitReason.ExceptionCreatingLogFile, ex); } ); } }
public void SarifLogger_EmitHashesWithNullOrEmptyAnalysisTargets() { var analysisTargetsArguments = new IEnumerable <string>[] { null, new List <string>() }; var sb = new StringBuilder(); int argumentsCount = analysisTargetsArguments.Count(); for (int i = 0; i < argumentsCount; i++) { IEnumerable <string> analysisTargets = analysisTargetsArguments[i]; sb.Clear(); using (var textWriter = new StringWriter(sb)) { using (var sarifLogger = new SarifLogger( textWriter, analysisTargets: analysisTargets, dataToInsert: OptionallyEmittedData.Hashes)) { LogSimpleResult(sarifLogger); } } string output = sb.ToString(); SarifLog sarifLog = JsonConvert.DeserializeObject <SarifLog>(output); sarifLog.Runs[0].Artifacts.Should().BeNull(); } }
public void SarifLogger_LogsSpecifiedInvocationProperties() { var sb = new StringBuilder(); using (var textWriter = new StringWriter(sb)) { using (var sarifLogger = new SarifLogger( textWriter, analysisTargets: null, loggingOptions: LoggingOptions.ComputeFileHashes, prereleaseInfo: null, invocationTokensToRedact: null, invocationPropertiesToLog: new[] { "WorkingDirectory", "ProcessId" })) { } } string logText = sb.ToString(); var sarifLog = JsonConvert.DeserializeObject <SarifLog>(logText); Invocation invocation = sarifLog.Runs[0].Invocation; // StartTime and EndTime should still be logged. invocation.StartTime.Should().NotBe(DateTime.MinValue); invocation.EndTime.Should().NotBe(DateTime.MinValue); // Specified properties should be logged. invocation.WorkingDirectory.Should().NotBeNull(); invocation.ProcessId.Should().NotBe(0); // Other properties should be empty. invocation.CommandLine.Should().BeNull(); invocation.FileName.Should().BeNull(); }
public void SarifLogger_AcceptsOverrideOfDefaultEncoding() { const string Utf8 = "UTF-8"; const string Utf7 = "UTF-7"; // Start off with a run that specifies the default file encoding. var run = new Run { DefaultEncoding = Utf8 }; var sb = new StringBuilder(); using (var textWriter = new StringWriter(sb)) { // Create a logger that uses that run but specifies a different encoding. using (var sarifLogger = new SarifLogger( textWriter, run: run, defaultFileEncoding: Utf7)) { } } string logText = sb.ToString(); SarifLog sarifLog = JsonConvert.DeserializeObject <SarifLog>(logText); // The logger accepted the override for default file encoding. sarifLog.Runs[0].DefaultEncoding.Should().Be(Utf7); }
public void SarifLogger_TreatsInvocationPropertiesCaseInsensitively() { var sb = new StringBuilder(); using (var textWriter = new StringWriter(sb)) { using (var sarifLogger = new SarifLogger( textWriter, analysisTargets: null, loggingOptions: LoggingOptions.ComputeFileHashes, prereleaseInfo: null, invocationTokensToRedact: null, invocationPropertiesToLog: new[] { "WORKINGDIRECTORY", "prOCessID" })) { } } string logText = sb.ToString(); var sarifLog = JsonConvert.DeserializeObject <SarifLog>(logText); Invocation invocation = sarifLog.Runs[0].Invocation; // Specified properties should be logged. invocation.WorkingDirectory.Should().NotBeNull(); invocation.ProcessId.Should().NotBe(0); }
public void SarifLogger_TreatsInvocationPropertiesCaseInsensitively() { var sb = new StringBuilder(); using (var textWriter = new StringWriter(sb)) { using (var sarifLogger = new SarifLogger( textWriter, analysisTargets: null, dataToInsert: OptionallyEmittedData.Hashes, invocationTokensToRedact: null, invocationPropertiesToLog: new[] { "WORKINGDIRECTORY", "prOCessID" })) { LogSimpleResult(sarifLogger); } } string logText = sb.ToString(); var sarifLog = JsonConvert.DeserializeObject <SarifLog>(logText); Invocation invocation = sarifLog.Runs[0].Invocations?[0]; // Specified properties should be logged. invocation.WorkingDirectory.Should().NotBeNull(); invocation.ProcessId.Should().NotBe(0); }
private static void LogToolNotification( SarifLogger logger, string message, FailureLevel level = FailureLevel.Note, Exception ex = null) { ExceptionData exceptionData = null; if (ex != null) { exceptionData = new ExceptionData { Kind = ex.GetType().FullName, Message = ex.Message, Stack = Stack.CreateStacks(ex).FirstOrDefault() }; } TextWriter writer = level == FailureLevel.Error ? Console.Error : Console.Out; writer.WriteLine(message); logger.LogToolNotification(new Notification { Level = level, Message = new Message { Text = message }, Exception = exceptionData }); }
private static int Run(Options options) { Banner(); int exitCode = 1; using (var logger = new SarifLogger( options.LogFilePath, analysisTargets: new[] { options.InstanceFilePath, options.SchemaFilePath }, loggingOptions: LoggingOptions.Verbose, invocationTokensToRedact: null)) { DateTime start = DateTime.Now; exitCode = Validate(options.InstanceFilePath, options.SchemaFilePath, logger); TimeSpan elapsedTime = DateTime.Now - start; string message = string.Format(CultureInfo.CurrentCulture, ValidatorResources.ElapsedTime, elapsedTime); LogToolNotification(logger, message); } return(exitCode); }
private void InitializeOutputFile(TOptions analyzeOptions, TContext context, ISet <string> targets) { string filePath = analyzeOptions.OutputFilePath; AggregatingLogger aggregatingLogger = (AggregatingLogger)context.Logger; if (!string.IsNullOrEmpty(filePath)) { InvokeCatchingRelevantIOExceptions ( () => { LogFilePersistenceOptions logFilePersistenceOptions = analyzeOptions.ConvertToLogFilePersistenceOptions(); OptionallyEmittedData dataToInsert = analyzeOptions.DataToInsert.ToFlags(); OptionallyEmittedData dataToRemove = analyzeOptions.DataToRemove.ToFlags(); SarifLogger sarifLogger; if (analyzeOptions.SarifOutputVersion != SarifVersion.OneZeroZero) { sarifLogger = new SarifLogger( analyzeOptions.OutputFilePath, logFilePersistenceOptions, dataToInsert, dataToRemove, tool: _tool, run: null, analysisTargets: targets, invocationTokensToRedact: GenerateSensitiveTokensList(), invocationPropertiesToLog: analyzeOptions.InvocationPropertiesToLog, levels: analyzeOptions.Level, kinds: analyzeOptions.Kind); } else { sarifLogger = new SarifOneZeroZeroLogger( analyzeOptions.OutputFilePath, logFilePersistenceOptions, dataToInsert, dataToRemove, tool: _tool, run: null, analysisTargets: targets, invocationTokensToRedact: GenerateSensitiveTokensList(), invocationPropertiesToLog: analyzeOptions.InvocationPropertiesToLog, levels: analyzeOptions.Level, kinds: analyzeOptions.Kind); } _pathToHashDataMap = sarifLogger.AnalysisTargetToHashDataMap; sarifLogger.AnalysisStarted(); aggregatingLogger.Loggers.Add(sarifLogger); }, (ex) => { Errors.LogExceptionCreatingLogFile(context, filePath, ex); ThrowExitApplicationException(context, ExitReason.ExceptionCreatingLogFile, ex); } ); } }
public void SarifLogger_WritesFileData() { var sb = new StringBuilder(); string file; using (var tempFile = new TempFile(".cpp")) using (var textWriter = new StringWriter(sb)) { file = tempFile.Name; File.WriteAllText(file, "#include \"windows.h\";"); using (var sarifLogger = new SarifLogger( textWriter, analysisTargets: new string[] { file }, dataToInsert: OptionallyEmittedData.Hashes, invocationTokensToRedact: null, invocationPropertiesToLog: null)) { LogSimpleResult(sarifLogger); } } string logText = sb.ToString(); string fileDataKey = new Uri(file).AbsoluteUri; var sarifLog = JsonConvert.DeserializeObject <SarifLog>(logText); sarifLog.Runs[0].Artifacts[0].MimeType.Should().Be(MimeType.Cpp); sarifLog.Runs[0].Artifacts[0].Hashes.Keys.Count.Should().Be(3); sarifLog.Runs[0].Artifacts[0].Hashes["md5"].Should().Be("4B9DC12934390387862CC4AB5E4A2159"); sarifLog.Runs[0].Artifacts[0].Hashes["sha-1"].Should().Be("9B59B1C1E3F5F7013B10F6C6B7436293685BAACE"); sarifLog.Runs[0].Artifacts[0].Hashes["sha-256"].Should().Be("0953D7B3ADA7FED683680D2107EE517A9DBEC2D0AF7594A91F058D104B7A2AEB"); }
private void LogSimpleResult(SarifLogger sarifLogger) { ReportingDescriptor rule = new ReportingDescriptor { Id = "RuleId" }; sarifLogger.Log(rule, CreateSimpleResult(rule)); }
private static void StreamOwnershipHelper(bool closeWriterOnDispose) { string expectedText = GetResourceContents("SimpleExample.sarif"); MemoryStream memoryStream = new MemoryStream(); var streamWriter = new StreamWriter(memoryStream); using (var logger = new SarifLogger( streamWriter, loggingOptions: LoggingOptions.PrettyPrint, dataToRemove: OptionallyEmittedData.NondeterministicProperties, closeWriterOnDispose: closeWriterOnDispose)) { logger.Log( new ReportingDescriptor { Id = "MyId" }, new Result { Message = new Message { Text = "My text" }, RuleId = "MyId" }); } // Important. Force streamwriter to commit everything. streamWriter.Flush(); memoryStream.Seek(0, SeekOrigin.Begin); using (var streamReader = new StreamReader(memoryStream)) using (var jsonTextReader = new JsonTextReader(streamReader)) { var jsonSerializer = new JsonSerializer(); SarifLog sarifLog = jsonSerializer.Deserialize <SarifLog>(jsonTextReader); // The tool metadata generated by the logger is very environment specific. // For example, this output changes depending on whether the test is // executed from within Visual Studio or via the command-line within // the AppVeyor environment. We therefore normalize this information. sarifLog.Runs[0].Tool = new Tool { Driver = new ToolComponent { Name = "SarifLoggerTests", Rules = new List <ReportingDescriptor> { new ReportingDescriptor { Id = "MyId" } } }, }; // Prove we did it. string actualText = JsonConvert.SerializeObject(sarifLog, formatting: Formatting.Indented); actualText.Should().BeEquivalentTo(expectedText); } }
private static void ReportResult(Result result, SarifLogger logger) { ReportingDescriptor rule = RuleFactory.GetRuleFromRuleId(result.RuleId); Console.Error.WriteLine( result.FormatForVisualStudio(rule)); logger.Log(rule, result); }
private static void ReportResults( Result[] results, SarifLogger logger) { foreach (Result result in results) { ReportResult(result, logger); } }
public void CallScopeMap01() { var t = typeof(ScopeMap01); var run = AnalyzeProcessor(t, "X: string", "X: string, a: int"); var s = SarifLogger.SarifRunToString(run); Assert.IsNotNull(run); Assert.IsTrue(run.BothAnalysesAgree()); }
private static void Main(string[] args) { if (args.Length < 1) { Console.WriteLine(@"Usage: SarifTrim [inputFilePath] [outputFilePath?] [removeParts?] removeParts: Semicolon-separated sections to remove. Options: UriBaseIds;CodeFlows;RelatedLocations;Graphs;GraphTraversals;Stacks;WebRequests;WebResponses"); return; } string inputFilePath = args[0]; string outputFilePath = (args.Length > 1 ? args[1] : Path.ChangeExtension(inputFilePath, $"trimmed{Path.GetExtension(inputFilePath)}")); // Split on comma, remove whitespace, and put in case-insensitive HashSet HashSet <string> removeParts = new HashSet <string>((args.Length > 2 ? args[2] : "").Split(';').Select(entry => entry.Trim()), StringComparer.OrdinalIgnoreCase); SarifLog log = null; using (new ConsoleWatch($"Loading \"{inputFilePath}\"...")) { log = SarifLog.LoadDeferred(inputFilePath); } using (new ConsoleWatch($"Trimming \"{inputFilePath}\" into \"{outputFilePath}\"...")) { Run run = log.Runs[0]; SarifConsolidator consolidator = new SarifConsolidator(run); consolidator.MessageLengthLimitChars = 1024; consolidator.RemoveUriBaseIds = (removeParts.Contains("UriBaseIds")); consolidator.RemoveCodeFlows = (removeParts.Contains("CodeFlows")); consolidator.RemoveRelatedLocations = (removeParts.Contains("RelatedLocations")); consolidator.RemoveGraphs = (removeParts.Contains("Graphs")); consolidator.RemoveStacks = (removeParts.Contains("Stacks")); consolidator.RemoveWebRequests = (removeParts.Contains("WebRequests")); consolidator.RemoveWebResponses = (removeParts.Contains("WebResponses")); // Consolidate the SarifLog per settings using (SarifLogger logger = new SarifLogger(outputFilePath, LogFilePersistenceOptions.OverwriteExistingOutputFile, tool: run.Tool, run: run)) { foreach (Result result in run.Results) { consolidator.Trim(result); logger.Log(result.GetRule(run), result); } } if (consolidator.UniqueThreadFlowLocations < consolidator.TotalThreadFlowLocations) { Console.WriteLine($"Consolidated {consolidator.TotalThreadFlowLocations:n0} ThreadFlowLocations into {consolidator.UniqueThreadFlowLocations:n0} unique ones."); } if (consolidator.UniqueLocations < consolidator.TotalLocations) { Console.WriteLine($"Consolidated {consolidator.TotalLocations:n0} Locations into {consolidator.UniqueLocations:n0} unique per-Result Locations."); } } }
protected void Verify(SarifValidationSkimmerBase skimmer, string testFileName) { string ruleName = skimmer.GetType().Name; string testDirectory = Path.Combine(Environment.CurrentDirectory, TestDataDirectory, ruleName); string targetPath = Path.Combine(testDirectory, testFileName); string expectedFilePath = MakeExpectedFilePath(testDirectory, testFileName); string actualFilePath = MakeActualFilePath(testDirectory, testFileName); string inputLogContents = File.ReadAllText(targetPath); JsonSerializerSettings settings = new JsonSerializerSettings { ContractResolver = SarifContractResolver.Instance }; SarifLog inputLog = JsonConvert.DeserializeObject <SarifLog>(inputLogContents, settings); using (var logger = new SarifLogger( actualFilePath, new string[] { targetPath }, verbose: false, logEnvironment: false, computeTargetsHash: false, prereleaseInfo: null, invocationTokensToRedact: null)) { logger.AnalysisStarted(); var context = new SarifValidationContext { Rule = skimmer, Logger = logger, TargetUri = new Uri(targetPath), SchemaFilePath = JsonSchemaFile, InputLogContents = inputLogContents, InputLog = inputLog }; skimmer.Initialize(context); context.Logger.AnalyzingTarget(context); skimmer.Analyze(context); logger.AnalysisStopped(RuntimeConditions.None); } string actualLogContents = File.ReadAllText(actualFilePath); string expectedLogContents = File.ReadAllText(expectedFilePath); // We can't just compare the text of the log files because properties // like start time, and absolute paths, will differ from run to run. // Until SarifLogger has a "deterministic" option (see http://github.com/Microsoft/sarif-sdk/issues/500), // we perform a selective compare of just the elements we care about. SelectiveCompare(actualLogContents, expectedLogContents); }
public void CallPassColumnValuesToMethodReducer() { var t = typeof(PassColumnValuesToMethodReducer); var run = AnalyzeProcessor(t, "A: string", "A: string"); var s = SarifLogger.SarifRunToString(run); Assert.IsNotNull(run); Assert.IsTrue(run.BothAnalysesAgree()); }
public void SarifLogger_ShouldLogByFailureLevel(FailureLevel level, bool verboseLogging, bool expectedReturn) { LoggingOptions loggingOptions = verboseLogging ? LoggingOptions.Verbose : LoggingOptions.None; var sb = new StringBuilder(); var logger = new SarifLogger(new StringWriter(sb), loggingOptions); bool result = logger.ShouldLog(level); result.Should().Be(expectedReturn); }
public void CallConditionalColumnReducer() { var t = typeof(ConditionalColumnReducer); var run = AnalyzeProcessor(t, "A: string, B: string", "OutputColumn: string"); var s = SarifLogger.SarifRunToString(run); Assert.IsNotNull(run); Assert.IsTrue(run.BothAnalysesAgree()); }
public void SarifLogger_DoNotScrapeFilesFromNotifications() { var sb = new StringBuilder(); using (var textWriter = new StringWriter(sb)) { using (var sarifLogger = new SarifLogger( textWriter, analysisTargets: null, dataToInsert: OptionallyEmittedData.Hashes, prereleaseInfo: null, invocationTokensToRedact: null, invocationPropertiesToLog: null)) { var toolNotification = new Notification { PhysicalLocation = new PhysicalLocation { FileLocation = new FileLocation { Uri = new Uri(@"file:///file0.cpp") } } }; sarifLogger.LogToolNotification(toolNotification); var configurationNotification = new Notification { PhysicalLocation = new PhysicalLocation { FileLocation = new FileLocation { Uri = new Uri(@"file:///file0.cpp") } } }; sarifLogger.LogConfigurationNotification(configurationNotification); string ruleId = "RuleId"; var rule = new Rule() { Id = ruleId }; var result = new Result() { RuleId = ruleId }; sarifLogger.Log(rule, result); } } string logText = sb.ToString(); var sarifLog = JsonConvert.DeserializeObject <SarifLog>(logText); sarifLog.Runs[0].Files.Should().BeNull(); }
private static void ReportInvalidSchemaErrors( SchemaValidationException ex, string schemaFile, SarifLogger logger) { foreach (SchemaValidationException wrappedException in ex.WrappedExceptions) { Result result = ResultFactory.CreateResult(wrappedException.JToken, wrappedException.ErrorNumber, wrappedException.Args); result.SetResultFile(schemaFile); ReportResult(result, logger); } }
protected void Verify(string testFileName, bool disablePrereleaseCompatibilityTransform) { string targetPath = Path.Combine(_testDirectory, testFileName); string actualFilePath = MakeActualFilePath(_testDirectory, testFileName); string inputLogContents = File.ReadAllText(targetPath); if (!disablePrereleaseCompatibilityTransform) { PrereleaseCompatibilityTransformer.UpdateToCurrentVersion(inputLogContents, formatting: Formatting.Indented, out inputLogContents); } SarifLog inputLog = JsonConvert.DeserializeObject <SarifLog>(inputLogContents); bool expectedResultsArePresent = inputLog.Runs[0].TryGetProperty(ExpectedResultsPropertyName, out ExpectedValidationResults expectedResults); expectedResultsArePresent.Should().Be(true); var skimmer = new TSkimmer(); using (var logger = new SarifLogger( actualFilePath, LoggingOptions.None, tool: null, run: null, analysisTargets: new string[] { targetPath }, invocationTokensToRedact: null)) { logger.AnalysisStarted(); var context = new SarifValidationContext { Rule = skimmer, Logger = logger, TargetUri = new Uri(targetPath), SchemaFilePath = JsonSchemaFile, InputLogContents = inputLogContents, InputLog = inputLog }; skimmer.Initialize(context); context.Logger.AnalyzingTarget(context); skimmer.Analyze(context); logger.AnalysisStopped(RuntimeConditions.None); } string actualLogContents = File.ReadAllText(actualFilePath); SarifLog outputLog = JsonConvert.DeserializeObject <SarifLog>(actualLogContents); Verify(outputLog.Runs[0], expectedResults); }
public void CallRowCountReducer() { var t = typeof(RowCountReducer); var run = AnalyzeProcessor(t, "X: string, Y: int", "X: string, Y: int"); var s = SarifLogger.SarifRunToString(run); Assert.IsNotNull(run); // Diego: This test fail because the processor does not read any input columns and do not write an output column explicitly // It seems the doing yield return is not enough Assert.IsTrue(run.BothAnalysesAgree()); }
public static SarifLog Analyze(string filePath, string text, string rulePath) { if (Skimmers == null) { IEnumerable <string> regexDefinitions = FileSystem.DirectoryGetFiles(Path.Combine(rulePath, @"..\bin\"), "*.json"); // Load all rules from JSON. This also automatically loads any validations file that // lives alongside the JSON. For a JSON file named PlaintextSecrets.json, the // corresponding validations assembly is named PlaintextSecrets.dll (i.e., only the // extension name changes from .json to .dll). Skimmers = AnalyzeCommand.CreateSkimmersFromDefinitionsFiles(FileSystem, regexDefinitions); } var sb = new StringBuilder(); // We should clear every time to prevent colision. FileRegionsCache.Instance.ClearCache(); using (var outputTextWriter = new StringWriter(sb)) using (var logger = new SarifLogger( outputTextWriter, LogFilePersistenceOptions.PrettyPrint, dataToInsert: OptionallyEmittedData.Hashes | OptionallyEmittedData.RegionSnippets | OptionallyEmittedData.ContextRegionSnippets | OptionallyEmittedData.ComprehensiveRegionProperties, levels: new List <FailureLevel> { FailureLevel.Error, FailureLevel.Warning, FailureLevel.Note, FailureLevel.None }, kinds: new List <ResultKind> { ResultKind.Fail })) { // The analysis will disable skimmers that raise an exception. This // hash set stores the disabled skimmers. When a skimmer is disabled, // that catastrophic event is logged as a SARIF notification. var disabledSkimmers = new HashSet <string>(); var context = new AnalyzeContext { TargetUri = new Uri(filePath, UriKind.RelativeOrAbsolute), FileContents = text, Logger = logger, DynamicValidation = true, }; using (context) { IEnumerable <Skimmer <AnalyzeContext> > applicableSkimmers = AnalyzeCommand.DetermineApplicabilityForTargetHelper(context, Skimmers, disabledSkimmers); AnalyzeCommand.AnalyzeTargetHelper(context, applicableSkimmers, disabledSkimmers); } } return(JsonConvert.DeserializeObject <SarifLog>(sb.ToString())); }
/// <inheritdoc/> public async Task <Stream> AnalyzeAsync(IEnumerable <string> targetFiles, CancellationToken cancellationToken) { targetFiles = targetFiles ?? throw new ArgumentNullException(nameof(targetFiles)); if (!targetFiles.Any()) { return(Stream.Null); } string solutionDirectory = await GetSolutionDirectoryAsync().ConfigureAwait(continueOnCapturedContext: false); var stream = new MemoryStream(); bool wasAnalyzed = false; using (var writer = new StreamWriter(stream, Encoding.UTF8, DefaultBufferSize, leaveOpen: true)) { using (SarifLogger sarifLogger = this.MakeSarifLogger(writer)) { sarifLogger.AnalysisStarted(); foreach (string targetFile in targetFiles) { bool currentAnalysis; var uri = new Uri(targetFile, UriKind.Absolute); string text = File.ReadAllText(targetFile); currentAnalysis = this.AnalyzeCore(uri, text, solutionDirectory, sarifLogger, cancellationToken); if (!wasAnalyzed && currentAnalysis) { wasAnalyzed = currentAnalysis; } } sarifLogger.AnalysisStopped(RuntimeConditions.None); } if (wasAnalyzed) { await writer.FlushAsync().ConfigureAwait(continueOnCapturedContext: false); } } if (!wasAnalyzed) { stream.Dispose(); return(Stream.Null); } return(stream); }