Esempio n. 1
0
        public override void VisitMethodReference(IMethodReferenceOperation operation)
        {
            var member = operation.Member;
            var method = operation.Method;

            base.VisitMethodReference(operation);
        }
Esempio n. 2
0
 public override bool VisitMethodReference([NotNull] IMethodReferenceOperation operation1,
                                           [CanBeNull] IOperation argument)
 {
     return(argument is IMethodReferenceOperation operation2 && AreBaseOperationsEqual(operation1, operation2) &&
            AreSymbolsEqual(operation1.Method, operation2.Method) && operation1.IsVirtual == operation2.IsVirtual &&
            AreSymbolsEqual(operation1.Member, operation2.Member));
 }
Esempio n. 3
0
        public override void VisitMethodReference(IMethodReferenceOperation operation)
        {
            Assert.Equal(OperationKind.MethodReference, operation.Kind);
            VisitMemberReference(operation);

            Assert.Same(operation.Member, operation.Method);
            var isVirtual = operation.IsVirtual;
        }
Esempio n. 4
0
        public sealed override void Initialize(AnalysisContext context)
        {
            ImmutableHashSet <string> cachedDeserializationMethodNames = this.DeserializationMethodNames;

            Debug.Assert(!cachedDeserializationMethodNames.IsEmpty);

            context.EnableConcurrentExecution();

            // Security analyzer - analyze and report diagnostics on generated code.
            context.ConfigureGeneratedCodeAnalysis(GeneratedCodeAnalysisFlags.Analyze | GeneratedCodeAnalysisFlags.ReportDiagnostics);

            context.RegisterCompilationStartAction(
                (CompilationStartAnalysisContext compilationStartAnalysisContext) =>
            {
                INamedTypeSymbol?deserializerTypeSymbol =
                    compilationStartAnalysisContext.Compilation.GetOrCreateTypeByMetadataName(this.DeserializerTypeMetadataName);
                if (deserializerTypeSymbol == null)
                {
                    return;
                }

                compilationStartAnalysisContext.RegisterOperationAction(
                    (OperationAnalysisContext operationAnalysisContext) =>
                {
                    IInvocationOperation invocationOperation =
                        (IInvocationOperation)operationAnalysisContext.Operation;
                    if (Equals(invocationOperation.Instance?.Type, deserializerTypeSymbol) &&
                        cachedDeserializationMethodNames.Contains(invocationOperation.TargetMethod.MetadataName))
                    {
                        operationAnalysisContext.ReportDiagnostic(
                            Diagnostic.Create(
                                this.MethodUsedDescriptor,
                                invocationOperation.Syntax.GetLocation(),
                                invocationOperation.TargetMethod.ToDisplayString(
                                    SymbolDisplayFormat.MinimallyQualifiedFormat)));
                    }
                },
                    OperationKind.Invocation);

                compilationStartAnalysisContext.RegisterOperationAction(
                    (OperationAnalysisContext operationAnalysisContext) =>
                {
                    IMethodReferenceOperation methodReferenceOperation =
                        (IMethodReferenceOperation)operationAnalysisContext.Operation;
                    if (Equals(methodReferenceOperation.Instance?.Type, deserializerTypeSymbol) &&
                        cachedDeserializationMethodNames.Contains(methodReferenceOperation.Method.MetadataName))
                    {
                        operationAnalysisContext.ReportDiagnostic(
                            Diagnostic.Create(
                                this.MethodUsedDescriptor,
                                methodReferenceOperation.Syntax.GetLocation(),
                                methodReferenceOperation.Method.ToDisplayString(
                                    SymbolDisplayFormat.MinimallyQualifiedFormat)));
                    }
                },
                    OperationKind.MethodReference);
            });
        }
        private static void AnalyzeEventAssignmentMethod([NotNull] IMethodReferenceOperation binding,
                                                         [NotNull] IEventAssignmentOperation assignment, OperationAnalysisContext context)
        {
            string eventTargetName     = GetEventTargetName(assignment.EventReference.Instance);
            string handlerNameExpected = string.Concat(eventTargetName, "On", assignment.EventReference.Event.Name);

            string handlerNameActual = binding.Method.Name;

            if (handlerNameActual != handlerNameExpected)
            {
                context.ReportDiagnostic(Diagnostic.Create(Rule, binding.Syntax.GetLocation(), handlerNameActual,
                                                           assignment.EventReference.Event.Name, handlerNameExpected));
            }
        }
