public bool TryGetOrComputeResult(
            ImmutableArray <IOperation> operationBlocks,
            IMethodSymbol containingMethod,
            bool trackInstanceFields,
            out DataFlowAnalysisResult <DisposeBlockAnalysisResult, DisposeAbstractValue> disposeAnalysisResult,
            out DataFlowAnalysisResult <PointsToBlockAnalysisResult, PointsToAbstractValue> pointsToAnalysisResult,
            out ImmutableDictionary <IFieldSymbol, PointsToAbstractValue> trackedInstanceFieldPointsToMap)
        {
            foreach (var operationRoot in operationBlocks)
            {
                IBlockOperation topmostBlock = operationRoot.GetTopmostParentBlock();
                if (topmostBlock != null)
                {
                    var cfg = ControlFlowGraph.Create(topmostBlock);

                    // Invoking an instance method may likely invalidate all the instance field analysis state, i.e.
                    // reference type fields might be re-assigned to point to different objects in the called method.
                    // An optimistic points to analysis assumes that the points to values of instance fields don't change on invoking an instance method.
                    // A pessimistic points to analysis resets all the instance state and assumes the instance field might point to any object, hence has unknown state.
                    // For dispose analysis, we want to perform an optimistic points to analysis as we assume a disposable field is not likely to be re-assigned to a separate object in helper method invocations in Dispose.
                    pointsToAnalysisResult = PointsToAnalysis.GetOrComputeResult(cfg, containingMethod, _wellKnownTypeProvider, pessimisticAnalysis: false);
                    disposeAnalysisResult  = DisposeAnalysis.GetOrComputeResult(cfg, containingMethod, _wellKnownTypeProvider, _disposeOwnershipTransferLikelyTypes, pointsToAnalysisResult,
                                                                                trackInstanceFields, out trackedInstanceFieldPointsToMap);
                    return(true);
                }
            }

            disposeAnalysisResult           = null;
            pointsToAnalysisResult          = null;
            trackedInstanceFieldPointsToMap = null;
            return(false);
        }
Exemple #2
0
        private static TaintedDataAnalysisResult GetOrComputeResult(
            ControlFlowGraph cfg,
            Compilation compilation,
            ISymbol containingMethod,
            TaintedDataSymbolMap <SourceInfo> taintedSourceInfos,
            TaintedDataSymbolMap <SanitizerInfo> taintedSanitizerInfos,
            TaintedDataSymbolMap <SinkInfo> taintedSinkInfos,
            InterproceduralAnalysisConfiguration interproceduralAnalysisConfig)
        {
            WellKnownTypeProvider  wellKnownTypeProvider  = WellKnownTypeProvider.GetOrCreate(compilation);
            PointsToAnalysisResult pointsToAnalysisResult = PointsToAnalysis.GetOrComputeResult(
                cfg,
                containingMethod,
                wellKnownTypeProvider,
                interproceduralAnalysisConfig,
                interproceduralAnalysisPredicateOpt: null,
                pessimisticAnalysis: true,
                performCopyAnalysis: false);

            TaintedDataAnalysisContext analysisContext = TaintedDataAnalysisContext.Create(
                TaintedDataAbstractValueDomain.Default,
                wellKnownTypeProvider,
                cfg,
                containingMethod,
                interproceduralAnalysisConfig,
                pessimisticAnalysis: false,
                pointsToAnalysisResult: pointsToAnalysisResult,
                getOrComputeAnalysisResult: GetOrComputeResultForAnalysisContext,
                taintedSourceInfos: taintedSourceInfos,
                taintedSanitizerInfos: taintedSanitizerInfos,
                taintedSinkInfos: taintedSinkInfos);

            return(GetOrComputeResultForAnalysisContext(analysisContext));
        }
Exemple #3
0
        public void GeneratePTG(MethodDefinition method)
        {
            var methodInfo = programInfo.GetOrAdd(method);

            //GenerateIL(method);
            //GenerateTAC(method);
            //GenerateCFG(method);
            //GenerateWebs(method);
            GenerateSSA(method);

            if (!methodInfo.Contains("PTG_TEXT"))
            {
                var cfg = methodInfo.Get <ControlFlowGraph>("CFG");

                // Points-to
                var pointsTo = new PointsToAnalysis(cfg, method);
                var result   = pointsTo.Analyze();

                var ptg = result[cfg.Exit.Id].Output;
                //ptg.RemoveVariablesExceptParameters();
                //ptg.RemoveTemporalVariables();

                var text = DGMLSerializer.Serialize(ptg);

                methodInfo.Set("PTG_TEXT", text);
            }
        }
Exemple #4
0
        private static bool ReportDiagnosticIfNecessary(OperationAnalysisContext operationContext,
                                                        IOperation argumentValue,
                                                        SyntaxNode syntax,
                                                        ISymbol invokedSymbol,
                                                        ISymbol containingMethod)
        {
            if (argumentValue.Type.SpecialType != SpecialType.System_String || !argumentValue.ConstantValue.HasValue)
            {
                // We have a candidate for diagnostic. perform more precise dataflow analysis.
                var topmostBlock = argumentValue.GetTopmostParentBlock();
                if (topmostBlock != null)
                {
                    var cfg = ControlFlowGraph.Create(topmostBlock);
                    var wellKnownTypeProvider        = WellKnownTypeProvider.GetOrCreate(operationContext.Compilation);
                    var copyAnalysisResult           = CopyAnalysis.GetOrComputeResult(cfg, containingMethod, wellKnownTypeProvider);
                    var nullAnalysisResult           = NullAnalysis.GetOrComputeResult(cfg, containingMethod, wellKnownTypeProvider);
                    var pointsToAnalysisResult       = PointsToAnalysis.GetOrComputeResult(cfg, containingMethod, wellKnownTypeProvider, nullAnalysisResult);
                    var stringContentResult          = StringContentAnalysis.GetOrComputeResult(cfg, containingMethod, wellKnownTypeProvider, copyAnalysisResult, nullAnalysisResult, pointsToAnalysisResult);
                    StringContentAbstractValue value = stringContentResult[argumentValue];
                    if (value.NonLiteralState == StringContainsNonLiteralState.No)
                    {
                        // The value is a constant literal or default/unitialized, so avoid flagging this usage.
                        return(false);
                    }
                }

                // Review if the symbol passed to {invocation} in {method/field/constructor/etc} has user input.
                operationContext.ReportDiagnostic(syntax.CreateDiagnostic(Rule,
                                                                          invokedSymbol.ToDisplayString(SymbolDisplayFormat.MinimallyQualifiedFormat),
                                                                          containingMethod.Name));
                return(true);
            }

            return(false);
        }
Exemple #5
0
        public static Set <string> ComputeAnalizableMethods(Node node, PointsToAnalysis ptwe)
        {
            AnalyzableMethodFinder amf = new AnalyzableMethodFinder(ptwe);

            amf.Visit(node);
            return(amf.analizableMethods);
        }
Exemple #6
0
 public MyCGGenerator(CallGraph cg, Method m, AnalyzableMethodFinder methodsFinder)
 {
     this.current       = m;
     this.cg            = cg;
     this.currentPTWE   = methodsFinder.ptwe;
     this.methodsFinder = methodsFinder;
 }
 // Constructor
 public PointsToAndWriteEffects(Method m, PointsToAnalysis pta) : base(m,pta)
 {
     this.writeEffects = new AbstractEffects();
     this.allWriteEffects = new AbstractEffects();
     this.readEffects = new AbstractEffects();
     this.allReadEffects = new AbstractEffects();
     this.callToNonAnalyzableMethods = new Dictionary<Label, Set<Method>>();
     // this.nonNullState = null;
 }
Exemple #8
0
        public ConsistencyState(Method m, PointsToAnalysis pta)
            : base(m, pta)
        {
            consistency = new Dictionary <IPTAnalysisNode, AbstractValue>();


            exposedNodes      = new Set <IPTAnalysisNode>();
            this.nonNullState = null;
        }
Exemple #9
0
        public static CallGraph ComputeAnalyzableMethods(Node node, PointsToAnalysis ptwe)
        {
            Set <AssemblyNode> assemblies = new Set <AssemblyNode>();

            // AnalyzableMethodFinder amf = new AnalyzableMethodFinder(node,);
            AnalyzableMethodFinder amf = new AnalyzableMethodFinder(ptwe);

            if (node is AssemblyNode)
            {
                AssemblyNode assemblyNode = (AssemblyNode)node;
                amf.assemblies.Add(node);
                foreach (AssemblyReference reference in assemblyNode.AssemblyReferences)
                {
                    amf.assemblies.Add(reference.Assembly);
                }
            }
            amf.Visit(node);

            /*
             * foreach (AssemblyNode an in amf.assemblies)
             * {
             *  Console.Out.WriteLine("*ENTRE*");
             *  amf.Visit(an);
             * }
             */

            // amf.Visit(node);
            if (PointsToAnalysis.verbose)
            {
                Set <CallGraph> cgs;
                cgs = new Set <CallGraph>();
                cgs.Add(amf.cg);
                CallGraph.GenerateDotGraph(Console.Out, cgs);
            }
            return(amf.cg);
        }
