private static bool MatchesParameter(ISymbol symbol, IObjectCreationOperation creation, string stringArgumentValue)
        {
            if (MatchesParameterCore(symbol, stringArgumentValue))
            {
                return(true);
            }

            var operation = creation.Parent;

            while (operation != null)
            {
                symbol = null;
                switch (operation.Kind)
                {
                case OperationKind.LocalFunction:
                    symbol = ((ILocalFunctionOperation)operation).Symbol;
                    break;

                case OperationKind.AnonymousFunction:
                    symbol = ((IAnonymousFunctionOperation)operation).Symbol;
                    break;
                }

                if (symbol != null && MatchesParameterCore(symbol, stringArgumentValue))
                {
                    return(true);
                }

                operation = operation.Parent;
            }

            return(false);
        }
        private static Diagnostic?CheckArgument(
            ISymbol targetSymbol,
            IObjectCreationOperation creation,
            IParameterSymbol parameter,
            string stringArgument,
            OperationAnalysisContext context)
        {
            bool matchesParameter = MatchesParameter(targetSymbol, creation, stringArgument);

            if (IsMessage(parameter) && matchesParameter)
            {
                var dictBuilder = ImmutableDictionary.CreateBuilder <string, string?>();
                dictBuilder.Add(MessagePosition, parameter.Ordinal.ToString(CultureInfo.InvariantCulture));
                return(context.Operation.CreateDiagnostic(RuleIncorrectMessage, dictBuilder.ToImmutable(), targetSymbol.Name, stringArgument, parameter.Name, creation.Type.Name));
            }
            else if (HasParameters(targetSymbol) && IsParameterName(parameter) && !matchesParameter)
            {
                // Allow argument exceptions in accessors to use the associated property symbol name.
                if (!MatchesAssociatedSymbol(targetSymbol, stringArgument))
                {
                    return(context.Operation.CreateDiagnostic(RuleIncorrectParameterName, targetSymbol.Name, stringArgument, parameter.Name, creation.Type.Name));
                }
            }

            return(null);
        }
Example #3
0
            public override ParameterValidationAbstractValue VisitObjectCreation(IObjectCreationOperation operation, object argument)
            {
                var value = base.VisitObjectCreation(operation, argument);

                ProcessRegularInvocationOrCreation(operation.Constructor, operation.Arguments, operation);
                return(value);
            }
            private void AnalyzeObjectCreationInternal(OperationAnalysisContext context, ISymbol variable, IOperation valueOpt)
            {
                IObjectCreationOperation objCreation = valueOpt as IObjectCreationOperation;

                if (objCreation == null)
                {
                    return;
                }

                if (_objectCreationOperationsAnalyzed.Contains(objCreation))
                {
                    return;
                }
                else
                {
                    _objectCreationOperationsAnalyzed.Add(objCreation);
                }

                if (SecurityDiagnosticHelpers.IsXmlDocumentCtorDerived(objCreation.Constructor, _xmlTypes))
                {
                    AnalyzeObjectCreationForXmlDocument(context, variable, objCreation);
                }
                else if (SecurityDiagnosticHelpers.IsXmlTextReaderCtorDerived(objCreation.Constructor, _xmlTypes))
                {
                    AnalyzeObjectCreationForXmlTextReader(context, variable, objCreation);
                }
                else if (SecurityDiagnosticHelpers.IsXmlReaderSettingsCtor(objCreation.Constructor, _xmlTypes))
                {
                    AnalyzeObjectCreationForXmlReaderSettings(context, variable, objCreation);
                }
                else
                {
                    AnalyzeMethodOverloads(context, objCreation.Constructor, objCreation.Arguments, objCreation.Syntax);
                }
            }
