Example #1
0
        public void Log(ReportingDescriptor rule, Result result)
        {
            if (!cacheLoggingData)
            {
                return;
            }

            switch (result.Level)
            {
            // These result types are optionally emitted.
            case FailureLevel.None:
            case FailureLevel.Note:
            {
                if (Verbose)
                {
                    CacheResult(rule, result);
                }
                break;
            }

            // These result types are always emitted.
            case FailureLevel.Error:
            case FailureLevel.Warning:
            {
                CacheResult(rule, result);
                break;
            }

            default:
            {
                throw new InvalidOperationException();
            }
            }
        }
        public void SarifExtensions_Result_GetMessageText_Concise_Truncated()
        {
            var result = new Result
            {
                Message = new Message
                {
                    Id = "ruleStr1"
                }
            };

            var rule = new ReportingDescriptor
            {
                MessageStrings = new Dictionary <string, MultiformatMessageString>
                {
                    ["ruleStr1"] = new MultiformatMessageString {
                        Text = "First sentence is very long. Second sentence."
                    }
                }
            };

            const string Expected  = "First sentence is ve\u2026"; // \u2026 is Unicode "horizontal ellipsis".
            int          maxLength = Expected.Length - 1;          // The -1 is for the ellipsis character.
            string       actual    = result.GetMessageText(rule, concise: true, maxLength);

            Assert.Equal(Expected, actual);
        }
Example #3
0
        public static string FormatForVisualStudio(this Result result, ReportingDescriptor rule)
        {
            if (result == null)
            {
                throw new ArgumentNullException(nameof(result));
            }

            if (rule == null)
            {
                throw new ArgumentNullException(nameof(rule));
            }

            var messageLines = new List <string>();

            foreach (var location in result.Locations)
            {
                Uri    uri  = location.PhysicalLocation.ArtifactLocation.Uri;
                string path = uri.IsAbsoluteUri && uri.IsFile ? uri.LocalPath : uri.ToString();
                messageLines.Add(
                    string.Format(
                        CultureInfo.InvariantCulture, "{0}{1}: {2} {3}: {4}",
                        path,
                        location.PhysicalLocation.Region.FormatForVisualStudio(),
                        result.Level.FormatForVisualStudio(),
                        result.RuleId,
                        result.GetMessageText(rule)
                        ));
            }

            return(string.Join(Environment.NewLine, messageLines));
        }
        public void SarifExtensions_Result_GetMessageText_Concise()
        {
            var result = new Result()
            {
                Message = new Message()
                {
                    Arguments = new List <string> {
                        "fox", "dog"
                    },
                    MessageId = "ruleStr1"
                }
            };

            var rule = new ReportingDescriptor()
            {
                MessageStrings = new Dictionary <string, MultiformatMessageString>()
                {
                    ["ruleStr1"] = new MultiformatMessageString {
                        Text = "The quick brown {0} jumps over the lazy {1}. That {1} sure is lazy!"
                    }
                }
            };

            string expected = "The quick brown fox jumps over the lazy dog.";
            string actual   = result.GetMessageText(rule, concise: true);

            Assert.Equal(expected, actual);
        }
        public virtual ReportingDescriptor VisitReportingDescriptor(ReportingDescriptor node)
        {
            if (node != null)
            {
                node.Name             = VisitNullChecked(node.Name);
                node.ShortDescription = VisitNullChecked(node.ShortDescription);
                node.FullDescription  = VisitNullChecked(node.FullDescription);
                if (node.MessageStrings != null)
                {
                    var keys = node.MessageStrings.Keys.ToArray();
                    foreach (var key in keys)
                    {
                        var value = node.MessageStrings[key];
                        if (value != null)
                        {
                            node.MessageStrings[key] = VisitNullChecked(value);
                        }
                    }
                }

                node.DefaultConfiguration = VisitNullChecked(node.DefaultConfiguration);
                node.Help = VisitNullChecked(node.Help);
            }

            return(node);
        }
Example #6
0
        private void LogSimpleResult(SarifLogger sarifLogger)
        {
            ReportingDescriptor rule = new ReportingDescriptor {
                Id = "RuleId"
            };

            sarifLogger.Log(rule, CreateSimpleResult(rule));
        }
