/// <summary>Converts a tool log file into the SARIF format.</summary>
        /// <exception cref="ArgumentNullException">Thrown when one or more required arguments are null.</exception>
        /// <exception cref="ArgumentException">Thrown when one or more arguments have unsupported or
        /// illegal values.</exception>
        /// <exception cref="InvalidOperationException">Thrown when the requested operation is invalid.</exception>
        /// <param name="toolFormat">The tool format of the input file.</param>
        /// <param name="inputFileName">The input log file name.</param>
        /// <param name="outputFileName">The name of the file to which the resulting SARIF log shall be
        /// written. This cannot be a directory.</param>
        /// <param name="conversionOptions">Options for controlling the conversion.</param>
        /// <param name="pluginAssemblyPath">Path to plugin assembly containing converter types.</param>
        public void ConvertToStandardFormat(
            string toolFormat,
            string inputFileName,
            string outputFileName,
            LogFilePersistenceOptions logFilePersistenceOptions = LogFilePersistenceOptions.None,
            OptionallyEmittedData dataToInsert = OptionallyEmittedData.None,
            string pluginAssemblyPath          = null)
        {
            if (inputFileName == null)
            {
                throw new ArgumentNullException(nameof(inputFileName));
            }
            if (outputFileName == null)
            {
                throw new ArgumentNullException(nameof(outputFileName));
            }

            // FileMode settings here will results in an exception being raised if the input
            // file does not exist, and that an existing output file will be overwritten
            using (FileStream input = File.OpenRead(inputFileName))
                using (FileStream outputTextStream = File.Create(outputFileName))
                    using (var outputTextWriter = new StreamWriter(outputTextStream))
                        using (var outputJson = new JsonTextWriter(outputTextWriter))
                        {
                            if (logFilePersistenceOptions.HasFlag(LogFilePersistenceOptions.PrettyPrint))
                            {
                                outputJson.Formatting = Formatting.Indented;
                            }

                            using (var output = new ResultLogJsonWriter(outputJson))
                            {
                                ConvertToStandardFormat(toolFormat, input, output, dataToInsert, pluginAssemblyPath);
                            }
                        }
        }
Пример #2
0
        /// <summary>Converts a tool log file into the SARIF format.</summary>
        /// <exception cref="ArgumentNullException">Thrown when one or more required arguments are null.</exception>
        /// <exception cref="ArgumentException">Thrown when one or more arguments have unsupported or
        /// illegal values.</exception>
        /// <exception cref="InvalidOperationException">Thrown when the requested operation is invalid.</exception>
        /// <param name="toolFormat">The tool format of the input file.</param>
        /// <param name="inputFileName">The input log file name.</param>
        /// <param name="outputFileName">The name of the file to which the resulting SARIF log shall be
        /// written. This cannot be a directory.</param>
        /// <param name="conversionOptions">Options for controlling the conversion.</param>
        /// <param name="pluginAssemblyPath">Path to plugin assembly containing converter types.</param>
        public void ConvertToStandardFormat(
            string toolFormat,
            string inputFileName,
            string outputFileName,
            LoggingOptions loggingOptions = LoggingOptions.None,
            string pluginAssemblyPath     = null)
        {
            if (inputFileName == null)
            {
                throw new ArgumentNullException(nameof(inputFileName));
            }
            if (outputFileName == null)
            {
                throw new ArgumentNullException(nameof(outputFileName));
            }

            if (Directory.Exists(outputFileName))
            {
                throw new ArgumentException("Specified file output path exists but is a directory.", nameof(outputFileName));
            }

            if (!loggingOptions.Includes(LoggingOptions.OverwriteExistingOutputFile) && File.Exists(outputFileName))
            {
                throw new InvalidOperationException("Output file already exists and option to overwrite was not specified.");
            }

            if (toolFormat.MatchesToolFormat(ToolFormat.PREfast))
            {
                string sarif = ConvertPREfastToStandardFormat(inputFileName);
                File.WriteAllText(outputFileName, sarif);
            }
            else
            {
                // FileMode settings here will results in an exception being raised if the input
                // file does not exist, and that an existing output file will be overwritten
                using (var input = File.OpenRead(inputFileName))
                    using (var outputTextStream = File.Create(outputFileName))
                        using (var outputTextWriter = new StreamWriter(outputTextStream))
                            using (var outputJson = new JsonTextWriter(outputTextWriter))
                            {
                                if (loggingOptions.Includes(LoggingOptions.PrettyPrint))
                                {
                                    outputJson.Formatting = Formatting.Indented;
                                }

                                using (var output = new ResultLogJsonWriter(outputJson))
                                {
                                    ConvertToStandardFormat(toolFormat, input, output, loggingOptions, pluginAssemblyPath);
                                }
                            }
            }
        }