Esempio n. 6
0
        private void AnalyzeOperation(OperationAnalysisContext context)
        {
            var symbol = context.Operation switch
            {
                IObjectCreationOperation creation => creation.Constructor,
                IInvocationOperation invocation => invocation.TargetMethod,
                IFieldReferenceOperation field => field.Member,
                IMethodReferenceOperation method => method.Member,
                IPropertyReferenceOperation property => property.Member,
                IEventReferenceOperation @event => @event.Member,
                _ => throw new InvalidOperationException("Unexpected operation kind: " + context.Operation.Kind),
            };

            VisitOperationSymbol(context, symbol);
        }
        public override void Initialize(AnalysisContext context)
        {
            context.EnableConcurrentExecution();

            // Security analyzer - analyze and report diagnostics on generated code.
            context.ConfigureGeneratedCodeAnalysis(GeneratedCodeAnalysisFlags.Analyze | GeneratedCodeAnalysisFlags.ReportDiagnostics);

            HazardousUsageEvaluatorCollection hazardousUsageEvaluators = new HazardousUsageEvaluatorCollection(
                SecurityHelpers.JavaScriptSerializerDeserializationMethods.Select(
                    (string methodName) => new HazardousUsageEvaluator(methodName, HazardousUsageCallback)));

            context.RegisterCompilationStartAction(
                (CompilationStartAnalysisContext compilationStartAnalysisContext) =>
            {
                WellKnownTypeProvider wellKnownTypeProvider = WellKnownTypeProvider.GetOrCreate(compilationStartAnalysisContext.Compilation);
                if (!wellKnownTypeProvider.TryGetTypeByMetadataName(WellKnownTypeNames.SystemWebScriptSerializationJavaScriptSerializer, out INamedTypeSymbol javaScriptSerializerSymbol) ||
                    !wellKnownTypeProvider.TryGetTypeByMetadataName(WellKnownTypeNames.SystemWebScriptSerializationJavaScriptTypeResolver, out INamedTypeSymbol javaScriptTypeResolverSymbol) ||
                    !wellKnownTypeProvider.TryGetTypeByMetadataName(WellKnownTypeNames.SystemWebScriptSerializationSimpleTypeResolver, out INamedTypeSymbol simpleTypeResolverSymbol))
                {
                    return;
                }

                // If JavaScriptSerializer is initialized with a SimpleTypeResolver, then that instance is flagged.
                ConstructorMapper constructorMapper = new ConstructorMapper(
                    (IMethodSymbol constructorMethod, IReadOnlyList <PointsToAbstractValue> argumentPointsToAbstractValues) =>
                {
                    PropertySetAbstractValueKind kind;
                    if (constructorMethod.Parameters.Length == 0)
                    {
                        kind = PropertySetAbstractValueKind.Unflagged;
                    }
                    else if (constructorMethod.Parameters.Length == 1 &&
                             javaScriptTypeResolverSymbol.Equals(constructorMethod.Parameters[0].Type))
                    {
                        PointsToAbstractValue pointsTo = argumentPointsToAbstractValues[0];
                        switch (pointsTo.Kind)
                        {
                        case PointsToAbstractValueKind.Invalid:
                        case PointsToAbstractValueKind.UnknownNull:
                        case PointsToAbstractValueKind.Undefined:
                            kind = PropertySetAbstractValueKind.Unflagged;
                            break;

                        case PointsToAbstractValueKind.KnownLocations:
                            if (pointsTo.Locations.Any(l => !l.IsNull && simpleTypeResolverSymbol.Equals(l.LocationTypeOpt)))
                            {
                                kind = PropertySetAbstractValueKind.Flagged;
                            }
                            else if (pointsTo.Locations.Any(l =>
                                                            !l.IsNull &&
                                                            javaScriptTypeResolverSymbol.Equals(l.LocationTypeOpt) &&
                                                            (l.CreationOpt == null || l.CreationOpt.Kind != OperationKind.ObjectCreation)))
                            {
                                // Points to a JavaScriptTypeResolver, but we don't know if the instance is a SimpleTypeResolver.
                                kind = PropertySetAbstractValueKind.MaybeFlagged;
                            }
                            else
                            {
                                kind = PropertySetAbstractValueKind.Unflagged;
                            }

                            break;

                        case PointsToAbstractValueKind.UnknownNotNull:
                        case PointsToAbstractValueKind.Unknown:
                            kind = PropertySetAbstractValueKind.MaybeFlagged;
                            break;

                        default:
                            Debug.Fail($"Unhandled PointsToAbstractValueKind {pointsTo.Kind}");
                            kind = PropertySetAbstractValueKind.Unflagged;
                            break;
                        }
                    }
                    else
                    {
                        Debug.Fail($"Unhandled JavaScriptSerializer constructor {constructorMethod.ToDisplayString(SymbolDisplayFormat.MinimallyQualifiedFormat)}");
                        kind = PropertySetAbstractValueKind.Unflagged;
                    }

                    return(PropertySetAbstractValue.GetInstance(kind));
                });

                PooledHashSet <(IOperation Operation, ISymbol ContainingSymbol)> rootOperationsNeedingAnalysis = PooledHashSet <(IOperation, ISymbol)> .GetInstance();

                compilationStartAnalysisContext.RegisterOperationBlockStartAction(
                    (OperationBlockStartAnalysisContext operationBlockStartAnalysisContext) =>
                {
                    operationBlockStartAnalysisContext.RegisterOperationAction(
                        (OperationAnalysisContext operationAnalysisContext) =>
                    {
                        IInvocationOperation invocationOperation =
                            (IInvocationOperation)operationAnalysisContext.Operation;
                        if ((javaScriptSerializerSymbol.Equals(invocationOperation.Instance?.Type) &&
                             SecurityHelpers.JavaScriptSerializerDeserializationMethods.Contains(invocationOperation.TargetMethod.Name)) ||
                            simpleTypeResolverSymbol.Equals(invocationOperation.TargetMethod.ReturnType) ||
                            javaScriptTypeResolverSymbol.Equals(invocationOperation.TargetMethod.ReturnType))
                        {
                            lock (rootOperationsNeedingAnalysis)
                            {
                                rootOperationsNeedingAnalysis.Add((invocationOperation.GetRoot(), operationAnalysisContext.ContainingSymbol));
                            }
                        }
                    },
                        OperationKind.Invocation);

                    operationBlockStartAnalysisContext.RegisterOperationAction(
                        (OperationAnalysisContext operationAnalysisContext) =>
                    {
                        IMethodReferenceOperation methodReferenceOperation =
                            (IMethodReferenceOperation)operationAnalysisContext.Operation;
                        if (javaScriptSerializerSymbol.Equals(methodReferenceOperation.Instance?.Type) &&
                            SecurityHelpers.JavaScriptSerializerDeserializationMethods.Contains(methodReferenceOperation.Method.Name))
                        {
                            lock (rootOperationsNeedingAnalysis)
                            {
                                rootOperationsNeedingAnalysis.Add((operationAnalysisContext.Operation.GetRoot(), operationAnalysisContext.ContainingSymbol));
                            }
                        }
                    },
                        OperationKind.MethodReference);
                });

                compilationStartAnalysisContext.RegisterCompilationEndAction(
                    (CompilationAnalysisContext compilationAnalysisContext) =>
                {
                    PooledDictionary <(Location Location, IMethodSymbol Method), HazardousUsageEvaluationResult> allResults = null;
                    try
                    {
                        lock (rootOperationsNeedingAnalysis)
                        {
                            if (!rootOperationsNeedingAnalysis.Any())
                            {
                                return;
                            }

                            allResults = PropertySetAnalysis.BatchGetOrComputeHazardousUsages(
                                compilationAnalysisContext.Compilation,
                                rootOperationsNeedingAnalysis,
                                WellKnownTypeNames.SystemWebScriptSerializationJavaScriptSerializer,
                                constructorMapper,
                                PropertyMappers,
                                hazardousUsageEvaluators,
                                InterproceduralAnalysisConfiguration.Create(
                                    compilationAnalysisContext.Options,
                                    SupportedDiagnostics,
                                    defaultInterproceduralAnalysisKind: InterproceduralAnalysisKind.ContextSensitive,
                                    cancellationToken: compilationAnalysisContext.CancellationToken));
                        }

                        if (allResults == null)
                        {
                            return;
                        }

                        foreach (KeyValuePair <(Location Location, IMethodSymbol Method), HazardousUsageEvaluationResult> kvp
                                 in allResults)
                        {
                            DiagnosticDescriptor descriptor;
                            switch (kvp.Value)
                            {
                            case HazardousUsageEvaluationResult.Flagged:
                                descriptor = DefinitelyWithSimpleTypeResolver;
                                break;

                            case HazardousUsageEvaluationResult.MaybeFlagged:
                                descriptor = MaybeWithSimpleTypeResolver;
                                break;

                            default:
                                Debug.Fail($"Unhandled result value {kvp.Value}");
                                continue;
                            }

                            compilationAnalysisContext.ReportDiagnostic(
                                Diagnostic.Create(
                                    descriptor,
                                    kvp.Key.Location,
                                    kvp.Key.Method.ToDisplayString(
                                        SymbolDisplayFormat.MinimallyQualifiedFormat)));
                        }
                    }
                    finally
                    {
                        rootOperationsNeedingAnalysis.Free();
                        allResults?.Free();
                    }
                });
            });
        }