Exemple #10
0
 public ConsistentyElementFactory(PointsToAnalysis pta) : base(pta)
 {
 }
        public override void Initialize(AnalysisContext context)
        {
            context.EnableConcurrentExecution();
            context.ConfigureGeneratedCodeAnalysis(GeneratedCodeAnalysisFlags.Analyze);

            context.RegisterCompilationStartAction(compilationContext =>
            {
                if (!DisposeAnalysisHelper.TryGetOrCreate(compilationContext.Compilation, out DisposeAnalysisHelper? disposeAnalysisHelper))
                {
                    return;
                }

                var fieldDisposeValueMap = new ConcurrentDictionary <IFieldSymbol, /*disposed*/ bool>();
                void addOrUpdateFieldDisposedValue(IFieldSymbol field, bool disposed)
                {
                    Debug.Assert(!field.IsStatic);
                    Debug.Assert(disposeAnalysisHelper !.IsDisposable(field.Type));

                    fieldDisposeValueMap.AddOrUpdate(field,
                                                     addValue: disposed,
                                                     updateValueFactory: (f, currentValue) => currentValue || disposed);
                };

                var hasErrors = false;
                compilationContext.RegisterOperationAction(_ => hasErrors = true, OperationKind.Invalid);

                // Disposable fields with initializer at declaration must be disposed.
                compilationContext.RegisterOperationAction(operationContext =>
                {
                    if (!ShouldAnalyze(operationContext.ContainingSymbol.ContainingType))
                    {
                        return;
                    }

                    var initializedFields = ((IFieldInitializerOperation)operationContext.Operation).InitializedFields;
                    foreach (var field in initializedFields)
                    {
                        if (!field.IsStatic &&
                            disposeAnalysisHelper.GetDisposableFields(field.ContainingType).Contains(field))
                        {
                            addOrUpdateFieldDisposedValue(field, disposed: false);
                        }
                    }
                },
                                                           OperationKind.FieldInitializer);

                // Instance fields initialized in constructor/method body with a locally created disposable object must be disposed.
                compilationContext.RegisterOperationBlockStartAction(operationBlockStartContext =>
                {
                    if (!(operationBlockStartContext.OwningSymbol is IMethodSymbol containingMethod) ||
                        !ShouldAnalyze(containingMethod.ContainingType))
                    {
                        return;
                    }

                    if (disposeAnalysisHelper.HasAnyDisposableCreationDescendant(operationBlockStartContext.OperationBlocks, containingMethod))
                    {
                        PointsToAnalysisResult?lazyPointsToAnalysisResult = null;

                        operationBlockStartContext.RegisterOperationAction(operationContext =>
                        {
                            var fieldReference = (IFieldReferenceOperation)operationContext.Operation;
                            var field          = fieldReference.Field;

                            // Only track instance fields on the current instance.
                            if (field.IsStatic || fieldReference.Instance?.Kind != OperationKind.InstanceReference)
                            {
                                return;
                            }

                            // Check if this is a Disposable field that is not currently being tracked.
                            if (fieldDisposeValueMap.ContainsKey(field) ||
                                !disposeAnalysisHelper.GetDisposableFields(field.ContainingType).Contains(field))
                            {
                                return;
                            }

                            // We have a field reference for a disposable field.
                            // Check if it is being assigned a locally created disposable object.
                            if (fieldReference.Parent is ISimpleAssignmentOperation simpleAssignmentOperation &&
                                simpleAssignmentOperation.Target == fieldReference)
                            {
                                if (lazyPointsToAnalysisResult == null)
                                {
                                    var cfg = operationBlockStartContext.OperationBlocks.GetControlFlowGraph();
                                    if (cfg == null)
                                    {
                                        hasErrors = true;
                                        return;
                                    }

                                    var wellKnownTypeProvider         = WellKnownTypeProvider.GetOrCreate(operationContext.Compilation);
                                    var interproceduralAnalysisConfig = InterproceduralAnalysisConfiguration.Create(
                                        operationBlockStartContext.Options, Rule, InterproceduralAnalysisKind.None, operationBlockStartContext.CancellationToken);
                                    var pointsToAnalysisResult = PointsToAnalysis.TryGetOrComputeResult(cfg,
                                                                                                        containingMethod, operationBlockStartContext.Options, wellKnownTypeProvider, interproceduralAnalysisConfig,
                                                                                                        interproceduralAnalysisPredicateOpt: null,
                                                                                                        pessimisticAnalysis: false, performCopyAnalysis: false);
                                    if (pointsToAnalysisResult == null)
                                    {
                                        hasErrors = true;
                                        return;
                                    }

                                    Interlocked.CompareExchange(ref lazyPointsToAnalysisResult, pointsToAnalysisResult, null);
                                }

                                PointsToAbstractValue assignedPointsToValue = lazyPointsToAnalysisResult[simpleAssignmentOperation.Value.Kind, simpleAssignmentOperation.Value.Syntax];
                                foreach (var location in assignedPointsToValue.Locations)
                                {
                                    if (disposeAnalysisHelper.IsDisposableCreationOrDisposeOwnershipTransfer(location, containingMethod))
                                    {
                                        addOrUpdateFieldDisposedValue(field, disposed: false);
                                        break;
                                    }
                                }
                            }
                        },
                                                                           OperationKind.FieldReference);
                    }

                    // Mark fields disposed in Dispose method(s).
                    if (IsDisposeMethod(containingMethod))
                    {
                        var disposableFields = disposeAnalysisHelper.GetDisposableFields(containingMethod.ContainingType);
                        if (!disposableFields.IsEmpty)
                        {
                            if (disposeAnalysisHelper.TryGetOrComputeResult(operationBlockStartContext.OperationBlocks, containingMethod,
                                                                            operationBlockStartContext.Options, Rule, trackInstanceFields: true, trackExceptionPaths: false, cancellationToken: operationBlockStartContext.CancellationToken,
                                                                            disposeAnalysisResult: out var disposeAnalysisResult, pointsToAnalysisResult: out var pointsToAnalysisResult))
                            {
                                RoslynDebug.Assert(disposeAnalysisResult.TrackedInstanceFieldPointsToMap != null);

                                BasicBlock exitBlock = disposeAnalysisResult.ControlFlowGraph.GetExit();
                                foreach (var fieldWithPointsToValue in disposeAnalysisResult.TrackedInstanceFieldPointsToMap)
                                {
                                    IFieldSymbol field = fieldWithPointsToValue.Key;
                                    PointsToAbstractValue pointsToValue = fieldWithPointsToValue.Value;

                                    Debug.Assert(disposeAnalysisHelper.IsDisposable(field.Type));
                                    ImmutableDictionary <AbstractLocation, DisposeAbstractValue> disposeDataAtExit = disposeAnalysisResult.ExitBlockOutput.Data;
                                    var disposed = false;
                                    foreach (var location in pointsToValue.Locations)
                                    {
                                        if (disposeDataAtExit.TryGetValue(location, out DisposeAbstractValue disposeValue))
                                        {
                                            switch (disposeValue.Kind)
                                            {
                                            // For MaybeDisposed, conservatively mark the field as disposed as we don't support path sensitive analysis.
                                            case DisposeAbstractValueKind.MaybeDisposed:
                                            case DisposeAbstractValueKind.Unknown:
                                            case DisposeAbstractValueKind.Escaped:
                                            case DisposeAbstractValueKind.Disposed:
                                                disposed = true;
                                                addOrUpdateFieldDisposedValue(field, disposed);
                                                break;
                                            }
                                        }

                                        if (disposed)
                                        {
                                            break;
                                        }
                                    }
                                }
                            }
                        }
                    }
                });

                compilationContext.RegisterCompilationEndAction(compilationEndContext =>
                {
                    if (hasErrors)
                    {
                        return;
                    }

                    foreach (var kvp in fieldDisposeValueMap)
                    {
                        IFieldSymbol field = kvp.Key;
                        bool disposed      = kvp.Value;

                        // Flag non-disposed fields only if the containing type has a Dispose method implementation.
                        if (!disposed &&
                            HasDisposeMethod(field.ContainingType))
                        {
                            // '{0}' contains field '{1}' that is of IDisposable type '{2}', but it is never disposed. Change the Dispose method on '{0}' to call Close or Dispose on this field.
                            var arg1       = field.ContainingType.ToDisplayString(SymbolDisplayFormat.MinimallyQualifiedFormat);
                            var arg2       = field.Name;
                            var arg3       = field.Type.ToDisplayString(SymbolDisplayFormat.MinimallyQualifiedFormat);
                            var diagnostic = field.CreateDiagnostic(Rule, arg1, arg2, arg3);
                            compilationEndContext.ReportDiagnostic(diagnostic);
                        }
                    }
                });

                return;

                // Local functions
                bool ShouldAnalyze(INamedTypeSymbol namedType)
                {
                    // We only want to analyze types which are disposable (implement System.IDisposable directly or indirectly)
                    // and have at least one disposable field.
                    return(!hasErrors &&
                           disposeAnalysisHelper !.IsDisposable(namedType) &&
                           !disposeAnalysisHelper.GetDisposableFields(namedType).IsEmpty&&
                           !namedType.IsConfiguredToSkipAnalysis(compilationContext.Options, Rule, compilationContext.Compilation, compilationContext.CancellationToken));
                }

                bool IsDisposeMethod(IMethodSymbol method)
                => disposeAnalysisHelper !.GetDisposeMethodKind(method) != DisposeMethodKind.None;

                bool HasDisposeMethod(INamedTypeSymbol namedType)
                {
                    foreach (var method in namedType.GetMembers().OfType <IMethodSymbol>())
                    {
                        if (IsDisposeMethod(method))
                        {
                            return(true);
                        }
                    }

                    return(false);
                }
            });
        }
        public override void Initialize(AnalysisContext context)
        {
            context.EnableConcurrentExecution();
            context.ConfigureGeneratedCodeAnalysis(GeneratedCodeAnalysisFlags.None);

            context.RegisterCompilationStartAction(compilationContext =>
            {
                INamedTypeSymbol localizableStateAttributeSymbol  = WellKnownTypes.LocalizableAttribute(compilationContext.Compilation);
                INamedTypeSymbol conditionalAttributeSymbol       = WellKnownTypes.ConditionalAttribute(compilationContext.Compilation);
                INamedTypeSymbol systemConsoleSymbol              = WellKnownTypes.Console(compilationContext.Compilation);
                ImmutableHashSet <INamedTypeSymbol> typesToIgnore = GetTypesToIgnore(compilationContext.Compilation);

                compilationContext.RegisterOperationBlockStartAction(operationBlockStartContext =>
                {
                    if (!(operationBlockStartContext.OwningSymbol is IMethodSymbol containingMethod))
                    {
                        return;
                    }

                    var lazyStringContentResult = new Lazy <DataFlowAnalysisResult <StringContentBlockAnalysisResult, StringContentAbstractValue> >(
                        valueFactory: ComputeStringContentAnalysisResult, isThreadSafe: false);

                    operationBlockStartContext.RegisterOperationAction(operationContext =>
                    {
                        var argument = (IArgumentOperation)operationContext.Operation;
                        switch (argument.Parent?.Kind)
                        {
                        case OperationKind.Invocation:
                        case OperationKind.ObjectCreation:
                            AnalyzeArgument(argument.Parameter, containingPropertySymbolOpt: null, operation: argument, reportDiagnostic: operationContext.ReportDiagnostic);
                            return;
                        }
                    }, OperationKind.Argument);

                    operationBlockStartContext.RegisterOperationAction(operationContext =>
                    {
                        var propertyReference = (IPropertyReferenceOperation)operationContext.Operation;
                        if (propertyReference.Parent is IAssignmentOperation assignment &&
                            assignment.Target == propertyReference &&
                            !propertyReference.Property.IsIndexer &&
                            propertyReference.Property.SetMethod?.Parameters.Length == 1)
                        {
                            IParameterSymbol valueSetterParam = propertyReference.Property.SetMethod.Parameters[0];
                            AnalyzeArgument(valueSetterParam, propertyReference.Property, assignment, operationContext.ReportDiagnostic);
                        }
                    }, OperationKind.PropertyReference);

                    void AnalyzeArgument(IParameterSymbol parameter, IPropertySymbol containingPropertySymbolOpt, IOperation operation, Action <Diagnostic> reportDiagnostic)
                    {
                        if (ShouldBeLocalized(parameter, containingPropertySymbolOpt, localizableStateAttributeSymbol, conditionalAttributeSymbol, systemConsoleSymbol, typesToIgnore))
                        {
                            StringContentAbstractValue stringContentValue = lazyStringContentResult.Value[operation];
                            if (stringContentValue.IsLiteralState)
                            {
                                Debug.Assert(stringContentValue.LiteralValues.Count > 0);

                                // FxCop compat: Do not fire if the literal value came from a default parameter value
                                if (stringContentValue.LiteralValues.Count == 1 &&
                                    parameter.IsOptional &&
                                    parameter.ExplicitDefaultValue is string defaultValue &&
                                    defaultValue == stringContentValue.LiteralValues.Single())
                                {
                                    return;
                                }

                                // FxCop compat: Do not fire if none of the string literals have any non-control character.
                                if (!LiteralValuesHaveNonControlCharacters(stringContentValue.LiteralValues))
                                {
                                    return;
                                }

                                // FxCop compat: Filter out xml string literals.
                                var filteredStrings = stringContentValue.LiteralValues.Where(literal => !LooksLikeXmlTag(literal));
                                if (filteredStrings.Any())
                                {
                                    // Method '{0}' passes a literal string as parameter '{1}' of a call to '{2}'. Retrieve the following string(s) from a resource table instead: "{3}".
                                    var arg1       = containingMethod.ToDisplayString(SymbolDisplayFormat.MinimallyQualifiedFormat);
                                    var arg2       = parameter.Name;
                                    var arg3       = parameter.ContainingSymbol.ToDisplayString(SymbolDisplayFormat.MinimallyQualifiedFormat);
                                    var arg4       = FormatLiteralValues(filteredStrings);
                                    var diagnostic = operation.CreateDiagnostic(Rule, arg1, arg2, arg3, arg4);
                                    reportDiagnostic(diagnostic);
                                }
                            }
                        }
                    }

                    DataFlowAnalysisResult <StringContentBlockAnalysisResult, StringContentAbstractValue> ComputeStringContentAnalysisResult()
                    {
                        foreach (var operationRoot in operationBlockStartContext.OperationBlocks)
                        {
                            IBlockOperation topmostBlock = operationRoot.GetTopmostParentBlock();
                            if (topmostBlock != null)
                            {
                                var cfg = ControlFlowGraph.Create(topmostBlock);
                                var wellKnownTypeProvider  = WellKnownTypeProvider.GetOrCreate(operationBlockStartContext.Compilation);
                                var pointsToAnalysisResult = PointsToAnalysis.GetOrComputeResult(cfg, containingMethod, wellKnownTypeProvider);
                                var copyAnalysisResult     = CopyAnalysis.GetOrComputeResult(cfg, containingMethod, wellKnownTypeProvider, pointsToAnalysisResultOpt: pointsToAnalysisResult);
                                // Do another analysis pass to improve the results from PointsTo and Copy analysis.
                                pointsToAnalysisResult = PointsToAnalysis.GetOrComputeResult(cfg, containingMethod, wellKnownTypeProvider, pointsToAnalysisResult, copyAnalysisResult);
                                return(StringContentAnalysis.GetOrComputeResult(cfg, containingMethod, wellKnownTypeProvider, copyAnalysisResult, pointsToAnalysisResult));
                            }
                        }

                        return(null);
                    }
                });
            });
        }