Example #5
0
        public override void VisitObjectCreation(IObjectCreationOperation operation)
        {
            Assert.Equal(OperationKind.ObjectCreation, operation.Kind);
            var constructor = operation.Constructor;

            // When parameter-less struct constructor is inaccessible, the constructor symbol is null
            if (!operation.Type.IsValueType)
            {
                Assert.NotNull(constructor);

                if (constructor == null)
                {
                    Assert.Empty(operation.Arguments);
                }
            }

            IEnumerable <IOperation> children = operation.Arguments;

            if (operation.Initializer != null)
            {
                children = children.Concat(new[] { operation.Initializer });
            }

            AssertEx.Equal(children, operation.Children);
        }
        private static void CheckArgument(
            ISymbol targetSymbol,
            IObjectCreationOperation creation,
            IParameterSymbol parameter,
            string stringArgument,
            OperationAnalysisContext context)
        {
            bool matchesParameter    = MatchesParameter(targetSymbol, creation, stringArgument);
            LocalizableString format = null;

            if (IsMessage(parameter) && matchesParameter)
            {
                format = s_localizableMessageIncorrectMessage;
            }
            else if (IsParameterName(parameter) && !matchesParameter)
            {
                // Allow argument exceptions in accessors to use the associated property symbol name.
                if (MatchesAssociatedSymbol(targetSymbol, stringArgument))
                {
                    return;
                }

                format = s_localizableMessageIncorrectParameterName;
            }

            if (format != null)
            {
                ReportDiagnostic(context, format, targetSymbol.Name, stringArgument, parameter.Name, creation.Type.Name);
            }
        }
        public static void RegisterMemberAccess(this AnalysisContext context, Action <InvocationAnalysisContext> action)
        {
            var operationKinds = new[]
            {
                OperationKind.Invocation,
                OperationKind.SimpleAssignment,
                OperationKind.VariableDeclaration,
                OperationKind.ObjectCreation,
                OperationKind.FieldInitializer,
                OperationKind.FieldReference,
            };

            context.RegisterOperationAction(ctx =>
            {
                ISymbol?symbol = ctx.Operation switch
                {
                    IInvocationOperation invocation => invocation.TargetMethod,
                    IPropertyReferenceOperation property => property.Property.Type,
                    IObjectCreationOperation creation => creation.Type,
                    ISimpleAssignmentOperation assignment => assignment.Type,
                    IFieldInitializerOperation fieldInitializer => fieldInitializer.Type,
                    IFieldReferenceOperation fieldRef => fieldRef.Type,
                    IVariableDeclarationOperation variableDeclaration => variableDeclaration.Type,
                    _ => null,
                };

                if (symbol is null)
                {
                    return;
                }

                var location = ctx.Operation.Syntax.GetLocation();
                var newCtx   = new InvocationAnalysisContext(symbol, location, ctx.Compilation, ctx.Options, ctx.ReportDiagnostic, ctx.CancellationToken);

                action(newCtx);
            }, operationKinds);

            context.RegisterSymbolAction(ctx =>
            {
                var symbol = ctx.Symbol switch
                {
                    IPropertySymbol property => property.Type,
                    IParameterSymbol parameter => parameter.Type,
                    IMethodSymbol method => method.ReturnsVoid ? null : method.ReturnType,
                    IFieldSymbol field => field.Type,
                    _ => null,
                };

                if (symbol is null)
                {
                    return;
                }

                var location = ctx.Symbol.Locations[0];
                var newCtx   = new InvocationAnalysisContext(symbol, location, ctx.Compilation, ctx.Options, ctx.ReportDiagnostic, ctx.CancellationToken);

                action(newCtx);
            }, SymbolKind.Property, SymbolKind.Method, SymbolKind.Parameter, SymbolKind.Field);
        }
 internal static Location GetExceptionalLocation(this IObjectCreationOperation @this)
 {
     if (@this.Syntax is ObjectCreationExpressionSyntax creationSyntax)
     {
         return(creationSyntax.Type.GetLocation());
     }
     else
     {
         return(@this.Syntax.GetLocation());
     }
 }
Example #9
0
        public override Scope VisitObjectCreation(IObjectCreationOperation operation, Scope currentScope)
        {
            var scope = currentScope;

            foreach (var argument in operation.Arguments)
            {
                scope = argument.Accept(this, scope);
            }

            return(scope);
        }
            // So we can hook into constructor calls.
            public override TaintedDataAbstractValue VisitObjectCreation(IObjectCreationOperation operation, object argument)
            {
                TaintedDataAbstractValue         baseValue        = base.VisitObjectCreation(operation, argument);
                IEnumerable <IArgumentOperation> taintedArguments = GetTaintedArguments(operation.Arguments);

                if (taintedArguments.Any())
                {
                    ProcessTaintedDataEnteringInvocationOrCreation(operation.Constructor, taintedArguments, operation);
                }

                return(baseValue);
            }
Example #11
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);
        }
Example #12
0
        private static AbstractExpression ReadObjectCreation(IObjectCreationOperation op)
        {
            var context     = CodeReaderContext.GetContextOrThrow();
            var objectType  = context.CodeModel.Get <TypeMember>(op.Type);
            var initializer = ReadExpression(op.Initializer);

            return(new NewObjectExpression {
                Type = objectType,
                ConstructorCall = new MethodCallExpression {
                    Type = objectType,
                    Method = context.CodeModel.Get <ConstructorMember>(op.Constructor),
                    Arguments = op.Arguments.Select(ReadArgument).ToList()
                },
                ObjectInitializer = initializer as ObjectInitializerExpression,
                CollectionInitializer = initializer as CollectionInitializerExpression
            });
        }
