Beispiel #1
0
        private static void CheckForNullDereference(CSharpExplodedGraph explodedGraph, SyntaxNodeAnalysisContext context)
        {
            var nullPointerCheck = new NullPointerCheck(explodedGraph);

            explodedGraph.AddExplodedGraphCheck(nullPointerCheck);

            var nullIdentifiers = new HashSet <IdentifierNameSyntax>();

            void memberAccessedHandler(object sender, MemberAccessedEventArgs args) =>
            CollectMemberAccesses(args, nullIdentifiers, context.SemanticModel);

            nullPointerCheck.MemberAccessed += memberAccessedHandler;

            try
            {
                explodedGraph.Walk();
            }
            finally
            {
                nullPointerCheck.MemberAccessed -= memberAccessedHandler;
            }

            foreach (var nullIdentifier in nullIdentifiers)
            {
                context.ReportDiagnosticWhenActive(Diagnostic.Create(rule, nullIdentifier.GetLocation(), nullIdentifier.Identifier.ValueText));
            }
        }
            public AnalysisContext(CSharpExplodedGraph explodedGraph, SyntaxNodeAnalysisContext context)
            {
                this.context = context;

                nullPointerCheck = explodedGraph.NullPointerCheck;
                nullPointerCheck.MemberAccessed += MemberAccessedHandler;
            }
Beispiel #3
0
            public AnalysisContext(CSharpExplodedGraph explodedGraph)
            {
                this.objectDisposedPointerCheck = new ObjectDisposedPointerCheck(explodedGraph);
                this.objectDisposedPointerCheck.ObjectDisposed += ObjectDisposedHandler;

                explodedGraph.AddExplodedGraphCheck(this.objectDisposedPointerCheck);
            }
