internal FileDataVersionOne CreateFileData(FileData v2FileData) { FileDataVersionOne fileData = null; if (v2FileData != null) { fileData = new FileDataVersionOne { Hashes = v2FileData.Hashes?.Select(CreateHash).ToList(), Length = v2FileData.Length, MimeType = v2FileData.MimeType, Offset = v2FileData.Offset, ParentKey = v2FileData.ParentKey, Properties = v2FileData.Properties, Uri = v2FileData.FileLocation?.Uri, UriBaseId = v2FileData.FileLocation?.UriBaseId }; if (v2FileData.Contents != null) { fileData.Contents = MimeType.IsTextualMimeType(v2FileData.MimeType) ? SarifUtilities.GetUtf8Base64String(v2FileData.Contents.Text) : v2FileData.Contents.Binary; } } return(fileData); }
private void ParseVulnerability() { var result = new Result { Locations = new List <Location>(), RelatedLocations = new List <Location>(), CodeFlows = new [] { SarifUtilities.CreateSingleThreadedCodeFlow() } }; _reader.Read(); while (!AtEndOf(_strings.Vulnerability)) { if (AtStartOfNonEmpty(_strings.ClassId)) { result.RuleId = _reader.ReadElementContentAsString(); } else if (AtStartOfNonEmpty(_strings.ReplacementDefinitions)) { ParseReplacementDefinitions(result); } else if (AtStartOfNonEmpty(_strings.Trace)) { ParseLocationFromTrace(result); } _reader.Read(); } _results.Add(result); }
internal ReplacementVersionOne CreateReplacementVersionOne(Replacement v2Replacement, Encoding encoding) { ReplacementVersionOne replacement = null; if (v2Replacement != null) { replacement = new ReplacementVersionOne(); ArtifactContent insertedContent = v2Replacement.InsertedContent; if (insertedContent != null) { if (insertedContent.Binary != null) { replacement.InsertedBytes = insertedContent.Binary; } else if (insertedContent.Text != null) { if (encoding != null) { replacement.InsertedBytes = SarifUtilities.GetBase64String(insertedContent.Text, encoding); } else { // The encoding is null or not supported on the current platform throw new UnknownEncodingException(); } } } replacement.DeletedLength = v2Replacement.DeletedRegion.ByteLength; replacement.Offset = v2Replacement.DeletedRegion.ByteOffset; } return(replacement); }
public void CanConvertCodeFlowToTreeOnlyDeclarations() { var codeFlow = SarifUtilities.CreateSingleThreadedCodeFlow(new[] { new ThreadFlowLocation { NestingLevel = 0, // Declaration }, new ThreadFlowLocation { NestingLevel = 0, // Declaration }, new ThreadFlowLocation { NestingLevel = 0, // Declaration }, }); List <CallTreeNode> topLevelNodes = CodeFlowToTreeConverter.Convert(codeFlow, run: null); topLevelNodes.Count.Should().Be(3); topLevelNodes[0].Children.Should().BeEmpty(); topLevelNodes[1].Children.Should().BeEmpty(); topLevelNodes[2].Children.Should().BeEmpty(); topLevelNodes[1].Location.NestingLevel.Should().Be(0); // Declaration topLevelNodes[0].Location.NestingLevel.Should().Be(0); // Declaration topLevelNodes[2].Location.NestingLevel.Should().Be(0); // Declaration topLevelNodes[0].Parent.Should().Be(null); topLevelNodes[1].Parent.Should().Be(null); topLevelNodes[2].Parent.Should().Be(null); }
private FileDataVersionOne CreateFileDataVersionOne(Artifact v2FileData) { FileDataVersionOne fileData = null; if (v2FileData != null) { int parentIndex = v2FileData.ParentIndex; string parentKey = parentIndex == -1 ? null : _v2FileIndexToV1KeyMap?[parentIndex]; fileData = new FileDataVersionOne { Hashes = CreateHashVersionOneListFromV2Hashes(v2FileData.Hashes), Length = v2FileData.Length, MimeType = v2FileData.MimeType, Offset = v2FileData.Offset, ParentKey = parentKey, Properties = v2FileData.Properties, Uri = v2FileData.Location?.Uri, UriBaseId = v2FileData.Location?.UriBaseId }; if (v2FileData.Contents != null) { fileData.Contents = MimeType.IsTextualMimeType(v2FileData.MimeType) ? SarifUtilities.GetUtf8Base64String(v2FileData.Contents.Text) : v2FileData.Contents.Binary; } } return(fileData); }
public void SelectPreviousNextCommandsTest() { var codeFlow = SarifUtilities.CreateSingleThreadedCodeFlow(new[] { new ThreadFlowLocation { NestingLevel = 0 }, new ThreadFlowLocation { NestingLevel = 1 }, new ThreadFlowLocation { NestingLevel = 1 }, new ThreadFlowLocation { NestingLevel = 1 }, new ThreadFlowLocation { NestingLevel = 0 }, new ThreadFlowLocation { NestingLevel = 0 } }); var mockToolWindow = new Mock <IToolWindow>(); mockToolWindow.Setup(s => s.UpdateSelectionList(It.IsAny <object[]>())); CallTree callTree = new CallTree(CodeFlowToTreeConverter.Convert(codeFlow, run: null), mockToolWindow.Object); callTree.FindPrevious().Should().Be(null); callTree.FindNext().Should().Be(null); callTree.SelectedItem = callTree.TopLevelNodes[0]; callTree.FindPrevious().Should().Be(callTree.TopLevelNodes[0]); callTree.FindNext().Should().Be(callTree.TopLevelNodes[0].Children[0]); callTree.SelectedItem = callTree.TopLevelNodes[0].Children[0]; callTree.FindPrevious().Should().Be(callTree.TopLevelNodes[0]); callTree.FindNext().Should().Be(callTree.TopLevelNodes[0].Children[1]); callTree.SelectedItem = callTree.TopLevelNodes[0].Children[2]; callTree.FindPrevious().Should().Be(callTree.TopLevelNodes[0].Children[1]); callTree.FindNext().Should().Be(callTree.TopLevelNodes[1]); callTree.SelectedItem = callTree.TopLevelNodes[1]; callTree.FindPrevious().Should().Be(callTree.TopLevelNodes[0].Children[2]); callTree.FindNext().Should().Be(callTree.TopLevelNodes[2]); callTree.SelectedItem = callTree.TopLevelNodes[2]; callTree.FindPrevious().Should().Be(callTree.TopLevelNodes[1]); callTree.FindNext().Should().Be(callTree.TopLevelNodes[2]); }
public void SelectPreviousNextCommandsTest() { CodeFlow codeFlow = SarifUtilities.CreateSingleThreadedCodeFlow(new[] { new ThreadFlowLocation { NestingLevel = 0, }, new ThreadFlowLocation { NestingLevel = 1, }, new ThreadFlowLocation { NestingLevel = 1, }, new ThreadFlowLocation { NestingLevel = 1, }, new ThreadFlowLocation { NestingLevel = 0, }, new ThreadFlowLocation { NestingLevel = 0, }, }); var analysisStep = new AnalysisStep(CodeFlowToTreeConverter.Convert(codeFlow, run: null, resultId: 0, runIndex: 0)); analysisStep.FindPrevious().Should().Be(null); analysisStep.FindNext().Should().Be(null); analysisStep.SelectedItem = analysisStep.TopLevelNodes[0]; analysisStep.FindPrevious().Should().Be(analysisStep.TopLevelNodes[0]); analysisStep.FindNext().Should().Be(analysisStep.TopLevelNodes[0].Children[0]); analysisStep.SelectedItem = analysisStep.TopLevelNodes[0].Children[0]; analysisStep.FindPrevious().Should().Be(analysisStep.TopLevelNodes[0]); analysisStep.FindNext().Should().Be(analysisStep.TopLevelNodes[0].Children[1]); analysisStep.SelectedItem = analysisStep.TopLevelNodes[0].Children[2]; analysisStep.FindPrevious().Should().Be(analysisStep.TopLevelNodes[0].Children[1]); analysisStep.FindNext().Should().Be(analysisStep.TopLevelNodes[1]); analysisStep.SelectedItem = analysisStep.TopLevelNodes[1]; analysisStep.FindPrevious().Should().Be(analysisStep.TopLevelNodes[0].Children[2]); analysisStep.FindNext().Should().Be(analysisStep.TopLevelNodes[2]); analysisStep.SelectedItem = analysisStep.TopLevelNodes[2]; analysisStep.FindPrevious().Should().Be(analysisStep.TopLevelNodes[1]); analysisStep.FindNext().Should().Be(analysisStep.TopLevelNodes[2]); }
internal Artifact CreateFileData(FileDataVersionOne v1FileData, string key) { if (key == null) { throw new ArgumentNullException(nameof(key)); } Artifact fileData = null; if (v1FileData != null) { string parentKey = v1FileData.ParentKey; int parentIndex = parentKey == null ? -1 : _v1FileKeytoV2IndexMap[parentKey]; fileData = new Artifact { Hashes = v1FileData.Hashes?.Select(CreateHash).ToDictionary(p => p.Key, p => p.Value), Length = v1FileData.Length, MimeType = v1FileData.MimeType, Offset = v1FileData.Offset, ParentIndex = parentIndex, Properties = v1FileData.Properties }; fileData.Location = ArtifactLocation.CreateFromFilesDictionaryKey(key, parentKey); fileData.Location.UriBaseId = v1FileData.UriBaseId; if (v1FileData.Contents != null) { fileData.Contents = new ArtifactContent(); if (MimeType.IsTextualMimeType(v1FileData.MimeType)) { fileData.Contents.Text = SarifUtilities.DecodeBase64String(v1FileData.Contents); } else { fileData.Contents.Binary = v1FileData.Contents; } } } return(fileData); }
private static void AddLocationToResult(IEnumerable <CppCheckLocation> cppCheckLocations, Result result) { PhysicalLocation lastLocationConverted; var locations = new List <ThreadFlowLocation> { Capacity = cppCheckLocations.Count() }; if (locations.Capacity == 0) { return; } foreach (CppCheckLocation loc in cppCheckLocations) { locations.Add(new ThreadFlowLocation { Location = new Location { PhysicalLocation = loc.ToSarifPhysicalLocation() }, Importance = ThreadFlowLocationImportance.Essential }); } // A codeflow doesn't make sense if you only have the result location, and nothing leading up to it. if (locations.Capacity > 1) { result.CodeFlows = new List <CodeFlow>() { SarifUtilities.CreateSingleThreadedCodeFlow(locations) }; } // Set the result's location to the last location in the code flow. lastLocationConverted = locations[locations.Count - 1].Location.PhysicalLocation; result.Locations = new List <Location> { new Location { PhysicalLocation = lastLocationConverted } }; }
private CallTree CreateCallTree() { var codeFlow = SarifUtilities.CreateSingleThreadedCodeFlow(new[] { new ThreadFlowLocation { NestingLevel = 0, Importance = ThreadFlowLocationImportance.Unimportant, }, new ThreadFlowLocation { NestingLevel = 1, Importance = ThreadFlowLocationImportance.Important, }, new ThreadFlowLocation { NestingLevel = 1, Importance = ThreadFlowLocationImportance.Essential, }, new ThreadFlowLocation { NestingLevel = 1, Importance = ThreadFlowLocationImportance.Unimportant, }, new ThreadFlowLocation { NestingLevel = 0, Importance = ThreadFlowLocationImportance.Unimportant, }, new ThreadFlowLocation { NestingLevel = 0, Importance = ThreadFlowLocationImportance.Essential, } }); var mockToolWindow = new Mock <IToolWindow>(); mockToolWindow.Setup(s => s.UpdateSelectionList(It.IsAny <object[]>())); CallTree callTree = new CallTree(CodeFlowToTreeConverter.Convert(codeFlow, run: null), mockToolWindow.Object); return(callTree); }
internal FileData CreateFileData(FileDataVersionOne v1FileData) { FileData fileData = null; if (v1FileData != null) { fileData = new FileData { Hashes = v1FileData.Hashes?.Select(CreateHash).ToList(), Length = v1FileData.Length, MimeType = v1FileData.MimeType, Offset = v1FileData.Offset, ParentKey = v1FileData.ParentKey, Properties = v1FileData.Properties }; if (v1FileData.Uri != null) { fileData.FileLocation = new FileLocation { Uri = v1FileData.Uri, UriBaseId = v1FileData.UriBaseId }; } if (v1FileData.Contents != null) { fileData.Contents = new FileContent(); if (MimeType.IsTextualMimeType(v1FileData.MimeType)) { fileData.Contents.Text = SarifUtilities.DecodeBase64String(v1FileData.Contents); } else { fileData.Contents.Binary = v1FileData.Contents; } } } return(fileData); }
private AnalysisStep CreateAnalysisStep() { CodeFlow codeFlow = SarifUtilities.CreateSingleThreadedCodeFlow(new[] { new ThreadFlowLocation { NestingLevel = 0, Importance = ThreadFlowLocationImportance.Unimportant, }, new ThreadFlowLocation { NestingLevel = 1, Importance = ThreadFlowLocationImportance.Important, }, new ThreadFlowLocation { NestingLevel = 1, Importance = ThreadFlowLocationImportance.Essential, }, new ThreadFlowLocation { NestingLevel = 1, Importance = ThreadFlowLocationImportance.Unimportant, }, new ThreadFlowLocation { NestingLevel = 0, Importance = ThreadFlowLocationImportance.Unimportant, }, new ThreadFlowLocation { NestingLevel = 0, Importance = ThreadFlowLocationImportance.Essential, }, }); var analysisStep = new AnalysisStep(CodeFlowToTreeConverter.Convert(codeFlow, run: null, resultId: 0, runIndex: 0)); return(analysisStep); }
public void CanConvertCodeFlowToTreeOnlyDeclarations() { CodeFlow codeFlow = SarifUtilities.CreateSingleThreadedCodeFlow(new[] { new ThreadFlowLocation { NestingLevel = 0, // Declaration }, new ThreadFlowLocation { NestingLevel = 0, // Declaration }, new ThreadFlowLocation { NestingLevel = 0, // Declaration }, }); List <AnalysisStepNode> topLevelNodes = CodeFlowToTreeConverter.Convert(codeFlow, run: null, resultId: 0, runIndex: 0); topLevelNodes.Count.Should().Be(3); topLevelNodes[0].Children.Should().BeEmpty(); topLevelNodes[1].Children.Should().BeEmpty(); topLevelNodes[2].Children.Should().BeEmpty(); topLevelNodes[1].Location.NestingLevel.Should().Be(0); // Declaration topLevelNodes[0].Location.NestingLevel.Should().Be(0); // Declaration topLevelNodes[2].Location.NestingLevel.Should().Be(0); // Declaration topLevelNodes[0].Parent.Should().Be(null); topLevelNodes[1].Parent.Should().Be(null); topLevelNodes[2].Parent.Should().Be(null); List <AnalysisStepNode> flatNodes = CodeFlowToTreeConverter.ToFlatList(codeFlow, run: null, resultId: 0, runIndex: 0); VerifyCodeFlowFlatList(flatNodes, codeFlow, run: null); }
private Result ProcessSdvDefectStream(Stream input) { var result = new Result { Locations = new List <Location>(), CodeFlows = new [] { SarifUtilities.CreateSingleThreadedCodeFlow() } }; using (var reader = new StreamReader(input)) { int nestingLevel = 0; string line; while (!string.IsNullOrEmpty(line = reader.ReadLine())) { ProcessLine(line, ref nestingLevel, result); } } return(result); }
public void CanConvertCodeFlowToTree() { var codeFlow = SarifUtilities.CreateSingleThreadedCodeFlow(new[] { new ThreadFlowLocation { NestingLevel = 0, // Call Location = new Location { Message = new Message { Text = "first parent" } } }, new ThreadFlowLocation { NestingLevel = 1, // Call Location = new Location { Message = new Message { Text = "second parent" } } }, new ThreadFlowLocation { NestingLevel = 2, // CallReturn }, new ThreadFlowLocation { NestingLevel = 1, // Call Location = new Location { Message = new Message { Text = "third parent" } } }, new ThreadFlowLocation { NestingLevel = 2, // CallReturn }, new ThreadFlowLocation { NestingLevel = 1, // Call Location = new Location { Message = new Message { Text = "fourth parent" } } }, new ThreadFlowLocation { NestingLevel = 2, // CallReturn }, new ThreadFlowLocation { NestingLevel = 1, // CallReturn }, new ThreadFlowLocation { NestingLevel = 0, // Call Location = new Location { Message = new Message { Text = "fifth parent" } } }, new ThreadFlowLocation { NestingLevel = 1, // CallReturn, } }); List <CallTreeNode> topLevelNodes = CodeFlowToTreeConverter.Convert(codeFlow, run: null); topLevelNodes.Count.Should().Be(2); topLevelNodes[0].Children.Count.Should().Be(4); topLevelNodes[0].Children[2].Children.Count.Should().Be(1); // Check that we have the right nodes at the right places in the tree. topLevelNodes[0].Location.NestingLevel.Should().Be(0); // Call topLevelNodes[0].Children[0].Location.NestingLevel.Should().Be(1); // Call topLevelNodes[0].Children[0].Children[0].Location.NestingLevel.Should().Be(2); // CallReturn topLevelNodes[0].Children[1].Location.NestingLevel.Should().Be(1); // Call topLevelNodes[0].Children[1].Children[0].Location.NestingLevel.Should().Be(2); // CallReturn topLevelNodes[0].Children[2].Location.NestingLevel.Should().Be(1); // Call topLevelNodes[0].Children[2].Children[0].Location.NestingLevel.Should().Be(2); // CallReturn topLevelNodes[0].Children[3].Location.NestingLevel.Should().Be(1); // CallReturn topLevelNodes[1].Location.NestingLevel.Should().Be(0); // Call topLevelNodes[1].Children[0].Location.NestingLevel.Should().Be(1); // CallReturn // Check parents topLevelNodes[0].Parent.Should().Be(null); topLevelNodes[0].Children[0].Parent.Location.Location.Message.Text.Should().Be("first parent"); topLevelNodes[0].Children[0].Children[0].Parent.Location.Location.Message.Text.Should().Be("second parent"); topLevelNodes[0].Children[1].Parent.Location.Location.Message.Text.Should().Be("first parent"); topLevelNodes[0].Children[1].Children[0].Parent.Location.Location.Message.Text.Should().Be("third parent"); topLevelNodes[0].Children[2].Parent.Location.Location.Message.Text.Should().Be("first parent"); topLevelNodes[0].Children[2].Children[0].Parent.Location.Location.Message.Text.Should().Be("fourth parent"); topLevelNodes[0].Children[3].Parent.Location.Location.Message.Text.Should().Be("first parent"); topLevelNodes[1].Parent.Should().Be(null); topLevelNodes[1].Children[0].Parent.Location.Location.Message.Text.Should().Be("fifth parent"); }
private void ParseLocationsFromTraces(Result result) { CodeFlow codeFlow = null; string nodeLabel = null; string lastNodeId = null; bool? isDefault = null; while (!AtEndOf(_strings.Unified)) { if (AtStartOf(_strings.Trace)) { codeFlow = SarifUtilities.CreateSingleThreadedCodeFlow(); result.CodeFlows.Add(codeFlow); while (!AtEndOf(_strings.Trace)) { if (AtStartOf(_strings.NodeRef)) { string nodeId = _reader.GetAttribute(_strings.IdAttribute); if (!string.IsNullOrWhiteSpace(nodeId)) { var tfl = new ThreadFlowLocation(); _tflToNodeIdDictionary.Add(tfl, nodeId); codeFlow.ThreadFlows[0].Locations.Add(tfl); } _reader.Read(); } else if (AtStartOf(_strings.Node)) { if (isDefault == null) { // We haven't found the default node yet, so check this one. string isDefaultValue = _reader.GetAttribute(_strings.IsDefaultAttribute); if (!string.IsNullOrWhiteSpace(isDefaultValue) && bool.TryParse(isDefaultValue, out bool val) && val == true) { // This is the default, set the flag so we know to add a result location isDefault = val; } } nodeLabel = _reader.GetAttribute(_strings.LabelAttribute); _reader.Read(); } else if (AtStartOf(_strings.SourceLocation)) { // Note: SourceLocation is an empty element (it has only attributes), // so we can't call AtStartOfNonEmpty here. string snippetId = _reader.GetAttribute(_strings.SnippetAttribute); PhysicalLocation physicalLocation = ParsePhysicalLocationFromSourceInfo(); // Step past the empty SourceLocation element. _reader.Read(); string actionType = null; if (AtStartOf(_strings.Action)) { actionType = _reader.GetAttribute(_strings.TypeAttribute); actionType = actionType ?? string.Empty; // We use empty string to indicates there is an // Action element without a type attribute. // If we don't have a label, get the <Action> value if (string.IsNullOrWhiteSpace(nodeLabel)) { nodeLabel = _reader.ReadElementContentAsString(); } } if (actionType == string.Empty) { if (codeFlow.ThreadFlows[0].Locations.Count > 0) { // If there is no type attribute on the Action element, we treat // it as a note about the prior node. ThreadFlowLocation tfl = codeFlow.ThreadFlows[0].Locations.Last(); // Annotate the location with the Action text. if (tfl?.Location != null) { tfl.Location.Annotations = new List <Region>(); Region region = physicalLocation.Region; region.Message = new Message { Text = nodeLabel }; tfl.Location.Annotations.Add(region); } } } else { var location = new Location { PhysicalLocation = physicalLocation }; if (isDefault == true) { result.Locations = new List <Location>(); result.Locations.Add(location.DeepClone()); result.RelatedLocations.Add(location.DeepClone()); // Keep track of the snippet associated with the default location. // That's the snippet that we'll associate with the result. lastNodeId = snippetId; isDefault = false; // This indicates we have already found the default node. } var tfl = new ThreadFlowLocation { Kinds = new List <string> { actionType }, Location = location }; if (!string.IsNullOrWhiteSpace(nodeLabel)) { tfl.Location.Message = new Message { Text = nodeLabel }; } // Remember the id of the snippet associated with this location. // We'll use it to fill the snippet text when we read the Snippets element later on. if (!string.IsNullOrEmpty(snippetId)) { _tflToSnippetIdDictionary.Add(tfl, snippetId); } codeFlow.ThreadFlows[0].Locations.Add(tfl); } } else { _reader.Read(); } } } else { _reader.Read(); } } if (result.RelatedLocations.Any()) { Location relatedLocation = result.RelatedLocations.Last(); if (relatedLocation != null) { relatedLocation.PhysicalLocation.Id = 1; } } if (!string.IsNullOrEmpty(lastNodeId)) { _resultToSnippetIdDictionary.Add(result, lastNodeId); } }
/// <summary>Converts this instance to <see cref="Result"/>.</summary> /// <returns>This instance as an <see cref="Result"/>.</returns> public Result ToSarifIssue() { if (this.Locations.Length == 0) { throw new InvalidOperationException("At least one location must be present in a SARIF result."); } var result = new Result { RuleId = this.Id, }; result.SetProperty("Severity", this.Severity); if (!string.IsNullOrEmpty(this.VerboseMessage)) { result.Message = new Message { Text = this.VerboseMessage }; } else { result.Message = new Message { Text = this.Message }; } PhysicalLocation lastLocationConverted; if (this.Locations.Length == 1) { lastLocationConverted = this.Locations[0].ToSarifPhysicalLocation(); } else { var locations = new List <ThreadFlowLocation> { Capacity = this.Locations.Length }; foreach (CppCheckLocation loc in this.Locations) { locations.Add(new ThreadFlowLocation { Location = new Location { PhysicalLocation = loc.ToSarifPhysicalLocation() }, Importance = ThreadFlowLocationImportance.Essential }); } result.CodeFlows = new List <CodeFlow>() { SarifUtilities.CreateSingleThreadedCodeFlow(locations) }; // In the N != 1 case, set the overall location's location to // the last entry in the execution flow. lastLocationConverted = locations[locations.Count - 1].Location.PhysicalLocation; } result.Locations = new List <Location> { new Location { PhysicalLocation = lastLocationConverted } }; return(result); }
/// <summary>Converts a Fortify result to a static analysis results interchange format result.</summary> /// <param name="fortify">The Fortify result convert.</param> /// <returns> /// A SARIF result <see cref="Result"/> containing the same content as the supplied /// <see cref="FortifyIssue"/>. /// </returns> public static Result ConvertFortifyIssueToSarifIssue(FortifyIssue fortify) { var result = new Result(); result.RuleId = fortify.Category; if (!string.IsNullOrWhiteSpace(fortify.InstanceId)) { if (result.PartialFingerprints == null) { result.PartialFingerprints = new Dictionary <string, string>(); } SarifUtilities.AddOrUpdateDictionaryEntry(result.PartialFingerprints, "InstanceId", fortify.InstanceId); } List <string> messageComponents = new List <string>(); if (fortify.Abstract != null) { messageComponents.Add(fortify.Abstract); } if (fortify.AbstractCustom != null) { messageComponents.Add(fortify.AbstractCustom); } if (messageComponents.Count == 0) { result.Message = new Message { Text = String.Format(CultureInfo.InvariantCulture, ConverterResources.FortifyFallbackMessage, result.RuleId) }; } else { result.Message = new Message { Text = String.Join(Environment.NewLine, messageComponents) }; } result.SetProperty("kingdom", fortify.Kingdom); if (fortify.Priority != null) { result.SetProperty("priority", fortify.Priority); } if (!fortify.CweIds.IsDefaultOrEmpty) { result.SetProperty("cwe", String.Join(", ", fortify.CweIds.Select(id => id.ToString(CultureInfo.InvariantCulture)))); } if (fortify.RuleId != null) { result.SetProperty("fortifyRuleId", fortify.RuleId); } PhysicalLocation primaryOrSink = ConvertFortifyLocationToPhysicalLocation(fortify.PrimaryOrSink); result.Locations = new List <Location> { new Location { PhysicalLocation = primaryOrSink } }; if (fortify.Source != null) { PhysicalLocation source = ConvertFortifyLocationToPhysicalLocation(fortify.Source); var locations = new List <CodeFlowLocation>() { new CodeFlowLocation { Location = new Location { PhysicalLocation = source } }, new CodeFlowLocation { Location = new Location { PhysicalLocation = primaryOrSink } } }; result.CodeFlows = new List <CodeFlow>() { SarifUtilities.CreateSingleThreadedCodeFlow(locations) }; } return(result); }
public void CanConvertCodeFlowToFlatListNonZeroBasedLevel() { CodeFlow codeFlow = SarifUtilities.CreateSingleThreadedCodeFlow(new[] { new ThreadFlowLocation { NestingLevel = 5, Location = new Location { Message = new Message { Text = "location level 5", }, PhysicalLocation = new PhysicalLocation { ArtifactLocation = new ArtifactLocation { Index = 0, } }, }, }, new ThreadFlowLocation { NestingLevel = 6, Location = new Location { Message = new Message { Text = "location level 6", }, PhysicalLocation = new PhysicalLocation { ArtifactLocation = new ArtifactLocation { Index = 0, } }, }, }, new ThreadFlowLocation { NestingLevel = 7, Location = new Location { Message = new Message { Text = "location level 7", }, PhysicalLocation = new PhysicalLocation { ArtifactLocation = new ArtifactLocation { Index = 0, } }, }, }, new ThreadFlowLocation { NestingLevel = 8, Location = new Location { Message = new Message { Text = "location level 8", }, PhysicalLocation = new PhysicalLocation { ArtifactLocation = new ArtifactLocation { Index = 0, } }, }, }, new ThreadFlowLocation { NestingLevel = 7, }, new ThreadFlowLocation { NestingLevel = 6, }, new ThreadFlowLocation { NestingLevel = 5, }, new ThreadFlowLocation { NestingLevel = 5, Location = new Location { Message = new Message { Text = "location level 5", }, PhysicalLocation = new PhysicalLocation { ArtifactLocation = new ArtifactLocation { Index = 1 } }, }, }, new ThreadFlowLocation { NestingLevel = 5, Location = new Location { Message = new Message { Text = "location level 5", }, PhysicalLocation = new PhysicalLocation { ArtifactLocation = new ArtifactLocation { Index = 2 } }, }, }, }); var run = new Run { Artifacts = new[] { new Artifact { Location = new ArtifactLocation { Uri = new Uri("path/to/file1.cpp", UriKind.Relative), } }, new Artifact { Location = new ArtifactLocation { Uri = new Uri("path/to/file2.cpp", UriKind.Relative), } }, new Artifact { Location = new ArtifactLocation { Uri = new Uri("path/to/file3.cpp", UriKind.Relative), } }, }, }; List <AnalysisStepNode> nodes = CodeFlowToTreeConverter.ToFlatList(codeFlow, run, resultId: 0, runIndex: 0); VerifyCodeFlowFlatList(nodes, codeFlow, run: null); }
public void CanConvertCodeFlowToTreeNonCallOrReturn() { var codeFlow = SarifUtilities.CreateSingleThreadedCodeFlow(new[] { new ThreadFlowLocation { NestingLevel = 0, // Call Location = new Location { Message = new Message { Text = "first parent", }, }, }, new ThreadFlowLocation { NestingLevel = 1, // Declaration }, new ThreadFlowLocation { NestingLevel = 1, // Declaration }, new ThreadFlowLocation { NestingLevel = 1, // Declaration }, new ThreadFlowLocation { NestingLevel = 1, // CallReturn }, new ThreadFlowLocation { NestingLevel = 0, // Call Location = new Location { Message = new Message { Text = "second parent", }, }, }, new ThreadFlowLocation { NestingLevel = 1, // Declaration }, new ThreadFlowLocation { NestingLevel = 1, // Declaration }, new ThreadFlowLocation { NestingLevel = 1, // CallReturn }, }); List <AnalysisStepNode> topLevelNodes = CodeFlowToTreeConverter.Convert(codeFlow, run: null, resultId: 0, runIndex: 0); topLevelNodes.Count.Should().Be(2); topLevelNodes[0].Children.Count.Should().Be(4); topLevelNodes[1].Children.Count.Should().Be(3); // Spot-check that we have the right nodes at the right places in the tree. topLevelNodes[0].Location.NestingLevel.Should().Be(0); // Call topLevelNodes[0].Children[0].Location.NestingLevel.Should().Be(1); // Declaration topLevelNodes[0].Children[3].Location.NestingLevel.Should().Be(1); // CallReturn topLevelNodes[1].Location.NestingLevel.Should().Be(0); // Call topLevelNodes[1].Children[2].Location.NestingLevel.Should().Be(1); // CallReturn // Check parents topLevelNodes[0].Parent.Should().Be(null); topLevelNodes[0].Children[0].Parent.Location.Location.Message.Text.Should().Be("first parent"); topLevelNodes[0].Children[1].Parent.Location.Location.Message.Text.Should().Be("first parent"); topLevelNodes[0].Children[2].Parent.Location.Location.Message.Text.Should().Be("first parent"); topLevelNodes[0].Children[3].Parent.Location.Location.Message.Text.Should().Be("first parent"); topLevelNodes[1].Parent.Should().Be(null); topLevelNodes[1].Children[0].Parent.Location.Location.Message.Text.Should().Be("second parent"); topLevelNodes[1].Children[1].Parent.Location.Location.Message.Text.Should().Be("second parent"); topLevelNodes[1].Children[2].Parent.Location.Location.Message.Text.Should().Be("second parent"); }
internal Result CreateResult(FxCopLogReader.Context context) { Result result = new Result(); string uniqueId = context.GetUniqueId(); if (!string.IsNullOrWhiteSpace(uniqueId)) { if (result.PartialFingerprints == null) { result.PartialFingerprints = new Dictionary <string, string>(); } SarifUtilities.AddOrUpdateDictionaryEntry(result.PartialFingerprints, "UniqueId", uniqueId); } string status = context.Status; if ("ExcludedInSource".Equals(status)) { result.Suppressions = new List <Suppression> { new Suppression { Kind = SuppressionKind.InSource } }; } else if ("ExcludedInProject".Equals(status)) { result.BaselineState = BaselineState.Unchanged; } result.RuleId = context.CheckId; string messageText = context.Message ?? ConverterResources.FxCopNoMessage; result.Message = new Message { Arguments = context.Items, Id = context.ResolutionName, Text = messageText }; var location = new Location(); string sourceFile = GetFilePath(context); string targetFile = context.Target; // If both source and target have values and they're different, set analysis target if (!string.IsNullOrWhiteSpace(sourceFile) && !string.IsNullOrWhiteSpace(targetFile) && !sourceFile.Equals(targetFile)) { result.AnalysisTarget = BuildFileLocationFromFxCopReference(targetFile); } else { // One or the other or both is null, or they're different sourceFile = string.IsNullOrWhiteSpace(sourceFile) ? targetFile : sourceFile; } // Don't emit a location if neither physical location nor logical location information // is present. This is the case for CA0001 (unexpected error in analysis tool). // https://docs.microsoft.com/en-us/visualstudio/code-quality/ca0001?view=vs-2019 bool emitLocation = false; // If we have a value, set physical location if (!string.IsNullOrWhiteSpace(sourceFile)) { location.PhysicalLocation = new PhysicalLocation { ArtifactLocation = BuildFileLocationFromFxCopReference(sourceFile), Region = context.Line == null ? null : Extensions.CreateRegion(context.Line.Value) }; emitLocation = true; } string fullyQualifiedLogicalName = CreateFullyQualifiedLogicalName(context, out int logicalLocationIndex); if (!string.IsNullOrWhiteSpace(fullyQualifiedLogicalName) || logicalLocationIndex > -1) { location.LogicalLocation = new LogicalLocation { FullyQualifiedName = fullyQualifiedLogicalName, Index = logicalLocationIndex }; emitLocation = true; } if (emitLocation) { result.Locations = new List <Location> { location }; } bool mapsDirectlyToSarifName; result.Level = ConvertFxCopLevelToResultLevel(context.Level ?? "Warning", out mapsDirectlyToSarifName); if (!mapsDirectlyToSarifName) { // We will not recapitulate FxCop MessageLevel names (such as // "Error" and "Warning") as a property. For names that differ // (such as "CriticalWarning" and "Information"), we will also // include the FxCop-specific values in the property bag. AddProperty(result, context.Level, "Level"); } AddProperty(result, context.Category, "Category"); AddProperty(result, context.FixCategory, "FixCategory"); return(result); }
private void GenerateCodeFlows(Defect defect, Result result) { List <SFA> sfas = defect?.Path?.SFAs; if (sfas == null || sfas.Count == 0) { return; } int step = 0; var locations = new List <ThreadFlowLocation>(); bool pathUsesKeyEvents = defect.Path.SFAs.Any(x => !string.IsNullOrWhiteSpace(x?.KeyEvent?.Id)); foreach (var sfa in defect.Path.SFAs) { var region = new Region() { StartColumn = sfa.Column + 1, StartLine = sfa.Line }; var uri = new Uri($"{sfa.FilePath}{sfa.FileName}", UriKind.Relative); var fileLocation = new PhysicalLocation(id: 0, fileLocation: new FileLocation(uri: uri, uriBaseId: null), region: region, contextRegion: null); var threadFlowLocation = new ThreadFlowLocation { Location = new Location { PhysicalLocation = fileLocation }, Step = ++step }; if (pathUsesKeyEvents) { if (string.IsNullOrWhiteSpace(sfa.KeyEvent?.Id)) { threadFlowLocation.Importance = ThreadFlowLocationImportance.Unimportant; } else { threadFlowLocation.SetProperty("keyEventId", sfa.KeyEvent.Id); if (Enum.TryParse(sfa.KeyEvent.Importance, true, out ThreadFlowLocationImportance importance)) { threadFlowLocation.Importance = importance; } if (!string.IsNullOrWhiteSpace(sfa.KeyEvent.Message) && threadFlowLocation.Location?.Message != null) { threadFlowLocation.Location.Message.Text = sfa.KeyEvent.Message; } } } locations.Add(threadFlowLocation); } result.CodeFlows = new List <CodeFlow>() { SarifUtilities.CreateSingleThreadedCodeFlow(locations) }; }
internal Result CreateResult(FxCopLogReader.Context context) { Result result = new Result(); string uniqueId = context.GetUniqueId(); if (!String.IsNullOrWhiteSpace(uniqueId)) { if (result.PartialFingerprints == null) { result.PartialFingerprints = new Dictionary <string, string>(); } SarifUtilities.AddOrUpdateDictionaryEntry(result.PartialFingerprints, "UniqueId", uniqueId); } string status = context.Status; if ("ExcludedInSource".Equals(status)) { result.SuppressionStates = SuppressionStates.SuppressedInSource; } else if ("ExcludedInProject".Equals(status)) { result.BaselineState = BaselineState.Unchanged; } result.RuleId = context.CheckId; result.Message = new Message { Arguments = context.Items, MessageId = context.ResolutionName, Text = context.Message }; var location = new Location(); string sourceFile = GetFilePath(context); string targetFile = context.Target; // If both source and target have values and they're different, set analysis target if (!string.IsNullOrWhiteSpace(sourceFile) && !string.IsNullOrWhiteSpace(targetFile) && !sourceFile.Equals(targetFile)) { result.AnalysisTarget = BuildFileLocationFromFxCopReference(targetFile); } else { // One or the other or both is null, or they're different sourceFile = string.IsNullOrWhiteSpace(sourceFile) ? targetFile : sourceFile; } // If we have a value, set physical location if (!string.IsNullOrWhiteSpace(sourceFile)) { location.PhysicalLocation = new PhysicalLocation { ArtifactLocation = BuildFileLocationFromFxCopReference(sourceFile), Region = context.Line == null ? null : Extensions.CreateRegion(context.Line.Value) }; } location.FullyQualifiedLogicalName = CreateFullyQualifiedLogicalName(context, out int logicalLocationIndex); location.LogicalLocationIndex = logicalLocationIndex; result.Locations = new List <Location> { location }; bool mapsDirectlyToSarifName; result.Level = ConvertFxCopLevelToResultLevel(context.Level ?? "Warning", out mapsDirectlyToSarifName); if (!mapsDirectlyToSarifName) { // We will not recapitulate FxCop MessageLevel names (such as // "Error" and "Warning") as a property. For names that differ // (such as "CriticalWarning" and "Information"), we will also // include the FxCop-specific values in the property bag. AddProperty(result, context.Level, "Level"); } AddProperty(result, context.Category, "Category"); AddProperty(result, context.FixCategory, "FixCategory"); return(result); }
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); }
public void CanConvertCodeFlowToFlatListZeroBasedLevel() { CodeFlow codeFlow = SarifUtilities.CreateSingleThreadedCodeFlow(new[] { new ThreadFlowLocation { NestingLevel = 0, Location = new Location { Message = new Message { Text = "location level 0", }, PhysicalLocation = new PhysicalLocation { ArtifactLocation = new ArtifactLocation { Uri = new Uri("path/to/file.cpp", UriKind.Relative), } }, }, }, new ThreadFlowLocation { NestingLevel = 1, Location = new Location { Message = new Message { Text = "location level 1", }, PhysicalLocation = new PhysicalLocation { ArtifactLocation = new ArtifactLocation { Uri = new Uri("path/to/file.cpp", UriKind.Relative), } }, }, }, new ThreadFlowLocation { NestingLevel = 2, }, new ThreadFlowLocation { NestingLevel = 1, Location = new Location { Message = new Message { Text = "location level 1", }, PhysicalLocation = new PhysicalLocation { ArtifactLocation = new ArtifactLocation { Uri = new Uri("path/to/file.cpp", UriKind.Relative), } }, }, }, new ThreadFlowLocation { NestingLevel = 2, }, new ThreadFlowLocation { NestingLevel = 1, Location = new Location { Message = new Message { Text = "location level 1", }, PhysicalLocation = new PhysicalLocation { ArtifactLocation = new ArtifactLocation { Uri = new Uri("path/to/file.cpp", UriKind.Relative), } }, }, }, new ThreadFlowLocation { NestingLevel = 2, }, new ThreadFlowLocation { NestingLevel = 1, }, new ThreadFlowLocation { NestingLevel = 0, Location = new Location { Message = new Message { Text = "location level 0", }, PhysicalLocation = new PhysicalLocation { ArtifactLocation = new ArtifactLocation { Uri = new Uri("path/to/file.cpp", UriKind.Relative), } }, }, }, new ThreadFlowLocation { NestingLevel = 1, }, }); List <AnalysisStepNode> nodes = CodeFlowToTreeConverter.ToFlatList(codeFlow, run: null, resultId: 0, runIndex: 0); VerifyCodeFlowFlatList(nodes, codeFlow, run: null); }