Esempio n. 1
0
        public virtual void Dispose()
        {
            // Disposing the json writer closes the stream but the textwriter
            // still needs to be disposed or closed to write the results
            if (_issueLogJsonWriter != null)
            {
                _issueLogJsonWriter.CloseResults();

                if (_run?.Invocations?.Count > 0 && _run.Invocations[0].StartTimeUtc != new DateTime() &&
                    !_dataToRemove.HasFlag(OptionallyEmittedData.NondeterministicProperties))
                {
                    _run.Invocations[0].EndTimeUtc = DateTime.UtcNow;
                }

                _issueLogJsonWriter.CompleteRun();
                _issueLogJsonWriter.Dispose();
            }

            if (_closeWriterOnDispose)
            {
                if (_textWriter != null)
                {
                    _textWriter.Dispose();
                }
                if (_jsonTextWriter == null)
                {
                    _jsonTextWriter.Close();
                }
            }

            GC.SuppressFinalize(this);
        }
Esempio n. 2
0
        public SarifLogger(
            TextWriter textWriter,
            LogFilePersistenceOptions logFilePersistenceOptions = DefaultLogFilePersistenceOptions,
            OptionallyEmittedData dataToInsert = OptionallyEmittedData.None,
            OptionallyEmittedData dataToRemove = OptionallyEmittedData.None,
            Tool tool = null,
            Run run   = null,
            IEnumerable <string> analysisTargets           = null,
            IEnumerable <string> invocationTokensToRedact  = null,
            IEnumerable <string> invocationPropertiesToLog = null,
            string defaultFileEncoding        = null,
            bool closeWriterOnDispose         = true,
            IEnumerable <FailureLevel> levels = null,
            IEnumerable <ResultKind> kinds    = null) : this(textWriter, logFilePersistenceOptions, closeWriterOnDispose, levels, kinds)
        {
            if (dataToInsert.HasFlag(OptionallyEmittedData.Hashes))
            {
                AnalysisTargetToHashDataMap = HashUtilities.MultithreadedComputeTargetFileHashes(analysisTargets);
            }

            _run = run ?? new Run();

            if (dataToInsert.HasFlag(OptionallyEmittedData.RegionSnippets) || dataToInsert.HasFlag(OptionallyEmittedData.ContextRegionSnippets))
            {
                _insertOptionalDataVisitor = new InsertOptionalDataVisitor(dataToInsert, _run);
            }

            EnhanceRun(
                analysisTargets,
                dataToInsert,
                dataToRemove,
                invocationTokensToRedact,
                invocationPropertiesToLog,
                defaultFileEncoding,
                AnalysisTargetToHashDataMap);

            tool = tool ?? Tool.CreateFromAssemblyData();

            _run.Tool     = tool;
            _dataToInsert = dataToInsert;
            _dataToRemove = dataToRemove;
            _issueLogJsonWriter.Initialize(_run);

            // Map existing Rules to ensure duplicates aren't created
            if (_run.Tool.Driver?.Rules != null)
            {
                for (int i = 0; i < _run.Tool.Driver.Rules.Count; ++i)
                {
                    RuleToIndexMap[_run.Tool.Driver.Rules[i]] = i;
                }
            }

            _persistArtifacts =
                (_dataToInsert & OptionallyEmittedData.Hashes) != 0 ||
                (_dataToInsert & OptionallyEmittedData.TextFiles) != 0 ||
                (_dataToInsert & OptionallyEmittedData.BinaryFiles) != 0;
        }
        public override Invocation VisitInvocation(Invocation node)
        {
            if (_dataToRemove.HasFlag(OptionallyEmittedData.NondeterministicProperties))
            {
                node.StartTimeUtc = new DateTime();
                node.EndTimeUtc   = new DateTime();
            }

            return(base.VisitInvocation(node));
        }