Beispiel #4
0
        private void CheckForEmptyCollectionAccess(CSharpExplodedGraph explodedGraph, SyntaxNodeAnalysisContext context)
        {
            var check = new EmptyCollectionAccessedCheck(explodedGraph);

            explodedGraph.AddExplodedGraphCheck(check);

            var emptyCollections    = new HashSet <SyntaxNode>();
            var nonEmptyCollections = new HashSet <SyntaxNode>();

            void explorationEnded(object sender, EventArgs args) => emptyCollections.Except(nonEmptyCollections)
            .Select(node => Diagnostic.Create(rule, node.GetLocation()))
            .ToList()
            .ForEach(d => context.ReportDiagnosticWhenActive(d));

            void collectionAccessedHandler(object sender, CollectionAccessedEventArgs args) =>
            (args.IsEmpty ? emptyCollections : nonEmptyCollections).Add(args.Node);

            explodedGraph.ExplorationEnded += explorationEnded;
            check.CollectionAccessed       += collectionAccessedHandler;
            try
            {
                explodedGraph.Walk();
            }
            finally
            {
                check.CollectionAccessed       -= collectionAccessedHandler;
                explodedGraph.ExplorationEnded -= explorationEnded;
            }
        }
        private void CheckForEmptyCollectionAccess(CSharpExplodedGraph explodedGraph, SyntaxNodeAnalysisContext context)
        {
            var check = new EmptyCollectionAccessedCheck(explodedGraph);

            explodedGraph.AddExplodedGraphCheck(check);

            var emptyCollections    = new HashSet <SyntaxNode>();
            var nonEmptyCollections = new HashSet <SyntaxNode>();

            EventHandler <CollectionAccessedEventArgs> collectionAccessedHandler = (sender, args) =>
                                                                                   (args.IsEmpty ? emptyCollections : nonEmptyCollections).Add(args.Node);

            check.CollectionAccessed += collectionAccessedHandler;
            try
            {
                explodedGraph.Walk();
            }
            finally
            {
                check.CollectionAccessed -= collectionAccessedHandler;
            }

            foreach (var node in emptyCollections.Except(nonEmptyCollections))
            {
                context.ReportDiagnosticWhenActive(Diagnostic.Create(rule, node.GetLocation()));
            }
        }
            public AnalysisContext(CSharpExplodedGraph explodedGraph)
            {
                nullPointerCheck = new NullValueAccessedCheck(explodedGraph);
                nullPointerCheck.ValuePropertyAccessed += AddIdentifier;

                explodedGraph.AddExplodedGraphCheck(nullPointerCheck);
            }
        private static void Analyze(CSharpSyntaxNode declarationBody, ISymbol symbol, Action <CSharpExplodedGraph, SyntaxNodeAnalysisContext> runAnalysis, SyntaxNodeAnalysisContext context)
        {
            if (declarationBody == null ||
                declarationBody.ContainsDiagnostics)
            {
                return;
            }

            if (!CSharpControlFlowGraph.TryGet(declarationBody, context.SemanticModel, out var cfg))
            {
                return;
            }

            var lva = CSharpLiveVariableAnalysis.Analyze(cfg, symbol, context.SemanticModel);

            try
            {
                var explodedGraph = new CSharpExplodedGraph(cfg, symbol, context.SemanticModel, lva);
                runAnalysis(explodedGraph, context);
            }
            catch (Exception e)
            {
                // Roslyn/MSBuild is currently cutting exception message at the end of the line instead
                // of displaying the full message. As a workaround, we replace the line ending with ' ## '.
                // See https://github.com/dotnet/roslyn/issues/1455 and https://github.com/dotnet/roslyn/issues/24346
                var sb = new StringBuilder();
                sb.AppendLine($"Error processing method: {symbol?.Name ?? "{unknown}"}");
                sb.AppendLine($"Method file: {declarationBody.GetLocation()?.GetLineSpan().Path ?? "{unknown}"}");
                sb.AppendLine($"Method line: {declarationBody.GetLocation()?.GetLineSpan().StartLinePosition.ToString() ?? "{unknown}"}");
                sb.AppendLine($"Inner exception: {e}");

                throw new SymbolicExecutionException(sb.ToString().Replace(Environment.NewLine, " ## "), e);
            }
        }
        public void ExplodedGraph_BothBranchesVisited_NonCondition()
        {
            var testInput    = "var str = this?.ToString();";
            var method       = ControlFlowGraphTest.CompileWithMethodBody(string.Format(TestInput, testInput), "Bar", out var semanticModel);
            var methodSymbol = semanticModel.GetDeclaredSymbol(method);

            var cfg = CSharpControlFlowGraph.Create(method.Body, semanticModel);
            var lva = CSharpLiveVariableAnalysis.Analyze(cfg, methodSymbol, semanticModel);

            var explodedGraph    = new CSharpExplodedGraph(cfg, methodSymbol, semanticModel, lva);
            var explorationEnded = false;

            explodedGraph.ExplorationEnded += (sender, args) => { explorationEnded = true; };

            var countConditionEvaluated = 0;

            explodedGraph.ConditionEvaluated += (sender, args) => { countConditionEvaluated++; };

            var visitedBlocks = new HashSet <Block>();

            explodedGraph.InstructionProcessed +=
                (sender, args) =>
            {
                visitedBlocks.Add(args.ProgramPoint.Block);
            };

            explodedGraph.Walk();

            explorationEnded.Should().BeTrue();
            visitedBlocks.Count.Should().Be(cfg.Blocks.Count() - 1 /* Exit block */);
            countConditionEvaluated.Should().Be(0);
        }