Esempio n. 8
0
 public virtual void VisitMethodReference(IMethodReferenceOperation operation)
 {
     DefaultVisit(operation);
 }
 public override GlobalFlowStateAnalysisValueSet VisitMethodReference(IMethodReferenceOperation operation, object?argument)
 {
     return(GetValueOrDefault(base.VisitMethodReference(operation, argument)));
 }
Esempio n. 10
0
 public override IOperation VisitMethodReference(IMethodReferenceOperation operation, object argument)
 {
     return(new MethodReferenceExpression(operation.Method, operation.IsVirtual, Visit(operation.Instance), ((Operation)operation).SemanticModel, operation.Syntax, operation.Type, operation.ConstantValue, operation.IsImplicit));
 }
        public override TAbstractAnalysisValue VisitMethodReference(IMethodReferenceOperation operation, object argument)
        {
            var value = base.VisitMethodReference(operation, argument);

            return(ComputeAnalysisValueForReferenceOperation(operation, value));
        }
 public abstract void SetLocalFunctionTargetForDelegate(IOperation write, IMethodReferenceOperation localFunctionTarget);
        public sealed override void Initialize(AnalysisContext context)
        {
            ImmutableHashSet <string> cachedDeserializationMethodNames = this.DeserializationMethodNames;

            Debug.Assert(!cachedDeserializationMethodNames.IsEmpty);

            context.EnableConcurrentExecution();

            // Security analyzer - analyze and report diagnostics on generated code.
            context.ConfigureGeneratedCodeAnalysis(GeneratedCodeAnalysisFlags.Analyze | GeneratedCodeAnalysisFlags.ReportDiagnostics);

            context.RegisterCompilationStartAction(
                (CompilationStartAnalysisContext compilationStartAnalysisContext) =>
            {
                WellKnownTypeProvider wellKnownTypeProvider = WellKnownTypeProvider.GetOrCreate(
                    compilationStartAnalysisContext.Compilation);
                INamedTypeSymbol?deserializerTypeSymbol =
                    wellKnownTypeProvider.GetOrCreateTypeByMetadataName(this.DeserializerTypeMetadataName);
                if (deserializerTypeSymbol == null)
                {
                    return;
                }

                compilationStartAnalysisContext.RegisterOperationAction(
                    (OperationAnalysisContext operationAnalysisContext) =>
                {
                    IInvocationOperation invocationOperation =
                        (IInvocationOperation)operationAnalysisContext.Operation;
                    if (invocationOperation.Instance?.Type?.DerivesFrom(deserializerTypeSymbol) == true &&
                        cachedDeserializationMethodNames.Contains(invocationOperation.TargetMethod.MetadataName))
                    {
                        DiagnosticDescriptor?chosenDiagnostic =
                            this.ChooseDiagnosticDescriptor(operationAnalysisContext, wellKnownTypeProvider);
                        if (chosenDiagnostic != null)
                        {
                            operationAnalysisContext.ReportDiagnostic(
                                invocationOperation.CreateDiagnostic(
                                    chosenDiagnostic,
                                    invocationOperation.TargetMethod.ToDisplayString(
                                        SymbolDisplayFormat.MinimallyQualifiedFormat)));
                        }
                    }
                },
                    OperationKind.Invocation);

                compilationStartAnalysisContext.RegisterOperationAction(
                    (OperationAnalysisContext operationAnalysisContext) =>
                {
                    IMethodReferenceOperation methodReferenceOperation =
                        (IMethodReferenceOperation)operationAnalysisContext.Operation;
                    if (methodReferenceOperation.Instance?.Type?.DerivesFrom(deserializerTypeSymbol) == true &&
                        cachedDeserializationMethodNames.Contains(methodReferenceOperation.Method.MetadataName))
                    {
                        DiagnosticDescriptor?chosenDiagnostic =
                            this.ChooseDiagnosticDescriptor(operationAnalysisContext, wellKnownTypeProvider);
                        if (chosenDiagnostic != null)
                        {
                            operationAnalysisContext.ReportDiagnostic(
                                methodReferenceOperation.CreateDiagnostic(
                                    chosenDiagnostic,
                                    methodReferenceOperation.Method.ToDisplayString(
                                        SymbolDisplayFormat.MinimallyQualifiedFormat)));
                        }
                    }
                },
                    OperationKind.MethodReference);
            });
        }