Esempio n. 4
0
        public SarifLogger(
            TextWriter textWriter,
            LoggingOptions loggingOptions      = DefaultLoggingOptions,
            OptionallyEmittedData dataToInsert = OptionallyEmittedData.None,
            OptionallyEmittedData dataToRemove = OptionallyEmittedData.None,
            Tool tool = null,
            Run run   = null,
            IEnumerable <string> analysisTargets           = null,
            IEnumerable <string> invocationTokensToRedact  = null,
            IEnumerable <string> invocationPropertiesToLog = null,
            string defaultFileEncoding = null) : this(textWriter, loggingOptions)
        {
            if (dataToInsert.HasFlag(OptionallyEmittedData.Hashes))
            {
                AnalysisTargetToHashDataMap = HashUtilities.MultithreadedComputeTargetFileHashes(analysisTargets);
            }

            _run = run ?? CreateRun(
                analysisTargets,
                dataToInsert,
                dataToRemove,
                invocationTokensToRedact,
                invocationPropertiesToLog,
                defaultFileEncoding,
                AnalysisTargetToHashDataMap);

            tool = tool ?? Tool.CreateFromAssemblyData();

            _run.Tool     = tool;
            _dataToInsert = dataToInsert;
            _dataToRemove = dataToRemove;
            _issueLogJsonWriter.Initialize(_run);
        }
        public override int Run(TOptions options)
        {
            //  To correctly initialize the logger, we must first add Hashes to dataToInsert
#pragma warning disable CS0618 // Type or member is obsolete
            if (options.ComputeFileHashes)
#pragma warning restore CS0618
            {
                OptionallyEmittedData dataToInsert = options.DataToInsert.ToFlags();
                dataToInsert |= OptionallyEmittedData.Hashes;

                options.DataToInsert = Enum.GetValues(typeof(OptionallyEmittedData)).Cast <OptionallyEmittedData>()
                                       .Where(oed => dataToInsert.HasFlag(oed)).ToList();
            }

            // 0. Initialize an common logger that drives all outputs. This
            //    object drives logging for console, statistics, etc.
            using (AggregatingLogger logger = InitializeLogger(options))
            {
                //  Once the logger has been correctly initialized, we can raise a warning
                _rootContext = CreateContext(options, logger, RuntimeErrors);
#pragma warning disable CS0618 // Type or member is obsolete
                if (options.ComputeFileHashes)
#pragma warning restore CS0618
                {
                    Warnings.LogObsoleteOption(_rootContext, "--hashes", SdkResources.ComputeFileHashes_ReplaceInsertHashes);
                }

                try
                {
                    Analyze(options, logger);
                }
                catch (ExitApplicationException <ExitReason> ex)
                {
                    // These exceptions have already been logged
                    ExecutionException = ex;
                    return(FAILURE);
                }
                catch (Exception ex)
                {
                    // These exceptions escaped our net and must be logged here
                    RuntimeErrors     |= Errors.LogUnhandledEngineException(_rootContext, ex);
                    ExecutionException = ex;
                    return(FAILURE);
                }
                finally
                {
                    logger.AnalysisStopped(RuntimeErrors);
                }
            }

            bool succeeded = (RuntimeErrors & ~RuntimeConditions.Nonfatal) == RuntimeConditions.None;

            if (options.RichReturnCode)
            {
                return((int)RuntimeErrors);
            }

            return(succeeded ? SUCCESS : FAILURE);
        }
Esempio n. 6
0
 private static void Validate(Artifact fileData, OptionallyEmittedData dataToInsert)
 {
     if (dataToInsert.HasFlag(OptionallyEmittedData.TextFiles))
     {
         fileData.Contents.Should().NotBeNull();
     }
     else
     {
         fileData.Contents.Should().BeNull();
     }
 }
        public void Artifact_PersistBinaryAndTextFileContents(
            string fileExtension,
            OptionallyEmittedData dataToInsert,
            bool shouldBePersisted)
        {
            string filePath     = Path.GetTempFileName() + fileExtension;
            string fileContents = Guid.NewGuid().ToString();
            Uri    uri          = new Uri(filePath);

            try
            {
                File.WriteAllText(filePath, fileContents);
                Artifact fileData = Artifact.Create(uri, dataToInsert);
                fileData.Location.Should().BeNull();

                if (dataToInsert.HasFlag(OptionallyEmittedData.Hashes))
                {
                    fileData.Hashes.Should().NotBeNull();
                }
                else
                {
                    fileData.Hashes.Should().BeNull();
                }

                string encodedFileContents = Convert.ToBase64String(File.ReadAllBytes(filePath));

                if (shouldBePersisted)
                {
                    string mimeType = MimeType.DetermineFromFileExtension(uri);
                    if (MimeType.IsBinaryMimeType(mimeType))
                    {
                        fileData.Contents.Binary.Should().Be(encodedFileContents);
                        fileData.Contents.Text.Should().BeNull();
                    }
                    else
                    {
                        fileData.Contents.Binary.Should().BeNull();
                        fileData.Contents.Text.Should().Be(fileContents);
                    }
                }
                else
                {
                    fileData.Contents.Should().BeNull();
                }
            }
            finally
            {
                if (File.Exists(filePath))
                {
                    File.Delete(filePath);
                }
            }
        }