Beispiel #9
0
            public AnalysisContext(CSharpExplodedGraph explodedGraph, SyntaxNodeAnalysisContext context)
            {
                this.explodedGraph = explodedGraph;
                this.context       = context;

                explodedGraph.MemberAccessed += MemberAccessedHandler;
            }
        public void ExplodedGraph_LoopExploration()
        {
            var testInput    = "var i = 0; while (i < 1) { i = i + 1; }";
            var method       = ControlFlowGraphTest.CompileWithMethodBody(string.Format(TestInput, testInput), "Bar", out var semanticModel);
            var methodSymbol = semanticModel.GetDeclaredSymbol(method);

            var cfg = CSharpControlFlowGraph.Create(method.Body, semanticModel);
            var lva = CSharpLiveVariableAnalysis.Analyze(cfg, methodSymbol, semanticModel);

            var explodedGraph    = new CSharpExplodedGraph(cfg, methodSymbol, semanticModel, lva);
            var explorationEnded = false;

            explodedGraph.ExplorationEnded += (sender, args) => { explorationEnded = true; };

            var exceeded = 0;

            explodedGraph.ProgramPointVisitCountExceedLimit += (sender, args) =>
            {
                exceeded++;
                args.ProgramPoint.Block.Instructions.Should().Contain(i => i.ToString() == "i < 1");
            };

            explodedGraph.Walk();

            explorationEnded.Should().BeTrue();
            exceeded.Should().Be(1);
        }
        private static void CheckForMultipleDispose(CSharpExplodedGraph explodedGraph, SyntaxNodeAnalysisContext context)
        {
            var objectDisposedCheck = new ObjectDisposedPointerCheck(explodedGraph);

            explodedGraph.AddExplodedGraphCheck(objectDisposedCheck);

            // Store the nodes that should be reported and ignore duplicate reports for the same node.
            // This is needed because we generate two CFG blocks for the finally statements and even
            // though the syntax nodes are the same, when there is a return inside a try/catch block
            // the walked CFG paths could be different and FPs will appear.
            var nodesToReport = new Dictionary <SyntaxNode, string>();

            void memberAccessedHandler(object sender, ObjectDisposedEventArgs args)
            {
                nodesToReport[args.SyntaxNode] = args.SymbolName;
            }

            objectDisposedCheck.ObjectDisposed += memberAccessedHandler;

            try
            {
                explodedGraph.Walk();
            }
            finally
            {
                objectDisposedCheck.ObjectDisposed -= memberAccessedHandler;
            }

            foreach (var item in nodesToReport)
            {
                context.ReportDiagnosticWhenActive(Diagnostic.Create(rule, item.Key.GetLocation(), item.Value));
            }
        }
        private static void CheckEmptyNullableAccess(CSharpExplodedGraph explodedGraph, SyntaxNodeAnalysisContext context)
        {
            var nullPointerCheck = new NullValueAccessedCheck(explodedGraph);

            explodedGraph.AddExplodedGraphCheck(nullPointerCheck);

            var nullIdentifiers = new HashSet <IdentifierNameSyntax>();

            void nullValueAccessedHandler(object sender, MemberAccessedEventArgs args) => nullIdentifiers.Add(args.Identifier);

            nullPointerCheck.ValuePropertyAccessed += nullValueAccessedHandler;

            try
            {
                explodedGraph.Walk();
            }
            finally
            {
                nullPointerCheck.ValuePropertyAccessed -= nullValueAccessedHandler;
            }

            foreach (var nullIdentifier in nullIdentifiers)
            {
                context.ReportDiagnosticWhenActive(Diagnostic.Create(rule, nullIdentifier.Parent.GetLocation(), nullIdentifier.Identifier.ValueText));
            }
        }