Esempio n. 14
0
 private static AbstractExpression ReadMethodReference(IMethodReferenceOperation op)
 {
     throw new NotImplementedException();
 }
Esempio n. 15
0
 public override void VisitMethodReference(IMethodReferenceOperation operation)
 {
     Collector.AddCall(Caller, operation.Method, operation.Instance?.Type ?? operation.Method.ContainingType);
     base.VisitMethodReference(operation);
 }
        public sealed override void Initialize(AnalysisContext context)
        {
            ImmutableHashSet <string> cachedDeserializationMethodNames = this.DeserializationMethodNames;

            Debug.Assert(!string.IsNullOrWhiteSpace(this.DeserializerTypeMetadataName));
            Debug.Assert(!string.IsNullOrWhiteSpace(this.SerializationBinderPropertyMetadataName));
            Debug.Assert(!cachedDeserializationMethodNames.IsEmpty);
            Debug.Assert(this.BinderDefinitelyNotSetDescriptor != null);
            Debug.Assert(this.BinderMaybeNotSetDescriptor != null);

            context.EnableConcurrentExecution();

            // Security analyzer - analyze and report diagnostics on generated code.
            context.ConfigureGeneratedCodeAnalysis(GeneratedCodeAnalysisFlags.Analyze | GeneratedCodeAnalysisFlags.ReportDiagnostics);

            // For PropertySetAnalysis dataflow analysis.
            PropertyMapperCollection propertyMappers = new PropertyMapperCollection(
                new PropertyMapper(
                    this.SerializationBinderPropertyMetadataName,
                    PropertySetCallbacks.FlagIfNull));

            HazardousUsageEvaluatorCollection hazardousUsageEvaluators =
                new HazardousUsageEvaluatorCollection(
                    cachedDeserializationMethodNames.Select(
                        methodName => new HazardousUsageEvaluator(
                            methodName,
                            PropertySetCallbacks.HazardousIfAllFlaggedOrAllUnknown)));

            context.RegisterCompilationStartAction(
                (CompilationStartAnalysisContext compilationStartAnalysisContext) =>
            {
                if (!compilationStartAnalysisContext.Compilation.TryGetOrCreateTypeByMetadataName(
                        this.DeserializerTypeMetadataName,
                        out INamedTypeSymbol? deserializerTypeSymbol))
                {
                    return;
                }

                PooledHashSet <(IOperation Operation, ISymbol ContainingSymbol)> rootOperationsNeedingAnalysis = PooledHashSet <(IOperation, ISymbol)> .GetInstance();

                compilationStartAnalysisContext.RegisterOperationBlockStartAction(
                    (OperationBlockStartAnalysisContext operationBlockStartAnalysisContext) =>
                {
                    var owningSymbol = operationBlockStartAnalysisContext.OwningSymbol;

                    // TODO: Handle case when exactly one of the below rules is configured to skip analysis.
                    if (owningSymbol.IsConfiguredToSkipAnalysis(operationBlockStartAnalysisContext.Options,
                                                                BinderDefinitelyNotSetDescriptor !, operationBlockStartAnalysisContext.Compilation, operationBlockStartAnalysisContext.CancellationToken) &&
                        owningSymbol.IsConfiguredToSkipAnalysis(operationBlockStartAnalysisContext.Options,
                                                                BinderMaybeNotSetDescriptor !, operationBlockStartAnalysisContext.Compilation, operationBlockStartAnalysisContext.CancellationToken))
                    {
                        return;
                    }

                    operationBlockStartAnalysisContext.RegisterOperationAction(
                        (OperationAnalysisContext operationAnalysisContext) =>
                    {
                        IObjectCreationOperation creationOperation =
                            (IObjectCreationOperation)operationAnalysisContext.Operation;
                        if (deserializerTypeSymbol.Equals(creationOperation.Type))
                        {
                            lock (rootOperationsNeedingAnalysis)
                            {
                                rootOperationsNeedingAnalysis.Add((operationAnalysisContext.Operation.GetRoot(), operationAnalysisContext.ContainingSymbol));
                            }
                        }
                    },
                        OperationKind.ObjectCreation);

                    operationBlockStartAnalysisContext.RegisterOperationAction(
                        (OperationAnalysisContext operationAnalysisContext) =>
                    {
                        IInvocationOperation invocationOperation =
                            (IInvocationOperation)operationAnalysisContext.Operation;
                        if (Equals(invocationOperation.Instance?.Type, deserializerTypeSymbol) &&
                            cachedDeserializationMethodNames.Contains(invocationOperation.TargetMethod.Name))
                        {
                            lock (rootOperationsNeedingAnalysis)
                            {
                                rootOperationsNeedingAnalysis.Add((operationAnalysisContext.Operation.GetRoot(), operationAnalysisContext.ContainingSymbol));
                            }
                        }
                    },
                        OperationKind.Invocation);

                    operationBlockStartAnalysisContext.RegisterOperationAction(
                        (OperationAnalysisContext operationAnalysisContext) =>
                    {
                        IMethodReferenceOperation methodReferenceOperation =
                            (IMethodReferenceOperation)operationAnalysisContext.Operation;
                        if (Equals(methodReferenceOperation.Instance?.Type, deserializerTypeSymbol) &&
                            cachedDeserializationMethodNames.Contains(
                                methodReferenceOperation.Method.MetadataName))
                        {
                            lock (rootOperationsNeedingAnalysis)
                            {
                                rootOperationsNeedingAnalysis.Add((operationAnalysisContext.Operation.GetRoot(), operationAnalysisContext.ContainingSymbol));
                            }
                        }
                    },
                        OperationKind.MethodReference);
                });

                compilationStartAnalysisContext.RegisterCompilationEndAction(
                    (CompilationAnalysisContext compilationAnalysisContext) =>
                {
                    PooledDictionary <(Location Location, IMethodSymbol?Method), HazardousUsageEvaluationResult>?allResults = null;
                    try
                    {
                        lock (rootOperationsNeedingAnalysis)
                        {
                            if (!rootOperationsNeedingAnalysis.Any())
                            {
                                return;
                            }

                            allResults = PropertySetAnalysis.BatchGetOrComputeHazardousUsages(
                                compilationAnalysisContext.Compilation,
                                rootOperationsNeedingAnalysis,
                                compilationAnalysisContext.Options,
                                this.DeserializerTypeMetadataName,
                                DoNotUseInsecureDeserializerWithoutBinderBase.ConstructorMapper,
                                propertyMappers,
                                hazardousUsageEvaluators,
                                InterproceduralAnalysisConfiguration.Create(
                                    compilationAnalysisContext.Options,
                                    SupportedDiagnostics,
                                    rootOperationsNeedingAnalysis.First().Operation.Syntax.SyntaxTree,
                                    compilationAnalysisContext.Compilation,
                                    defaultInterproceduralAnalysisKind: InterproceduralAnalysisKind.ContextSensitive,
                                    cancellationToken: compilationAnalysisContext.CancellationToken));
                        }

                        if (allResults == null)
                        {
                            return;
                        }

                        foreach (KeyValuePair <(Location Location, IMethodSymbol?Method), HazardousUsageEvaluationResult> kvp
                                 in allResults)
                        {
                            DiagnosticDescriptor descriptor;
                            switch (kvp.Value)
                            {
                            case HazardousUsageEvaluationResult.Flagged:
                                descriptor = this.BinderDefinitelyNotSetDescriptor !;
                                break;

                            case HazardousUsageEvaluationResult.MaybeFlagged:
                                descriptor = this.BinderMaybeNotSetDescriptor !;
                                break;

                            default:
                                Debug.Fail($"Unhandled result value {kvp.Value}");
                                continue;
                            }

                            RoslynDebug.Assert(kvp.Key.Method != null);            // HazardousUsageEvaluations only for invocations.
                            compilationAnalysisContext.ReportDiagnostic(
                                Diagnostic.Create(
                                    descriptor,
                                    kvp.Key.Location,
                                    kvp.Key.Method.ToDisplayString(
                                        SymbolDisplayFormat.MinimallyQualifiedFormat)));
                        }
                    }
                    finally
                    {
                        rootOperationsNeedingAnalysis.Free(compilationAnalysisContext.CancellationToken);
                        allResults?.Free(compilationAnalysisContext.CancellationToken);
                    }
                });
            });
        }