Example #7
0
 private void CacheResult(ReportingDescriptor rule, Result result)
 {
     if (!HashToResultsMap.TryGetValue(currentFileHash, out List <Tuple <ReportingDescriptor, Result> > results))
     {
         results = HashToResultsMap[currentFileHash] = new List <Tuple <ReportingDescriptor, Result> >();
     }
     results.Add(new Tuple <ReportingDescriptor, Result>(rule, result));
 }
Example #8
0
        /// <summary>
        ///  Look up the ReportingDescriptor for this Result.
        /// </summary>
        /// <param name="run">Run instance containing this Result</param>
        /// <returns>ReportingDescriptor for Result Rule, if available</returns>
        public ReportingDescriptor GetRule(Run run = null)
        {
            // Follows SARIF Spec 3.52.3 (reportingDescriptor lookup)

            // Ensure run argument or Result.Run was set
            if (run == null)
            {
                EnsureRunProvided();
                run = this.Run;
            }

            if (run != null)
            {
                // Find the 'ToolComponent' for this Result (Run.Tool.Driver if absent)
                ToolComponent component           = run.GetToolComponentFromReference(this.Rule?.ToolComponent);
                IList <ReportingDescriptor> rules = component?.Rules;

                // Look up by this.RuleIndex, if present
                if (this.RuleIndex >= 0)
                {
                    return(GetRuleByIndex(rules, this.RuleIndex));
                }

                // Look up by this.Rule.Index, if present
                if (this.Rule?.Index >= 0)
                {
                    return(GetRuleByIndex(rules, this.Rule.Index));
                }

                // Look up by this.Rule.Guid, if present
                if (!string.IsNullOrEmpty(this.Rule?.Guid) && rules != null)
                {
                    ReportingDescriptor rule = component.GetRuleByGuid(this.Rule.Guid);
                    if (rule != null)
                    {
                        return(rule);
                    }
                }

                // Look up by this.RuleId or this.Rule.Id, if present
                string ruleId = this.RuleId ?? this.Rule?.Id;
                if (ruleId != null && rules != null)
                {
                    ReportingDescriptor rule = component.GetRuleById(ruleId);
                    if (rule != null)
                    {
                        return(rule);
                    }
                }
            }

            // Otherwise, metadata is not available and RuleId is the only available property
            return(new ReportingDescriptor()
            {
                Id = this.RuleId ?? this.Rule?.Id
            });
        }
Example #9
0
        /// <summary>
        /// Initializes a new instance of the <see cref="ReportingDescriptor" /> class from the specified instance.
        /// </summary>
        /// <param name="other">
        /// The instance from which the new instance is to be initialized.
        /// </param>
        /// <exception cref="ArgumentNullException">
        /// Thrown if <paramref name="other" /> is null.
        /// </exception>
        public ReportingDescriptor(ReportingDescriptor other)
        {
            if (other == null)
            {
                throw new ArgumentNullException(nameof(other));
            }

            Init(other.Id, other.Guid, other.Name, other.DeprecatedIds, other.ShortDescription, other.FullDescription, other.MessageStrings, other.DefaultConfiguration, other.HelpUri, other.Help, other.TaxonomyReferences, other.OptionalTaxonomyReferences, other.Properties);
        }
Example #10
0
 private Result CreateSimpleResult(ReportingDescriptor rule)
 {
     return(new Result
     {
         RuleId = rule.Id,
         Message = new Message {
             Text = "Some testing occurred."
         }
     });
 }
Example #11
0
        public ReportingDescriptor GetRuleByGuid(string ruleGuid)
        {
            ReportingDescriptor rule = null;

            // Build lookup if not built or possibly out-of-date
            if (_cachedRulesByGuid?.TryGetValue(ruleGuid, out rule) != true)
            {
                BuildRuleCaches();
                _cachedRulesByGuid.TryGetValue(ruleGuid, out rule);
            }

            return(rule);
        }
Example #12
0
        public ReportingDescriptor GetRuleById(string ruleId)
        {
            ReportingDescriptor rule = null;

            // Build lookup if not built or possibly out-of-date
            if (_cachedRulesById == null || !_cachedRulesById.TryGetValue(ruleId, out rule))
            {
                BuildRuleCaches();
                _cachedRulesById.TryGetValue(ruleId, out rule);
            }

            return(rule);
        }