Пример #3
0
        private static string GetJson(Action <ResultLogJsonWriter> testContent)
        {
            StringBuilder result = new StringBuilder();

            using (var str = new StringWriter(result))
                using (var json = new JsonTextWriter(str))
                    using (var uut = new ResultLogJsonWriter(json))
                    {
                        testContent(uut);
                    }

            return(result.ToString());
        }
Пример #4
0
        /// <summary>Converts a tool log file into the SARIF format.</summary>
        /// <exception cref="ArgumentNullException">Thrown when one or more required arguments are null.</exception>
        /// <exception cref="ArgumentException">Thrown when one or more arguments have unsupported or
        /// illegal values.</exception>
        /// <exception cref="InvalidOperationException">Thrown when the requested operation is invalid.</exception>
        /// <param name="toolFormat">The tool format of the input file.</param>
        /// <param name="inputFileName">The input log file name.</param>
        /// <param name="outputFileName">The name of the file to which the resulting SARIF log shall be
        /// written. This cannot be a directory.</param>
        /// <param name="conversionOptions">Options for controlling the conversion.</param>
        public void ConvertToStandardFormat(
            ToolFormat toolFormat,
            string inputFileName,
            string outputFileName,
            ToolFormatConversionOptions conversionOptions)
        {
            if (toolFormat == ToolFormat.PREfast)
            {
                string sarif = ConvertPREfastToStandardFormat(inputFileName);
                File.WriteAllText(outputFileName, sarif);
            }

            if (inputFileName == null)
            {
                throw new ArgumentNullException("inputFileName");
            }
            ;
            if (outputFileName == null)
            {
                throw new ArgumentNullException("outputFileName");
            }
            ;

            if (Directory.Exists(outputFileName))
            {
                throw new ArgumentException("Specified file output path exists but is a directory.", "outputFileName");
            }

            if (!conversionOptions.HasFlag(ToolFormatConversionOptions.OverwriteExistingOutputFile) && File.Exists(outputFileName))
            {
                throw new InvalidOperationException("Output file already exists and option to overwrite was not specified.");
            }

            // FileMode settings here will results in an exception being raised if the input
            // file does not exist, and that an existing output file will be overwritten
            using (var input = File.OpenRead(inputFileName))
                using (var outputTextStream = File.Create(outputFileName))
                    using (var outputTextWriter = new StreamWriter(outputTextStream))
                        using (var outputJson = new JsonTextWriter(outputTextWriter))
                        {
                            if (conversionOptions.HasFlag(ToolFormatConversionOptions.PrettyPrint))
                            {
                                outputJson.Formatting = Formatting.Indented;
                            }

                            using (var output = new ResultLogJsonWriter(outputJson))
                            {
                                ConvertToStandardFormat(toolFormat, input, output);
                            }
                        }
        }
