Example #1
0
        private bool ValidateOptions(RewriteOptions rewriteOptions)
        {
            bool valid = true;

            valid &= rewriteOptions.ValidateOutputOptions();

            valid &= DriverUtilities.ReportWhetherOutputFileCanBeCreated(rewriteOptions.OutputFilePath, rewriteOptions.Force, _fileSystem);

            return(valid);
        }
Example #2
0
        private bool ValidateOptions(ApplyPolicyOptions applyPolicyOptions)
        {
            bool valid = true;

            valid &= applyPolicyOptions.Validate();

            valid &= DriverUtilities.ReportWhetherOutputFileCanBeCreated(applyPolicyOptions.OutputFilePath, applyPolicyOptions.Force, _fileSystem);

            return(valid);
        }
Example #3
0
        private static bool ValidateOptions(ConvertOptions convertOptions, IFileSystem fileSystem)
        {
            bool valid = true;

            valid &= convertOptions.ValidateOutputOptions();

            valid &= DriverUtilities.ReportWhetherOutputFileCanBeCreated(convertOptions.OutputFilePath, convertOptions.Force, fileSystem);

            return(valid);
        }
Example #4
0
        public int Run(MergeOptions mergeOptions)
        {
            try
            {
                string outputDirectory = mergeOptions.OutputFolderPath ?? Environment.CurrentDirectory;
                string outputFilePath  = Path.Combine(outputDirectory, GetOutputFileName(mergeOptions));

                if (!DriverUtilities.ReportWhetherOutputFileCanBeCreated(outputFilePath, mergeOptions.Force, _fileSystem))
                {
                    return(FAILURE);
                }

                HashSet <string> sarifFiles = CreateTargetsSet(mergeOptions.TargetFileSpecifiers, mergeOptions.Recurse, _fileSystem);

                IEnumerable <SarifLog> allRuns = ParseFiles(sarifFiles);

                // Build one SarifLog with all the Runs.
                SarifLog combinedLog = allRuns.Merge();

                // If there were no input files, the Merge operation set combinedLog.Runs to null. Although
                // null is valid in certain error cases, it is not valid here. Here, the correct value is
                // an empty list. See the SARIF spec, §3.13.4, "runs property".
                combinedLog.Runs = combinedLog.Runs ?? new List <Run>();

                combinedLog.Version   = SarifVersion.Current;
                combinedLog.SchemaUri = combinedLog.Version.ConvertToSchemaUri();

                OptionallyEmittedData dataToInsert = mergeOptions.DataToInsert.ToFlags();

                if (dataToInsert != OptionallyEmittedData.None)
                {
                    combinedLog = new InsertOptionalDataVisitor(dataToInsert).VisitSarifLog(combinedLog);
                }

                // Write output to file.
                Formatting formatting = mergeOptions.PrettyPrint
                    ? Formatting.Indented
                    : Formatting.None;

                _fileSystem.CreateDirectory(outputDirectory);

                WriteSarifFile(_fileSystem, combinedLog, outputFilePath, formatting);
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex);
                return(FAILURE);
            }
            return(SUCCESS);
        }
Example #5
0
        private bool ValidateOptions(TransformOptions transformOptions)
        {
            bool valid = true;

            if (transformOptions.SarifOutputVersion != SarifVersion.OneZeroZero && transformOptions.SarifOutputVersion != SarifVersion.Current)
            {
                Console.WriteLine(MultitoolResources.ErrorInvalidTransformTargetVersion);
                valid = false;
            }

            valid &= transformOptions.Validate();

            valid &= DriverUtilities.ReportWhetherOutputFileCanBeCreated(transformOptions.OutputFilePath, transformOptions.Force, _fileSystem);

            return(valid);
        }