Example #13
0
        private ISymbol?GetUnoSymbolFromOperation(IOperation operation)
        {
            ISymbol symbol = operation switch
            {
                IInvocationOperation invocationOperation => invocationOperation.TargetMethod,
                IObjectCreationOperation objectCreation => objectCreation.Type,
                IFieldReferenceOperation fieldReferenceOperation => fieldReferenceOperation.Field,
                IPropertyReferenceOperation propertyReferenceOperation => propertyReferenceOperation.Property,
                    _ => throw new InvalidOperationException("This code path is unreachable.")
            };


            if (IsUnoSymbol(symbol))
            {
                return(symbol);
            }

            return(null);
        }
Example #14
0
                bool IsViolatingCodeActionObjectCreation(IObjectCreationOperation objectCreation)
                {
                    return(objectCreation.Constructor.ContainingType.GetBaseTypesAndThis().All(namedType => !IsCodeActionWithOverriddenEquivalenceKey(namedType)));

                    // Local functions
                    bool IsCodeActionWithOverriddenEquivalenceKey(INamedTypeSymbol namedType)
                    {
                        if (namedType == null || namedType.Equals(_codeActionSymbol))
                        {
                            return(false);
                        }

                        // We are already tracking CodeActions with equivalence key in this compilation.
                        if (namedType.ContainingAssembly.Equals(_sourceAssembly))
                        {
                            return(_codeActionsWithEquivalenceKey != null && _codeActionsWithEquivalenceKey.Contains(namedType));
                        }

                        // For types in different compilation, perfom the check.
                        return(IsCodeActionWithOverriddenEquivlanceKeyCore(namedType));
                    }
                }