Пример #5
0
        public SarifLogger(TextWriter textWriter, bool verbose)
        {
            Verbose = verbose;

            _textWriter = textWriter;

            _jsonTextWriter = new JsonTextWriter(_textWriter);

            // for debugging it is nice to have the following line added.
            _jsonTextWriter.Formatting       = Newtonsoft.Json.Formatting.Indented;
            _jsonTextWriter.DateFormatString = DateTimeConverter.DateTimeFormat;

            _issueLogJsonWriter = new ResultLogJsonWriter(_jsonTextWriter);
        }
Пример #6
0
        protected static string GetJson(Action <ResultLogJsonWriter> testContent)
        {
            StringBuilder result = new StringBuilder();

            using (var str = new StringWriter(result))
                using (var json = new JsonTextWriter(str)
                {
                    Formatting = Formatting.Indented, DateTimeZoneHandling = DateTimeZoneHandling.Utc
                })
                    using (var uut = new ResultLogJsonWriter(json))
                    {
                        testContent(uut);
                    }

            return(result.ToString());
        }
        private static SarifLog RunAnalyzeCommand(TestAnalyzeOptions options, IFileSystem fileSystem = null, int expectedReturnCode = 0)
        {
            // If no log file is specified, we will convert the console output into a log file
            bool captureConsoleOutput = string.IsNullOrEmpty(options.OutputFilePath);

            var command = new TestAnalyzeCommand(fileSystem)
            {
                _captureConsoleOutput = captureConsoleOutput
            };

            command.DefaultPlugInAssemblies = new Assembly[] { typeof(AnalyzeCommandBaseTests).Assembly };

            try
            {
                HashUtilities.FileSystem = fileSystem;
                command.Run(options).Should().Be(expectedReturnCode);
            }
            finally
            {
                HashUtilities.FileSystem = null;
            }

            SarifLog sarifLog = null;

            if (captureConsoleOutput)
            {
                var converter = new MSBuildConverter(verbose: true);

                var sb = new StringBuilder();

                using (var input = new MemoryStream(Encoding.UTF8.GetBytes(command._consoleLogger.CapturedOutput)))
                    using (var outputTextWriter = new StringWriter(sb))
                        using (var outputJson = new JsonTextWriter(outputTextWriter))
                            using (var output = new ResultLogJsonWriter(outputJson))
                            {
                                converter.Convert(input, output, OptionallyEmittedData.None);
                            }
                sarifLog = JsonConvert.DeserializeObject <SarifLog>(sb.ToString());
            }
            else
            {
                sarifLog = JsonConvert.DeserializeObject <SarifLog>(File.ReadAllText(options.OutputFilePath));
            }

            return(sarifLog);
        }
Пример #8
0
        public static string GetConverterJson(IToolFileConverter converter, byte[] inputData)
        {
            using (var input = new MemoryStream(inputData))
            {
                using (var output = new StringWriter())
                {
                    var json = new JsonTextWriter(output);
                    json.Formatting  = Newtonsoft.Json.Formatting.Indented;
                    json.CloseOutput = false;
                    using (var outputWriter = new ResultLogJsonWriter(json))
                    {
                        converter.Convert(input, outputWriter);
                    }

                    return(output.ToString());
                }
            }
        }