Example #6
0
        public int Run(ResultMatchingOptions matchingOptions)
        {
            try
            {
                SarifLog baselineFile = null;
                if (!string.IsNullOrEmpty(matchingOptions.PreviousFilePath))
                {
                    baselineFile = ReadSarifFile <SarifLog>(_fileSystem, matchingOptions.PreviousFilePath);
                }

                string outputFilePath = matchingOptions.OutputFilePath;
                if (string.IsNullOrEmpty(outputFilePath))
                {
                    outputFilePath = Path.GetFileNameWithoutExtension(matchingOptions.PreviousFilePath) + "-annotated.sarif";
                }

                if (!DriverUtilities.ReportWhetherOutputFileCanBeCreated(outputFilePath, matchingOptions.Force, _fileSystem))
                {
                    return(FAILURE);
                }

                var currentSarifLogs = new List <SarifLog>();

                foreach (string currentFilePath in matchingOptions.CurrentFilePaths)
                {
                    currentSarifLogs.Add(ReadSarifFile <SarifLog>(_fileSystem, currentFilePath));
                }

                ISarifLogMatcher matcher = ResultMatchingBaselinerFactory.GetDefaultResultMatchingBaseliner();

                SarifLog output = matcher.Match(new SarifLog[] { baselineFile }, currentSarifLogs).First();

                Newtonsoft.Json.Formatting formatting = matchingOptions.PrettyPrint
                        ? Newtonsoft.Json.Formatting.Indented
                        : Newtonsoft.Json.Formatting.None;

                WriteSarifFile(_fileSystem, output, outputFilePath, formatting);
            }

            catch (Exception ex)
            {
                Console.WriteLine(ex.ToString());
                return(FAILURE);
            }

            return(SUCCESS);
        }
Example #7
0
        private bool ValidateOptions(RewriteOptions rewriteOptions)
        {
            if (!rewriteOptions.Validate())
            {
                return(false);
            }

            //  While this is returning true for inline cases, I think it's doing so for the wrong reasons.
            //  TODO: validate whether "actualOutputPath" can be created.
            //  #2270 https://github.com/microsoft/sarif-sdk/issues/2270
            if (!DriverUtilities.ReportWhetherOutputFileCanBeCreated(rewriteOptions.OutputFilePath, rewriteOptions.Force, _fileSystem))
            {
                return(false);
            }

            return(true);
        }
Example #8
0
        private bool ValidateOptions(FileWorkItemsOptions options, IFileSystem fileSystem)
        {
            bool valid = true;

            // The CommandLine package lets you declare an option of any type with a constructor
            // that accepts a string. We could have declared the property corresponding to the
            // "project-uri" option to be of type Uri, in which case CommandLine would have
            // populated it by invoking the Uri(string) ctor. This overload requires its argument
            // to be an absolute URI. This happens to be what we want; the problem is that if the
            // user supplies a relative URI, CommandLine produces this error:
            //
            //   Option 'p, project-uri' is defined with a bad format.
            //   Required option 'p, project-uri' is missing.
            //
            // That's not as helpful as a message like this:
            //
            //   The value of the 'p, project-uri' option must be an absolute URI.
            //
            // Therefore we declare the property corresponding to "project-uri" as a string.
            // We convert it to a URI with the ctor Uri(string, UriKind.RelativeOrAbsolute).
            // If it succeeds, we can assign the result to a Uri-valued property; if it fails,
            // we can produce a helpful error message.
            options.ProjectUri = new Uri(options.ProjectUriString, UriKind.RelativeOrAbsolute);

            if (!options.ProjectUri.IsAbsoluteUri)
            {
                string optionDescription = DriverUtilities.GetOptionDescription <FileWorkItemsOptions>(nameof(options.ProjectUriString));
                Console.Error.WriteLine(
                    string.Format(
                        CultureInfo.CurrentCulture,
                        MultitoolResources.WorkItemFiling_ErrorUriIsNotAbsolute,
                        options.ProjectUriString,
                        optionDescription));
                valid = false;
            }

            valid &= options.ValidateOutputOptions();

            valid &= DriverUtilities.ReportWhetherOutputFileCanBeCreated(options.OutputFilePath, options.Force, fileSystem);

            return(valid);
        }
        internal bool ValidateOptions(PageOptions options, IFileSystem fileSystem)
        {
            bool valid = true;

            valid &= ValidateNonNegativeCommandLineOption <PageOptions>(options.RunIndex, nameof(options.RunIndex));
            valid &= ValidateNonNegativeCommandLineOption <PageOptions>(options.Index, nameof(options.Index));
            valid &= ValidateNonNegativeCommandLineOption <PageOptions>(options.Count, nameof(options.Count));

            if (!fileSystem.FileExists(options.InputFilePath))
            {
                Console.Error.WriteLine(
                    string.Format(
                        CultureInfo.CurrentCulture,
                        MultitoolResources.InputFileNotFound,
                        options.InputFilePath));
                valid = false;
            }

            valid &= DriverUtilities.ReportWhetherOutputFileCanBeCreated(options.OutputFilePath, options.Force, fileSystem);

            return(valid);
        }
        private bool ValidateOptions(FileWorkItemsOptions options, SarifWorkItemContext sarifWorkItemContext, IFileSystem fileSystem)
        {
            bool valid = true;

            // The CommandLine package lets you declare an option of any type with a constructor
            // that accepts a string. We could have declared the property corresponding to the
            // "project-uri" option to be of type Uri, in which case CommandLine would have
            // populated it by invoking the Uri(string) ctor. This overload requires its argument
            // to be an absolute URI. This happens to be what we want; the problem is that if the
            // user supplies a relative URI, CommandLine produces this error:
            //
            //   Option 'p, project-uri' is defined with a bad format.
            //   Required option 'p, project-uri' is missing.
            //
            // That's not as helpful as a message like this:
            //
            //   The value of the 'p, project-uri' option must be an absolute URI.
            //
            // Therefore we declare the property corresponding to "project-uri" as a string.
            // We convert it to a URI with the ctor Uri(string, UriKind.RelativeOrAbsolute).
            // If it succeeds, we can assign the result to a Uri-valued property (persisted in the
            // context object); if it fails, we can produce a helpful error message.

            valid &= ValidateHostUri(options.HostUri, sarifWorkItemContext);

            valid &= options.Validate();

            if (!string.IsNullOrEmpty(options.OutputFilePath))
            {
                valid &= DriverUtilities.ReportWhetherOutputFileCanBeCreated(options.OutputFilePath, options.Force, fileSystem);
            }

            valid &= EnsurePersonalAccessToken(sarifWorkItemContext);

            return(valid);
        }