Exemple #13
0
        public override void Initialize(AnalysisContext context)
        {
            context.EnableConcurrentExecution();
            context.ConfigureGeneratedCodeAnalysis(GeneratedCodeAnalysisFlags.None);
            context.RegisterCompilationStartAction(compilationContext =>
            {
                var iDisposable = WellKnownTypes.IDisposable(compilationContext.Compilation);
                if (iDisposable == null)
                {
                    return;
                }

                var iCollection        = WellKnownTypes.ICollection(compilationContext.Compilation);
                var genericICollection = WellKnownTypes.GenericICollection(compilationContext.Compilation);
                var disposeOwnershipTransferLikelyTypes = GetDisposeOwnershipTransferLikelyTypes(compilationContext.Compilation);
                compilationContext.RegisterOperationBlockStartAction(operationBlockStartContext =>
                {
                    bool hasDisposableCreation = false;
                    operationBlockStartContext.RegisterOperationAction(operationContext =>
                    {
                        if (!hasDisposableCreation &&
                            operationContext.Operation.Type.IsDisposable(iDisposable))
                        {
                            hasDisposableCreation = true;
                        }
                    },
                                                                       OperationKind.ObjectCreation,
                                                                       OperationKind.TypeParameterObjectCreation,
                                                                       OperationKind.DynamicObjectCreation,
                                                                       OperationKind.Invocation);

                    operationBlockStartContext.RegisterOperationBlockEndAction(operationBlockEndContext =>
                    {
                        if (!hasDisposableCreation ||
                            !(operationBlockEndContext.OwningSymbol is IMethodSymbol containingMethod))
                        {
                            return;
                        }

                        foreach (var operationRoot in operationBlockEndContext.OperationBlocks)
                        {
                            IBlockOperation topmostBlock = operationRoot.GetTopmostParentBlock();
                            if (topmostBlock != null)
                            {
                                var cfg = ControlFlowGraph.Create(topmostBlock);
                                var nullAnalysisResult     = NullAnalysis.GetOrComputeResult(cfg, containingMethod.ContainingType);
                                var pointsToAnalysisResult = PointsToAnalysis.GetOrComputeResult(cfg, containingMethod.ContainingType, nullAnalysisResult);
                                var disposeAnalysisResult  = DisposeAnalysis.GetOrComputeResult(cfg, iDisposable, iCollection,
                                                                                                genericICollection, disposeOwnershipTransferLikelyTypes, containingMethod.ContainingType, pointsToAnalysisResult, nullAnalysisResult);
                                ImmutableDictionary <AbstractLocation, DisposeAbstractValue> disposeDataAtExit = disposeAnalysisResult[cfg.Exit].InputData;
                                foreach (var kvp in disposeDataAtExit)
                                {
                                    AbstractLocation location         = kvp.Key;
                                    DisposeAbstractValue disposeValue = kvp.Value;
                                    if (disposeValue.Kind == DisposeAbstractValueKind.NotDisposed ||
                                        ((disposeValue.Kind == DisposeAbstractValueKind.Disposed ||
                                          disposeValue.Kind == DisposeAbstractValueKind.MaybeDisposed) &&
                                         disposeValue.DisposingOperations.Count > 0 &&
                                         disposeValue.DisposingOperations.All(d => d.IsInsideCatchClause())))
                                    {
                                        Debug.Assert(location.CreationOpt != null);

                                        // CA2000: In method '{0}', call System.IDisposable.Dispose on object created by '{1}' before all references to it are out of scope.
                                        var arg1       = containingMethod.ToDisplayString(SymbolDisplayFormat.MinimallyQualifiedFormat);
                                        var arg2       = location.CreationOpt.Syntax.ToString();
                                        var diagnostic = location.CreationOpt.Syntax.CreateDiagnostic(Rule, arg1, arg2);
                                        operationBlockEndContext.ReportDiagnostic(diagnostic);
                                    }
                                }

                                break;
                            }
                        }
                    });
                });
            });
        }
        /// <summary>
        /// Analyzers should use <see cref="BatchGetOrComputeHazardousUsages"/> instead.  Gets hazardous usages of an object based on a set of its properties.
        /// </summary>
        /// <param name="cfg">Control flow graph of the code.</param>
        /// <param name="compilation">Compilation containing the code.</param>
        /// <param name="owningSymbol">Symbol of the code to examine.</param>
        /// <param name="typeToTrackMetadataName">Name of the type to track.</param>
        /// <param name="constructorMapper">How constructor invocations map to <see cref="PropertySetAbstractValueKind"/>s.</param>
        /// <param name="propertyMappers">How property assignments map to <see cref="PropertySetAbstractValueKind"/>.</param>
        /// <param name="hazardousUsageEvaluators">When and how to evaluate <see cref="PropertySetAbstractValueKind"/>s to for hazardous usages.</param>
        /// <param name="interproceduralAnalysisConfig">Interprocedural dataflow analysis configuration.</param>
        /// <param name="pessimisticAnalysis">Whether to be pessimistic.</param>
        /// <returns>Property set analysis result.</returns>
        internal static PropertySetAnalysisResult GetOrComputeResult(
            ControlFlowGraph cfg,
            Compilation compilation,
            ISymbol owningSymbol,
            AnalyzerOptions analyzerOptions,
            string typeToTrackMetadataName,
            ConstructorMapper constructorMapper,
            PropertyMapperCollection propertyMappers,
            HazardousUsageEvaluatorCollection hazardousUsageEvaluators,
            InterproceduralAnalysisConfiguration interproceduralAnalysisConfig,
            bool pessimisticAnalysis = false)
        {
            if (constructorMapper == null)
            {
                throw new ArgumentNullException(nameof(constructorMapper));
            }

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

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

            constructorMapper.Validate(propertyMappers.PropertyValuesCount);

            var wellKnownTypeProvider = WellKnownTypeProvider.GetOrCreate(compilation);

            PointsToAnalysisResult     pointsToAnalysisResult;
            ValueContentAnalysisResult valueContentAnalysisResultOpt;

            if (!constructorMapper.RequiresValueContentAnalysis && !propertyMappers.RequiresValueContentAnalysis)
            {
                pointsToAnalysisResult = PointsToAnalysis.TryGetOrComputeResult(
                    cfg,
                    owningSymbol,
                    analyzerOptions,
                    wellKnownTypeProvider,
                    interproceduralAnalysisConfig,
                    interproceduralAnalysisPredicateOpt: null,
                    pessimisticAnalysis,
                    performCopyAnalysis: false);
                if (pointsToAnalysisResult == null)
                {
                    return(null);
                }

                valueContentAnalysisResultOpt = null;
            }
            else
            {
                valueContentAnalysisResultOpt = ValueContentAnalysis.TryGetOrComputeResult(
                    cfg,
                    owningSymbol,
                    analyzerOptions,
                    wellKnownTypeProvider,
                    interproceduralAnalysisConfig,
                    out var copyAnalysisResult,
                    out pointsToAnalysisResult,
                    pessimisticAnalysis,
                    performCopyAnalysis: false);
                if (valueContentAnalysisResultOpt == null)
                {
                    return(null);
                }
            }

            var analysisContext = PropertySetAnalysisContext.Create(
                PropertySetAbstractValueDomain.Default,
                wellKnownTypeProvider,
                cfg,
                owningSymbol,
                analyzerOptions,
                interproceduralAnalysisConfig,
                pessimisticAnalysis,
                pointsToAnalysisResult,
                valueContentAnalysisResultOpt,
                TryGetOrComputeResultForAnalysisContext,
                typeToTrackMetadataName,
                constructorMapper,
                propertyMappers,
                hazardousUsageEvaluators);
            var result = TryGetOrComputeResultForAnalysisContext(analysisContext);

            return(result);
        }
