Beispiel #1
0
        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);
        }
        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);
        }
Beispiel #3
0
        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]);
        }
        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);
        }
        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);
        }
Beispiel #9
0
        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);
        }
Beispiel #10
0
        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)
            };
        }
        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");
        }
Beispiel #12
0
        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);
            }
        }
Beispiel #13
0
        /// <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);
        }
Beispiel #14
0
        /// <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);
        }
Beispiel #15
0
        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");
        }
        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 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);
        }