Пример #9
0
        public static void ProcessLogFile(string filePath, Solution solution, string toolFormat = ToolFormat.None)
        {
            SarifLog log;

            JsonSerializerSettings settings = new JsonSerializerSettings()
            {
                ContractResolver = SarifContractResolver.Instance,
            };

            string logText;

            if (toolFormat.MatchesToolFormat(ToolFormat.None))
            {
                logText = File.ReadAllText(filePath);
            }
            else if (toolFormat.MatchesToolFormat(ToolFormat.PREfast))
            {
                logText = ToolFormatConverter.ConvertPREfastToStandardFormat(filePath);
            }
            else
            {
                // We have conversion to do
                var converter = new ToolFormatConverter();
                var sb        = new StringBuilder();

                using (var input = new MemoryStream(File.ReadAllBytes(filePath)))
                {
                    var outputTextWriter = new StringWriter(sb);
                    var outputJson       = new JsonTextWriter(outputTextWriter);
                    var output           = new ResultLogJsonWriter(outputJson);

                    input.Seek(0, SeekOrigin.Begin);
                    converter.ConvertToStandardFormat(toolFormat, input, output);

                    // This is serving as a flush mechanism
                    output.Dispose();

                    logText = sb.ToString();
                }
            }

            log = JsonConvert.DeserializeObject <SarifLog>(logText, settings);
            ProcessSarifLog(log, filePath, solution);
        }
        public static void ProcessLogFile(string filePath, Solution solution, string toolFormat = ToolFormat.None)
        {
            SarifLog log = null;

            JsonSerializerSettings settingsV2 = new JsonSerializerSettings()
            {
                ContractResolver = SarifContractResolver.Instance,
            };

            string logText;

            if (toolFormat.MatchesToolFormat(ToolFormat.None))
            {
                logText = File.ReadAllText(filePath);
                string pattern = @"""version""\s*:\s*""1.0.0""";
                Match  match   = Regex.Match(logText, pattern, RegexOptions.Compiled | RegexOptions.Multiline);

                if (match.Success)
                {
                    // They're opening a v1 log, so we need to transform it.
                    // Ask if they'd like to save the v2 log.
                    int result = VsShellUtilities.ShowMessageBox(SarifViewerPackage.ServiceProvider,
                                                                 Resources.TransformV1_DialogMessage,
                                                                 null, // title
                                                                 OLEMSGICON.OLEMSGICON_QUERY,
                                                                 OLEMSGBUTTON.OLEMSGBUTTON_YESNOCANCEL,
                                                                 OLEMSGDEFBUTTON.OLEMSGDEFBUTTON_FIRST);
                    MessageDialogCommand response = (MessageDialogCommand)Enum.Parse(typeof(MessageDialogCommand), result.ToString());

                    if (response == MessageDialogCommand.Cancel)
                    {
                        return;
                    }

                    JsonSerializerSettings settingsV1 = new JsonSerializerSettings()
                    {
                        ContractResolver = SarifContractResolverVersionOne.Instance,
                    };

                    SarifLogVersionOne v1Log = JsonConvert.DeserializeObject <SarifLogVersionOne>(logText, settingsV1);
                    var transformer          = new SarifVersionOneToCurrentVisitor();
                    transformer.VisitSarifLogVersionOne(v1Log);
                    log = transformer.SarifLog;

                    if (response == MessageDialogCommand.Yes)
                    {
                        // Prompt for a location to save the transformed log.
                        var saveFileDialog = new SaveFileDialog();

                        saveFileDialog.Title            = Resources.SaveTransformedV1Log_DialogTitle;
                        saveFileDialog.Filter           = "SARIF log files (*.sarif)|*.sarif";
                        saveFileDialog.RestoreDirectory = true;

                        filePath = Path.GetFileNameWithoutExtension(filePath) + ".v2.sarif";
                        saveFileDialog.FileName         = Path.GetFileName(filePath);
                        saveFileDialog.InitialDirectory = Path.GetDirectoryName(filePath);

                        if (saveFileDialog.ShowDialog() != DialogResult.OK)
                        {
                            return;
                        }

                        filePath = saveFileDialog.FileName;
                        string error = null;

                        try
                        {
                            File.WriteAllText(filePath, JsonConvert.SerializeObject(log, settingsV2));
                        }
                        catch (UnauthorizedAccessException)
                        {
                            error = string.Format(Resources.SaveTransformedV1LogFail_Access_DialogMessage, filePath);
                        }
                        catch (SecurityException)
                        {
                            error = string.Format(Resources.SaveTransformedV1LogFail_Access_DialogMessage, filePath);
                        }
                        catch (Exception ex)
                        {
                            error = string.Format(Resources.SaveTransformedV1LogFail_General_Dialog, ex.Message);
                        }

                        if (error != null)
                        {
                            VsShellUtilities.ShowMessageBox(SarifViewerPackage.ServiceProvider,
                                                            error,
                                                            null, // title
                                                            OLEMSGICON.OLEMSGICON_CRITICAL,
                                                            OLEMSGBUTTON.OLEMSGBUTTON_OK,
                                                            OLEMSGDEFBUTTON.OLEMSGDEFBUTTON_FIRST);
                        }
                    }
                }
            }
            else
            {
                // We have conversion to do
                var converter = new ToolFormatConverter();
                var sb        = new StringBuilder();

                using (var input = new MemoryStream(File.ReadAllBytes(filePath)))
                {
                    var outputTextWriter = new StringWriter(sb);
                    var outputJson       = new JsonTextWriter(outputTextWriter);
                    var output           = new ResultLogJsonWriter(outputJson);

                    input.Seek(0, SeekOrigin.Begin);
                    converter.ConvertToStandardFormat(toolFormat, input, output);

                    // This is serving as a flush mechanism
                    output.Dispose();

                    logText = sb.ToString();
                }
            }

            if (log == null)
            {
                log = JsonConvert.DeserializeObject <SarifLog>(logText, settingsV2);
            }

            ProcessSarifLog(log, filePath, solution);

            SarifTableDataSource.Instance.BringToFront();
        }