Esempio n. 8
0
        public SarifLogger(
            TextWriter textWriter,
            LoggingOptions loggingOptions      = DefaultLoggingOptions,
            OptionallyEmittedData dataToInsert = OptionallyEmittedData.None,
            OptionallyEmittedData dataToRemove = OptionallyEmittedData.None,
            Tool tool = null,
            Run run   = null,
            IEnumerable <string> analysisTargets           = null,
            IEnumerable <string> invocationTokensToRedact  = null,
            IEnumerable <string> invocationPropertiesToLog = null,
            string defaultFileEncoding = null,
            bool closeWriterOnDispose  = true) : this(textWriter, loggingOptions, closeWriterOnDispose)
        {
            if (dataToInsert.HasFlag(OptionallyEmittedData.Hashes))
            {
                AnalysisTargetToHashDataMap = HashUtilities.MultithreadedComputeTargetFileHashes(analysisTargets);
            }

            _run = run ?? CreateRun(
                analysisTargets,
                dataToInsert,
                dataToRemove,
                invocationTokensToRedact,
                invocationPropertiesToLog,
                defaultFileEncoding,
                AnalysisTargetToHashDataMap);

            tool = tool ?? Tool.CreateFromAssemblyData();

            _run.Tool     = tool;
            _dataToInsert = dataToInsert;
            _dataToRemove = dataToRemove;
            _issueLogJsonWriter.Initialize(_run);

            // Map existing Rules to ensure duplicates aren't created
            if (_run.Tool.Driver?.Rules != null)
            {
                for (int i = 0; i < _run.Tool.Driver.Rules.Count; ++i)
                {
                    RuleToIndexMap[_run.Tool.Driver.Rules[i]] = i;
                }
            }
        }
Esempio n. 9
0
        public override Run VisitRun(Run node)
        {
            _run = node;

            if (_originalUriBaseIds != null)
            {
                _run.OriginalUriBaseIds = _run.OriginalUriBaseIds ?? new Dictionary <string, ArtifactLocation>();

                foreach (string key in _originalUriBaseIds.Keys)
                {
                    _run.OriginalUriBaseIds[key] = _originalUriBaseIds[key];
                }
            }

            if (node == null)
            {
                return(null);
            }

            bool scrapeFileReferences = _dataToInsert.HasFlag(OptionallyEmittedData.Hashes) ||
                                        _dataToInsert.HasFlag(OptionallyEmittedData.TextFiles) ||
                                        _dataToInsert.HasFlag(OptionallyEmittedData.BinaryFiles);

            if (scrapeFileReferences)
            {
                var visitor = new AddFileReferencesVisitor();
                visitor.VisitRun(node);
            }

            Run visited = base.VisitRun(node);

            return(visited);
        }