Exemple #15
0
 /// <summary>
 /// Constructor
 /// </summary>
 /// <param name="t"></param>
 /// <param name="pta"></param>
 public PointsToInferer(TypeSystem t, PointsToAnalysis pta)
 {
   this.pointsToStateAnalysys = pta;
   typeSystem = t;
   iVisitor = GetInstructionVisitor(this);
 }
Exemple #16
0
    // Constructor
    public PointsToState(Method m, PointsToAnalysis pta)
    {
      this.pta = pta;

      this.pointsToGraph = new PTGraph(m);

      // this.callToNonAnalyzableMethods = new Dictionary<Label, Set<Method>>();
      this.method = m;
      // this.exceptions = new Set<TypeNode>();
      this.currentException = null;

      this.methodAssumptions = new Set<Method>();

      this.isDefault = true;

    }
Exemple #17
0
 public MyCGGenerator(CallGraph cg, Method m, PointsToAnalysis currentPTWE)
 {
     this.current     = m;
     this.cg          = cg;
     this.currentPTWE = currentPTWE;
 }
Exemple #18
0
 public AnalyzableMethodFinder(PointsToAnalysis ptwe)
 {
     this.ptwe = ptwe;
     this.unitUnderAnalysis = ptwe.unitUnderAnalysis;
     cg = new CallGraph();
 }
 public ExposureElementFactory(PointsToAnalysis pta) : base(pta)
 {
 }
        public override void Initialize(AnalysisContext context)
        {
            context.EnableConcurrentExecution();
            context.ConfigureGeneratedCodeAnalysis(GeneratedCodeAnalysisFlags.None);

            context.RegisterCompilationStartAction(compilationContext =>
            {
                compilationContext.RegisterOperationBlockStartAction(operationBlockStartContext =>
                {
                    if (!(operationBlockStartContext.OwningSymbol is IMethodSymbol containingMethod))
                    {
                        return;
                    }

                    foreach (var operationRoot in operationBlockStartContext.OperationBlocks)
                    {
                        IBlockOperation topmostBlock = operationRoot.GetTopmostParentBlock();
                        if (topmostBlock != null && topmostBlock.HasAnyOperationDescendant(op => (op as IBinaryOperation)?.IsComparisonOperator() == true || op.Kind == OperationKind.Coalesce || op.Kind == OperationKind.ConditionalAccess))
                        {
                            var cfg = ControlFlowGraph.Create(topmostBlock);
                            var wellKnownTypeProvider  = WellKnownTypeProvider.GetOrCreate(operationBlockStartContext.Compilation);
                            var nullAnalysisResult     = NullAnalysis.GetOrComputeResult(cfg, containingMethod, wellKnownTypeProvider);
                            var pointsToAnalysisResult = PointsToAnalysis.GetOrComputeResult(cfg, containingMethod, wellKnownTypeProvider, nullAnalysisResult);
                            var copyAnalysisResult     = CopyAnalysis.GetOrComputeResult(cfg, containingMethod, wellKnownTypeProvider, nullAnalysisResultOpt: nullAnalysisResult, pointsToAnalysisResultOpt: pointsToAnalysisResult);
                            // Do another null analysis pass to improve the results from PointsTo and Copy analysis.
                            nullAnalysisResult = NullAnalysis.GetOrComputeResult(cfg, containingMethod, wellKnownTypeProvider, copyAnalysisResult, pointsToAnalysisResultOpt: pointsToAnalysisResult);
                            var stringContentAnalysisResult = StringContentAnalysis.GetOrComputeResult(cfg, containingMethod, wellKnownTypeProvider, copyAnalysisResult, nullAnalysisResult, pointsToAnalysisResult);

                            operationBlockStartContext.RegisterOperationAction(operationContext =>
                            {
                                PredicateValueKind GetPredicateKind(IBinaryOperation operation)
                                {
                                    if (operation.IsComparisonOperator())
                                    {
                                        PredicateValueKind binaryPredicateKind = nullAnalysisResult.GetPredicateKind(operation);
                                        if (binaryPredicateKind != PredicateValueKind.Unknown)
                                        {
                                            return(binaryPredicateKind);
                                        }

                                        binaryPredicateKind = copyAnalysisResult.GetPredicateKind(operation);
                                        if (binaryPredicateKind != PredicateValueKind.Unknown)
                                        {
                                            return(binaryPredicateKind);
                                        }

                                        binaryPredicateKind = stringContentAnalysisResult.GetPredicateKind(operation);
                                        if (binaryPredicateKind != PredicateValueKind.Unknown)
                                        {
                                            return(binaryPredicateKind);
                                        }
                                        ;
                                    }

                                    return(PredicateValueKind.Unknown);
                                }

                                var binaryOperation = (IBinaryOperation)operationContext.Operation;
                                PredicateValueKind predicateKind = GetPredicateKind(binaryOperation);
                                if (predicateKind != PredicateValueKind.Unknown &&
                                    (!(binaryOperation.LeftOperand is IBinaryOperation leftBinary) || GetPredicateKind(leftBinary) == PredicateValueKind.Unknown) &&
                                    (!(binaryOperation.RightOperand is IBinaryOperation rightBinary) || GetPredicateKind(rightBinary) == PredicateValueKind.Unknown))
                                {
                                    // '{0}' is always '{1}'. Remove or refactor the condition(s) to avoid dead code.
                                    var arg1 = binaryOperation.Syntax.ToString();
                                    var arg2 = predicateKind == PredicateValueKind.AlwaysTrue ?
                                               (binaryOperation.Language == LanguageNames.VisualBasic ? "True" : "true") :
                                               (binaryOperation.Language == LanguageNames.VisualBasic ? "False" : "false");
                                    var diagnostic = binaryOperation.CreateDiagnostic(AlwaysTrueFalseOrNullRule, arg1, arg2);
                                    operationContext.ReportDiagnostic(diagnostic);
                                }
                            }, OperationKind.BinaryOperator);

                            operationBlockStartContext.RegisterOperationAction(operationContext =>
                            {
                                IOperation nullCheckedOperation = operationContext.Operation.Kind == OperationKind.Coalesce ?
                                                                  ((ICoalesceOperation)operationContext.Operation).Value :
                                                                  ((IConditionalAccessOperation)operationContext.Operation).Operation;

                                // '{0}' is always/never '{1}'. Remove or refactor the condition(s) to avoid dead code.
                                DiagnosticDescriptor rule;
                                switch (nullAnalysisResult[nullCheckedOperation])
                                {
                                case NullAbstractValue.Null:
                                    rule = AlwaysTrueFalseOrNullRule;
                                    break;

                                case NullAbstractValue.NotNull:
                                    rule = NeverNullRule;
                                    break;

                                default:
                                    return;
                                }

                                var arg1       = nullCheckedOperation.Syntax.ToString();
                                var arg2       = nullCheckedOperation.Language == LanguageNames.VisualBasic ? "Nothing" : "null";
                                var diagnostic = nullCheckedOperation.CreateDiagnostic(rule, arg1, arg2);
                                operationContext.ReportDiagnostic(diagnostic);
                            }, OperationKind.Coalesce, OperationKind.ConditionalAccess);
                        }
                    }
                });
            });
        }
 public Exposure(Method m, PointsToAnalysis pta) : base(m, pta)
 {
     //inconsistentExpr = new Dictionary<Label, Set<VariableEffect>>();
     //problems = new Dictionary<Label, string>();
     //callsToWarn = new Set<Label>();
 }
        public override void Initialize(AnalysisContext context)
        {
            if (!Debugger.IsAttached) // prefer single thread for debugging in development
            {
                context.EnableConcurrentExecution();
            }

            if (context.IsAuditMode())
            {
                context.ConfigureGeneratedCodeAnalysis(GeneratedCodeAnalysisFlags.Analyze | GeneratedCodeAnalysisFlags.ReportDiagnostics);
            }
            else
            {
                context.ConfigureGeneratedCodeAnalysis(GeneratedCodeAnalysisFlags.None);
            }

            context.RegisterCompilationStartAction(
                (CompilationStartAnalysisContext compilationContext) =>
            {
                var config = Configuration.GetOrCreate(compilationContext);

                if (config.AuditMode)
                {
                    TaintedDataSymbolMap <SinkInfo> sinkInfoSymbolMap = config.TaintConfiguration.GetSinkSymbolMap(this.SinkKind);
                    if (sinkInfoSymbolMap.IsEmpty)
                    {
                        return;
                    }

                    Compilation compilation = compilationContext.Compilation;
                    compilationContext.RegisterOperationBlockStartAction(
                        operationBlockStartContext =>
                    {
                        ISymbol owningSymbol                = operationBlockStartContext.OwningSymbol;
                        AnalyzerOptions options             = operationBlockStartContext.Options;
                        CancellationToken cancellationToken = operationBlockStartContext.CancellationToken;
                        if (options.IsConfiguredToSkipAnalysis(TaintedDataEnteringSinkDescriptor, owningSymbol, compilation, cancellationToken))
                        {
                            return;
                        }

                        WellKnownTypeProvider wellKnownTypeProvider = WellKnownTypeProvider.GetOrCreate(compilation);

                        void CreateWarning(OperationAnalysisContext operationAnalysisContext, Location location, ISymbol paramSymbol, ISymbol symbol)
                        {
                            // Something like:
                            // CA3001: Potential SQL injection vulnerability was found where '{0}' in method '{1}' may be tainted by user-controlled data from '{2}' in method '{3}'.
                            Diagnostic diagnostic = Diagnostic.Create(
                                this.TaintedDataEnteringSinkDescriptor,
                                location,
                                additionalLocations: new Location[] { location },
                                messageArgs: new object[] {
                                paramSymbol.Name,
                                symbol.ToDisplayString(SymbolDisplayFormat.MinimallyQualifiedFormat),
                                symbol.ToDisplayString(SymbolDisplayFormat.MinimallyQualifiedFormat),
                                symbol.ToDisplayString(SymbolDisplayFormat.MinimallyQualifiedFormat)
                            });
                            operationAnalysisContext.ReportDiagnostic(diagnostic);
                        }

                        bool IsConstant(IOperation operation, IOperation value, OperationAnalysisContext operationAnalysisContext)
                        {
                            if (value.ConstantValue.HasValue || value is ITypeOfOperation)
                            {
                                return(true);
                            }

                            if (!operation.TryGetEnclosingControlFlowGraph(out var cfg))
                            {
                                return(false);
                            }

                            var valueContentResult = ValueContentAnalysis.TryGetOrComputeResult(cfg, owningSymbol, wellKnownTypeProvider,
                                                                                                operationAnalysisContext.Options, TaintedDataEnteringSinkDescriptor, PointsToAnalysisKind.Complete, operationAnalysisContext.CancellationToken);
                            if (valueContentResult == null)
                            {
                                return(false);
                            }

                            ValueContentAbstractValue abstractValue = valueContentResult[value.Kind, value.Syntax];
                            return(abstractValue.NonLiteralState == ValueContainsNonLiteralState.No);
                        }

                        operationBlockStartContext.RegisterOperationAction(
                            operationAnalysisContext =>
                        {
                            IAssignmentOperation operation = (IAssignmentOperation)operationAnalysisContext.Operation;
                            if (!(operation.Target is IPropertyReferenceOperation propertyReferenceOperation))
                            {
                                return;
                            }

                            IEnumerable <SinkInfo>?infosForType = sinkInfoSymbolMap.GetInfosForType(propertyReferenceOperation.Member.ContainingType);
                            if (infosForType != null &&
                                infosForType.Any(x => x.SinkProperties.Contains(propertyReferenceOperation.Member.MetadataName)) &&
                                !IsConstant(operation, operation.Value, operationAnalysisContext))
                            {
                                CreateWarning(
                                    operationAnalysisContext,
                                    propertyReferenceOperation.Syntax.GetLocation(),
                                    operation.Value.Type,
                                    propertyReferenceOperation.Member);
                            }
                        },
                            OperationKind.SimpleAssignment);

                        operationBlockStartContext.RegisterOperationAction(
                            operationAnalysisContext =>
                        {
                            IInvocationOperation invocationOperation = (IInvocationOperation)operationAnalysisContext.Operation;
                            IEnumerable <SinkInfo>?infosForType      = sinkInfoSymbolMap.GetInfosForType(invocationOperation.TargetMethod.ContainingType);
                            if (infosForType == null)
                            {
                                return;
                            }

                            foreach (SinkInfo sinkInfo in infosForType)
                            {
                                foreach (IArgumentOperation taintedArgument in invocationOperation.Arguments.Where(x => !IsConstant(x, x.Value, operationAnalysisContext)))
                                {
                                    if (sinkInfo.SinkMethodParameters.TryGetValue(invocationOperation.TargetMethod.MetadataName, out ImmutableHashSet <string> sinkParameters) &&
                                        sinkParameters.Contains(taintedArgument.Parameter.MetadataName))
                                    {
                                        CreateWarning(operationAnalysisContext, invocationOperation.Syntax.GetLocation(), taintedArgument.Parameter, invocationOperation.TargetMethod);
                                        return;
                                    }
                                }
                            }
                        },
                            OperationKind.Invocation);

                        operationBlockStartContext.RegisterOperationAction(
                            operationAnalysisContext =>
                        {
                            IObjectCreationOperation invocationOperation = (IObjectCreationOperation)operationAnalysisContext.Operation;
                            IEnumerable <SinkInfo>?infosForType          = sinkInfoSymbolMap.GetInfosForType(invocationOperation.Constructor.ContainingType);
                            if (infosForType == null)
                            {
                                return;
                            }

                            foreach (SinkInfo sinkInfo in infosForType)
                            {
                                foreach (IArgumentOperation taintedArgument in invocationOperation.Arguments.Where(x => !IsConstant(x, x.Value, operationAnalysisContext)))
                                {
                                    if (sinkInfo.IsAnyStringParameterInConstructorASink &&
                                        taintedArgument.Parameter.Type.SpecialType == SpecialType.System_String)
                                    {
                                        CreateWarning(operationAnalysisContext, invocationOperation.Syntax.GetLocation(), taintedArgument.Parameter, invocationOperation.Constructor);
                                        return;
                                    }
                                    else if (sinkInfo.SinkMethodParameters.TryGetValue(invocationOperation.Constructor.MetadataName, out ImmutableHashSet <string> sinkParameters) &&
                                             sinkParameters.Contains(taintedArgument.Parameter.MetadataName))
                                    {
                                        CreateWarning(operationAnalysisContext, invocationOperation.Syntax.GetLocation(), taintedArgument.Parameter, invocationOperation.Constructor);
                                        return;
                                    }
                                }
                            }
                        },
                            OperationKind.ObjectCreation);
                    });
                }
                else
                {
                    TaintedDataSymbolMap <SourceInfo> sourceInfoSymbolMap = config.TaintConfiguration.GetSourceSymbolMap(this.SinkKind);
                    if (sourceInfoSymbolMap.IsEmpty)
                    {
                        return;
                    }

                    TaintedDataSymbolMap <SinkInfo> sinkInfoSymbolMap = config.TaintConfiguration.GetSinkSymbolMap(this.SinkKind);
                    if (sinkInfoSymbolMap.IsEmpty)
                    {
                        return;
                    }

                    Compilation compilation = compilationContext.Compilation;
                    compilationContext.RegisterOperationBlockStartAction(
                        operationBlockStartContext =>
                    {
                        ISymbol owningSymbol                = operationBlockStartContext.OwningSymbol;
                        AnalyzerOptions options             = operationBlockStartContext.Options;
                        CancellationToken cancellationToken = operationBlockStartContext.CancellationToken;
                        if (options.IsConfiguredToSkipAnalysis(TaintedDataEnteringSinkDescriptor, owningSymbol, compilation, cancellationToken))
                        {
                            return;
                        }

                        WellKnownTypeProvider wellKnownTypeProvider      = WellKnownTypeProvider.GetOrCreate(compilation);
                        Lazy <ControlFlowGraph?> controlFlowGraphFactory = new Lazy <ControlFlowGraph?>(
                            () => operationBlockStartContext.OperationBlocks.GetControlFlowGraph());
                        Lazy <PointsToAnalysisResult?> pointsToFactory = new Lazy <PointsToAnalysisResult?>(
                            () =>
                        {
                            if (controlFlowGraphFactory.Value == null)
                            {
                                return(null);
                            }

                            InterproceduralAnalysisConfiguration interproceduralAnalysisConfiguration = InterproceduralAnalysisConfiguration.Create(
                                options,
                                SupportedDiagnostics,
                                controlFlowGraphFactory.Value,
                                operationBlockStartContext.Compilation,
                                defaultInterproceduralAnalysisKind: InterproceduralAnalysisKind.ContextSensitive,
                                cancellationToken: cancellationToken,
                                defaultMaxInterproceduralMethodCallChain: config.MaxInterproceduralMethodCallChain,
                                defaultMaxInterproceduralLambdaOrLocalFunctionCallChain: config.MaxInterproceduralLambdaOrLocalFunctionCallChain);
                            return(PointsToAnalysis.TryGetOrComputeResult(
                                       controlFlowGraphFactory.Value,
                                       owningSymbol,
                                       options,
                                       wellKnownTypeProvider,
                                       PointsToAnalysisKind.Complete,
                                       interproceduralAnalysisConfiguration,
                                       interproceduralAnalysisPredicate: null));
                        });
                        Lazy <(PointsToAnalysisResult?, ValueContentAnalysisResult?)> valueContentFactory = new Lazy <(PointsToAnalysisResult?, ValueContentAnalysisResult?)>(
                            () =>
                        {
                            if (controlFlowGraphFactory.Value == null)
                            {
                                return(null, null);
                            }

                            InterproceduralAnalysisConfiguration interproceduralAnalysisConfiguration = InterproceduralAnalysisConfiguration.Create(
                                options,
                                SupportedDiagnostics,
                                controlFlowGraphFactory.Value,
                                operationBlockStartContext.Compilation,
                                defaultInterproceduralAnalysisKind: InterproceduralAnalysisKind.ContextSensitive,
                                cancellationToken: cancellationToken,
                                defaultMaxInterproceduralMethodCallChain: config.MaxInterproceduralMethodCallChain,
                                defaultMaxInterproceduralLambdaOrLocalFunctionCallChain: config.MaxInterproceduralLambdaOrLocalFunctionCallChain);
                            ValueContentAnalysisResult?valuecontentAnalysisResult = ValueContentAnalysis.TryGetOrComputeResult(
                                controlFlowGraphFactory.Value,
                                owningSymbol,
                                options,
                                wellKnownTypeProvider,
                                PointsToAnalysisKind.Complete,
                                interproceduralAnalysisConfiguration,
                                out _,
                                out PointsToAnalysisResult? p);

                            return(p, valuecontentAnalysisResult);
                        });

                        var rootOperationsNeedingAnalysis = PooledHashSet <IOperation> .GetInstance();

                        operationBlockStartContext.RegisterOperationAction(
                            operationAnalysisContext =>
                        {
                            IPropertyReferenceOperation propertyReferenceOperation = (IPropertyReferenceOperation)operationAnalysisContext.Operation;
                            if (sourceInfoSymbolMap.IsSourceProperty(propertyReferenceOperation.Property))
                            {
                                lock (rootOperationsNeedingAnalysis)
                                {
                                    rootOperationsNeedingAnalysis.Add(propertyReferenceOperation.GetRoot());
                                }
                            }
                        },
                            OperationKind.PropertyReference);

                        if (sourceInfoSymbolMap.RequiresFieldReferenceAnalysis)
                        {
                            operationBlockStartContext.RegisterOperationAction(
                                operationAnalysisContext =>
                            {
                                IFieldReferenceOperation fieldReferenceOperation = (IFieldReferenceOperation)operationAnalysisContext.Operation;
                                if (sourceInfoSymbolMap.IsSourceField(fieldReferenceOperation.Field))
                                {
                                    lock (rootOperationsNeedingAnalysis)
                                    {
                                        rootOperationsNeedingAnalysis.Add(fieldReferenceOperation.GetRoot());
                                    }
                                }
                            },
                                OperationKind.FieldReference);
                        }

                        if (sourceInfoSymbolMap.RequiresParameterReferenceAnalysis)
                        {
                            operationBlockStartContext.RegisterOperationAction(
                                operationAnalysisContext =>
                            {
                                IParameterReferenceOperation parameterReferenceOperation = (IParameterReferenceOperation)operationAnalysisContext.Operation;
                                if (sourceInfoSymbolMap.IsSourceParameter(parameterReferenceOperation.Parameter, wellKnownTypeProvider))
                                {
                                    lock (rootOperationsNeedingAnalysis)
                                    {
                                        rootOperationsNeedingAnalysis.Add(parameterReferenceOperation.GetRoot());
                                    }
                                }
                            },
                                OperationKind.ParameterReference);
                        }

                        operationBlockStartContext.RegisterOperationAction(
                            operationAnalysisContext =>
                        {
                            IInvocationOperation invocationOperation = (IInvocationOperation)operationAnalysisContext.Operation;
                            if (sourceInfoSymbolMap.IsSourceMethod(
                                    invocationOperation.TargetMethod,
                                    invocationOperation.Arguments,
                                    pointsToFactory,
                                    valueContentFactory,
                                    out _))
                            {
                                lock (rootOperationsNeedingAnalysis)
                                {
                                    rootOperationsNeedingAnalysis.Add(invocationOperation.GetRoot());
                                }
                            }
                        },
                            OperationKind.Invocation);

                        if (config.TaintConfiguration.HasTaintArraySource(SinkKind, config))
                        {
                            operationBlockStartContext.RegisterOperationAction(
                                operationAnalysisContext =>
                            {
                                IArrayInitializerOperation arrayInitializerOperation = (IArrayInitializerOperation)operationAnalysisContext.Operation;
                                if (arrayInitializerOperation.GetAncestor <IArrayCreationOperation>(OperationKind.ArrayCreation)?.Type is IArrayTypeSymbol arrayTypeSymbol &&
                                    sourceInfoSymbolMap.IsSourceConstantArrayOfType(arrayTypeSymbol, arrayInitializerOperation))
                                {
                                    lock (rootOperationsNeedingAnalysis)
                                    {
                                        rootOperationsNeedingAnalysis.Add(operationAnalysisContext.Operation.GetRoot());
                                    }
                                }
                            },
                                OperationKind.ArrayInitializer);
                        }

                        operationBlockStartContext.RegisterOperationBlockEndAction(
                            operationBlockAnalysisContext =>
                        {
                            try
                            {
                                lock (rootOperationsNeedingAnalysis)
                                {
                                    if (!rootOperationsNeedingAnalysis.Any())
                                    {
                                        return;
                                    }

                                    if (controlFlowGraphFactory.Value == null)
                                    {
                                        return;
                                    }

                                    foreach (IOperation rootOperation in rootOperationsNeedingAnalysis)
                                    {
                                        TaintedDataAnalysisResult?taintedDataAnalysisResult = TaintedDataAnalysis.TryGetOrComputeResult(
                                            controlFlowGraphFactory.Value,
                                            operationBlockAnalysisContext.Compilation,
                                            operationBlockAnalysisContext.OwningSymbol,
                                            operationBlockAnalysisContext.Options,
                                            TaintedDataEnteringSinkDescriptor,
                                            sourceInfoSymbolMap,
                                            config.TaintConfiguration.GetSanitizerSymbolMap(this.SinkKind),
                                            sinkInfoSymbolMap,
                                            operationBlockAnalysisContext.CancellationToken,
                                            config.MaxInterproceduralMethodCallChain,
                                            config.MaxInterproceduralLambdaOrLocalFunctionCallChain);
                                        if (taintedDataAnalysisResult == null)
                                        {
                                            return;
                                        }

                                        foreach (TaintedDataSourceSink sourceSink in taintedDataAnalysisResult.TaintedDataSourceSinks)
                                        {
                                            if (!sourceSink.SinkKinds.Contains(this.SinkKind))
                                            {
                                                continue;
                                            }

                                            foreach (SymbolAccess sourceOrigin in sourceSink.SourceOrigins)
                                            {
                                                // Something like:
                                                // CA3001: Potential SQL injection vulnerability was found where '{0}' in method '{1}' may be tainted by user-controlled data from '{2}' in method '{3}'.
                                                Diagnostic diagnostic = Diagnostic.Create(
                                                    this.TaintedDataEnteringSinkDescriptor,
                                                    sourceSink.Sink.Location,
                                                    additionalLocations: new Location[] { sourceOrigin.Location },
                                                    messageArgs: new object[] {
                                                    sourceSink.Sink.Symbol.Name,
                                                    sourceSink.Sink.AccessingMethod.ToDisplayString(SymbolDisplayFormat.MinimallyQualifiedFormat),
                                                    sourceOrigin.Symbol.ToDisplayString(SymbolDisplayFormat.MinimallyQualifiedFormat),
                                                    sourceOrigin.AccessingMethod.ToDisplayString(SymbolDisplayFormat.MinimallyQualifiedFormat)
                                                });
                                                operationBlockAnalysisContext.ReportDiagnostic(diagnostic);
                                            }
                                        }
                                    }
                                }
                            }
                            finally
                            {
                                rootOperationsNeedingAnalysis.Free(compilationContext.CancellationToken);
                            }
                        });
                    });
                }
            });
        }