Пример #11
0
        public static async Task ProcessLogFileCoreAsync(string filePath, string toolFormat, bool promptOnLogConversions, bool cleanErrors, bool openInEditor)
        {
            SarifLog log            = null;
            string   logText        = null;
            string   outputPath     = null;
            bool     saveOutputFile = true;

            if (toolFormat.MatchesToolFormat(ToolFormat.None))
            {
                await RetryInvokeAsync(
                    async() =>
                {
                    using (var logStreamReader = new StreamReader(filePath, Encoding.UTF8))
                    {
                        logText = await logStreamReader.ReadToEndAsync().ConfigureAwait(continueOnCapturedContext: false);
                    }
                },
                    retryInterval : TimeSpan.FromMilliseconds(300),
                    maxAttemptCount : 5);

                Match match = MatchVersionProperty(logText);
                if (match.Success)
                {
                    string inputVersion = match.Groups["version"].Value;

                    if (inputVersion == SarifUtilities.V1_0_0)
                    {
                        // They're opening a v1 log, so we need to transform it.
                        // Ask if they'd like to save the v2 log.
                        MessageDialogCommand response = promptOnLogConversions ?
                                                        await PromptToSaveProcessedLogAsync(Resources.TransformV1_DialogMessage).ConfigureAwait(continueOnCapturedContext: false) :
                                                        MessageDialogCommand.No;

                        if (response == MessageDialogCommand.Cancel)
                        {
                            return;
                        }

                        var settingsV1 = new JsonSerializerSettings()
                        {
                            ContractResolver = SarifContractResolverVersionOne.Instance,
                        };

                        SarifLogVersionOne v1Log = JsonConvert.DeserializeObject <SarifLogVersionOne>(logText, settingsV1);
                        var transformer          = new SarifVersionOneToCurrentVisitor();
                        transformer.VisitSarifLogVersionOne(v1Log);
                        log = transformer.SarifLog;

                        if (response == MessageDialogCommand.Yes)
                        {
                            // Prompt for a location to save the transformed log.
                            outputPath = await PromptForFileSaveLocationAsync(Resources.SaveTransformedV1Log_DialogTitle, filePath).ConfigureAwait(continueOnCapturedContext: false);

                            if (string.IsNullOrEmpty(outputPath))
                            {
                                return;
                            }
                        }

                        logText = JsonConvert.SerializeObject(log);
                    }
                    else if (inputVersion != VersionConstants.StableSarifVersion)
                    {
                        // It's an older v2 version, so send it through the pre-release compat transformer.
                        // Ask if they'd like to save the transformed log.
                        MessageDialogCommand response = promptOnLogConversions ?
                                                        await PromptToSaveProcessedLogAsync(string.Format(Resources.TransformPrereleaseV2_DialogMessage, VersionConstants.StableSarifVersion)).ConfigureAwait(continueOnCapturedContext: false) :
                                                        MessageDialogCommand.No;

                        if (response == MessageDialogCommand.Cancel)
                        {
                            return;
                        }

                        log = PrereleaseCompatibilityTransformer.UpdateToCurrentVersion(logText, Formatting.Indented, out logText);

                        if (response == MessageDialogCommand.Yes)
                        {
                            // Prompt for a location to save the transformed log.
                            outputPath = await PromptForFileSaveLocationAsync(Resources.SaveTransformedPrereleaseV2Log_DialogTitle, filePath).ConfigureAwait(continueOnCapturedContext: false);

                            if (string.IsNullOrEmpty(outputPath))
                            {
                                return;
                            }
                        }
                    }
                    else
                    {
                        // Since we didn't do any pre-processing, we don't need to write to a temp location.
                        outputPath     = filePath;
                        saveOutputFile = false;
                    }
                }
                else
                {
                    await ThreadHelper.JoinableTaskFactory.SwitchToMainThreadAsync();

                    // The version property wasn't found within the first 100 characters.
                    // Per the spec, it should appear first in the sarifLog object.
                    VsShellUtilities.ShowMessageBox(ServiceProvider.GlobalProvider,
                                                    Resources.VersionPropertyNotFound_DialogTitle,
                                                    null, // title
                                                    OLEMSGICON.OLEMSGICON_QUERY,
                                                    OLEMSGBUTTON.OLEMSGBUTTON_OK,
                                                    OLEMSGDEFBUTTON.OLEMSGDEFBUTTON_FIRST);
                    return;
                }
            }
            else
            {
                // They're opening a non-SARIF log, so we need to convert it.
                // Ask if they'd like to save the converted log.
                MessageDialogCommand response = promptOnLogConversions ?
                                                await PromptToSaveProcessedLogAsync(Resources.ConvertNonSarifLog_DialogMessage).ConfigureAwait(continueOnCapturedContext: false) :
                                                MessageDialogCommand.No;

                if (response == MessageDialogCommand.Cancel)
                {
                    return;
                }

                // The converter doesn't have async methods, so spin
                // up a task to do this.
                await System.Threading.Tasks.Task.Run(() =>
                {
                    var sb = new StringBuilder();
                    using (FileStream fileStream = File.OpenRead(filePath))
                    {
                        using (var outputTextWriter = new StringWriter(sb))
                            using (var outputJson = new JsonTextWriter(outputTextWriter))
                                using (var output = new ResultLogJsonWriter(outputJson))
                                {
                                    var converter = new ToolFormatConverter();
                                    converter.ConvertToStandardFormat(toolFormat, fileStream, output);
                                }

                        logText = sb.ToString();

                        if (response == MessageDialogCommand.Yes)
                        {
                            // Prompt for a location to save the converted log.
                            outputPath = PromptForFileSaveLocationAsync(Resources.SaveConvertedLog_DialogTitle, filePath).Result;
                        }
                    }
                }).ConfigureAwait(continueOnCapturedContext: false);
            }

            if (string.IsNullOrEmpty(outputPath))
            {
                outputPath = Path.GetTempFileName() + ".sarif";
            }

            if (saveOutputFile)
            {
                await SaveLogFileAsync(outputPath, logText).ConfigureAwait(continueOnCapturedContext: false);
            }

            if (log == null)
            {
                log = JsonConvert.DeserializeObject <SarifLog>(logText);
            }

            await ProcessSarifLogAsync(log, outputPath, cleanErrors : cleanErrors, openInEditor : openInEditor).ConfigureAwait(continueOnCapturedContext: false);
        }