Example #11
0
        public int RunWithoutCatch(QueryOptions options)
        {
            bool valid = DriverUtilities.ReportWhetherOutputFileCanBeCreated(options.OutputFilePath, options.Force, _fileSystem);

            if (!valid)
            {
                return(FAILURE);
            }

            Stopwatch w             = Stopwatch.StartNew();
            int       originalTotal = 0;
            int       matchCount    = 0;

            // Parse the Query and create a Result evaluator for it
            IExpression expression = ExpressionParser.ParseExpression(options.Expression);
            IExpressionEvaluator <Result> evaluator = expression.ToEvaluator <Result>(SarifEvaluators.ResultEvaluator);

            // Read the log
            SarifLog log = ReadSarifFile <SarifLog>(_fileSystem, options.InputFilePath);

            foreach (Run run in log.Runs)
            {
                if (run.Results == null)
                {
                    continue;
                }
                run.SetRunOnResults();

                originalTotal += run.Results.Count;

                // Find matches for Results in the Run
                BitArray matches = new BitArray(run.Results.Count);
                evaluator.Evaluate(run.Results, matches);

                // Count the new matches
                matchCount += matches.TrueCount();

                // Filter the Run.Results to the matches
                run.Results = matches.MatchingSubset <Result>(run.Results);

                // Write to console, if caller requested
                if (options.WriteToConsole)
                {
                    foreach (Result result in run.Results)
                    {
                        Console.WriteLine(result.FormatForVisualStudio());
                    }
                }
            }

            // Remove any Runs with no remaining matches
            log.Runs = log.Runs.Where(r => (r?.Results?.Count ?? 0) > 0).ToList();

            w.Stop();
            Console.WriteLine($"Found {matchCount:n0} of {originalTotal:n0} results matched in {w.Elapsed.TotalSeconds:n1}s.");

            // Write to Output file, if caller requested
            if (!string.IsNullOrEmpty(options.OutputFilePath) && (options.Force || !_fileSystem.FileExists(options.OutputFilePath)))
            {
                Console.WriteLine($"Writing matches to {options.OutputFilePath}.");
                WriteSarifFile <SarifLog>(_fileSystem, log, options.OutputFilePath, (options.PrettyPrint ? Formatting.Indented : Formatting.None));
            }

            // Return exit code based on configuration
            if (options.ReturnCount)
            {
                return(matchCount);
            }
            else if (options.NonZeroExitCodeIfCountOver >= 0 && matchCount > options.NonZeroExitCodeIfCountOver)
            {
                return(TOO_MANY_RESULTS);
            }
            else
            {
                return(SUCCESS);
            }
        }