Exemple #23
0
    // Copy Constructor
    public PointsToState(PointsToState cState)
    {
      this.pta = cState.pta;
      pointsToGraph = new PTGraph(cState.pointsToGraph);

      // callToNonAnalyzableMethods = new Dictionary<Label, Set<Method>>(cState.callToNonAnalyzableMethods);
      method = cState.method;
      methodLabel = cState.methodLabel;
      //exceptions = cState.exceptions;
      currentException = cState.currentException;

      methodAssumptions = cState.methodAssumptions;
      isDefault = cState.isDefault;

    }
Exemple #24
0
        //internal INonNullState nonNullstateForCurrentBlock;

        public ObjectConsistencyInferer(TypeSystem t, PointsToAnalysis pta)
            : base(t, pta)
        {
        }
Exemple #25
0
 public CGGenerator(CallGraph cg, AnalyzableMethodFinder amf)
 {
     this.cg   = cg;
     this.ptwe = amf.ptwe;
     this.amf  = amf;
 }
Exemple #26
0
 /// <summary>
 /// Constructor
 /// </summary>
 /// <param name="pta"></param>
 public PointsToInstructionVisitor(PointsToInferer pta)
 {
   this.pta = pta;
   PointsToAnalysis = this.pta.pointsToStateAnalysys;
 }
 public WriteEffectsElementFactory(PointsToAnalysis pta) : base(pta) { }
 public Exposure(Method m,PointsToAnalysis pta): base(m,pta)
 {
     
     //inconsistentExpr = new Dictionary<Label, Set<VariableEffect>>();
     //problems = new Dictionary<Label, string>();
     //callsToWarn = new Set<Label>();
 }