Example #13
0
        public static string GetMessageText(this Result result, ReportingDescriptor rule, bool concise = false)
        {
            if (result == null)
            {
                throw new ArgumentNullException(nameof(result));
            }

            string text = result.Message?.Text;

            if (string.IsNullOrEmpty(text))
            {
                text = string.Empty;    // Ensure that it's not null.

                if (rule != null)
                {
                    string messageId = result.Message?.MessageId;
                    MultiformatMessageString formatString = null;

                    if (!string.IsNullOrWhiteSpace(messageId) &&
                        rule.MessageStrings?.TryGetValue(messageId, out formatString) == true)
                    {
                        string[] arguments = null;

                        if (result.Message?.Arguments != null)
                        {
                            arguments = new string[result.Message.Arguments.Count];
                            result.Message.Arguments.CopyTo(arguments, 0);
                        }
                        else
                        {
                            arguments = new string[0];
                        }

                        text = GetFormattedMessage(formatString.Text, arguments);
                    }
                }
            }

            if (concise)
            {
                text = GetFirstSentence(text);
            }

            return(text);
        }
Example #14
0
        public void SarifLogger_AcceptsSubrulesInResultRuleId()
        {
            var sb = new StringBuilder();

            using (var textWriter = new StringWriter(sb))
            {
                using (var sarifLogger = new SarifLogger(textWriter))
                {
                    var rule = new ReportingDescriptor {
                        Id = "RuleId"
                    };
                    var result = new Result {
                        RuleId = "RuleId/1"
                    };

                    Action action = () => sarifLogger.Log(rule, result);
                    action.Should().NotThrow();
                }
            }
        }
Example #15
0
        public void Log(ReportingDescriptor rule, Result result)
        {
            if (result == null)
            {
                throw new ArgumentNullException(nameof(result));
            }

            string message = result.GetMessageText(rule);

            // TODO we need better retrieval for locations than these defaults
            // Note that we can potentially emit many messages from a single result
            PhysicalLocation physicalLocation = result.Locations?.First().PhysicalLocation;

            WriteToConsole(
                result.Kind,
                result.Level,
                physicalLocation?.ArtifactLocation?.Uri,
                physicalLocation?.Region,
                result.RuleId,
                message);
        }
Example #16
0
        public virtual ReportingDescriptor VisitReportingDescriptor(ReportingDescriptor node)
        {
            if (node != null)
            {
                node.ShortDescription = VisitNullChecked(node.ShortDescription);
                node.FullDescription  = VisitNullChecked(node.FullDescription);
                if (node.MessageStrings != null)
                {
                    var keys = node.MessageStrings.Keys.ToArray();
                    foreach (var key in keys)
                    {
                        var value = node.MessageStrings[key];
                        if (value != null)
                        {
                            node.MessageStrings[key] = VisitNullChecked(value);
                        }
                    }
                }

                node.DefaultConfiguration = VisitNullChecked(node.DefaultConfiguration);
                node.Help = VisitNullChecked(node.Help);
                if (node.TaxonomyReferences != null)
                {
                    for (int index_0 = 0; index_0 < node.TaxonomyReferences.Count; ++index_0)
                    {
                        node.TaxonomyReferences[index_0] = VisitNullChecked(node.TaxonomyReferences[index_0]);
                    }
                }

                if (node.OptionalTaxonomyReferences != null)
                {
                    for (int index_0 = 0; index_0 < node.OptionalTaxonomyReferences.Count; ++index_0)
                    {
                        node.OptionalTaxonomyReferences[index_0] = VisitNullChecked(node.OptionalTaxonomyReferences[index_0]);
                    }
                }
            }

            return(node);
        }
Example #17
0
        public void SarifLogger_ResultAndRuleIdMismatch()
        {
            var sb = new StringBuilder();

            using (var writer = new StringWriter(sb))
                using (var sarifLogger = new SarifLogger(writer, LoggingOptions.Verbose))
                {
                    var rule = new ReportingDescriptor
                    {
                        Id = "ActualId"
                    };

                    var result = new Result
                    {
                        RuleId  = "IncorrectRuleId",
                        Message = new Message {
                            Text = "test message"
                        }
                    };

                    Assert.Throws <ArgumentException>(() => sarifLogger.Log(rule, result));
                }
        }