Beispiel #13
0
            public AnalysisContext(CSharpExplodedGraph explodedGraph)
            {
                check = new EmptyCollectionAccessedCheck(explodedGraph);
                check.CollectionAccessed += CollectionAccessedHandler;

                explodedGraph.AddExplodedGraphCheck(check);
            }
        public void ExplodedGraph_SequentialInput_Max()
        {
            var inputBuilder = new StringBuilder();

            for (var i = 0; i < CSharpExplodedGraph.MaxStepCount / 2 + 1; i++)
            {
                inputBuilder.AppendLine($"var x{i} = true;");
            }
            var testInput    = inputBuilder.ToString();
            var method       = ControlFlowGraphTest.CompileWithMethodBody(string.Format(TestInput, testInput), "Bar", out var semanticModel);
            var methodSymbol = semanticModel.GetDeclaredSymbol(method);

            var cfg = CSharpControlFlowGraph.Create(method.Body, semanticModel);
            var lva = CSharpLiveVariableAnalysis.Analyze(cfg, methodSymbol, semanticModel);

            var explodedGraph    = new CSharpExplodedGraph(cfg, methodSymbol, semanticModel, lva);
            var explorationEnded = false;

            explodedGraph.ExplorationEnded += (sender, args) => { explorationEnded = true; };
            var maxStepCountReached = false;

            explodedGraph.MaxStepCountReached += (sender, args) => { maxStepCountReached = true; };

            var numberOfExitBlockReached = 0;

            explodedGraph.ExitBlockReached += (sender, args) => { numberOfExitBlockReached++; };

            explodedGraph.Walk();

            explorationEnded.Should().BeFalse();
            maxStepCountReached.Should().BeTrue();
            numberOfExitBlockReached.Should().Be(0);
        }
Beispiel #15
0
        private void Analyze(CSharpExplodedGraph explodedGraph, SyntaxNodeAnalysisContext context)
        {
            var analyzerContexts = InitializeAnalyzers(explodedGraph, context).ToList();

            try
            {
                explodedGraph.ExplorationEnded += ExplorationEndedHandler;

                explodedGraph.Walk();
            }
            finally
            {
                explodedGraph.ExplorationEnded -= ExplorationEndedHandler;
            }

            // Some of the rules can return good results if the tree was only partially visited; others need to completely
            // walk the tree in order to avoid false positives.
            //
            // Due to this we split the rules in two sets and report the diagnostics in steps:
            // - When the tree is successfully visited and ExplorationEnded event is raised.
            // - When the tree visit ends (explodedGraph.Walk() returns). This will happen even if the maximum number of steps was
            // reached or if an exception was thrown during analysis.
            ReportDiagnostics(analyzerContexts, context, true);

            void ExplorationEndedHandler(object sender, EventArgs args)
            {
                ReportDiagnostics(analyzerContexts, context, false);
            }
        }
Beispiel #16
0
        public void ExplodedGraph_SingleBranchVisited_If()
        {
            string        testInput = "var a = false; bool b; if (a) { b = true; } else { b = false; } a = b;";
            SemanticModel semanticModel;
            var           method         = ControlFlowGraphTest.CompileWithMethodBody(string.Format(TestInput, testInput), "Bar", out semanticModel);
            var           methodSymbol   = semanticModel.GetDeclaredSymbol(method);
            var           varDeclarators = method.DescendantNodes().OfType <VariableDeclaratorSyntax>();
            var           aSymbol        = semanticModel.GetDeclaredSymbol(varDeclarators.First(d => d.Identifier.ToString() == "a"));
            var           bSymbol        = semanticModel.GetDeclaredSymbol(varDeclarators.First(d => d.Identifier.ToString() == "b"));

            var cfg = CSharpControlFlowGraph.Create(method.Body, semanticModel);
            var lva = CSharpLiveVariableAnalysis.Analyze(cfg, methodSymbol, semanticModel);

            var explodedGraph    = new CSharpExplodedGraph(cfg, methodSymbol, semanticModel, lva);
            var explorationEnded = false;

            explodedGraph.ExplorationEnded += (sender, args) => { explorationEnded = true; };

            var numberOfExitBlockReached = 0;

            explodedGraph.ExitBlockReached += (sender, args) => { numberOfExitBlockReached++; };

            var numberOfLastInstructionVisits = 0;
            var numberOfProcessedInstructions = 0;

            explodedGraph.InstructionProcessed +=
                (sender, args) =>
            {
                numberOfProcessedInstructions++;
                if (args.Instruction.ToString() == "a = false")
                {
                    args.ProgramState.GetSymbolValue(aSymbol).Should().Be(SymbolicValue.False);
                }
                if (args.Instruction.ToString() == "b = true")
                {
                    Execute.Assertion.FailWith("We should never get into this branch");
                }
                if (args.Instruction.ToString() == "b = false")
                {
                    args.ProgramState.GetSymbolValue(bSymbol).Should().Be(SymbolicValue.False);
                    args.ProgramState.GetSymbolValue(aSymbol)
                    .Should().BeNull("a is dead, so there should be no associated value to it.");
                }
                if (args.Instruction.ToString() == "a = b")
                {
                    numberOfLastInstructionVisits++;
                }
            };

            explodedGraph.Walk();

            explorationEnded.Should().BeTrue();
            numberOfProcessedInstructions.Should().Be(8);
            numberOfExitBlockReached.Should().Be(1);
            numberOfLastInstructionVisits.Should().Be(1);
        }
        private void Analyze(CSharpExplodedGraph explodedGraph, SyntaxNodeAnalysisContext context)
        {
            var analyzerContexts = InitializeAnalyzers(explodedGraph, context).ToList();

            var steps = explodedGraph.Walk(_maxSteps, _cancellationToken);

            Steps = Math.Max(Steps, steps);

            ReportDiagnostics(analyzerContexts, context);
        }