Exemple #29
0
 public ElementFactory(PointsToAnalysis pta)
 {
   this.pta = pta;
 }
 public ExposureElementFactory(PointsToAnalysis pta) : base(pta) { }
        private static TaintedDataAnalysisResult?TryGetOrComputeResult(
            ControlFlowGraph cfg,
            Compilation compilation,
            ISymbol containingMethod,
            AnalyzerOptions analyzerOptions,
            TaintedDataSymbolMap <SourceInfo> taintedSourceInfos,
            TaintedDataSymbolMap <SanitizerInfo> taintedSanitizerInfos,
            TaintedDataSymbolMap <SinkInfo> taintedSinkInfos,
            InterproceduralAnalysisConfiguration interproceduralAnalysisConfig)
        {
            if (cfg == null)
            {
                Debug.Fail("Expected non-null CFG");
                return(null);
            }

            WellKnownTypeProvider      wellKnownTypeProvider      = WellKnownTypeProvider.GetOrCreate(compilation);
            ValueContentAnalysisResult?valueContentAnalysisResult = null;
            CopyAnalysisResult?        copyAnalysisResult         = null;
            PointsToAnalysisResult?    pointsToAnalysisResult     = null;

            if (taintedSourceInfos.RequiresValueContentAnalysis || taintedSanitizerInfos.RequiresValueContentAnalysis || taintedSinkInfos.RequiresValueContentAnalysis)
            {
                valueContentAnalysisResult = ValueContentAnalysis.TryGetOrComputeResult(
                    cfg,
                    containingMethod,
                    analyzerOptions,
                    wellKnownTypeProvider,
                    PointsToAnalysisKind.Complete,
                    interproceduralAnalysisConfig,
                    out copyAnalysisResult,
                    out pointsToAnalysisResult,
                    pessimisticAnalysis: true,
                    performCopyAnalysis: false);
                if (valueContentAnalysisResult == null)
                {
                    return(null);
                }
            }
            else
            {
                pointsToAnalysisResult = PointsToAnalysis.TryGetOrComputeResult(
                    cfg,
                    containingMethod,
                    analyzerOptions,
                    wellKnownTypeProvider,
                    PointsToAnalysisKind.Complete,
                    interproceduralAnalysisConfig,
                    interproceduralAnalysisPredicate: null,
                    pessimisticAnalysis: true,
                    performCopyAnalysis: false);
                if (pointsToAnalysisResult == null)
                {
                    return(null);
                }
            }

            TaintedDataAnalysisContext analysisContext = TaintedDataAnalysisContext.Create(
                TaintedDataAbstractValueDomain.Default,
                wellKnownTypeProvider,
                cfg,
                containingMethod,
                analyzerOptions,
                interproceduralAnalysisConfig,
                pessimisticAnalysis: false,
                copyAnalysisResult: copyAnalysisResult,
                pointsToAnalysisResult: pointsToAnalysisResult,
                valueContentAnalysisResult: valueContentAnalysisResult,
                tryGetOrComputeAnalysisResult: TryGetOrComputeResultForAnalysisContext,
                taintedSourceInfos: taintedSourceInfos,
                taintedSanitizerInfos: taintedSanitizerInfos,
                taintedSinkInfos: taintedSinkInfos);

            return(TryGetOrComputeResultForAnalysisContext(analysisContext));
        }