Example #18
0
 public static string GetMessageText(this Result result, ReportingDescriptor rule)
 {
     return(GetMessageText(result, rule, concise: false));
 }
Example #19
0
 public bool ValueEquals(ReportingDescriptor other) => ValueComparer.Equals(this, other);
Example #20
0
 public void Log(ReportingDescriptor rule, Result result)
 {
     NoteTestResult(result.Kind, result.Locations.First().PhysicalLocation.ArtifactLocation.Uri.LocalPath);
 }
Example #21
0
        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,
                           invocationTokensToRedact: null,
                           invocationPropertiesToLog: null))
                {
                    var toolNotification = new Notification
                    {
                        Locations = new List <Location>
                        {
                            new Location
                            {
                                PhysicalLocation = new PhysicalLocation {
                                    ArtifactLocation = new ArtifactLocation {
                                        Uri = new Uri(@"file:///file.cpp")
                                    }
                                }
                            }
                        },
                        Message = new Message {
                            Text = "A notification was raised."
                        }
                    };
                    sarifLogger.LogToolNotification(toolNotification);

                    var configurationNotification = new Notification
                    {
                        Locations = new List <Location>
                        {
                            new Location
                            {
                                PhysicalLocation = new PhysicalLocation {
                                    ArtifactLocation = new ArtifactLocation {
                                        Uri = new Uri(@"file:///file.cpp")
                                    }
                                }
                            }
                        },
                        Message = new Message {
                            Text = "A notification was raised."
                        }
                    };
                    sarifLogger.LogConfigurationNotification(configurationNotification);

                    string ruleId = "RuleId";
                    var    rule   = new ReportingDescriptor {
                        Id = ruleId
                    };

                    var result = new Result
                    {
                        RuleId  = ruleId,
                        Message = new Message {
                            Text = "Some testing occurred."
                        }
                    };

                    sarifLogger.Log(rule, result);
                }
            }

            string logText  = sb.ToString();
            var    sarifLog = JsonConvert.DeserializeObject <SarifLog>(logText);

            sarifLog.Runs[0].Artifacts.Should().BeNull();
        }
Example #22
0
        public void SarifLogger_ScrapesFilesFromResult()
        {
            var sb = new StringBuilder();

            using (var textWriter = new StringWriter(sb))
            {
                using (var sarifLogger = new SarifLogger(
                           textWriter,
                           analysisTargets: null,
                           dataToInsert: OptionallyEmittedData.Hashes,
                           invocationTokensToRedact: null,
                           invocationPropertiesToLog: null))
                {
                    string ruleId = "RuleId";
                    var    rule   = new ReportingDescriptor {
                        Id = ruleId
                    };

                    var result = new Result
                    {
                        RuleId  = ruleId,
                        Message = new Message {
                            Text = "Some testing occurred."
                        },
                        AnalysisTarget = new ArtifactLocation {
                            Uri = new Uri(@"file:///file0.cpp")
                        },
                        Locations = new[]
                        {
                            new Location
                            {
                                PhysicalLocation = new PhysicalLocation
                                {
                                    ArtifactLocation = new ArtifactLocation
                                    {
                                        Uri = new Uri(@"file:///file1.cpp")
                                    }
                                }
                            },
                        },
                        Fixes = new[]
                        {
                            new Fix
                            {
                                ArtifactChanges = new[]
                                {
                                    new ArtifactChange
                                    {
                                        ArtifactLocation = new ArtifactLocation
                                        {
                                            Uri = new Uri(@"file:///file2.cpp")
                                        },
                                        Replacements = new[]
                                        {
                                            new Replacement {
                                                DeletedRegion = new Region {
                                                    StartLine = 1
                                                }
                                            }
                                        }
                                    }
                                },
                            }
                        },
                        RelatedLocations = new[]
                        {
                            new Location
                            {
                                PhysicalLocation = new PhysicalLocation
                                {
                                    ArtifactLocation = new ArtifactLocation
                                    {
                                        Uri = new Uri(@"file:///file3.cpp")
                                    }
                                }
                            }
                        },
                        Stacks = new[]
                        {
                            new Stack
                            {
                                Frames = new[]
                                {
                                    new StackFrame
                                    {
                                        Location = new Location
                                        {
                                            PhysicalLocation = new PhysicalLocation
                                            {
                                                ArtifactLocation = new ArtifactLocation
                                                {
                                                    Uri = new Uri(@"file:///file4.cpp")
                                                }
                                            }
                                        }
                                    }
                                }
                            }
                        },
                        CodeFlows = new[]
                        {
                            new CodeFlow
                            {
                                ThreadFlows = new[]
                                {
                                    new ThreadFlow
                                    {
                                        Locations = new[]
                                        {
                                            new ThreadFlowLocation
                                            {
                                                Location = new Location
                                                {
                                                    PhysicalLocation = new PhysicalLocation
                                                    {
                                                        ArtifactLocation = new ArtifactLocation
                                                        {
                                                            Uri = new Uri(@"file:///file5.cpp")
                                                        }
                                                    }
                                                }
                                            }
                                        }
                                    }
                                }
                            }
                        }
                    };

                    sarifLogger.Log(rule, result);
                }
            }

            string logText  = sb.ToString();
            var    sarifLog = JsonConvert.DeserializeObject <SarifLog>(logText);

            int fileCount = 6;

            for (int i = 0; i < fileCount; ++i)
            {
                string fileName    = @"file" + i + ".cpp";
                string fileDataKey = "file:///" + fileName;
                sarifLog.Runs[0].Artifacts.Where(f => f.Location.Uri.AbsoluteUri.ToString().Contains(fileDataKey)).Any().Should().BeTrue();
            }

            sarifLog.Runs[0].Artifacts.Count.Should().Be(fileCount);
        }