Example #15
0
        private static void CheckArgument(
            ISymbol targetSymbol,
            IObjectCreationOperation creation,
            IParameterSymbol parameter,
            string stringArgument,
            OperationAnalysisContext context)
        {
            bool matchesParameter    = MatchesParameter(targetSymbol, creation, stringArgument);
            LocalizableString format = null;

            if (IsMessage(parameter) && matchesParameter)
            {
                format = s_localizableMessageIncorrectMessage;
            }
            else if (IsParameterName(parameter) && !matchesParameter)
            {
                format = s_localizableMessageIncorrectParameterName;
            }

            if (format != null)
            {
                ReportDiagnostic(context, format, targetSymbol.Name, stringArgument, parameter.Name, creation.Type.Name);
            }
        }
        private static async Task <Document> AddNullMessageToArgumentListAsync(Document document, IObjectCreationOperation creation, CancellationToken token)
        {
            DocumentEditor editor = await DocumentEditor.CreateAsync(document, token).ConfigureAwait(false);

            SyntaxNode argument    = AddNameOfIfLiteral(creation.Arguments[0].Value, editor.Generator);
            SyntaxNode newCreation = editor.Generator.ObjectCreationExpression(creation.Type, editor.Generator.Argument(editor.Generator.NullLiteralExpression()), argument);

            editor.ReplaceNode(creation.Syntax, newCreation);
            return(editor.GetChangedDocument());
        }
 public override ValueContentAbstractValue VisitObjectCreation(IObjectCreationOperation operation, object argument)
 {
     // TODO: Analyze string constructor
     // https://github.com/dotnet/roslyn-analyzers/issues/1547
     return(base.VisitObjectCreation(operation, argument));
 }
        public sealed override void Initialize(AnalysisContext context)
        {
            context.EnableConcurrentExecution();

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

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

                if (!wellKnownTypeProvider.TryGetOrCreateTypeByMetadataName(
                        WellKnownTypeNames.SystemDataDataSet,
                        out INamedTypeSymbol? dataSetTypeSymbol) ||
                    !wellKnownTypeProvider.TryGetOrCreateTypeByMetadataName(
                        WellKnownTypeNames.SystemDataDataTable,
                        out INamedTypeSymbol? dataTableTypeSymbol))
                {
                    return;
                }

                INamedTypeSymbol?dataContractSerializerTypeSymbol = wellKnownTypeProvider.GetOrCreateTypeByMetadataName(
                    WellKnownTypeNames.SystemRuntimeSerializationDataContractSerializer);
                INamedTypeSymbol?dataContractJsonSerializerTypeSymbol =
                    wellKnownTypeProvider.GetOrCreateTypeByMetadataName(
                        WellKnownTypeNames.SystemRuntimeSerializationJsonDataContractJsonSerializer);
                INamedTypeSymbol?javaScriptSerializerTypeSymbol = wellKnownTypeProvider.GetOrCreateTypeByMetadataName(
                    WellKnownTypeNames.SystemWebScriptSerializationJavaScriptSerializer);
                INamedTypeSymbol?typeTypeSymbol = wellKnownTypeProvider.GetOrCreateTypeByMetadataName(
                    WellKnownTypeNames.SystemType);
                INamedTypeSymbol?xmlSerializerTypeSymbol = wellKnownTypeProvider.GetOrCreateTypeByMetadataName(
                    WellKnownTypeNames.SystemXmlSerializationXmlSerializer);
                INamedTypeSymbol?jsonNetJsonSerializerTypeSymbol = wellKnownTypeProvider.GetOrCreateTypeByMetadataName(
                    WellKnownTypeNames.NewtonsoftJsonJsonSerializer);
                INamedTypeSymbol?jsonNetJsonConvertTypeSymbol = wellKnownTypeProvider.GetOrCreateTypeByMetadataName(
                    WellKnownTypeNames.NewtonsoftJsonJsonConvert);

                if (dataContractSerializerTypeSymbol == null &&
                    dataContractJsonSerializerTypeSymbol == null &&
                    javaScriptSerializerTypeSymbol == null &&
                    xmlSerializerTypeSymbol == null &&
                    jsonNetJsonSerializerTypeSymbol == null &&
                    jsonNetJsonConvertTypeSymbol == null)
                {
                    return;
                }

                InsecureDeserializationTypeDecider decider = InsecureDeserializationTypeDecider.GetOrCreate(compilation);

                compilationStartAnalysisContext.RegisterOperationAction(
                    (OperationAnalysisContext operationAnalysisContext) =>
                {
                    IInvocationOperation invocationOperation =
                        (IInvocationOperation)operationAnalysisContext.Operation;
                    if (!IsDeserializationMethod(
                            invocationOperation,
                            out ObjectGraphOptions? optionsToUse,
                            out IEnumerable <(ITypeSymbol DeserializedTypeSymbol, IOperation OperationForLocation)>?deserializedTypes))
                    {
                        return;
                    }

                    RoslynDebug.Assert(optionsToUse != null);
                    RoslynDebug.Assert(deserializedTypes != null);

                    ReportDiagnosticsForInsecureTypes(operationAnalysisContext, optionsToUse, deserializedTypes);
                },
                    OperationKind.Invocation);

                compilationStartAnalysisContext.RegisterOperationAction(
                    (OperationAnalysisContext operationAnalysisContext) =>
                {
                    IObjectCreationOperation objectCreationOperation =
                        (IObjectCreationOperation)operationAnalysisContext.Operation;
                    if (!IsDeserializationConstructor(
                            objectCreationOperation,
                            out ObjectGraphOptions? optionsToUse,
                            out IEnumerable <(ITypeSymbol DeserializedTypeSymbol, IOperation OperationForLocation)>?deserializedTypes))
                    {
                        return;
                    }

                    RoslynDebug.Assert(optionsToUse != null);
                    RoslynDebug.Assert(deserializedTypes != null);

                    ReportDiagnosticsForInsecureTypes(operationAnalysisContext, optionsToUse, deserializedTypes);
                },
                    OperationKind.ObjectCreation);

                return;

                // Local functions.

                // Determines if the invoked method is for deserialization, and what type of deserialization.
                bool IsDeserializationMethod(
                    IInvocationOperation invocationOperation,
                    out ObjectGraphOptions? optionsToUse,
                    out IEnumerable <(ITypeSymbol DeserializedTypeSymbol, IOperation OperationForLocation)>?deserializedTypes)
                {
                    optionsToUse      = null;
                    deserializedTypes = null;

                    IMethodSymbol targetMethod = invocationOperation.TargetMethod;
                    if (invocationOperation.Instance?.Type?.DerivesFrom(javaScriptSerializerTypeSymbol) == true)
                    {
                        if (targetMethod.MetadataName == "DeserializeObject" &&
                            invocationOperation.Parent?.Kind == OperationKind.Conversion &&
                            invocationOperation.Parent is IConversionOperation javaScriptConversionOperation)
                        {
                            optionsToUse      = ObjectGraphOptions.JavaScriptSerializerOptions;
                            deserializedTypes = new[]
                            {
                                (javaScriptConversionOperation.Type, (IOperation)javaScriptConversionOperation)
                            };
                        }
Example #19
0
            private void AnalyzeObjectCreationForXmlTextReader(OperationAnalysisContext context, ISymbol variable, IObjectCreationOperation objCreation)
            {
                if (variable == null || !_xmlTextReaderEnvironments.TryGetValue(variable, out XmlTextReaderEnvironment env))
                {
                    env = new XmlTextReaderEnvironment(_isFrameworkSecure)
                    {
                        XmlTextReaderDefinition = objCreation.Syntax
                    };
                }

                if (objCreation.Constructor.ContainingType != _xmlTypes.XmlTextReader)
                {
                    env.IsDtdProcessingDisabled = true;
                    env.IsSecureResolver        = true;
                }

                if (objCreation.Initializer != null)
                {
                    foreach (IOperation init in objCreation.Initializer.Initializers)
                    {
                        if (init is IAssignmentOperation assign)
                        {
                            var             propValue = assign.Value;
                            IPropertySymbol prop      = context.Compilation.GetSemanticModel(context.Operation.Syntax.SyntaxTree)?.GetSymbolInfo(assign.Target.Syntax).Symbol as IPropertySymbol;
                            if (prop == null)
                            {
                                continue;
                            }

                            if (propValue is IConversionOperation operation &&
                                SecurityDiagnosticHelpers.IsXmlTextReaderXmlResolverPropertyDerived(prop, _xmlTypes))
                            {
                                env.IsXmlResolverSet = true;

                                if (SecurityDiagnosticHelpers.IsXmlSecureResolverType(operation.Operand.Type, _xmlTypes))
                                {
                                    env.IsSecureResolver = true;
                                }
                                else if (SecurityDiagnosticHelpers.IsExpressionEqualsNull(operation.Operand))
                                {
                                    env.IsSecureResolver = true;
                                }
                                else
                                {
                                    env.IsSecureResolver = false;
                                }
                            }
                            else if (SecurityDiagnosticHelpers.IsXmlTextReaderDtdProcessingPropertyDerived(prop, _xmlTypes))
                            {
                                env.IsDtdProcessingSet      = true;
                                env.IsDtdProcessingDisabled = !SecurityDiagnosticHelpers.IsExpressionEqualsDtdProcessingParse(propValue);
                            }
                        }
                    }
                }
        private void OnCompilationStart(CompilationStartAnalysisContext compilationContext)
        {
            var restrictedInternalsVisibleToMap = GetRestrictedInternalsVisibleToMap(compilationContext.Compilation);

            if (restrictedInternalsVisibleToMap.IsEmpty)
            {
                return;
            }

            var namespaceToIsBannedMap = new ConcurrentDictionary <INamespaceSymbol, /*isBanned*/ bool>();

            // Verify all explicit type name specifications in declarations and executable code.
            compilationContext.RegisterSyntaxNodeAction(
                context =>
            {
                var name = (TNameSyntax)context.Node;
                if (!IsInTypeOnlyContext(name) ||
                    name.Parent is TNameSyntax)
                {
                    // Bail out if we are not in type only context or the parent is also a name
                    // which will be analyzed separately.
                    return;
                }

                var typeInfo = context.SemanticModel.GetTypeInfo(name, context.CancellationToken);
                VerifySymbol(typeInfo.Type as INamedTypeSymbol, name,
                             context.ReportDiagnostic, restrictedInternalsVisibleToMap, namespaceToIsBannedMap);
            },
                NameSyntaxKinds);

            // Verify all member usages in executable code.
            compilationContext.RegisterOperationAction(
                context =>
            {
                var symbol = context.Operation switch
                {
                    IObjectCreationOperation objectCreation => objectCreation.Constructor,
                    IInvocationOperation invocation => invocation.TargetMethod,
                    IMemberReferenceOperation memberReference => memberReference.Member,
                    IConversionOperation conversion => conversion.OperatorMethod,
                    IUnaryOperation unary => unary.OperatorMethod,
                    IBinaryOperation binary => binary.OperatorMethod,
                    IIncrementOrDecrementOperation incrementOrDecrement => incrementOrDecrement.OperatorMethod,
                    _ => throw new NotImplementedException($"Unhandled OperationKind: {context.Operation.Kind}"),
                };

                VerifySymbol(symbol, context.Operation.Syntax,
                             context.ReportDiagnostic, restrictedInternalsVisibleToMap, namespaceToIsBannedMap);
            },
                OperationKind.ObjectCreation,
                OperationKind.Invocation,
                OperationKind.EventReference,
                OperationKind.FieldReference,
                OperationKind.MethodReference,
                OperationKind.PropertyReference,
                OperationKind.Conversion,
                OperationKind.UnaryOperator,
                OperationKind.BinaryOperator,
                OperationKind.Increment,
                OperationKind.Decrement);
        }
            protected override void PostProcessArgument(IArgumentOperation operation, bool isEscaped)
            {
                base.PostProcessArgument(operation, isEscaped);
                if (isEscaped)
                {
                    // Discover if a disposable object is being passed into the creation method for this new disposable object
                    // and if the new disposable object assumes ownership of that passed in disposable object.
                    if (IsDisposeOwnershipTransfer())
                    {
                        var pointsToValue = GetPointsToAbstractValue(operation.Value);
                        HandlePossibleEscapingOperation(operation, pointsToValue.Locations);
                        return;
                    }
                    else if (FlowBranchConditionKind == ControlFlowConditionKind.WhenFalse &&
                             operation.Parameter.RefKind == RefKind.Out &&
                             operation.Parent is IInvocationOperation invocation &&
                             invocation.TargetMethod.ReturnType.SpecialType == SpecialType.System_Boolean)
                    {
                        // Case 1:
                        //      // Assume 'obj' is not a valid object on the 'else' path.
                        //      if (TryXXX(out IDisposable obj))
                        //      {
                        //          obj.Dispose();
                        //      }
                        //
                        //      return;

                        // Case 2:
                        //      if (!TryXXX(out IDisposable obj))
                        //      {
                        //          return; // Assume 'obj' is not a valid object on this path.
                        //      }
                        //
                        //      obj.Dispose();

                        HandlePossibleInvalidatingOperation(operation);
                        return;
                    }
                }

                // Ref or out argument values from callee might be escaped by assigning to field.
                if (operation.Parameter.RefKind == RefKind.Out || operation.Parameter.RefKind == RefKind.Ref)
                {
                    HandlePossibleEscapingOperation(operation, GetEscapedLocations(operation));
                }

                return;

                // Local functions.
                bool IsDisposeOwnershipTransfer()
                {
                    if (operation.Parameter.RefKind == RefKind.Out)
                    {
                        // Out arguments are always owned by the caller.
                        return(false);
                    }

                    return(operation.Parent switch
                    {
                        IObjectCreationOperation _ => DisposeOwnershipTransferAtConstructor ||
                        DisposeOwnershipTransferLikelyTypes.Contains(operation.Parameter.Type),

                        IInvocationOperation invocation => DisposeOwnershipTransferAtMethodCall ||
                        IsDisposableCreationSpecialCase(invocation.TargetMethod) && DisposeOwnershipTransferLikelyTypes.Contains(operation.Parameter.Type),

                        _ => false,
                    });
                }
            public override NullAbstractValue VisitObjectCreation(IObjectCreationOperation operation, object argument)
            {
                var _ = base.VisitObjectCreation(operation, argument);

                return(NullAbstractValue.NotNull);
            }
Example #23
0
            private void AnalyzeObjectCreationForXmlDocument(OperationAnalysisContext context, ISymbol variable, IObjectCreationOperation objCreation)
            {
                if (variable == null || !_xmlDocumentEnvironments.TryGetValue(variable, out var xmlDocumentEnvironment))
                {
                    xmlDocumentEnvironment = new XmlDocumentEnvironment
                    {
                        IsSecureResolver = false,
                        IsXmlResolverSet = false
                    };
                }

                xmlDocumentEnvironment.XmlDocumentDefinition = objCreation.Syntax;
                SyntaxNode node = objCreation.Syntax;
                bool       isXmlDocumentSecureResolver = false;

                if (!Equals(objCreation.Constructor.ContainingType, _xmlTypes.XmlDocument))
                {
                    isXmlDocumentSecureResolver = true;
                }

                // propertyInitlizer is not returned any more
                // and no way to get propertysymbol
                if (objCreation.Initializer != null)
                {
                    foreach (IOperation init in objCreation.Initializer.Initializers)
                    {
                        if (init is IAssignmentOperation assign)
                        {
                            var propValue = assign.Value;
                            if (!(assign.Target is IPropertyReferenceOperation propertyReference))
                            {
                                continue;
                            }

                            var prop = propertyReference.Property;
                            if (prop.MatchPropertyDerivedByName(_xmlTypes.XmlDocument, "XmlResolver"))
                            {
                                if (!(propValue is IConversionOperation operation))
                                {
                                    return;
                                }

                                if (SecurityDiagnosticHelpers.IsXmlSecureResolverType(operation.Operand.Type, _xmlTypes))
                                {
                                    isXmlDocumentSecureResolver = true;
                                }
                                else if (SecurityDiagnosticHelpers.IsExpressionEqualsNull(operation.Operand))
                                {
                                    isXmlDocumentSecureResolver = true;
                                }
                                else // Non secure resolvers
                                {
                                    context.ReportDiagnostic(assign.Syntax.CreateDiagnostic(RuleXmlDocumentWithNoSecureResolver));
                                    return;
                                }
                            }
                            else
                            {
                                AnalyzeNeverSetProperties(context, prop, assign.Syntax.GetLocation());
                            }
                        }
                    }
                }

                xmlDocumentEnvironment.IsSecureResolver = isXmlDocumentSecureResolver;

                if (variable != null)
                {
                    _xmlDocumentEnvironments[variable] = xmlDocumentEnvironment;
                }
                else if (!xmlDocumentEnvironment.IsSecureResolver) // Insecure temp object
                {
                    context.ReportDiagnostic(node.CreateDiagnostic(RuleXmlDocumentWithNoSecureResolver));
                }

                return;
            }
            public override PropertySetAbstractValue VisitObjectCreation(IObjectCreationOperation operation, object?argument)
            {
                PropertySetAbstractValue abstractValue = base.VisitObjectCreation(operation, argument);

                if (this.TrackedTypeSymbols.Any(s => operation.Type.GetBaseTypesAndThis().Contains(s)))
                {
                    ConstructorMapper constructorMapper = this.DataFlowAnalysisContext.ConstructorMapper;
                    if (!constructorMapper.PropertyAbstractValues.IsEmpty)
                    {
                        abstractValue = PropertySetAbstractValue.GetInstance(constructorMapper.PropertyAbstractValues);
                    }
                    else if (constructorMapper.MapFromPointsToAbstractValue != null)
                    {
                        using ArrayBuilder <PointsToAbstractValue> builder = ArrayBuilder <PointsToAbstractValue> .GetInstance();

                        foreach (IArgumentOperation argumentOperation in operation.Arguments)
                        {
                            builder.Add(this.GetPointsToAbstractValue(argumentOperation));
                        }

                        abstractValue = constructorMapper.MapFromPointsToAbstractValue(operation.Constructor, builder);
                    }
                    else if (constructorMapper.MapFromValueContentAbstractValue != null)
                    {
                        Debug.Assert(this.DataFlowAnalysisContext.ValueContentAnalysisResult != null);
                        using ArrayBuilder <PointsToAbstractValue> pointsToBuilder = ArrayBuilder <PointsToAbstractValue> .GetInstance();

                        using ArrayBuilder <ValueContentAbstractValue> valueContentBuilder = ArrayBuilder <ValueContentAbstractValue> .GetInstance();

                        foreach (IArgumentOperation argumentOperation in operation.Arguments)
                        {
                            pointsToBuilder.Add(this.GetPointsToAbstractValue(argumentOperation));
                            valueContentBuilder.Add(this.GetValueContentAbstractValue(argumentOperation.Value));
                        }

                        abstractValue = constructorMapper.MapFromValueContentAbstractValue(operation.Constructor, valueContentBuilder, pointsToBuilder);
                    }
                    else
                    {
                        Debug.Fail("Unhandled ConstructorMapper");
                        return(abstractValue);
                    }

                    PointsToAbstractValue pointsToAbstractValue = this.GetPointsToAbstractValue(operation);
                    this.SetAbstractValue(pointsToAbstractValue, abstractValue);
                }
                else
                {
                    if (TryFindNonTrackedTypeHazardousUsageEvaluator(
                            operation.Constructor,
                            operation.Arguments,
                            out HazardousUsageEvaluator? hazardousUsageEvaluator,
                            out IOperation? propertySetInstance))
                    {
                        this.EvaluatePotentialHazardousUsage(
                            operation.Syntax,
                            operation.Constructor,
                            propertySetInstance,
                            (PropertySetAbstractValue abstractValue) => hazardousUsageEvaluator.InvocationEvaluator !(
                                operation.Constructor,
                                abstractValue));
                    }
                }

                return(abstractValue);
            }
        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);
                    }
                });
            });
        }
        private static async Task <Document> SwapArgumentsOrderAsync(Document document, IObjectCreationOperation creation, int paramPosition, int argumentCount, CancellationToken token)
        {
            DocumentEditor editor = await DocumentEditor.CreateAsync(document, token).ConfigureAwait(false);

            SyntaxNode parameter = AddNameOfIfLiteral(creation.Arguments[paramPosition].Value, editor.Generator);
            SyntaxNode newCreation;

            if (argumentCount == 2)
            {
                if (paramPosition == 0)
                {
                    newCreation = editor.Generator.ObjectCreationExpression(creation.Type, creation.Arguments[1].Syntax, parameter);
                }
                else
                {
                    newCreation = editor.Generator.ObjectCreationExpression(creation.Type, parameter, creation.Arguments[0].Syntax);
                }
            }
            else
            {
                Debug.Assert(argumentCount == 3);
                if (paramPosition == 0)
                {
                    newCreation = editor.Generator.ObjectCreationExpression(creation.Type, creation.Arguments[1].Syntax, parameter, creation.Arguments[2].Syntax);
                }
                else
                {
                    newCreation = editor.Generator.ObjectCreationExpression(creation.Type, parameter, creation.Arguments[1].Syntax, creation.Arguments[0].Syntax);
                }
            }
            editor.ReplaceNode(creation.Syntax, newCreation);
            return(editor.GetChangedDocument());
        }