Exemple #32
0
 public CGGenerator(CallGraph cg, PointsToAnalysis ptwe)
 {
     this.cg   = cg;
     this.ptwe = ptwe;
 }
        //internal INonNullState nonNullstateForCurrentBlock;

        public ObjectConsistencyInferer(TypeSystem t, PointsToAnalysis pta)
            : base(t, pta)
        {
        }
Exemple #34
0
        public override void Initialize(AnalysisContext context)
        {
            context.EnableConcurrentExecution();
            context.ConfigureGeneratedCodeAnalysis(GeneratedCodeAnalysisFlags.Analyze | GeneratedCodeAnalysisFlags.ReportDiagnostics);

            context.RegisterCompilationStartAction(
                (CompilationStartAnalysisContext compilationContext) =>
            {
                TaintedDataConfig taintedDataConfig = TaintedDataConfig.GetOrCreate(compilationContext.Compilation);
                TaintedDataSymbolMap <SourceInfo> sourceInfoSymbolMap = taintedDataConfig.GetSourceSymbolMap(this.SinkKind);
                if (sourceInfoSymbolMap.IsEmpty)
                {
                    return;
                }

                TaintedDataSymbolMap <SinkInfo> sinkInfoSymbolMap = taintedDataConfig.GetSinkSymbolMap(this.SinkKind);
                if (sinkInfoSymbolMap.IsEmpty)
                {
                    return;
                }

                compilationContext.RegisterOperationBlockStartAction(
                    operationBlockStartContext =>
                {
                    ISymbol owningSymbol = operationBlockStartContext.OwningSymbol;
                    if (owningSymbol.IsConfiguredToSkipAnalysis(operationBlockStartContext.Options,
                                                                TaintedDataEnteringSinkDescriptor, operationBlockStartContext.Compilation, operationBlockStartContext.CancellationToken))
                    {
                        return;
                    }

                    PooledHashSet <IOperation> rootOperationsNeedingAnalysis = PooledHashSet <IOperation> .GetInstance();

                    operationBlockStartContext.RegisterOperationAction(
                        operationAnalysisContext =>
                    {
                        IPropertyReferenceOperation propertyReferenceOperation = (IPropertyReferenceOperation)operationAnalysisContext.Operation;
                        IOperation rootOperation = operationAnalysisContext.Operation.GetRoot();
                        if (sourceInfoSymbolMap.IsSourceProperty(propertyReferenceOperation.Property))
                        {
                            lock (rootOperationsNeedingAnalysis)
                            {
                                rootOperationsNeedingAnalysis.Add(rootOperation);
                            }
                        }
                    },
                        OperationKind.PropertyReference);

                    operationBlockStartContext.RegisterOperationAction(
                        operationAnalysisContext =>
                    {
                        IInvocationOperation invocationOperation = (IInvocationOperation)operationAnalysisContext.Operation;
                        IOperation rootOperation = operationAnalysisContext.Operation.GetRoot();
                        PooledDictionary <PointsToCheck, ImmutableHashSet <string> > evaluateWithPointsToAnalysis         = null;
                        PooledDictionary <ValueContentCheck, ImmutableHashSet <string> > evaluateWithValueContentAnalysis = null;
                        PointsToAnalysisResult pointsToAnalysisResult         = null;
                        ValueContentAnalysisResult valueContentAnalysisResult = null;
                        if (rootOperation.TryGetEnclosingControlFlowGraph(out ControlFlowGraph cfg))
                        {
                            pointsToAnalysisResult = PointsToAnalysis.TryGetOrComputeResult(
                                cfg,
                                owningSymbol,
                                operationAnalysisContext.Options,
                                WellKnownTypeProvider.GetOrCreate(operationAnalysisContext.Compilation),
                                InterproceduralAnalysisConfiguration.Create(
                                    operationAnalysisContext.Options,
                                    SupportedDiagnostics,
                                    defaultInterproceduralAnalysisKind: InterproceduralAnalysisKind.ContextSensitive,
                                    cancellationToken: operationAnalysisContext.CancellationToken),
                                interproceduralAnalysisPredicateOpt: null);
                            if (pointsToAnalysisResult == null)
                            {
                                return;
                            }
                        }

                        if (sourceInfoSymbolMap.RequiresValueContentAnalysis)
                        {
                            valueContentAnalysisResult = ValueContentAnalysis.TryGetOrComputeResult(
                                cfg,
                                owningSymbol,
                                operationAnalysisContext.Options,
                                WellKnownTypeProvider.GetOrCreate(operationAnalysisContext.Compilation),
                                InterproceduralAnalysisConfiguration.Create(
                                    operationAnalysisContext.Options,
                                    SupportedDiagnostics,
                                    defaultInterproceduralAnalysisKind: InterproceduralAnalysisKind.ContextSensitive,
                                    cancellationToken: operationAnalysisContext.CancellationToken),
                                out var copyAnalysisResult,
                                out pointsToAnalysisResult);
                            if (valueContentAnalysisResult == null)
                            {
                                return;
                            }
                        }

                        try
                        {
                            if (sourceInfoSymbolMap.IsSourceMethod(
                                    invocationOperation.TargetMethod,
                                    invocationOperation.Arguments,
                                    invocationOperation.Arguments.Select(o => pointsToAnalysisResult[o.Kind, o.Syntax]).ToImmutableArray(),
                                    invocationOperation.Arguments.Select(o => valueContentAnalysisResult[o.Kind, o.Syntax]).ToImmutableArray(),
                                    out _))
                            {
                                lock (rootOperationsNeedingAnalysis)
                                {
                                    rootOperationsNeedingAnalysis.Add(rootOperation);
                                }
                            }
                        }
                        finally
                        {
                            evaluateWithPointsToAnalysis?.Free();
                            evaluateWithValueContentAnalysis?.Free();
                        }
                    },
                        OperationKind.Invocation);

                    if (taintedDataConfig.HasTaintArraySource(SinkKind))
                    {
                        operationBlockStartContext.RegisterOperationAction(
                            operationAnalysisContext =>
                        {
                            IArrayInitializerOperation arrayInitializerOperation = (IArrayInitializerOperation)operationAnalysisContext.Operation;
                            if (arrayInitializerOperation.GetAncestor <IArrayCreationOperation>(OperationKind.ArrayCreation)?.Type is IArrayTypeSymbol arrayTypeSymbol &&
                                sourceInfoSymbolMap.IsSourceConstantArrayOfType(arrayTypeSymbol))
                            {
                                lock (rootOperationsNeedingAnalysis)
                                {
                                    rootOperationsNeedingAnalysis.Add(operationAnalysisContext.Operation.GetRoot());
                                }
                            }
                        },
                            OperationKind.ArrayInitializer);
                    }

                    operationBlockStartContext.RegisterOperationBlockEndAction(
                        operationBlockAnalysisContext =>
                    {
                        try
                        {
                            lock (rootOperationsNeedingAnalysis)
                            {
                                if (!rootOperationsNeedingAnalysis.Any())
                                {
                                    return;
                                }

                                foreach (IOperation rootOperation in rootOperationsNeedingAnalysis)
                                {
                                    if (!rootOperation.TryGetEnclosingControlFlowGraph(out var cfg))
                                    {
                                        continue;
                                    }

                                    TaintedDataAnalysisResult taintedDataAnalysisResult = TaintedDataAnalysis.TryGetOrComputeResult(
                                        cfg,
                                        operationBlockAnalysisContext.Compilation,
                                        operationBlockAnalysisContext.OwningSymbol,
                                        operationBlockAnalysisContext.Options,
                                        TaintedDataEnteringSinkDescriptor,
                                        sourceInfoSymbolMap,
                                        taintedDataConfig.GetSanitizerSymbolMap(this.SinkKind),
                                        sinkInfoSymbolMap,
                                        operationBlockAnalysisContext.CancellationToken);
                                    if (taintedDataAnalysisResult == null)
                                    {
                                        return;
                                    }

                                    foreach (TaintedDataSourceSink sourceSink in taintedDataAnalysisResult.TaintedDataSourceSinks)
                                    {
                                        if (!sourceSink.SinkKinds.Contains(this.SinkKind))
                                        {
                                            continue;
                                        }

                                        foreach (SymbolAccess sourceOrigin in sourceSink.SourceOrigins)
                                        {
                                            // Something like:
                                            // CA3001: Potential SQL injection vulnerability was found where '{0}' in method '{1}' may be tainted by user-controlled data from '{2}' in method '{3}'.
                                            Diagnostic diagnostic = Diagnostic.Create(
                                                this.TaintedDataEnteringSinkDescriptor,
                                                sourceSink.Sink.Location,
                                                additionalLocations: new Location[] { sourceOrigin.Location },
                                                messageArgs: new object[] {
                                                sourceSink.Sink.Symbol.ToDisplayString(SymbolDisplayFormat.MinimallyQualifiedFormat),
                                                sourceSink.Sink.AccessingMethod.ToDisplayString(SymbolDisplayFormat.MinimallyQualifiedFormat),
                                                sourceOrigin.Symbol.ToDisplayString(SymbolDisplayFormat.MinimallyQualifiedFormat),
                                                sourceOrigin.AccessingMethod.ToDisplayString(SymbolDisplayFormat.MinimallyQualifiedFormat)
                                            });
                                            operationBlockAnalysisContext.ReportDiagnostic(diagnostic);
                                        }
                                    }
                                }
                            }
                        }
                        finally
                        {
                            rootOperationsNeedingAnalysis.Free();
                        }
                    });
                });
            });
        }
 public ConsistencyState(Method m, PointsToAnalysis pta)
     : base(m,pta)
 {
     consistency = new Dictionary<IPTAnalysisNode, AbstractValue>();
     
     
     exposedNodes = new Set<IPTAnalysisNode>();
     this.nonNullState = null;
 }