Esempio n. 10
0
        private void EnhanceRun(
            IEnumerable <string> analysisTargets,
            OptionallyEmittedData dataToInsert,
            OptionallyEmittedData dataToRemove,
            IEnumerable <string> invocationTokensToRedact,
            IEnumerable <string> invocationPropertiesToLog,
            string defaultFileEncoding = null,
            IDictionary <string, HashData> filePathToHashDataMap = null)
        {
            _run.Invocations ??= new List <Invocation>();
            if (defaultFileEncoding != null)
            {
                _run.DefaultEncoding = defaultFileEncoding;
            }

            Encoding encoding = SarifUtilities.GetEncodingFromName(_run.DefaultEncoding);

            if (analysisTargets != null)
            {
                _run.Artifacts ??= new List <Artifact>();

                foreach (string target in analysisTargets)
                {
                    Uri uri = new Uri(UriHelper.MakeValidUri(target), UriKind.RelativeOrAbsolute);

                    HashData hashData = null;
                    if (dataToInsert.HasFlag(OptionallyEmittedData.Hashes))
                    {
                        filePathToHashDataMap?.TryGetValue(target, out hashData);
                    }

                    var artifact = Artifact.Create(
                        new Uri(target, UriKind.RelativeOrAbsolute),
                        dataToInsert,
                        encoding,
                        hashData: hashData);

                    var fileLocation = new ArtifactLocation
                    {
                        Uri = uri
                    };

                    artifact.Location = fileLocation;

                    // This call will insert the file object into run.Files if not already present
                    artifact.Location.Index = _run.GetFileIndex(
                        artifact.Location,
                        addToFilesTableIfNotPresent: true,
                        dataToInsert: dataToInsert,
                        encoding: encoding,
                        hashData: hashData);
                }
            }

            var invocation = Invocation.Create(
                emitMachineEnvironment: dataToInsert.HasFlag(OptionallyEmittedData.EnvironmentVariables),
                emitTimestamps: !dataToRemove.HasFlag(OptionallyEmittedData.NondeterministicProperties),
                invocationPropertiesToLog);

            // TODO we should actually redact across the complete log file context
            // by a dedicated rewriting visitor or some other approach.

            if (invocationTokensToRedact != null)
            {
                invocation.CommandLine = Redact(invocation.CommandLine, invocationTokensToRedact);
                invocation.Machine     = Redact(invocation.Machine, invocationTokensToRedact);
                invocation.Account     = Redact(invocation.Account, invocationTokensToRedact);

                if (invocation.WorkingDirectory != null)
                {
                    invocation.WorkingDirectory.Uri = Redact(invocation.WorkingDirectory.Uri, invocationTokensToRedact);
                }

                if (invocation.EnvironmentVariables != null)
                {
                    string[] keys = invocation.EnvironmentVariables.Keys.ToArray();

                    foreach (string key in keys)
                    {
                        string value = invocation.EnvironmentVariables[key];
                        invocation.EnvironmentVariables[key] = Redact(value, invocationTokensToRedact);
                    }
                }
            }

            _run.Invocations.Add(invocation);
        }