Example #12
0
        public int Run(MergeOptions mergeOptions)
        {
            Stopwatch w = Stopwatch.StartNew();

            try
            {
                _options = mergeOptions;
                string outputDirectory = mergeOptions.OutputDirectoryPath ?? Environment.CurrentDirectory;
                string outputFilePath  = Path.Combine(outputDirectory, GetOutputFileName(_options));

                if (_options.SplittingStrategy == 0)
                {
                    if (!DriverUtilities.ReportWhetherOutputFileCanBeCreated(outputFilePath, _options.Force, _fileSystem))
                    {
                        return(FAILURE);
                    }
                }

                var logLoadOptions = new BoundedChannelOptions(1000)
                {
                    SingleWriter = true,
                    SingleReader = false,
                };
                _logLoadChannel = Channel.CreateBounded <string>(logLoadOptions);

                var mergeLogsOptions = new UnboundedChannelOptions()
                {
                    SingleWriter = false,
                    SingleReader = true
                };
                _mergeLogsChannel = Channel.CreateUnbounded <SarifLog>(mergeLogsOptions);

                _options.Threads = _options.Threads > 0 ? _options.Threads : Environment.ProcessorCount;

                // creating readers
                var readers = new Task <bool> [_options.Threads];
                for (int i = 0; i < _options.Threads; i++)
                {
                    readers[i] = Task.Run(LoadSarifLogs);
                }

                // reading and dispatching
                FindFilesAsync().Wait();

                // creating writer
                var writer = Task.Run(MergeSarifLogsAsync);

                // waiting all readers and closing merge channel
                Task.WhenAll(readers)
                .ContinueWith(_ => _mergeLogsChannel.Writer.Complete())
                .Wait();

                // waiting writer
                writer.Wait();

                foreach (string key in _idToSarifLogMap.Keys)
                {
                    SarifLog mergedLog = _idToSarifLogMap[key]
                                         .InsertOptionalData(this._options.DataToInsert.ToFlags())
                                         .RemoveOptionalData(this._options.DataToInsert.ToFlags());

                    // If there were no input files, the Merge operation set combinedLog.Runs to null. Although
                    // null is valid in certain error cases, it is not valid here. Here, the correct value is
                    // an empty list. See the SARIF spec, §3.13.4, "runs property".
                    mergedLog.Runs ??= new List <Run>();
                    mergedLog.Version   = SarifVersion.Current;
                    mergedLog.SchemaUri = mergedLog.Version.ConvertToSchemaUri();

                    _fileSystem.DirectoryCreateDirectory(outputDirectory);
                    outputFilePath = Path.Combine(outputDirectory, GetOutputFileName(_options, key));
                    WriteSarifFile(_fileSystem, mergedLog, outputFilePath, _options.Minify);
                }
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex);
                return(FAILURE);
            }
            finally
            {
                Console.WriteLine($"Merge completed in {w.Elapsed}.");
            }
            return(SUCCESS);
        }
        public int Run(ResultMatchSetOptions options)
        {
            int returnCode = SUCCESS;

            options.OutputFolderPath ??= Path.Combine(options.FolderPath, "Out");

            ISarifLogMatcher matcher = ResultMatchingBaselinerFactory.GetDefaultResultMatchingBaseliner();

            // Remove previous results.
            if (_fileSystem.DirectoryExists(options.OutputFolderPath) && options.Force)
            {
                _fileSystem.DirectoryDelete(options.OutputFolderPath, true);
            }

            // Create output folder.
            _fileSystem.DirectoryCreate(options.OutputFolderPath);

            string   previousFileName = "";
            string   previousGroup = "";
            SarifLog previousLog = null, currentLog = null;

            foreach (string filePath in Directory.GetFiles(options.FolderPath, "*.sarif"))
            {
                string fileName     = Path.GetFileName(filePath);
                string currentGroup = GetGroupName(fileName);

                try
                {
                    currentLog = ReadSarifFile <SarifLog>(_fileSystem, filePath);

                    // Compare each log with the previous one in the same group.
                    if (currentGroup.Equals(previousGroup) && currentLog?.Runs?[0]?.Results.Count != 0 && previousLog?.Runs?[0]?.Results.Count != 0)
                    {
                        Console.WriteLine();
                        Console.WriteLine($"{previousFileName} -> {fileName}:");
                        SarifLog mergedLog = matcher.Match(new[] { previousLog }, new[] { currentLog }).First();

                        // Write the same and different count and different IDs.
                        WriteDifferences(mergedLog);

                        // Write the log, if there were any changed results
                        if (mergedLog.Runs[0].Results.Any(r => r.BaselineState != BaselineState.Unchanged))
                        {
                            string outputFilePath = Path.Combine(options.OutputFolderPath, fileName);

                            if (DriverUtilities.ReportWhetherOutputFileCanBeCreated(outputFilePath, options.Force, _fileSystem))
                            {
                                WriteSarifFile(_fileSystem, mergedLog, outputFilePath, options.Formatting);
                            }
                            else
                            {
                                returnCode = FAILURE;
                            }
                        }
                    }
                }
                catch (Exception ex) when(!Debugger.IsAttached)
                {
                    Console.WriteLine(ex.ToString());
                    returnCode = FAILURE;
                }

                previousFileName = fileName;
                previousGroup    = currentGroup;
                previousLog      = currentLog;
            }

            return(returnCode);
        }