Exemple #36
0
        public override void Initialize(AnalysisContext context)
        {
            context.EnableConcurrentExecution();
            context.ConfigureGeneratedCodeAnalysis(GeneratedCodeAnalysisFlags.Analyze | GeneratedCodeAnalysisFlags.ReportDiagnostics);

            context.RegisterCompilationStartAction(
                (CompilationStartAnalysisContext compilationContext) =>
            {
                Compilation compilation             = compilationContext.Compilation;
                TaintedDataConfig taintedDataConfig = TaintedDataConfig.GetOrCreate(compilation);
                TaintedDataSymbolMap <SourceInfo> sourceInfoSymbolMap = taintedDataConfig.GetSourceSymbolMap(this.SinkKind);
                if (sourceInfoSymbolMap.IsEmpty)
                {
                    return;
                }

                TaintedDataSymbolMap <SinkInfo> sinkInfoSymbolMap = taintedDataConfig.GetSinkSymbolMap(this.SinkKind);
                if (sinkInfoSymbolMap.IsEmpty)
                {
                    return;
                }

                compilationContext.RegisterOperationBlockStartAction(
                    operationBlockStartContext =>
                {
                    ISymbol owningSymbol                = operationBlockStartContext.OwningSymbol;
                    AnalyzerOptions options             = operationBlockStartContext.Options;
                    CancellationToken cancellationToken = operationBlockStartContext.CancellationToken;
                    if (options.IsConfiguredToSkipAnalysis(TaintedDataEnteringSinkDescriptor, owningSymbol, compilation))
                    {
                        return;
                    }

                    WellKnownTypeProvider wellKnownTypeProvider      = WellKnownTypeProvider.GetOrCreate(compilation);
                    Lazy <ControlFlowGraph?> controlFlowGraphFactory = new Lazy <ControlFlowGraph?>(
                        () => operationBlockStartContext.OperationBlocks.GetControlFlowGraph());
                    Lazy <PointsToAnalysisResult?> pointsToFactory = new Lazy <PointsToAnalysisResult?>(
                        () =>
                    {
                        if (controlFlowGraphFactory.Value == null)
                        {
                            return(null);
                        }

                        InterproceduralAnalysisConfiguration interproceduralAnalysisConfiguration = InterproceduralAnalysisConfiguration.Create(
                            options,
                            SupportedDiagnostics,
                            controlFlowGraphFactory.Value,
                            operationBlockStartContext.Compilation,
                            defaultInterproceduralAnalysisKind: InterproceduralAnalysisKind.ContextSensitive);
                        return(PointsToAnalysis.TryGetOrComputeResult(
                                   controlFlowGraphFactory.Value,
                                   owningSymbol,
                                   options,
                                   wellKnownTypeProvider,
                                   PointsToAnalysisKind.Complete,
                                   interproceduralAnalysisConfiguration,
                                   interproceduralAnalysisPredicate: null));
                    });
                    Lazy <(PointsToAnalysisResult?, ValueContentAnalysisResult?)> valueContentFactory = new Lazy <(PointsToAnalysisResult?, ValueContentAnalysisResult?)>(
                        () =>
                    {
                        if (controlFlowGraphFactory.Value == null)
                        {
                            return(null, null);
                        }

                        InterproceduralAnalysisConfiguration interproceduralAnalysisConfiguration = InterproceduralAnalysisConfiguration.Create(
                            options,
                            SupportedDiagnostics,
                            controlFlowGraphFactory.Value,
                            operationBlockStartContext.Compilation,
                            defaultInterproceduralAnalysisKind: InterproceduralAnalysisKind.ContextSensitive);
                        ValueContentAnalysisResult?valuecontentAnalysisResult = ValueContentAnalysis.TryGetOrComputeResult(
                            controlFlowGraphFactory.Value,
                            owningSymbol,
                            options,
                            wellKnownTypeProvider,
                            PointsToAnalysisKind.Complete,
                            interproceduralAnalysisConfiguration,
                            out _,
                            out PointsToAnalysisResult? p);

                        return(p, valuecontentAnalysisResult);
                    });

                    PooledHashSet <IOperation> rootOperationsNeedingAnalysis = PooledHashSet <IOperation> .GetInstance();

                    operationBlockStartContext.RegisterOperationAction(
                        operationAnalysisContext =>
                    {
                        IPropertyReferenceOperation propertyReferenceOperation = (IPropertyReferenceOperation)operationAnalysisContext.Operation;
                        if (sourceInfoSymbolMap.IsSourceProperty(propertyReferenceOperation.Property))
                        {
                            lock (rootOperationsNeedingAnalysis)
                            {
                                rootOperationsNeedingAnalysis.Add(propertyReferenceOperation.GetRoot());
                            }
                        }
                    },
                        OperationKind.PropertyReference);

                    if (sourceInfoSymbolMap.RequiresParameterReferenceAnalysis)
                    {
                        operationBlockStartContext.RegisterOperationAction(
                            operationAnalysisContext =>
                        {
                            IParameterReferenceOperation parameterReferenceOperation = (IParameterReferenceOperation)operationAnalysisContext.Operation;
                            if (sourceInfoSymbolMap.IsSourceParameter(parameterReferenceOperation.Parameter, wellKnownTypeProvider))
                            {
                                lock (rootOperationsNeedingAnalysis)
                                {
                                    rootOperationsNeedingAnalysis.Add(parameterReferenceOperation.GetRoot());
                                }
                            }
                        },
                            OperationKind.ParameterReference);
                    }

                    operationBlockStartContext.RegisterOperationAction(
                        operationAnalysisContext =>
                    {
                        IInvocationOperation invocationOperation = (IInvocationOperation)operationAnalysisContext.Operation;
                        if (sourceInfoSymbolMap.IsSourceMethod(
                                invocationOperation.TargetMethod,
                                invocationOperation.Arguments,
                                pointsToFactory,
                                valueContentFactory,
                                out _))
                        {
                            lock (rootOperationsNeedingAnalysis)
                            {
                                rootOperationsNeedingAnalysis.Add(invocationOperation.GetRoot());
                            }
                        }
                    },
                        OperationKind.Invocation);

                    if (TaintedDataConfig.HasTaintArraySource(SinkKind))
                    {
                        operationBlockStartContext.RegisterOperationAction(
                            operationAnalysisContext =>
                        {
                            IArrayInitializerOperation arrayInitializerOperation = (IArrayInitializerOperation)operationAnalysisContext.Operation;
                            if (arrayInitializerOperation.GetAncestor <IArrayCreationOperation>(OperationKind.ArrayCreation)?.Type is IArrayTypeSymbol arrayTypeSymbol &&
                                sourceInfoSymbolMap.IsSourceConstantArrayOfType(arrayTypeSymbol, arrayInitializerOperation))
                            {
                                lock (rootOperationsNeedingAnalysis)
                                {
                                    rootOperationsNeedingAnalysis.Add(operationAnalysisContext.Operation.GetRoot());
                                }
                            }
                        },
                            OperationKind.ArrayInitializer);
                    }

                    operationBlockStartContext.RegisterOperationBlockEndAction(
                        operationBlockAnalysisContext =>
                    {
                        try
                        {
                            lock (rootOperationsNeedingAnalysis)
                            {
                                if (!rootOperationsNeedingAnalysis.Any())
                                {
                                    return;
                                }

                                if (controlFlowGraphFactory.Value == null)
                                {
                                    return;
                                }

                                foreach (IOperation rootOperation in rootOperationsNeedingAnalysis)
                                {
                                    TaintedDataAnalysisResult?taintedDataAnalysisResult = TaintedDataAnalysis.TryGetOrComputeResult(
                                        controlFlowGraphFactory.Value,
                                        operationBlockAnalysisContext.Compilation,
                                        operationBlockAnalysisContext.OwningSymbol,
                                        operationBlockAnalysisContext.Options,
                                        TaintedDataEnteringSinkDescriptor,
                                        sourceInfoSymbolMap,
                                        taintedDataConfig.GetSanitizerSymbolMap(this.SinkKind),
                                        sinkInfoSymbolMap);
                                    if (taintedDataAnalysisResult == null)
                                    {
                                        return;
                                    }

                                    foreach (TaintedDataSourceSink sourceSink in taintedDataAnalysisResult.TaintedDataSourceSinks)
                                    {
                                        if (!sourceSink.SinkKinds.Contains(this.SinkKind))
                                        {
                                            continue;
                                        }

                                        foreach (SymbolAccess sourceOrigin in sourceSink.SourceOrigins)
                                        {
                                            // Something like:
                                            // CA3001: Potential SQL injection vulnerability was found where '{0}' in method '{1}' may be tainted by user-controlled data from '{2}' in method '{3}'.
                                            Diagnostic diagnostic = Diagnostic.Create(
                                                this.TaintedDataEnteringSinkDescriptor,
                                                sourceSink.Sink.Location,
                                                additionalLocations: new Location[] { sourceOrigin.Location },
                                                messageArgs: new object[] {
                                                sourceSink.Sink.Symbol.ToDisplayString(SymbolDisplayFormat.MinimallyQualifiedFormat),
                                                sourceSink.Sink.AccessingMethod.ToDisplayString(SymbolDisplayFormat.MinimallyQualifiedFormat),
                                                sourceOrigin.Symbol.ToDisplayString(SymbolDisplayFormat.MinimallyQualifiedFormat),
                                                sourceOrigin.AccessingMethod.ToDisplayString(SymbolDisplayFormat.MinimallyQualifiedFormat)
                                            });
                                            operationBlockAnalysisContext.ReportDiagnostic(diagnostic);
                                        }
                                    }
                                }
                            }
                        }
                        finally
                        {
                            rootOperationsNeedingAnalysis.Free(compilationContext.CancellationToken);
                        }
                    });
                });
            });
        }
 public ConsistentyElementFactory(PointsToAnalysis pta) : base(pta) { }