Esempio n. 11
0
        protected override string ConstructTestOutputFromInputResource(string inputResourceName, object parameter)
        {
            SarifLog actualLog = PrereleaseCompatibilityTransformer.UpdateToCurrentVersion(
                GetResourceText(inputResourceName),
                formatting: Formatting.Indented,
                updatedLog: out _);

            // Some of the tests operate on SARIF files that mention the absolute path of the file
            // that was "analyzed" (InsertOptionalDataVisitor.txt). That path depends on the repo
            // root, and so can vary depending on the machine where the tests are run. To avoid
            // this problem, both the input files and the expected output files contain a fixed
            // string "REPLACED_AT_TEST_RUNTIME" in place of the directory portion of the path. But some
            // of the tests must read the contents of the analyzed file (for instance, when the
            // test requires snippets or file hashes to be inserted). Those test require the actual
            // path. Therefore we replace the fixed string with the actual path, execute the
            // visitor, and then restore the fixed string so the actual output can be compared
            // to the expected output.
            string enlistmentRoot = GitHelper.Default.GetRepositoryRoot(Environment.CurrentDirectory, useCache: false);

            if (inputResourceName == "Inputs.CoreTests-Relative.sarif")
            {
                Uri originalUri = actualLog.Runs[0].OriginalUriBaseIds["TESTROOT"].Uri;
                string uriString = originalUri.ToString();

                uriString = uriString.Replace(EnlistmentRoot, enlistmentRoot);

                actualLog.Runs[0].OriginalUriBaseIds["TESTROOT"] = new ArtifactLocation { Uri = new Uri(uriString, UriKind.Absolute) };

                var visitor = new InsertOptionalDataVisitor(_currentOptionallyEmittedData);
                visitor.Visit(actualLog.Runs[0]);

                // Restore the remanufactured URI so that file diffing succeeds.
                actualLog.Runs[0].OriginalUriBaseIds["TESTROOT"] = new ArtifactLocation { Uri = originalUri };

                // In some of the tests, the visitor added an originalUriBaseId for the repo root.
                // Adjust that one, too.
                string repoRootUriBaseId = InsertOptionalDataVisitor.GetUriBaseId(0);
                if (actualLog.Runs[0].OriginalUriBaseIds.TryGetValue(repoRootUriBaseId, out ArtifactLocation artifactLocation))
                {
                    Uri repoRootUri = artifactLocation.Uri;
                    string repoRootString = repoRootUri.ToString();
                    repoRootString = repoRootString.Replace(enlistmentRoot.Replace(@"\", "/"), EnlistmentRoot);

                    actualLog.Runs[0].OriginalUriBaseIds[repoRootUriBaseId] = new ArtifactLocation { Uri = new Uri(repoRootString, UriKind.Absolute) };
                }
            }
            else if (inputResourceName == "Inputs.CoreTests-Absolute.sarif")
            {
                Uri originalUri = actualLog.Runs[0].Artifacts[0].Location.Uri;
                string uriString = originalUri.ToString();

                uriString = uriString.Replace(EnlistmentRoot, enlistmentRoot);

                actualLog.Runs[0].Artifacts[0].Location = new ArtifactLocation { Uri = new Uri(uriString, UriKind.Absolute) };

                var visitor = new InsertOptionalDataVisitor(_currentOptionallyEmittedData);
                visitor.Visit(actualLog.Runs[0]);

                // Restore the remanufactured URI so that file diffing matches
                actualLog.Runs[0].Artifacts[0].Location = new ArtifactLocation { Uri = originalUri };
            }
            else
            {
                var visitor = new InsertOptionalDataVisitor(_currentOptionallyEmittedData);
                visitor.Visit(actualLog.Runs[0]);
            }

            // Verify and remove Guids, because they'll vary with every run and can't be compared to a fixed expected output.
            if (_currentOptionallyEmittedData.HasFlag(OptionallyEmittedData.Guids))
            {
                for (int i = 0; i < actualLog.Runs[0].Results.Count; ++i)
                {
                    Result result = actualLog.Runs[0].Results[i];
                    result.Guid.Should().NotBeNullOrEmpty(because: "OptionallyEmittedData.Guids flag was set");

                    result.Guid = null;
                }
            }

            if (_currentOptionallyEmittedData.HasFlag(OptionallyEmittedData.VersionControlDetails))
            {
                VersionControlDetails versionControlDetails = actualLog.Runs[0].VersionControlProvenance[0];

                // Verify and replace the mapped directory (enlistment root), because it varies
                // from machine to machine.
                var mappedUri = new Uri(enlistmentRoot + @"\", UriKind.Absolute);
                versionControlDetails.MappedTo.Uri.Should().Be(mappedUri);
                versionControlDetails.MappedTo.Uri = new Uri($"file:///{EnlistmentRoot}/");

                // When OptionallyEmittedData includes any file-related content, the visitor inserts
                // an artifact that points to the enlistment root. So we have to verify and adjust
                // that as well.
                IList<Artifact> artifacts = actualLog.Runs[0].Artifacts;
                if (artifacts.Count >= 2)
                {
                    artifacts[1].Location.Uri.Should().Be(enlistmentRoot);
                    artifacts[1].Location.Uri = new Uri($"file:///{EnlistmentRoot}/");
                }

                // Verify and replace the remote repo URI, because it would be different in a fork.
                var gitHelper = new GitHelper();
                Uri remoteUri = gitHelper.GetRemoteUri(enlistmentRoot);

                versionControlDetails.RepositoryUri.Should().Be(remoteUri);
                versionControlDetails.RepositoryUri = new Uri("https://REMOTE_URI");

                // Verify and remove branch and revision id, because they vary from run to run.
                versionControlDetails.Branch.Should().NotBeNullOrEmpty(because: "OptionallyEmittedData.VersionControlInformation flag was set");
                versionControlDetails.Branch = null;

                versionControlDetails.RevisionId.Should().NotBeNullOrEmpty(because: "OptionallyEmittedData.VersionControlInformation flag was set");
                versionControlDetails.RevisionId = null;
            }

            return JsonConvert.SerializeObject(actualLog, Formatting.Indented);
        }
Esempio n. 12
0
        public override Run VisitRun(Run node)
        {
            _run          = node;
            _gitHelper    = new GitHelper(_fileSystem, _processRunner);
            _repoRootUris = new HashSet <Uri>();

            if (_originalUriBaseIds != null)
            {
                _run.OriginalUriBaseIds ??= new Dictionary <string, ArtifactLocation>();

                foreach (string key in _originalUriBaseIds.Keys)
                {
                    _run.OriginalUriBaseIds[key] = _originalUriBaseIds[key];
                }
            }

            if (node == null)
            {
                return(null);
            }

            bool scrapeFileReferences = _dataToInsert.HasFlag(OptionallyEmittedData.Hashes) ||
                                        _dataToInsert.HasFlag(OptionallyEmittedData.TextFiles) ||
                                        _dataToInsert.HasFlag(OptionallyEmittedData.BinaryFiles);

            if (scrapeFileReferences)
            {
                var visitor = new AddFileReferencesVisitor();
                visitor.VisitRun(node);
            }

            Run visited = base.VisitRun(node);

            // After all the ArtifactLocations have been visited,
            if (_run.VersionControlProvenance == null && _dataToInsert.HasFlag(OptionallyEmittedData.VersionControlDetails))
            {
                _run.VersionControlProvenance = CreateVersionControlProvenance();
            }

            return(visited);
        }
Esempio n. 13
0
        public static Artifact Create(
            Uri uri,
            OptionallyEmittedData dataToInsert = OptionallyEmittedData.None,
            string mimeType        = null,
            Encoding encoding      = null,
            IFileSystem fileSystem = null)
        {
            if (uri == null)
            {
                throw new ArgumentNullException(nameof(uri));
            }

            mimeType   = mimeType ?? SarifWriters.MimeType.DetermineFromFileExtension(uri);
            fileSystem = fileSystem ?? new FileSystem();

            var artifact = new Artifact()
            {
                Encoding = encoding?.WebName,
                MimeType = mimeType
            };

            // Attempt to persist file contents and/or compute file hash and persist
            // this information to the log file. In the event that there is some issue
            // accessing the file, for example, due to ACLs applied to a directory,
            // we currently swallow these exceptions without populating any requested
            // data or putting a notification in the log file that a problem
            // occurred. Something to discuss moving forward.
            try
            {
                bool workTodo = dataToInsert.HasFlag(OptionallyEmittedData.Hashes) ||
                                dataToInsert.HasFlag(OptionallyEmittedData.TextFiles) ||
                                dataToInsert.HasFlag(OptionallyEmittedData.BinaryFiles);

                if (!workTodo ||
                    !uri.IsAbsoluteUri ||
                    !uri.IsFile ||
                    !fileSystem.FileExists(uri.LocalPath))
                {
                    return(artifact);
                }

                string filePath = uri.LocalPath;

                if (dataToInsert.HasFlag(OptionallyEmittedData.BinaryFiles) &&
                    SarifWriters.MimeType.IsBinaryMimeType(mimeType))
                {
                    artifact.Contents = GetEncodedFileContents(fileSystem, filePath, mimeType, encoding);
                }

                if (dataToInsert.HasFlag(OptionallyEmittedData.TextFiles) &&
                    SarifWriters.MimeType.IsTextualMimeType(mimeType))
                {
                    artifact.Contents = GetEncodedFileContents(fileSystem, filePath, mimeType, encoding);
                }

                if (dataToInsert.HasFlag(OptionallyEmittedData.Hashes))
                {
                    HashData hashes = HashUtilities.ComputeHashes(filePath);
                    artifact.Hashes = new Dictionary <string, string>
                    {
                        { "md5", hashes.MD5 },
                        { "sha-1", hashes.Sha1 },
                        { "sha-256", hashes.Sha256 },
                    };
                }
            }
            catch (Exception e) when(e is IOException || e is UnauthorizedAccessException)
            {
            }

            return(artifact);
        }
Esempio n. 14
0
        private static Run CreateRun(
            IEnumerable <string> analysisTargets,
            OptionallyEmittedData dataToInsert,
            IEnumerable <string> invocationTokensToRedact,
            IEnumerable <string> invocationPropertiesToLog,
            string defaultFileEncoding = null)
        {
            var run = new Run
            {
                Invocations     = new List <Invocation>(),
                DefaultEncoding = defaultFileEncoding
            };

            if (analysisTargets != null)
            {
                run.Artifacts = new List <Artifact>();

                foreach (string target in analysisTargets)
                {
                    Uri uri = new Uri(UriHelper.MakeValidUri(target), UriKind.RelativeOrAbsolute);

                    var fileData = Artifact.Create(
                        new Uri(target, UriKind.RelativeOrAbsolute),
                        dataToInsert);

                    var fileLocation = new ArtifactLocation
                    {
                        Uri = uri
                    };

                    fileData.Location = fileLocation;

                    // This call will insert the file object into run.Files if not already present
                    fileData.Location.Index = run.GetFileIndex(fileData.Location, addToFilesTableIfNotPresent: true, dataToInsert);
                }
            }

            var invocation = Invocation.Create(dataToInsert.HasFlag(OptionallyEmittedData.EnvironmentVariables), invocationPropertiesToLog);

            // TODO we should actually redact across the complete log file context
            // by a dedicated rewriting visitor or some other approach.

            if (invocationTokensToRedact != null)
            {
                invocation.CommandLine = Redact(invocation.CommandLine, invocationTokensToRedact);
                invocation.Machine     = Redact(invocation.Machine, invocationTokensToRedact);
                invocation.Account     = Redact(invocation.Account, invocationTokensToRedact);

                if (invocation.WorkingDirectory != null)
                {
                    invocation.WorkingDirectory.Uri = Redact(invocation.WorkingDirectory.Uri, invocationTokensToRedact);
                }

                if (invocation.EnvironmentVariables != null)
                {
                    string[] keys = invocation.EnvironmentVariables.Keys.ToArray();

                    foreach (string key in keys)
                    {
                        string value = invocation.EnvironmentVariables[key];
                        invocation.EnvironmentVariables[key] = Redact(value, invocationTokensToRedact);
                    }
                }
            }

            run.Invocations.Add(invocation);
            return(run);
        }
Esempio n. 15
0
        protected override string ConstructTestOutputFromInputResource(string inputResourceName, object parameter)
        {
            PrereleaseCompatibilityTransformer.UpdateToCurrentVersion(
                GetResourceText(inputResourceName),
                formatting: Formatting.Indented,
                out string transformedLog);

            SarifLog actualLog = PrereleaseCompatibilityTransformer.UpdateToCurrentVersion(transformedLog, formatting: Formatting.None, out transformedLog);

            // For CoreTests only - this code rewrites the log persisted URI to match the test environment
            if (inputResourceName == "Inputs.CoreTests-Relative.sarif")
            {
                Uri    originalUri = actualLog.Runs[0].OriginalUriBaseIds["TESTROOT"].Uri;
                string uriString   = originalUri.ToString();

                string currentDirectory = Environment.CurrentDirectory;
                currentDirectory = currentDirectory.Substring(0, currentDirectory.IndexOf(@"\bld\"));
                uriString        = uriString.Replace("REPLACED_AT_TEST_RUNTIME", currentDirectory);

                actualLog.Runs[0].OriginalUriBaseIds["TESTROOT"] = new ArtifactLocation {
                    Uri = new Uri(uriString, UriKind.Absolute)
                };

                var visitor = new InsertOptionalDataVisitor(_currentOptionallyEmittedData);
                visitor.Visit(actualLog.Runs[0]);

                // Restore the remanufactured URI so that file diffing matches
                actualLog.Runs[0].OriginalUriBaseIds["TESTROOT"] = new ArtifactLocation {
                    Uri = originalUri
                };
            }
            else if (inputResourceName == "Inputs.CoreTests-Absolute.sarif")
            {
                Uri    originalUri = actualLog.Runs[0].Artifacts[0].Location.Uri;
                string uriString   = originalUri.ToString();

                string currentDirectory = Environment.CurrentDirectory;
                currentDirectory = currentDirectory.Substring(0, currentDirectory.IndexOf(@"\bld\"));
                uriString        = uriString.Replace("REPLACED_AT_TEST_RUNTIME", currentDirectory);

                actualLog.Runs[0].Artifacts[0].Location = new ArtifactLocation {
                    Uri = new Uri(uriString, UriKind.Absolute)
                };

                var visitor = new InsertOptionalDataVisitor(_currentOptionallyEmittedData);
                visitor.Visit(actualLog.Runs[0]);

                // Restore the remanufactured URI so that file diffing matches
                actualLog.Runs[0].Artifacts[0].Location = new ArtifactLocation {
                    Uri = originalUri
                };
            }
            else
            {
                var visitor = new InsertOptionalDataVisitor(_currentOptionallyEmittedData);
                visitor.Visit(actualLog.Runs[0]);
            }

            // Verify and remove Guids, because they'll vary with every run and can't be compared to a fixed expected output
            if (_currentOptionallyEmittedData.HasFlag(OptionallyEmittedData.Guids))
            {
                for (int i = 0; i < actualLog.Runs[0].Results.Count; ++i)
                {
                    Result result = actualLog.Runs[0].Results[i];
                    if (string.IsNullOrEmpty(result.Guid))
                    {
                        Assert.True(false, $"Results[{i}] had no Guid assigned, but OptionallyEmittedData.Guids flag was set.");
                    }

                    result.Guid = null;
                }
            }

            return(JsonConvert.SerializeObject(actualLog, Formatting.Indented));
        }