Beispiel #18
0
        public void ExplodedGraph_SequentialInput()
        {
            string        testInput = "var a = true; var b = false; b = !b; a = (b);";
            SemanticModel semanticModel;
            var           method         = ControlFlowGraphTest.CompileWithMethodBody(string.Format(TestInput, testInput), "Bar", out semanticModel);
            var           methodSymbol   = semanticModel.GetDeclaredSymbol(method);
            var           varDeclarators = method.DescendantNodes().OfType <VariableDeclaratorSyntax>();
            var           aSymbol        = semanticModel.GetDeclaredSymbol(varDeclarators.First(d => d.Identifier.ToString() == "a"));
            var           bSymbol        = semanticModel.GetDeclaredSymbol(varDeclarators.First(d => d.Identifier.ToString() == "b"));

            var cfg = CSharpControlFlowGraph.Create(method.Body, semanticModel);
            var lva = CSharpLiveVariableAnalysis.Analyze(cfg, methodSymbol, semanticModel);

            var explodedGraph    = new CSharpExplodedGraph(cfg, methodSymbol, semanticModel, lva);
            var explorationEnded = false;

            explodedGraph.ExplorationEnded += (sender, args) => { explorationEnded = true; };

            var numberOfExitBlockReached = 0;

            explodedGraph.ExitBlockReached += (sender, args) => { numberOfExitBlockReached++; };

            var numberOfProcessedInstructions = 0;

            explodedGraph.InstructionProcessed +=
                (sender, args) =>
            {
                numberOfProcessedInstructions++;
                if (args.Instruction.ToString() == "a = true")
                {
                    args.ProgramState.GetSymbolValue(aSymbol).Should().Be(SymbolicValue.True);
                }
                if (args.Instruction.ToString() == "b = false")
                {
                    args.ProgramState.GetSymbolValue(bSymbol).Should().Be(SymbolicValue.False);
                }
                if (args.Instruction.ToString() == "b = !b")
                {
                    args.ProgramState.GetSymbolValue(bSymbol).Should().NotBe(SymbolicValue.False);
                    args.ProgramState.GetSymbolValue(bSymbol).Should().NotBe(SymbolicValue.True);
                }
                if (args.Instruction.ToString() == "a = (b)")
                {
                    args.ProgramState.GetSymbolValue(bSymbol)
                    .Should().Be(args.ProgramState.GetSymbolValue(aSymbol));
                }
            };

            explodedGraph.Walk();

            explorationEnded.Should().BeTrue();
            numberOfProcessedInstructions.Should().Be(9);
            numberOfExitBlockReached.Should().Be(1);
        }