Esempio n. 17
0
 public override void VisitMethodReference([NotNull] IMethodReferenceOperation operation)
 {
     base.VisitMethodReference(operation);
 }
        public sealed override void Initialize(AnalysisContext context)
        {
            ImmutableHashSet <string> cachedDeserializationMethodNames = this.DeserializationMethodNames;

            Debug.Assert(!String.IsNullOrWhiteSpace(this.DeserializerTypeMetadataName));
            Debug.Assert(!String.IsNullOrWhiteSpace(this.SerializationBinderPropertyMetadataName));
            Debug.Assert(cachedDeserializationMethodNames != null);
            Debug.Assert(!cachedDeserializationMethodNames.IsEmpty);
            Debug.Assert(this.BinderDefinitelyNotSetDescriptor != null);
            Debug.Assert(this.BinderMaybeNotSetDescriptor != null);

            context.EnableConcurrentExecution();

            // Security analyzer - analyze and report diagnostics on generated code.
            context.ConfigureGeneratedCodeAnalysis(GeneratedCodeAnalysisFlags.Analyze | GeneratedCodeAnalysisFlags.ReportDiagnostics);

            // For PropertySetAnalysis dataflow analysis.
            PropertyMapperCollection propertyMappers = new PropertyMapperCollection(
                new PropertyMapper(
                    this.SerializationBinderPropertyMetadataName,
                    (PointsToAbstractValue pointsToAbstractValue) =>
            {
                // A null SerializationBinder is what we want to flag as hazardous.
                switch (pointsToAbstractValue.NullState)
                {
                case NullAbstractValue.Null:
                    return(PropertySetAbstractValueKind.Flagged);

                case NullAbstractValue.NotNull:
                    return(PropertySetAbstractValueKind.Unflagged);

                default:
                    return(PropertySetAbstractValueKind.MaybeFlagged);
                }
            }));

            HazardousUsageEvaluatorCollection hazardousUsageEvaluators =
                new HazardousUsageEvaluatorCollection(
                    cachedDeserializationMethodNames.Select(
                        methodName => new HazardousUsageEvaluator(methodName, DoNotUseInsecureDeserializerWithoutBinderBase.HazardousIfNull)));

            context.RegisterCompilationStartAction(
                (CompilationStartAnalysisContext compilationStartAnalysisContext) =>
            {
                WellKnownTypeProvider wellKnownTypeProvider =
                    WellKnownTypeProvider.GetOrCreate(compilationStartAnalysisContext.Compilation);

                if (!wellKnownTypeProvider.TryGetTypeByMetadataName(
                        this.DeserializerTypeMetadataName,
                        out INamedTypeSymbol deserializerTypeSymbol))
                {
                    return;
                }

                PooledHashSet <(IOperation Operation, ISymbol ContainingSymbol)> rootOperationsNeedingAnalysis = PooledHashSet <(IOperation, ISymbol)> .GetInstance();

                compilationStartAnalysisContext.RegisterOperationBlockStartAction(
                    (OperationBlockStartAnalysisContext operationBlockStartAnalysisContext) =>
                {
                    operationBlockStartAnalysisContext.RegisterOperationAction(
                        (OperationAnalysisContext operationAnalysisContext) =>
                    {
                        IObjectCreationOperation creationOperation =
                            (IObjectCreationOperation)operationAnalysisContext.Operation;
                        if (deserializerTypeSymbol.Equals(creationOperation.Type))
                        {
                            lock (rootOperationsNeedingAnalysis)
                            {
                                rootOperationsNeedingAnalysis.Add((operationAnalysisContext.Operation.GetRoot(), operationAnalysisContext.ContainingSymbol));
                            }
                        }
                    },
                        OperationKind.ObjectCreation);

                    operationBlockStartAnalysisContext.RegisterOperationAction(
                        (OperationAnalysisContext operationAnalysisContext) =>
                    {
                        IInvocationOperation invocationOperation =
                            (IInvocationOperation)operationAnalysisContext.Operation;
                        if (Equals(invocationOperation.Instance?.Type, deserializerTypeSymbol) &&
                            cachedDeserializationMethodNames.Contains(invocationOperation.TargetMethod.Name))
                        {
                            lock (rootOperationsNeedingAnalysis)
                            {
                                rootOperationsNeedingAnalysis.Add((operationAnalysisContext.Operation.GetRoot(), operationAnalysisContext.ContainingSymbol));
                            }
                        }
                    },
                        OperationKind.Invocation);

                    operationBlockStartAnalysisContext.RegisterOperationAction(
                        (OperationAnalysisContext operationAnalysisContext) =>
                    {
                        IMethodReferenceOperation methodReferenceOperation =
                            (IMethodReferenceOperation)operationAnalysisContext.Operation;
                        if (Equals(methodReferenceOperation.Instance?.Type, deserializerTypeSymbol) &&
                            cachedDeserializationMethodNames.Contains(
                                methodReferenceOperation.Method.MetadataName))
                        {
                            lock (rootOperationsNeedingAnalysis)
                            {
                                rootOperationsNeedingAnalysis.Add((operationAnalysisContext.Operation.GetRoot(), operationAnalysisContext.ContainingSymbol));
                            }
                        }
                    },
                        OperationKind.MethodReference);
                });

                compilationStartAnalysisContext.RegisterCompilationEndAction(
                    (CompilationAnalysisContext compilationAnalysisContext) =>
                {
                    PooledDictionary <(Location Location, IMethodSymbol Method), HazardousUsageEvaluationResult> allResults = null;
                    try
                    {
                        lock (rootOperationsNeedingAnalysis)
                        {
                            if (!rootOperationsNeedingAnalysis.Any())
                            {
                                return;
                            }

                            allResults = PropertySetAnalysis.BatchGetOrComputeHazardousUsages(
                                compilationAnalysisContext.Compilation,
                                rootOperationsNeedingAnalysis,
                                this.DeserializerTypeMetadataName,
                                DoNotUseInsecureDeserializerWithoutBinderBase.ConstructorMapper,
                                propertyMappers,
                                hazardousUsageEvaluators,
                                InterproceduralAnalysisConfiguration.Create(
                                    compilationAnalysisContext.Options,
                                    SupportedDiagnostics,
                                    defaultInterproceduralAnalysisKind: InterproceduralAnalysisKind.ContextSensitive,
                                    cancellationToken: compilationAnalysisContext.CancellationToken));
                        }

                        if (allResults == null)
                        {
                            return;
                        }

                        foreach (KeyValuePair <(Location Location, IMethodSymbol Method), HazardousUsageEvaluationResult> kvp
                                 in allResults)
                        {
                            DiagnosticDescriptor descriptor;
                            switch (kvp.Value)
                            {
                            case HazardousUsageEvaluationResult.Flagged:
                                descriptor = this.BinderDefinitelyNotSetDescriptor;
                                break;

                            case HazardousUsageEvaluationResult.MaybeFlagged:
                                descriptor = this.BinderMaybeNotSetDescriptor;
                                break;

                            default:
                                Debug.Fail($"Unhandled result value {kvp.Value}");
                                continue;
                            }

                            compilationAnalysisContext.ReportDiagnostic(
                                Diagnostic.Create(
                                    descriptor,
                                    kvp.Key.Location,
                                    kvp.Key.Method.ToDisplayString(
                                        SymbolDisplayFormat.MinimallyQualifiedFormat)));
                        }
                    }
                    finally
                    {
                        rootOperationsNeedingAnalysis.Free();
                        allResults?.Free();
                    }
                });
            });
        }
            public override NullAbstractValue VisitMethodReference(IMethodReferenceOperation operation, object argument)
            {
                var _ = base.VisitMethodReference(operation, argument);

                return(GetValueBasedOnInstanceOrReferenceValue(operation.Instance));
            }
Esempio n. 20
0
 public static bool IsLambdaOrLocalFunctionOrDelegateReference(this IMethodReferenceOperation operation)
 => operation.Method.IsLambdaOrLocalFunctionOrDelegate();
Esempio n. 21
0
 public override void SetLocalFunctionTargetForDelegate(IOperation write, IMethodReferenceOperation localFunctionTarget)
 => throw ExceptionUtilities.Unreachable;
Esempio n. 22
0
            public override PointsToAbstractValue VisitMethodReferenceCore(IMethodReferenceOperation operation, object argument)
            {
                var value = base.VisitMethodReferenceCore(operation, argument);

                return(GetValueBasedOnInstanceOrReferenceValue(operation.Instance, operation, value));
            }