Example #27
0
 private bool IsViolatingCodeActionObjectCreation(IObjectCreationOperation objectCreation)
 {
     return(objectCreation.Constructor.ContainingType.GetBaseTypesAndThis().All(namedType => !IsCodeActionWithOverriddenEquivalenceKey(namedType)));
 }
Example #28
0
 public override PointsToAbstractValue VisitObjectCreation(IObjectCreationOperation operation, object argument)
 {
     return(VisitTypeCreationWithArgumentsAndInitializer(operation.Arguments, operation.Initializer, operation, argument));
 }
Example #29
0
 public override IOperation VisitObjectCreation(IObjectCreationOperation operation, object argument)
 {
     return(new ObjectCreationExpression(operation.Constructor, Visit(operation.Initializer), VisitArray(operation.Arguments), ((Operation)operation).SemanticModel, operation.Syntax, operation.Type, operation.ConstantValue, operation.IsImplicit));
 }
Example #30
0
            private void AnalyzeObjectCreationForXmlDocument(OperationAnalysisContext context, ISymbol variable, IObjectCreationOperation objCreation)
            {
                XmlDocumentEnvironment xmlDocumentEnvironment;

                if (variable == null || !_xmlDocumentEnvironments.TryGetValue(variable, out xmlDocumentEnvironment))
                {
                    xmlDocumentEnvironment = new XmlDocumentEnvironment
                    {
                        IsSecureResolver = false,
                        IsXmlResolverSet = false
                    };
                }

                xmlDocumentEnvironment.XmlDocumentDefinition = objCreation.Syntax;
                SyntaxNode node = objCreation.Syntax;
                bool       isXmlDocumentSecureResolver = false;

                if (objCreation.Constructor.ContainingType != _xmlTypes.XmlDocument)
                {
                    isXmlDocumentSecureResolver = true;
                }

                // propertyInitlizer is not returned any more
                // and no way to get propertysymbol
                if (objCreation.Initializer != null)
                {
                    foreach (IOperation init in objCreation.Initializer.Initializers)
                    {
                        if (init is IAssignmentOperation assign)
                        {
                            var             propValue = assign.Value;
                            IPropertySymbol prop      = context.Compilation.GetSemanticModel(context.Operation.Syntax.SyntaxTree)?.GetSymbolInfo(assign.Target.Syntax).Symbol as IPropertySymbol;
                            if (prop == null)
                            {
                                continue;
                            }

                            if (prop.MatchPropertyDerivedByName(_xmlTypes.XmlDocument, "XmlResolver"))
                            {
                                IConversionOperation operation = propValue as IConversionOperation;

                                if (operation == null)
                                {
                                    return;
                                }

                                if (SecurityDiagnosticHelpers.IsXmlSecureResolverType(operation.Operand.Type, _xmlTypes))
                                {
                                    isXmlDocumentSecureResolver = true;
                                }
                                else if (SecurityDiagnosticHelpers.IsExpressionEqualsNull(operation.Operand))
                                {
                                    isXmlDocumentSecureResolver = true;
                                }
                                else // Non secure resolvers
                                {
                                    return;
                                }
                            }
                        }
                    }
                }

                xmlDocumentEnvironment.IsSecureResolver = isXmlDocumentSecureResolver;

                if (variable != null)
                {
                    _xmlDocumentEnvironments[variable] = xmlDocumentEnvironment;
                }
                else if (!xmlDocumentEnvironment.IsSecureResolver) // Insecure temp object
                {
                    Diagnostic diag = Diagnostic.Create(
                        RuleDoNotUseInsecureDtdProcessing,
                        node.GetLocation(),
                        SecurityDiagnosticHelpers.GetLocalizableResourceString(
                            nameof(MicrosoftNetFrameworkAnalyzersResources.XmlDocumentWithNoSecureResolverMessage)
                            )
                        );
                    context.ReportDiagnostic(diag);
                }
            }