Beispiel #19
0
        private void Analyze(CSharpExplodedGraph explodedGraph, SyntaxNodeAnalysisContext context)
        {
            var analyzerContexts = InitializeAnalyzers(explodedGraph, context).ToList();

            try
            {
                explodedGraph.Walk();
            }
            finally
            {
                foreach (var diagnostic in analyzerContexts.SelectMany(analyzerContext => analyzerContext.GetDiagnostics()))
                {
                    context.ReportDiagnosticWhenActive(diagnostic);
                }

                analyzerContexts.ForEach(analyzerContext => analyzerContext.Dispose());
            }
        }
Beispiel #20
0
        public void ExplodedGraph_AllBranchesVisited()
        {
            string        testInput = "int i = 1; switch (i) { case 1: default: cw1(); break; case 2: cw2(); break; }";
            SemanticModel semanticModel;
            var           method       = ControlFlowGraphTest.CompileWithMethodBody(string.Format(TestInput, testInput), "Bar", out semanticModel);
            var           methodSymbol = semanticModel.GetDeclaredSymbol(method);

            var cfg = CSharpControlFlowGraph.Create(method.Body, semanticModel);
            var lva = CSharpLiveVariableAnalysis.Analyze(cfg, methodSymbol, semanticModel);

            var explodedGraph    = new CSharpExplodedGraph(cfg, methodSymbol, semanticModel, lva);
            var explorationEnded = false;

            explodedGraph.ExplorationEnded += (sender, args) => { explorationEnded = true; };

            var numberOfExitBlockReached = 0;

            explodedGraph.ExitBlockReached += (sender, args) => { numberOfExitBlockReached++; };

            var numberOfCw1InstructionVisits  = 0;
            var numberOfCw2InstructionVisits  = 0;
            var numberOfProcessedInstructions = 0;

            explodedGraph.InstructionProcessed +=
                (sender, args) =>
            {
                numberOfProcessedInstructions++;
                if (args.Instruction.ToString() == "cw1()")
                {
                    numberOfCw1InstructionVisits++;
                }
                if (args.Instruction.ToString() == "cw2()")
                {
                    numberOfCw2InstructionVisits++;
                }
            };

            explodedGraph.Walk();

            explorationEnded.Should().BeTrue();
            numberOfExitBlockReached.Should().Be(1);
            numberOfCw1InstructionVisits.Should().Be(1);
            numberOfCw2InstructionVisits.Should().Be(1);
        }
        public void ExplodedGraph_BothBranchesVisited_StateMerge()
        {
            var testInput    = "var a = !true; bool b; if (inParameter) { b = false; } else { b = false; } a = b;";
            var method       = ControlFlowGraphTest.CompileWithMethodBody(string.Format(TestInput, testInput), "Bar", out var semanticModel);
            var methodSymbol = semanticModel.GetDeclaredSymbol(method);

            var varDeclarators = method.DescendantNodes().OfType <VariableDeclaratorSyntax>();
            var aSymbol        = semanticModel.GetDeclaredSymbol(varDeclarators.First(d => d.Identifier.ToString() == "a"));

            var cfg = CSharpControlFlowGraph.Create(method.Body, semanticModel);
            var lva = CSharpLiveVariableAnalysis.Analyze(cfg, methodSymbol, semanticModel);

            var explodedGraph    = new CSharpExplodedGraph(cfg, methodSymbol, semanticModel, lva);
            var explorationEnded = false;

            explodedGraph.ExplorationEnded += (sender, args) => { explorationEnded = true; };

            var numberOfExitBlockReached = 0;

            explodedGraph.ExitBlockReached += (sender, args) => { numberOfExitBlockReached++; };

            var numberOfLastInstructionVisits = 0;
            var numberOfProcessedInstructions = 0;

            explodedGraph.InstructionProcessed +=
                (sender, args) =>
            {
                numberOfProcessedInstructions++;
                if (args.Instruction.ToString() == "a = b")
                {
                    args.ProgramState.GetSymbolValue(aSymbol).Should().Be(SymbolicValue.False);
                    numberOfLastInstructionVisits++;
                }
            };

            explodedGraph.Walk();

            explorationEnded.Should().BeTrue();
            numberOfExitBlockReached.Should().Be(1);
            numberOfLastInstructionVisits.Should().Be(1);
        }
        public void ExplodedGraph_SingleBranchVisited_And()
        {
            var testInput      = "var a = false; if (a && !a) { a = true; }";
            var method         = ControlFlowGraphTest.CompileWithMethodBody(string.Format(TestInput, testInput), "Bar", out var semanticModel);
            var methodSymbol   = semanticModel.GetDeclaredSymbol(method);
            var varDeclarators = method.DescendantNodes().OfType <VariableDeclaratorSyntax>();
            var aSymbol        = semanticModel.GetDeclaredSymbol(varDeclarators.First(d => d.Identifier.ToString() == "a"));

            var cfg = CSharpControlFlowGraph.Create(method.Body, semanticModel);
            var lva = CSharpLiveVariableAnalysis.Analyze(cfg, methodSymbol, semanticModel);

            var explodedGraph    = new CSharpExplodedGraph(cfg, methodSymbol, semanticModel, lva);
            var explorationEnded = false;

            explodedGraph.ExplorationEnded += (sender, args) => { explorationEnded = true; };

            var numberOfExitBlockReached = 0;

            explodedGraph.ExitBlockReached += (sender, args) => { numberOfExitBlockReached++; };

            var numberOfProcessedInstructions = 0;

            explodedGraph.InstructionProcessed +=
                (sender, args) =>
            {
                numberOfProcessedInstructions++;
                if (args.Instruction.ToString() == "a = !true")
                {
                    args.ProgramState.GetSymbolValue(aSymbol).Should().Be(SymbolicValue.False);     // Roslyn is clever !true has const value.
                }
                if (args.Instruction.ToString() == "!a")
                {
                    Execute.Assertion.FailWith("We should never get into this branch");
                }
            };

            explodedGraph.Walk();

            explorationEnded.Should().BeTrue();
            numberOfExitBlockReached.Should().Be(1);
        }