Example #23
0
 public override ReportingDescriptor VisitReportingDescriptor(ReportingDescriptor node)
 {
     node.DeprecatedGuids[0] = "36D2C336-7730-425A-9A94-43593A2A651C";
     return(base.VisitReportingDescriptor(node));
 }
Example #24
0
        public void SarifLogger_WritesFileContentsForAnalysisTargets()
        {
            var sb = new StringBuilder();

            // Create a temporary file whose extension signals that it is textual.
            // This ensures that the ArtifactContents.Text property, rather than
            // the Binary property, is populated, so the test of the Text property
            // at the end will work.
            using (var tempFile = new TempFile(".txt"))
            {
                string tempFilePath      = tempFile.Name;
                string tempFileDirectory = Path.GetDirectoryName(tempFilePath);
                string tempFileName      = Path.GetFileName(tempFilePath);

                File.WriteAllText(tempFilePath, "#include \"windows.h\";");

                var run = new Run
                {
                    OriginalUriBaseIds = new Dictionary <string, ArtifactLocation>
                    {
                        [TempFileBaseId] = new ArtifactLocation
                        {
                            Uri = new Uri(tempFileDirectory, UriKind.Absolute)
                        }
                    },

                    // To get text contents, we also need to specify an encoding that
                    // Encoding.GetEncoding() will accept.
                    DefaultEncoding = "UTF-8"
                };

                var rule = new ReportingDescriptor
                {
                    Id = TestData.TestRuleId
                };

                // Create a result that refers to an artifact whose location is specified
                // by a relative reference together with a uriBaseId.
                var result = new Result
                {
                    RuleId  = rule.Id,
                    Message = new Message {
                        Text = "Testing."
                    },
                    Locations = new List <Location>
                    {
                        new Location
                        {
                            PhysicalLocation = new PhysicalLocation
                            {
                                ArtifactLocation = new ArtifactLocation
                                {
                                    Uri       = new Uri(tempFileName, UriKind.Relative),
                                    UriBaseId = TempFileBaseId
                                }
                            }
                        }
                    }
                };

                using (var textWriter = new StringWriter(sb))
                {
                    // Create a logger that inserts artifact contents.
                    using (var sarifLogger = new SarifLogger(
                               textWriter,
                               run: run,
                               dataToInsert: OptionallyEmittedData.TextFiles))
                    {
                        sarifLogger.Log(rule, result);
                    }

                    // The logger should have populated the artifact contents.
                    string   logText  = sb.ToString();
                    SarifLog sarifLog = JsonConvert.DeserializeObject <SarifLog>(logText);

                    sarifLog.Runs[0].Artifacts[0].Contents?.Text.Should().NotBeNullOrEmpty();
                }
            }
        }