Example #14
0
        public int Run(MergeOptions mergeOptions)
        {
            try
            {
                string outputDirectory = mergeOptions.OutputDirectoryPath ?? Environment.CurrentDirectory;
                string outputFilePath  = Path.Combine(outputDirectory, GetOutputFileName(mergeOptions));

                if (mergeOptions.SplittingStrategy == 0)
                {
                    if (!DriverUtilities.ReportWhetherOutputFileCanBeCreated(outputFilePath, mergeOptions.Force, _fileSystem))
                    {
                        return(FAILURE);
                    }
                }

                HashSet <string> sarifFiles = CreateTargetsSet(mergeOptions.TargetFileSpecifiers, mergeOptions.Recurse, _fileSystem);

                IEnumerable <SarifLog> allRuns = ParseFiles(sarifFiles);

                // Build one SarifLog with all the Runs.
                SarifLog mergedLog = allRuns
                                     .Merge(mergeOptions.MergeEmptyLogs)
                                     .InsertOptionalData(mergeOptions.DataToInsert.ToFlags())
                                     .RemoveOptionalData(mergeOptions.DataToInsert.ToFlags());

                // If there were no input files, the Merge operation set combinedLog.Runs to null. Although
                // null is valid in certain error cases, it is not valid here. Here, the correct value is
                // an empty list. See the SARIF spec, §3.13.4, "runs property".
                mergedLog.Runs ??= new List <Run>();
                mergedLog.Version   = SarifVersion.Current;
                mergedLog.SchemaUri = mergedLog.Version.ConvertToSchemaUri();

                if (mergeOptions.SplittingStrategy != SplittingStrategy.PerRule)
                {
                    // Write output to file.
                    Formatting formatting = mergeOptions.PrettyPrint
                        ? Formatting.Indented
                        : Formatting.None;

                    _fileSystem.CreateDirectory(outputDirectory);

                    WriteSarifFile(_fileSystem, mergedLog, outputFilePath, formatting);
                    return(0);
                }

                var ruleToRunsMap = new Dictionary <string, HashSet <Run> >();

                foreach (Run run in mergedLog.Runs)
                {
                    IList <Result> cachedResults = run.Results;

                    run.Results = null;

                    if (mergeOptions.MergeRuns)
                    {
                        run.Tool.Driver.Rules = null;
                        run.Artifacts         = null;
                        run.Invocations       = null;
                    }

                    Run emptyRun = run.DeepClone();
                    run.Results = cachedResults;

                    var idToRunMap = new Dictionary <string, Run>();

                    if (run.Results != null)
                    {
                        foreach (Result result in run.Results)
                        {
                            if (!idToRunMap.TryGetValue(result.RuleId, out Run splitRun))
                            {
                                splitRun = idToRunMap[result.RuleId] = emptyRun.DeepClone();
                            }
                            splitRun.Results ??= new List <Result>();

                            if (!ruleToRunsMap.TryGetValue(result.RuleId, out HashSet <Run> runs))
                            {
                                IEqualityComparer <Run> comparer = Microsoft.CodeAnalysis.Sarif.Run.ValueComparer;
                                runs = ruleToRunsMap[result.RuleId] = new HashSet <Run>(comparer);
                            }
                            runs.Add(splitRun);
                        }
                    }
                }

                foreach (string ruleId in ruleToRunsMap.Keys)
                {
                    HashSet <Run> runs       = ruleToRunsMap[ruleId];
                    var           perRuleLog = new SarifLog
                    {
                        Runs = new List <Run>(runs)
                    };

                    if (mergeOptions.MergeRuns)
                    {
                        new FixupVisitor().VisitSarifLog(perRuleLog);
                    }

                    Formatting formatting = mergeOptions.PrettyPrint
                        ? Formatting.Indented
                        : Formatting.None;

                    _fileSystem.CreateDirectory(outputDirectory);

                    outputFilePath = Path.Combine(outputDirectory, GetOutputFileName(mergeOptions, ruleId));

                    if (!DriverUtilities.ReportWhetherOutputFileCanBeCreated(outputFilePath, mergeOptions.Force, _fileSystem))
                    {
                        return(FAILURE);
                    }

                    WriteSarifFile(_fileSystem, perRuleLog, outputFilePath, formatting);
                }
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex);
                return(FAILURE);
            }
            return(SUCCESS);
        }