Beispiel #1
0
        public void AnalysisStepNodeToTextConverter_HandlesMessageAndSnippet()
        {
            const string snippet = "    int x = 42;";
            const string message = "my_function";

            var analysisStepNode = new AnalysisStepNode(resultId: 0, runIndex: 0)
            {
                Location = new ThreadFlowLocation
                {
                    Location = new Location
                    {
                        Message = new Message
                        {
                            Text = message,
                        },
                        PhysicalLocation = new PhysicalLocation
                        {
                            Region = new Region
                            {
                                StartLine = 42,
                                Snippet   = new ArtifactContent
                                {
                                    Text = snippet,
                                },
                            },
                        },
                    },
                },
            };

            VerifyConversion(analysisStepNode, message);
        }
Beispiel #2
0
        public static string MakeDisplayString(AnalysisStepNode node)
        {
            // Use the following preferences for the AnalysisStepNode text.
            // 1. ThreadFlowLocation.Location.Message.Text
            // 2. ThreadFlowLocation.Location.PhysicalLocation.Region.Snippet.Text
            // 3. "Continuing"
            string text = string.Empty;

            ThreadFlowLocation threadFlowLocation = node.Location;

            if (threadFlowLocation != null)
            {
                if (!string.IsNullOrWhiteSpace(threadFlowLocation.Location?.Message?.Text))
                {
                    text = threadFlowLocation.Location.Message.Text;
                }
                else if (!string.IsNullOrWhiteSpace(threadFlowLocation.Location?.PhysicalLocation?.Region?.Snippet?.Text))
                {
                    text = threadFlowLocation.Location.PhysicalLocation.Region.Snippet.Text.Trim();
                }
                else
                {
                    text = Resources.ContinuingAnalysisStepNodeMessage;
                }
            }

            return(text);
        }
Beispiel #3
0
        public void AnalysisStepNodeToTextConverter_HandlesRegionSnippet()
        {
            const string snippet = "    int x = 42;";

            var analysisStepNode = new AnalysisStepNode(resultId: 0, runIndex: 0)
            {
                Location = new ThreadFlowLocation
                {
                    Location = new Location
                    {
                        PhysicalLocation = new PhysicalLocation
                        {
                            Region = new Region
                            {
                                StartLine = 42,
                                Snippet   = new ArtifactContent
                                {
                                    Text = snippet,
                                },
                            },
                        },
                    },
                },
            };

            VerifyConversion(analysisStepNode, snippet.Trim());
        }
Beispiel #4
0
        public void AnalysisStepNodeToTextConverter_HandlesLocationMessage()
        {
            const string message = "my_function";

            var analysisStepNode = new AnalysisStepNode(resultId: 0, runIndex: 0)
            {
                Location = new ThreadFlowLocation
                {
                    Location = new Location
                    {
                        Message = new Message
                        {
                            Text = message,
                        },
                        PhysicalLocation = new PhysicalLocation
                        {
                            Region = new Region
                            {
                                StartLine = 42,
                            },
                        },
                    },
                },
            };

            VerifyConversion(analysisStepNode, message);
        }
Beispiel #5
0
        private static void VerifyConversion(AnalysisStepNode analysisStepNode, string expectedText)
        {
            var converter = new AnalysisStepNodeToTextConverter();

            string text = (string)converter.Convert(analysisStepNode, typeof(string), null, CultureInfo.CurrentCulture);

            text.Should().Be(expectedText);
        }