Beispiel #23
0
        public void ExplodedGraph_NonLocalNorFieldSymbolBranching()
        {
            string        testInput = "if (Property) { cw(); }";
            SemanticModel semanticModel;
            var           method         = ControlFlowGraphTest.CompileWithMethodBody(string.Format(TestInput, testInput), "Bar", out semanticModel);
            var           methodSymbol   = semanticModel.GetDeclaredSymbol(method);
            var           propertySymbol = semanticModel.GetSymbolInfo(
                method.DescendantNodes().OfType <IdentifierNameSyntax>().First(d => d.Identifier.ToString() == "Property")).Symbol;

            propertySymbol.Should().NotBeNull();

            var cfg = CSharpControlFlowGraph.Create(method.Body, semanticModel);
            var lva = CSharpLiveVariableAnalysis.Analyze(cfg, methodSymbol, semanticModel);

            var explodedGraph    = new CSharpExplodedGraph(cfg, methodSymbol, semanticModel, lva);
            var explorationEnded = false;

            explodedGraph.ExplorationEnded += (sender, args) => { explorationEnded = true; };

            var numberOfExitBlockReached = 0;

            explodedGraph.ExitBlockReached += (sender, args) => { numberOfExitBlockReached++; };

            var numberOfProcessedInstructions = 0;

            explodedGraph.InstructionProcessed +=
                (sender, args) =>
            {
                numberOfProcessedInstructions++;
                if (args.Instruction.ToString() == "Property")
                {
                    args.ProgramState.GetSymbolValue(propertySymbol).Should().BeNull();
                }
            };

            explodedGraph.Walk();

            explorationEnded.Should().BeTrue();
            numberOfExitBlockReached.Should().Be(1);
        }
        public void ExplodedGraph_SequentialInput_OutParameter()
        {
            var testInput          = "outParameter = true;";
            var method             = ControlFlowGraphTest.CompileWithMethodBody(string.Format(TestInput, testInput), "Bar", out var semanticModel);
            var methodSymbol       = semanticModel.GetDeclaredSymbol(method);
            var parameters         = method.DescendantNodes().OfType <ParameterSyntax>();
            var outParameterSymbol = semanticModel.GetDeclaredSymbol(parameters.First(d => d.Identifier.ToString() == "outParameter"));

            var cfg = CSharpControlFlowGraph.Create(method.Body, semanticModel);
            var lva = CSharpLiveVariableAnalysis.Analyze(cfg, methodSymbol, semanticModel);

            var explodedGraph    = new CSharpExplodedGraph(cfg, methodSymbol, semanticModel, lva);
            var explorationEnded = false;

            explodedGraph.ExplorationEnded += (sender, args) => { explorationEnded = true; };

            var numberOfExitBlockReached = 0;

            explodedGraph.ExitBlockReached += (sender, args) => { numberOfExitBlockReached++; };

            var numberOfProcessedInstructions = 0;

            explodedGraph.InstructionProcessed +=
                (sender, args) =>
            {
                numberOfProcessedInstructions++;
                if (args.Instruction.ToString() == "outParameter = true")
                {
                    args.ProgramState.GetSymbolValue(outParameterSymbol)
                    .Should().Be(SymbolicValue.True);
                }
            };

            explodedGraph.Walk();

            explorationEnded.Should().BeTrue();
            numberOfProcessedInstructions.Should().Be(2);
            numberOfExitBlockReached.Should().Be(1);
        }
Beispiel #25
0
        private static void CheckForMultipleDispose(CSharpExplodedGraph explodedGraph, SyntaxNodeAnalysisContext context)
        {
            var objectDisposedCheck = new ObjectDisposedPointerCheck(explodedGraph);

            explodedGraph.AddExplodedGraphCheck(objectDisposedCheck);

            void memberAccessedHandler(object sender, ObjectDisposedEventArgs args)
            {
                context.ReportDiagnosticWhenActive(
                    Diagnostic.Create(rule, args.Location, args.Name));
            }

            objectDisposedCheck.ObjectDisposed += memberAccessedHandler;

            try
            {
                explodedGraph.Walk();
            }
            finally
            {
                objectDisposedCheck.ObjectDisposed -= memberAccessedHandler;
            }
        }
Beispiel #26
0
 private IEnumerable <ISymbolicExecutionAnalysisContext> InitializeAnalyzers(CSharpExplodedGraph explodedGraph, SyntaxNodeAnalysisContext context) =>
 symbolicExecutionAnalyzerFactory
 .GetEnabledAnalyzers(context)
 .Select(analyzer => analyzer.AddChecks(explodedGraph, context));
Beispiel #27
0
 public ISymbolicExecutionAnalysisContext AddChecks(CSharpExplodedGraph explodedGraph, SyntaxNodeAnalysisContext context) =>
 new AnalysisContext(explodedGraph);
Beispiel #28
0
 public EmptyCollectionAccessedCheck(CSharpExplodedGraph explodedGraph)
     : base(explodedGraph)
 {
 }
 public NullValueAccessedCheck(CSharpExplodedGraph explodedGraph)
     : base(explodedGraph)
 {
 }
Beispiel #30
0
 public ObjectDisposedPointerCheck(CSharpExplodedGraph explodedGraph, AnalysisContext context) : base(explodedGraph) =>
     this.context = context;