Beispiel #6
0
        internal static List <AnalysisStepNode> Convert(CodeFlow codeFlow, Run run, int resultId, int runIndex)
        {
            var root = new AnalysisStepNode(resultId: resultId, runIndex: runIndex)
            {
                Children = new List <AnalysisStepNode>(),
            };

            ThreadFlow threadFlow = codeFlow.ThreadFlows?[0];

            if (threadFlow != null)
            {
                int lastNestingLevel         = 0;
                AnalysisStepNode lastParent  = root;
                AnalysisStepNode lastNewNode = null;

                foreach (ThreadFlowLocation location in threadFlow.Locations)
                {
                    ArtifactLocation artifactLocation = location.Location?.PhysicalLocation?.ArtifactLocation;

                    if (artifactLocation != null)
                    {
                        Uri uri = location.Location?.PhysicalLocation?.ArtifactLocation?.Uri;

                        if (uri == null && artifactLocation.Index > -1)
                        {
                            artifactLocation.Uri = run.Artifacts[artifactLocation.Index].Location.Uri;
                        }
                    }

                    var newNode = new AnalysisStepNode(resultId: resultId, runIndex: runIndex)
                    {
                        Location = location,
                        Children = new List <AnalysisStepNode>(),
                    };

                    if (location.NestingLevel > lastNestingLevel)
                    {
                        // The previous node was a call, so this new node's parent is that node
                        lastParent = lastNewNode;
                    }
                    else if (location.NestingLevel < lastNestingLevel)
                    {
                        // The previous node was a return, so this new node's parent is the previous node's grandparent
                        lastParent = lastNewNode.Parent.Parent;
                    }

                    newNode.Parent = lastParent;
                    lastParent.Children.Add(newNode);
                    lastNewNode      = newNode;
                    lastNestingLevel = location.NestingLevel;
                }

                root.Children.ForEach(n => n.Parent = null);
            }

            return(root.Children);
        }
        private void VerifyCodeFlowFlatList(IList <AnalysisStepNode> analysisStepNodes, CodeFlow codeFlow, Run run)
        {
            ThreadFlow threadFlow = codeFlow?.ThreadFlows?[0];

            if (threadFlow != null)
            {
                analysisStepNodes.Should().NotBeEmpty();
                analysisStepNodes.Count.Should().Be(threadFlow.Locations.Count);

                int minLevel = threadFlow.Locations.Min(l => l.NestingLevel);

                for (int i = 0; i < analysisStepNodes.Count; i++)
                {
                    AnalysisStepNode   node     = analysisStepNodes[i];
                    ThreadFlowLocation location = threadFlow.Locations[i];

                    node.Parent.Should().BeNull(); // flat list item doesn't have parent

                    ArtifactLocation artifactLocation = location.Location?.PhysicalLocation?.ArtifactLocation;
                    if (artifactLocation != null)
                    {
                        if (artifactLocation.Uri == null)
                        {
                            if (artifactLocation.Index > -1 && run?.Artifacts != null)
                            {
                                node.Location.Location.PhysicalLocation.ArtifactLocation.Uri
                                .Should()
                                .Be(run.Artifacts[artifactLocation.Index].Location.Uri);
                            }
                        }
                        else
                        {
                            node.Location.Location.PhysicalLocation.ArtifactLocation.Uri.Should().Be(artifactLocation.Uri);
                        }
                    }

                    node.NestingLevel.Should().Be(location.NestingLevel - minLevel);
                }
            }
            else
            {
                analysisStepNodes.Should().BeEmpty();
            }
        }
Beispiel #8
0
        public void AnalysisStepNodeToTextConverter_HandlesNoMessageNorSnippet()
        {
            var analysisStepNode = new AnalysisStepNode(resultId: 0, runIndex: 0)
            {
                Location = new ThreadFlowLocation
                {
                    Location = new Location
                    {
                        PhysicalLocation = new PhysicalLocation
                        {
                            Region = new Region
                            {
                                StartLine = 42,
                            },
                        },
                    },
                },
            };

            VerifyConversion(analysisStepNode, Microsoft.Sarif.Viewer.Resources.ContinuingAnalysisStepNodeMessage);
        }
Beispiel #9
0
        internal static List <AnalysisStepNode> ToFlatList(CodeFlow codeFlow, Run run, int resultId, int runIndex)
        {
            var results = new List <AnalysisStepNode>();

            ThreadFlow threadFlow = codeFlow.ThreadFlows?[0];

            if (threadFlow != null)
            {
                // nestingLevel is an integer value which is greater than or equals to 0
                // according to schema http://json.schemastore.org/sarif-2.1.0-rtm.5.
                // min nesting level can be used to offset nesting level starts from value greater than 0.e
                int minNestingLevel = threadFlow.Locations.Min(l => l.NestingLevel);

                foreach (ThreadFlowLocation location in threadFlow.Locations)
                {
                    ArtifactLocation artifactLocation = location.Location?.PhysicalLocation?.ArtifactLocation;

                    if (artifactLocation != null &&
                        artifactLocation.Uri == null &&
                        artifactLocation.Index > -1)
                    {
                        artifactLocation.Uri = run.Artifacts[artifactLocation.Index].Location.Uri;
                    }

                    var newNode = new AnalysisStepNode(resultId: resultId, runIndex: runIndex)
                    {
                        Location     = location,
                        Children     = new List <AnalysisStepNode>(),
                        NestingLevel = location.NestingLevel - minNestingLevel,
                    };

                    results.Add(newNode);
                }
            }

            return(results);
        }