示例#1
0
 protected override void Free()
 {
     _labelsDefined.Free();
     _labelsUsed.Free();
     _usingDeclarations.Free();
     base.Free();
 }
示例#2
0
        protected bool _convertInsufficientExecutionStackExceptionToCancelledByStackGuardException = false; // By default, just let the original exception to bubble up.

        protected override void Free()
        {
            _labelsDefined.Free();
            _labelsUsed.Free();

            base.Free();
        }
示例#3
0
 public void Free()
 {
     MethodsConvertedToDelegates.Free();
     ScopesThatCantBeStructs.Free();
     NeedsParentFrame.Free();
     ScopeTree.Free();
 }
示例#4
0
 public void Free()
 {
     foreach (var item in ThrowLocations)
     {
         item.Value.Free();
     }
     ThrowLocations.Free();
     CatchBlockUsed.Free();
 }
示例#5
0
        private void ExecuteCodeBlockActions(PooledHashSet <CodeBlockAnalyzerAction> blockActions, SyntaxNode declaredNode, ISymbol declaredSymbol, SemanticModel semanticModel)
        {
            foreach (var blockAction in blockActions)
            {
                ExecuteAndCatchIfThrows(blockAction.Analyzer,
                                        () => blockAction.Action(new CodeBlockAnalysisContext(declaredNode, declaredSymbol, semanticModel, _analyzerOptions, _addDiagnostic,
                                                                                              d => IsSupportedDiagnostic(blockAction.Analyzer, d), _cancellationToken)));
            }

            blockActions.Free();
        }
        private static void SetKnownToHaveNoDeclaredBaseCycles(ref PooledHashSet <NamedTypeSymbol> visited)
        {
            if (visited != null)
            {
                foreach (var v in visited)
                {
                    v.SetKnownToHaveNoDeclaredBaseCycles();
                }

                visited.Free();
                visited = null;
            }
        }
        public ImmutableArray <S> SelectDistinct <S>(Func <T, S> selector)
        {
            ArrayBuilder <S> result = ArrayBuilder <S> .GetInstance(Count);

            PooledHashSet <S> set = PooledHashSet <S> .GetInstance();

            foreach (T item in this)
            {
                S selected = selector(item);
                if (set.Add(selected))
                {
                    result.Add(selected);
                }
            }

            set.Free();
            return(result.ToImmutableAndFree());
        }
        public void RemoveDuplicates()
        {
            PooledHashSet <T> set = PooledHashSet <T> .GetInstance();

            int j = 0;

            for (int i = 0; i < Count; i++)
            {
                if (set.Add(this[i]))
                {
                    this[j] = this[i];
                    j++;
                }
            }

            Clip(j);
            set.Free();
        }
示例#9
0
        private static ISet <string> GetLanguageCodesForSupportedCountries(
            IEnumerable <string> countries)
        {
            PooledHashSet <string> instance = PooledHashSet <string> .GetInstance();

            try
            {
                foreach (string country in countries)
                {
                    instance.UnionWith(EmailAndPhoneNoMustNotBePresentInTheSource.GetSupportedLocales(country));
                }
                return((ISet <string>)instance.ToImmutableHashSet <string>());
            }
            finally
            {
                instance.Free();
            }
        }
示例#10
0
        // Determine if "type" inherits from "baseType", ignoring constructed types, and dealing
        // only with original types.
        private static bool InheritsFromIgnoringConstruction(
            this TypeSymbol type,
            NamedTypeSymbol baseType,
            CSharpCompilation compilation,
            ref HashSet <DiagnosticInfo> useSiteDiagnostics,
            ConsList <Symbol> basesBeingResolved = null)
        {
            Debug.Assert(type.IsDefinition);
            Debug.Assert(baseType.IsDefinition);

            PooledHashSet <NamedTypeSymbol> visited = null;
            var  current = type;
            bool result  = false;

            while ((object)current != null)
            {
                if (current.Equals(baseType))
                {
                    result = true;
                    break;
                }

                // NOTE(cyrusn): The base type of an 'original' type may not be 'original'. i.e.
                // "class Foo : IBar<int>".  We must map it back to the 'original' when as we walk up
                // the base type hierarchy.
                var next = current.GetNextBaseTypeNoUseSiteDiagnostics(basesBeingResolved, compilation, ref visited);
                if ((object)next == null)
                {
                    current = null;
                }
                else
                {
                    current = (TypeSymbol)next.OriginalDefinition;
                    current.AddUseSiteDiagnostics(ref useSiteDiagnostics);
                }
            }

            if (visited != null)
            {
                visited.Free();
            }

            return(result);
        }
            private void ReportInitializedNotUsedNotInitializedUsedLocalVars(
                CodeBlockAnalysisContext context)
            {
                PooledHashSet <IdentifierNameSyntax> instance1 = PooledHashSet <IdentifierNameSyntax> .GetInstance();

                PooledHashSet <IdentifierNameSyntax> instance2 = PooledHashSet <IdentifierNameSyntax> .GetInstance();

                try
                {
                    this.CollectInitializedNotUsedNotInitializedUsedLocalVars((HashSet <IdentifierNameSyntax>)instance1, (HashSet <IdentifierNameSyntax>)instance2);
                    VariableInitializationUsageAnalyzer.ReportInitializedNotUsedVariables(new Action <Diagnostic>(context.ReportDiagnostic), instance1);
                    VariableInitializationUsageAnalyzer.ReportNotInitializedVariables(new Action <Diagnostic>(context.ReportDiagnostic), instance2);
                }
                finally
                {
                    instance1.Free();
                    instance2.Free();
                }
            }
示例#12
0
        private void ExecuteCodeBlockActions(
            PooledHashSet <CodeBlockAnalyzerAction> blockActions,
            SyntaxNode declaredNode,
            ISymbol declaredSymbol,
            SemanticModel semanticModel,
            Action <Diagnostic> addDiagnostic,
            CodeBlockAnalyzerStateData analyzerStateOpt)
        {
            foreach (var blockAction in blockActions)
            {
                if (ShouldExecuteAction(analyzerStateOpt, blockAction))
                {
                    ExecuteAndCatchIfThrows(blockAction.Analyzer,
                                            () => blockAction.Action(new CodeBlockAnalysisContext(declaredNode, declaredSymbol, semanticModel, _analyzerOptions, addDiagnostic,
                                                                                                  d => IsSupportedDiagnostic(blockAction.Analyzer, d), _cancellationToken)));

                    analyzerStateOpt?.ProcessedActions.Add(blockAction);
                }
            }

            blockActions.Free();
        }
        private static void ReportInitializedNotUsedNotInitializedUsedVars(
            SyntaxNodeAnalysisContext context,
            Dictionary <string, IdentifierNameSyntax> firstGlobalVarInitializerSyntax,
            Dictionary <string, IdentifierNameSyntax> firstGlobalVarUsageSyntax,
            Dictionary <string, VariableDeclarationBaseSyntax> globalVariables)
        {
            PooledHashSet <IdentifierNameSyntax> instance1 = PooledHashSet <IdentifierNameSyntax> .GetInstance();

            PooledHashSet <IdentifierNameSyntax> instance2 = PooledHashSet <IdentifierNameSyntax> .GetInstance();

            try
            {
                VariableInitializationUsageAnalyzer.CollectInitializedNotUsedNotInitializedUsedGlobalVars((HashSet <IdentifierNameSyntax>)instance2, (HashSet <IdentifierNameSyntax>)instance1, firstGlobalVarInitializerSyntax, firstGlobalVarUsageSyntax, globalVariables);
                VariableInitializationUsageAnalyzer.ReportInitializedNotUsedVariables(new Action <Diagnostic>(context.ReportDiagnostic), instance1);
                VariableInitializationUsageAnalyzer.ReportNotInitializedVariables(new Action <Diagnostic>(context.ReportDiagnostic), instance2);
            }
            finally
            {
                instance1.Free();
                instance2.Free();
            }
        }
示例#14
0
        public override void Initialize(AnalysisContext context)
        {
            context.EnableConcurrentExecution();
            context.ConfigureGeneratedCodeAnalysis(GeneratedCodeAnalysisFlags.Analyze | GeneratedCodeAnalysisFlags.ReportDiagnostics);

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

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

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

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

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

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

                        return(p, valuecontentAnalysisResult);
                    });

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

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

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

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

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

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

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

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

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

                                        foreach (SymbolAccess sourceOrigin in sourceSink.SourceOrigins)
                                        {
                                            // Something like:
                                            // CA3001: Potential SQL injection vulnerability was found where '{0}' in method '{1}' may be tainted by user-controlled data from '{2}' in method '{3}'.
                                            Diagnostic diagnostic = Diagnostic.Create(
                                                this.TaintedDataEnteringSinkDescriptor,
                                                sourceSink.Sink.Location,
                                                additionalLocations: new Location[] { sourceOrigin.Location },
                                                messageArgs: new object[] {
                                                sourceSink.Sink.Symbol.ToDisplayString(SymbolDisplayFormat.MinimallyQualifiedFormat),
                                                sourceSink.Sink.AccessingMethod.ToDisplayString(SymbolDisplayFormat.MinimallyQualifiedFormat),
                                                sourceOrigin.Symbol.ToDisplayString(SymbolDisplayFormat.MinimallyQualifiedFormat),
                                                sourceOrigin.AccessingMethod.ToDisplayString(SymbolDisplayFormat.MinimallyQualifiedFormat)
                                            });
                                            operationBlockAnalysisContext.ReportDiagnostic(diagnostic);
                                        }
                                    }
                                }
                            }
                        }
                        finally
                        {
                            rootOperationsNeedingAnalysis.Free(compilationContext.CancellationToken);
                        }
                    });
                });
            });
        }
示例#15
0
 public void Free()
 {
     DeclaredLocals.Free();
 }
示例#16
0
        /// <summary>
        /// Determine if "type" inherits from or implements "baseType", ignoring constructed types, and dealing
        /// only with original types.
        /// </summary>
        private static bool InheritsFromOrImplementsIgnoringConstruction(
            this TypeSymbol type,
            NamedTypeSymbol baseType,
            CSharpCompilation compilation,
            ref HashSet <DiagnosticInfo> useSiteDiagnostics,
            ConsList <TypeSymbol> basesBeingResolved = null)
        {
            Debug.Assert(type.IsDefinition);
            Debug.Assert(baseType.IsDefinition);

            PooledHashSet <NamedTypeSymbol> interfacesLookedAt = null;
            ArrayBuilder <NamedTypeSymbol>  baseInterfaces     = null;

            bool baseTypeIsInterface = baseType.IsInterface;

            if (baseTypeIsInterface)
            {
                interfacesLookedAt = PooledHashSet <NamedTypeSymbol> .GetInstance();

                baseInterfaces = ArrayBuilder <NamedTypeSymbol> .GetInstance();
            }

            PooledHashSet <NamedTypeSymbol> visited = null;
            var  current = type;
            bool result  = false;

            while ((object)current != null)
            {
                Debug.Assert(current.IsDefinition);
                if (baseTypeIsInterface == current.IsInterfaceType() &&
                    current == (object)baseType)
                {
                    result = true;
                    break;
                }

                if (baseTypeIsInterface)
                {
                    getBaseInterfaces(current, baseInterfaces, interfacesLookedAt, basesBeingResolved);
                }

                // NOTE(cyrusn): The base type of an 'original' type may not be 'original'. i.e.
                // "class Goo : IBar<int>".  We must map it back to the 'original' when as we walk up
                // the base type hierarchy.
                var next = current.GetNextBaseTypeNoUseSiteDiagnostics(basesBeingResolved, compilation, ref visited);
                if ((object)next == null)
                {
                    current = null;
                }
                else
                {
                    current = (TypeSymbol)next.OriginalDefinition;
                    current.AddUseSiteDiagnostics(ref useSiteDiagnostics);
                }
            }

            visited?.Free();

            if (!result && baseTypeIsInterface)
            {
                Debug.Assert(!result);

                while (baseInterfaces.Count != 0)
                {
                    NamedTypeSymbol currentBase = baseInterfaces.Pop();

                    if (!currentBase.IsInterface)
                    {
                        continue;
                    }

                    Debug.Assert(currentBase.IsDefinition);
                    if (currentBase == (object)baseType)
                    {
                        result = true;
                        break;
                    }

                    getBaseInterfaces(currentBase, baseInterfaces, interfacesLookedAt, basesBeingResolved);
                }

                if (!result)
                {
                    foreach (var candidate in interfacesLookedAt)
                    {
                        candidate.AddUseSiteDiagnostics(ref useSiteDiagnostics);
                    }
                }
            }

            interfacesLookedAt?.Free();
            baseInterfaces?.Free();
            return(result);
示例#17
0
            private void OnSymbolEnd(SymbolAnalysisContext symbolEndContext, bool hasInvalidOperation)
            {
                // We bail out reporting diagnostics for named types which have any invalid operations, i.e. erroneous code.
                // We do so to ensure that we don't report false positives during editing scenarios in the IDE, where the user
                // is still editing code and fixing unresolved references to symbols, such as overload resolution errors.
                if (hasInvalidOperation)
                {
                    return;
                }

                // Report diagnostics for unused candidate members.
                var first = true;
                PooledHashSet <ISymbol> symbolsReferencedInDocComments = null;

                try
                {
                    var namedType = (INamedTypeSymbol)symbolEndContext.Symbol;
                    foreach (var member in namedType.GetMembers())
                    {
                        // Check if the underlying member is neither read nor a readable reference to the member is taken.
                        // If so, we flag the member as either unused (never written) or unread (written but not read).
                        if (TryRemove(member, out var valueUsageInfo) &&
                            !valueUsageInfo.ContainsReadOrReadableRef())
                        {
                            Debug.Assert(IsCandidateSymbol(member));
                            Debug.Assert(!member.IsImplicitlyDeclared);

                            if (first)
                            {
                                // Bail out if there are syntax errors in any of the declarations of the containing type.
                                // Note that we check this only for the first time that we report an unused or unread member for the containing type.
                                if (HasSyntaxErrors(namedType, symbolEndContext.CancellationToken))
                                {
                                    return;
                                }

                                // Compute the set of candidate symbols referenced in all the documentation comments within the named type declarations.
                                // This set is computed once and used for all the iterations of the loop.
                                symbolsReferencedInDocComments = GetCandidateSymbolsReferencedInDocComments(namedType, symbolEndContext.Compilation, symbolEndContext.CancellationToken);
                                first = false;
                            }

                            // Report IDE0051 or IDE0052 based on whether the underlying member has any Write/WritableRef/NonReadWriteRef references or not.
                            var rule = !valueUsageInfo.ContainsWriteOrWritableRef() && !valueUsageInfo.ContainsNonReadWriteRef() && !symbolsReferencedInDocComments.Contains(member)
                                ? s_removeUnusedMembersWithFadingRule
                                : s_removeUnreadMembersWithFadingRule;
                            var effectiveSeverity = rule.GetEffectiveSeverity(symbolEndContext.Compilation.Options);

                            // Most of the members should have a single location, except for partial methods.
                            // We report the diagnostic on the first location of the member.
                            var diagnostic = DiagnosticHelper.Create(
                                rule,
                                member.Locations[0],
                                effectiveSeverity,
                                additionalLocations: null,
                                properties: null,
                                member.ContainingType.Name,
                                member.Name);
                            symbolEndContext.ReportDiagnostic(diagnostic);
                        }
                    }
                }
                finally
                {
                    symbolsReferencedInDocComments?.Free();
                }

                return;
            }
        private static void AnalyzeSymbols(SymbolAnalysisContext ctx)
        {
            PooledHashSet <ISymbol> instance1 = PooledHashSet <ISymbol> .GetInstance();

            PooledHashSet <ISymbol> instance2 = PooledHashSet <ISymbol> .GetInstance();

            PooledHashSet <ISymbol> instance3 = PooledHashSet <ISymbol> .GetInstance();

            PooledHashSet <ISymbol> instance4 = PooledHashSet <ISymbol> .GetInstance();

            PooledHashSet <ISymbol> instance5 = PooledHashSet <ISymbol> .GetInstance();

            PooledHashSet <ISymbol> instance6 = PooledHashSet <ISymbol> .GetInstance();

            ImmutableArray <ISymbol> members = ((IContainerSymbol)ctx.Symbol).GetMembers();

            try
            {
                ImmutableArray <ISymbol> .Enumerator enumerator1 = members.GetEnumerator();
                while (enumerator1.MoveNext())
                {
                    ISymbol current1 = enumerator1.Current;
                    switch (current1.Kind)
                    {
                    case SymbolKind.GlobalVariable:
                        instance1.ConcurrentAdd <ISymbol>(current1);
                        continue;

                    case SymbolKind.Method:
                        instance2.ConcurrentAdd <ISymbol>(current1);
                        foreach (IVariableSymbol localVariable in ((IMethodSymbol)current1).LocalVariables)
                        {
                            instance3.ConcurrentAdd <ISymbol>((ISymbol)localVariable);
                        }
                        continue;

                    case SymbolKind.Field:
                        instance4.ConcurrentAdd <ISymbol>(current1);
                        continue;

                    case SymbolKind.Control:
                        Rule198GlobalLocalVariablesShouldNotHaveSameName.AnalyzeControls((IControlSymbol)current1, instance6);
                        continue;

                    case SymbolKind.Action:
                        Rule198GlobalLocalVariablesShouldNotHaveSameName.AnalyzeActions((IActionSymbol)current1, instance5);
                        continue;

                    case SymbolKind.Change:
                        IEnumerable <IControlSymbol> flattenedSymbolsOfKind1 = Rule198GlobalLocalVariablesShouldNotHaveSameName.GetFlattenedSymbolsOfKind <IControlSymbol>((IContainerSymbol)current1, SymbolKind.Control);
                        IEnumerable <IActionSymbol>  flattenedSymbolsOfKind2 = Rule198GlobalLocalVariablesShouldNotHaveSameName.GetFlattenedSymbolsOfKind <IActionSymbol>((IContainerSymbol)current1, SymbolKind.Action);
                        foreach (IControlSymbol controlSymbol in flattenedSymbolsOfKind1)
                        {
                            instance6.ConcurrentAdd <ISymbol>((ISymbol)controlSymbol);
                        }
                        using (IEnumerator <IActionSymbol> enumerator2 = flattenedSymbolsOfKind2.GetEnumerator())
                        {
                            while (enumerator2.MoveNext())
                            {
                                IActionSymbol current2 = enumerator2.Current;
                                instance5.ConcurrentAdd <ISymbol>((ISymbol)current2);
                            }
                            continue;
                        }

                    case SymbolKind.QueryDataItem:
                        foreach (IQueryColumnSymbol flattenedQueryColumn in ((IQueryDataItemSymbol)current1).FlattenedQueryColumns)
                        {
                            if (flattenedQueryColumn.Kind == SymbolKind.QueryColumn)
                            {
                                instance4.ConcurrentAdd <ISymbol>((ISymbol)flattenedQueryColumn);
                            }
                        }
                        continue;

                    case SymbolKind.RequestPage:
                        foreach (IControlSymbol flattenedControl in ((IPageBaseTypeSymbol)current1).FlattenedControls)
                        {
                            Rule198GlobalLocalVariablesShouldNotHaveSameName.AnalyzeControls(flattenedControl, instance4);
                        }
                        foreach (IActionSymbol flattenedAction in ((IPageBaseTypeSymbol)current1).FlattenedActions)
                        {
                            instance5.ConcurrentAdd <ISymbol>((ISymbol)flattenedAction);
                        }
                        continue;

                    case SymbolKind.XmlPortNode:
                        Rule198GlobalLocalVariablesShouldNotHaveSameName.AnalyzeXmlNode((IXmlPortNodeSymbol)current1, instance4);
                        continue;

                    default:
                        continue;
                    }
                }
                ImmutableHashSet <ISymbol> immutableHashSet1 = instance1.ToImmutableHashSet <ISymbol>((IEqualityComparer <ISymbol>)SemanticFacts.SymbolNameEqualityComparer);
                ImmutableHashSet <ISymbol> immutableHashSet2 = instance2.ToImmutableHashSet <ISymbol>((IEqualityComparer <ISymbol>)SemanticFacts.SymbolNameEqualityComparer);
                ImmutableHashSet <ISymbol> immutableHashSet3 = instance3.ToImmutableHashSet <ISymbol>();
                ImmutableHashSet <ISymbol> immutableHashSet4 = instance4.ToImmutableHashSet <ISymbol>((IEqualityComparer <ISymbol>)SemanticFacts.SymbolNameEqualityComparer);
                ImmutableHashSet <ISymbol> immutableHashSet5 = instance5.ToImmutableHashSet <ISymbol>((IEqualityComparer <ISymbol>)SemanticFacts.SymbolNameEqualityComparer);
                ImmutableHashSet <ISymbol> immutableHashSet6 = instance6.ToImmutableHashSet <ISymbol>((IEqualityComparer <ISymbol>)SemanticFacts.SymbolNameEqualityComparer);
                foreach (ISymbol symbol in immutableHashSet3)
                {
                    if (immutableHashSet1.Contains(symbol))
                    {
                        Rule198GlobalLocalVariablesShouldNotHaveSameName.ReportDiagnostic(ctx, DiagnosticDescriptors.Rule022GlobalLocalVariablesShouldNotHaveSameName, symbol);
                    }
                    if (immutableHashSet2.Contains(symbol) || immutableHashSet4.Contains(symbol) || (immutableHashSet5.Contains(symbol) || immutableHashSet6.Contains(symbol)))
                    {
                        Rule198GlobalLocalVariablesShouldNotHaveSameName.ReportDiagnostic(ctx, DiagnosticDescriptors.Rule023DoNotNameLocalVarAsFieldOrMethod, symbol);
                    }
                }
                foreach (ISymbol symbol in immutableHashSet2)
                {
                    if (immutableHashSet4.Contains(symbol) || immutableHashSet5.Contains(symbol) || immutableHashSet6.Contains(symbol))
                    {
                        Rule198GlobalLocalVariablesShouldNotHaveSameName.ReportDiagnostic(ctx, DiagnosticDescriptors.Rule024DoNotNameMethodAsField, symbol);
                    }
                }
                foreach (ISymbol symbol in immutableHashSet1)
                {
                    if (immutableHashSet4.Contains(symbol) || immutableHashSet2.Contains(symbol) || immutableHashSet5.Contains(symbol))
                    {
                        Rule198GlobalLocalVariablesShouldNotHaveSameName.ReportDiagnostic(ctx, DiagnosticDescriptors.Rule025DoNotNameGlobalVarAsFieldOrMethod, symbol);
                    }
                    else
                    {
                        ISymbol actualValue;
                        if (immutableHashSet6.Contains(symbol) && immutableHashSet6.TryGetValue(symbol, out actualValue) && actualValue.Kind != SymbolKind.Control)
                        {
                            Rule198GlobalLocalVariablesShouldNotHaveSameName.ReportDiagnostic(ctx, DiagnosticDescriptors.Rule025DoNotNameGlobalVarAsFieldOrMethod, symbol);
                        }
                    }
                }
            }
            finally
            {
                instance1.Free();
                instance2.Free();
                instance3.Free();
                instance4.Free();
                instance5.Free();
                instance6.Free();
            }
        }
示例#19
0
            private void OnSymbolEnd(SymbolAnalysisContext symbolEndContext, bool hasInvalidOrDynamicOperation)
            {
                // We bail out reporting diagnostics for named types if it contains following kind of operations:
                //  1. Invalid operations, i.e. erroneous code:
                //     We do so to ensure that we don't report false positives during editing scenarios in the IDE, where the user
                //     is still editing code and fixing unresolved references to symbols, such as overload resolution errors.
                //  2. Dynamic operations, where we do not know the exact member being referenced at compile time.
                if (hasInvalidOrDynamicOperation)
                {
                    return;
                }

                if (symbolEndContext.Symbol.GetAttributes().Any(a => a.AttributeClass == _structLayoutAttributeType))
                {
                    // Bail out for types with 'StructLayoutAttribute' as the ordering of the members is critical,
                    // and removal of unused members might break semantics.
                    return;
                }

                // Report diagnostics for unused candidate members.
                var first = true;
                PooledHashSet <ISymbol> symbolsReferencedInDocComments    = null;
                ArrayBuilder <string>   debuggerDisplayAttributeArguments = null;

                try
                {
                    var namedType = (INamedTypeSymbol)symbolEndContext.Symbol;
                    foreach (var member in namedType.GetMembers())
                    {
                        // Check if the underlying member is neither read nor a readable reference to the member is taken.
                        // If so, we flag the member as either unused (never written) or unread (written but not read).
                        if (TryRemove(member, out var valueUsageInfo) &&
                            !valueUsageInfo.IsReadFrom())
                        {
                            Debug.Assert(IsCandidateSymbol(member));
                            Debug.Assert(!member.IsImplicitlyDeclared);

                            if (first)
                            {
                                // Bail out if there are syntax errors in any of the declarations of the containing type.
                                // Note that we check this only for the first time that we report an unused or unread member for the containing type.
                                if (HasSyntaxErrors(namedType, symbolEndContext.CancellationToken))
                                {
                                    return;
                                }

                                // Compute the set of candidate symbols referenced in all the documentation comments within the named type declarations.
                                // This set is computed once and used for all the iterations of the loop.
                                symbolsReferencedInDocComments = GetCandidateSymbolsReferencedInDocComments(namedType, symbolEndContext.Compilation, symbolEndContext.CancellationToken);

                                // Compute the set of string arguments to DebuggerDisplay attributes applied to any symbol within the named type declaration.
                                // These strings may have an embedded reference to the symbol.
                                // This set is computed once and used for all the iterations of the loop.
                                debuggerDisplayAttributeArguments = GetDebuggerDisplayAttributeArguments(namedType);

                                first = false;
                            }

                            // Simple heuristic for members referenced in DebuggerDisplayAttribute's string argument:
                            // bail out if any of the DebuggerDisplay string arguments contains the member name.
                            // In future, we can consider improving this heuristic to parse the embedded expression
                            // and resolve symbol references.
                            if (debuggerDisplayAttributeArguments.Any(arg => arg.Contains(member.Name)))
                            {
                                continue;
                            }

                            // Report IDE0051 or IDE0052 based on whether the underlying member has any Write/WritableRef/NonReadWriteRef references or not.
                            var rule = !valueUsageInfo.IsWrittenTo() && !valueUsageInfo.IsNameOnly() && !symbolsReferencedInDocComments.Contains(member)
                                ? s_removeUnusedMembersRule
                                : s_removeUnreadMembersRule;

                            // Do not flag write-only properties that are not read.
                            // Write-only properties are assumed to have side effects
                            // visible through other means than a property getter.
                            if (rule == s_removeUnreadMembersRule &&
                                member is IPropertySymbol property &&
                                property.IsWriteOnly)
                            {
                                continue;
                            }

                            // Most of the members should have a single location, except for partial methods.
                            // We report the diagnostic on the first location of the member.
                            var diagnostic = DiagnosticHelper.CreateWithMessage(
                                rule,
                                member.Locations[0],
                                rule.GetEffectiveSeverity(symbolEndContext.Compilation.Options),
                                additionalLocations: null,
                                properties: null,
                                GetMessage(rule, member));
                            symbolEndContext.ReportDiagnostic(diagnostic);
                        }
                    }
                }
                finally
                {
                    symbolsReferencedInDocComments?.Free();
                    debuggerDisplayAttributeArguments?.Free();
                }

                return;
            }
示例#20
0
        private static void SetKnownToHaveNoDeclaredBaseCycles(ref PooledHashSet<NamedTypeSymbol> visited)
        {
            if (visited != null)
            {
                foreach (var v in visited)
                {
                    v.SetKnownToHaveNoDeclaredBaseCycles();
                }

                visited.Free();
                visited = null;
            }
        }
示例#21
0
        internal static TResult CompileWithRetry <TResult>(
            ImmutableArray <MetadataBlock> metadataBlocks,
            DiagnosticFormatter formatter,
            CreateContextDelegate createContext,
            CompileDelegate <TResult> compile,
            DkmUtilities.GetMetadataBytesPtrFunction getMetaDataBytesPtr,
            out string errorMessage)
        {
            TResult compileResult;

            PooledHashSet <AssemblyIdentity> assembliesLoadedInRetryLoop = null;
            bool tryAgain;
            var  linqLibrary = EvaluationContextBase.SystemLinqIdentity;

            do
            {
                errorMessage = null;

                var context     = createContext(metadataBlocks, useReferencedModulesOnly: false);
                var diagnostics = DiagnosticBag.GetInstance();
                compileResult = compile(context, diagnostics);
                tryAgain      = false;
                if (diagnostics.HasAnyErrors())
                {
                    bool useReferencedModulesOnly;
                    ImmutableArray <AssemblyIdentity> missingAssemblyIdentities;
                    errorMessage = context.GetErrorMessageAndMissingAssemblyIdentities(
                        diagnostics,
                        formatter,
                        preferredUICulture: null,
                        linqLibrary: linqLibrary,
                        useReferencedModulesOnly: out useReferencedModulesOnly,
                        missingAssemblyIdentities: out missingAssemblyIdentities);
                    // If there were LINQ-related errors, we'll initially add System.Linq (set above).
                    // If that doesn't work, we'll fall back to System.Core for subsequent retries.
                    linqLibrary = EvaluationContextBase.SystemCoreIdentity;

                    // Can we remove the `useReferencedModulesOnly` attempt if we're only using
                    // modules reachable from the current module? In short, can we avoid retrying?
                    if (useReferencedModulesOnly)
                    {
                        Debug.Assert(missingAssemblyIdentities.IsEmpty);
                        var otherContext     = createContext(metadataBlocks, useReferencedModulesOnly: true);
                        var otherDiagnostics = DiagnosticBag.GetInstance();
                        var otherResult      = compile(otherContext, otherDiagnostics);
                        if (!otherDiagnostics.HasAnyErrors())
                        {
                            errorMessage  = null;
                            compileResult = otherResult;
                        }
                        otherDiagnostics.Free();
                    }
                    else
                    {
                        if (!missingAssemblyIdentities.IsEmpty)
                        {
                            if (assembliesLoadedInRetryLoop == null)
                            {
                                assembliesLoadedInRetryLoop = PooledHashSet <AssemblyIdentity> .GetInstance();
                            }
                            // If any identities failed to add (they were already in the list), then don't retry.
                            if (assembliesLoadedInRetryLoop.AddAll(missingAssemblyIdentities))
                            {
                                tryAgain = ShouldTryAgainWithMoreMetadataBlocks(getMetaDataBytesPtr, missingAssemblyIdentities, ref metadataBlocks);
                            }
                        }
                    }
                }
                diagnostics.Free();
            } while (tryAgain);
            assembliesLoadedInRetryLoop?.Free();

            return(compileResult);
        }
示例#22
0
        public override void Initialize(AnalysisContext context)
        {
            context.EnableConcurrentExecution();
            context.ConfigureGeneratedCodeAnalysis(GeneratedCodeAnalysisFlags.Analyze | GeneratedCodeAnalysisFlags.ReportDiagnostics);

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

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

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

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

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

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

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

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

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

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

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

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

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

                                        foreach (SymbolAccess sourceOrigin in sourceSink.SourceOrigins)
                                        {
                                            // Something like:
                                            // CA3001: Potential SQL injection vulnerability was found where '{0}' in method '{1}' may be tainted by user-controlled data from '{2}' in method '{3}'.
                                            Diagnostic diagnostic = Diagnostic.Create(
                                                this.TaintedDataEnteringSinkDescriptor,
                                                sourceSink.Sink.Location,
                                                additionalLocations: new Location[] { sourceOrigin.Location },
                                                messageArgs: new object[] {
                                                sourceSink.Sink.Symbol.ToDisplayString(SymbolDisplayFormat.MinimallyQualifiedFormat),
                                                sourceSink.Sink.AccessingMethod.ToDisplayString(SymbolDisplayFormat.MinimallyQualifiedFormat),
                                                sourceOrigin.Symbol.ToDisplayString(SymbolDisplayFormat.MinimallyQualifiedFormat),
                                                sourceOrigin.AccessingMethod.ToDisplayString(SymbolDisplayFormat.MinimallyQualifiedFormat)
                                            });
                                            operationBlockAnalysisContext.ReportDiagnostic(diagnostic);
                                        }
                                    }
                                }
                            }
                        }
                        finally
                        {
                            rootOperationsNeedingAnalysis.Free();
                        }
                    });
                });
            });
        }
示例#23
0
        internal static TResult CompileWithRetry <TResult>(
            ImmutableArray <MetadataBlock> metadataBlocks,
            DiagnosticFormatter formatter,
            CreateContextDelegate createContext,
            CompileDelegate <TResult> compile,
            DkmUtilities.GetMetadataBytesPtrFunction getMetaDataBytesPtr,
            out string errorMessage)
        {
            TResult compileResult;

            PooledHashSet <AssemblyIdentity> assembliesLoadedInRetryLoop = null;
            bool tryAgain;

            do
            {
                errorMessage = null;

                var context     = createContext(metadataBlocks, useReferencedModulesOnly: false);
                var diagnostics = DiagnosticBag.GetInstance();
                compileResult = compile(context, diagnostics);
                tryAgain      = false;
                if (diagnostics.HasAnyErrors())
                {
                    bool useReferencedModulesOnly;
                    ImmutableArray <AssemblyIdentity> missingAssemblyIdentities;
                    errorMessage = context.GetErrorMessageAndMissingAssemblyIdentities(
                        diagnostics,
                        formatter,
                        preferredUICulture: null,
                        useReferencedModulesOnly: out useReferencedModulesOnly,
                        missingAssemblyIdentities: out missingAssemblyIdentities);
                    if (useReferencedModulesOnly)
                    {
                        Debug.Assert(missingAssemblyIdentities.IsEmpty);
                        var otherContext     = createContext(metadataBlocks, useReferencedModulesOnly: true);
                        var otherDiagnostics = DiagnosticBag.GetInstance();
                        var otherResult      = compile(otherContext, otherDiagnostics);
                        if (!otherDiagnostics.HasAnyErrors())
                        {
                            errorMessage  = null;
                            compileResult = otherResult;
                        }
                        otherDiagnostics.Free();
                    }
                    else
                    {
                        if (!missingAssemblyIdentities.IsEmpty)
                        {
                            if (assembliesLoadedInRetryLoop == null)
                            {
                                assembliesLoadedInRetryLoop = PooledHashSet <AssemblyIdentity> .GetInstance();
                            }
                            // If any identities failed to add (they were already in the list), then don't retry.
                            if (assembliesLoadedInRetryLoop.AddAll(missingAssemblyIdentities))
                            {
                                tryAgain = ShouldTryAgainWithMoreMetadataBlocks(getMetaDataBytesPtr, missingAssemblyIdentities, ref metadataBlocks);
                            }
                        }
                    }
                }
                diagnostics.Free();
            } while (tryAgain);
            assembliesLoadedInRetryLoop?.Free();

            return(compileResult);
        }
示例#24
0
        internal void ValidateParameterNameConflicts(
            ImmutableArray <TypeParameterSymbol> typeParameters,
            ImmutableArray <ParameterSymbol> parameters,
            bool allowShadowingNames,
            DiagnosticBag diagnostics)
        {
            PooledHashSet <string>?tpNames = null;

            if (!typeParameters.IsDefaultOrEmpty)
            {
                tpNames = PooledHashSet <string> .GetInstance();

                foreach (var tp in typeParameters)
                {
                    var name = tp.Name;
                    if (string.IsNullOrEmpty(name))
                    {
                        continue;
                    }

                    if (!tpNames.Add(name))
                    {
                        // Type parameter declaration name conflicts are detected elsewhere
                    }
                    else if (!allowShadowingNames)
                    {
                        ValidateDeclarationNameConflictsInScope(tp, diagnostics);
                    }
                }
            }

            PooledHashSet <string>?pNames = null;

            if (!parameters.IsDefaultOrEmpty)
            {
                pNames = PooledHashSet <string> .GetInstance();

                foreach (var p in parameters)
                {
                    var name = p.Name;
                    if (string.IsNullOrEmpty(name))
                    {
                        continue;
                    }

                    if (tpNames != null && tpNames.Contains(name))
                    {
                        // CS0412: 'X': a parameter or local variable cannot have the same name as a method type parameter
                        diagnostics.Add(ErrorCode.ERR_LocalSameNameAsTypeParam, GetLocation(p), name);
                    }

                    if (!pNames.Add(name))
                    {
                        // The parameter name '{0}' is a duplicate
                        diagnostics.Add(ErrorCode.ERR_DuplicateParamName, GetLocation(p), name);
                    }
                    else if (!allowShadowingNames)
                    {
                        ValidateDeclarationNameConflictsInScope(p, diagnostics);
                    }
                }
            }

            tpNames?.Free();
            pNames?.Free();
        }
示例#25
0
 public void Free()
 {
     MethodsConvertedToDelegates.Free();
     ScopeTree.Free();
 }
示例#26
0
 public void Dispose() => _usedNames.Free();
示例#27
0
 public void Free()
 {
     CapturedVariables.Free();
     CapturedEnvironments.Free();
 }
示例#28
0
        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,
                    (NullAbstractValue nullAbstractValue) =>
            {
                // A null SerializationBinder is what we want to flag as hazardous.
                switch (nullAbstractValue)
                {
                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;
                }

                compilationStartAnalysisContext.RegisterOperationBlockStartAction(
                    (OperationBlockStartAnalysisContext operationBlockStartAnalysisContext) =>
                {
                    PooledHashSet <IOperation> rootOperationsNeedingAnalysis = PooledHashSet <IOperation> .GetInstance();

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

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

                    operationBlockStartAnalysisContext.RegisterOperationBlockEndAction(
                        (OperationBlockAnalysisContext operationBlockAnalysisContext) =>
                    {
                        PooledDictionary <(Location Location, IMethodSymbol Method), HazardousUsageEvaluationResult> allResults = null;
                        try
                        {
                            lock (rootOperationsNeedingAnalysis)
                            {
                                if (!rootOperationsNeedingAnalysis.Any())
                                {
                                    return;
                                }

                                // Only instantiated if there are any results to report.
                                List <ControlFlowGraph> cfgs = new List <ControlFlowGraph>();

                                var interproceduralAnalysisConfig = InterproceduralAnalysisConfiguration.Create(
                                    operationBlockAnalysisContext.Options, SupportedDiagnostics,
                                    defaultInterproceduralAnalysisKind: InterproceduralAnalysisKind.None,
                                    cancellationToken: operationBlockAnalysisContext.CancellationToken,
                                    defaultMaxInterproceduralMethodCallChain: 1);             // By default, we only want to track method calls one level down.

                                foreach (IOperation rootOperation in rootOperationsNeedingAnalysis)
                                {
                                    ImmutableDictionary <(Location Location, IMethodSymbol Method), HazardousUsageEvaluationResult> dfaResult =
                                        PropertySetAnalysis.GetOrComputeHazardousUsages(
                                            rootOperation.GetEnclosingControlFlowGraph(),
                                            operationBlockAnalysisContext.Compilation,
                                            operationBlockAnalysisContext.OwningSymbol,
                                            this.DeserializerTypeMetadataName,
                                            DoNotUseInsecureDeserializerWithoutBinderBase.ConstructorMapper,
                                            propertyMappers,
                                            hazardousUsageEvaluators,
                                            interproceduralAnalysisConfig);
                                    if (dfaResult.IsEmpty)
                                    {
                                        continue;
                                    }

                                    if (allResults == null)
                                    {
                                        allResults = PooledDictionary <(Location Location, IMethodSymbol Method), HazardousUsageEvaluationResult> .GetInstance();
                                    }

                                    foreach (KeyValuePair <(Location Location, IMethodSymbol Method), HazardousUsageEvaluationResult> kvp
                                             in dfaResult)
                                    {
                                        allResults.Add(kvp.Key, kvp.Value);
                                    }
                                }
                            }

                            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;
                                }

                                operationBlockAnalysisContext.ReportDiagnostic(
                                    Diagnostic.Create(
                                        descriptor,
                                        kvp.Key.Location,
                                        kvp.Key.Method.ToDisplayString(
                                            SymbolDisplayFormat.MinimallyQualifiedFormat)));
                            }
                        }
                        finally
                        {
                            rootOperationsNeedingAnalysis.Free();
                            allResults?.Free();
                        }
                    });
                });
            });
        }
示例#29
0
        private void DefineNamespaceScopes(IMethodBody methodBody)
        {
            var  module        = Module;
            bool isVisualBasic = module.GenerateVisualBasicStylePdb;

            IMethodDefinition method = methodBody.MethodDefinition;

            var namespaceScopes = methodBody.ImportScope;

            // NOTE: All extern aliases are stored on the outermost namespace scope.
            PooledHashSet <string> lazyDeclaredExternAliases = null;

            if (!isVisualBasic)
            {
                foreach (var import in GetLastScope(namespaceScopes).GetUsedNamespaces(Context))
                {
                    if (import.TargetNamespaceOpt == null && import.TargetTypeOpt == null)
                    {
                        Debug.Assert(import.AliasOpt != null);
                        Debug.Assert(import.TargetAssemblyOpt == null);

                        if (lazyDeclaredExternAliases == null)
                        {
                            lazyDeclaredExternAliases = PooledHashSet <string> .GetInstance();
                        }

                        lazyDeclaredExternAliases.Add(import.AliasOpt);
                    }
                }
            }

            // file and namespace level
            for (IImportScope scope = namespaceScopes; scope != null; scope = scope.Parent)
            {
                foreach (UsedNamespaceOrType import in scope.GetUsedNamespaces(Context))
                {
                    var importString = TryEncodeImport(import, lazyDeclaredExternAliases, isProjectLevel: false);
                    if (importString != null)
                    {
                        UsingNamespace(importString, method);
                    }
                }
            }

            lazyDeclaredExternAliases?.Free();

            // project level
            if (isVisualBasic)
            {
                string defaultNamespace = module.DefaultNamespace;

                if (defaultNamespace != null)
                {
                    // VB marks the default/root namespace with an asterisk
                    UsingNamespace("*" + defaultNamespace, module);
                }

                foreach (string assemblyName in module.LinkedAssembliesDebugInfo)
                {
                    UsingNamespace("&" + assemblyName, module);
                }

                foreach (UsedNamespaceOrType import in module.GetImports(Context))
                {
                    var importString = TryEncodeImport(import, null, isProjectLevel: true);
                    if (importString != null)
                    {
                        UsingNamespace(importString, method);
                    }
                }

                // VB current namespace -- VB appends the namespace of the container without prefixes
                UsingNamespace(GetOrCreateSerializedNamespaceName(method.ContainingNamespace), method);
            }
        }
            public override TaintedDataAbstractValue VisitInvocation_NonLambdaOrDelegateOrLocalFunction(
                IMethodSymbol method,
                IOperation visitedInstance,
                ImmutableArray <IArgumentOperation> visitedArguments,
                bool invokedAsDelegate,
                IOperation originalOperation,
                TaintedDataAbstractValue defaultValue)
            {
                // Always invoke base visit.
                TaintedDataAbstractValue result = base.VisitInvocation_NonLambdaOrDelegateOrLocalFunction(
                    method,
                    visitedInstance,
                    visitedArguments,
                    invokedAsDelegate,
                    originalOperation,
                    defaultValue);

                IEnumerable <IArgumentOperation> taintedArguments = GetTaintedArguments(visitedArguments);

                if (taintedArguments.Any())
                {
                    ProcessTaintedDataEnteringInvocationOrCreation(method, taintedArguments, originalOperation);
                }

                PooledHashSet <string>           taintedTargets        = null;
                PooledHashSet <(string, string)> taintedParameterPairs = null;

                try
                {
                    if (this.IsSanitizingMethod(method))
                    {
                        result = TaintedDataAbstractValue.NotTainted;
                    }
                    else if (visitedInstance != null && this.IsSanitizingInstanceMethod(method))
                    {
                        result = TaintedDataAbstractValue.NotTainted;
                        SetTaintedForEntity(visitedInstance, result);
                    }
                    else if (this.DataFlowAnalysisContext.SourceInfos.IsSourceMethod(
                                 method,
                                 visitedArguments,
                                 new Lazy <PointsToAnalysisResult>(() => DataFlowAnalysisContext.PointsToAnalysisResultOpt),
                                 new Lazy <ValueContentAnalysisResult>(() => DataFlowAnalysisContext.ValueContentAnalysisResultOpt),
                                 out taintedTargets))
                    {
                        foreach (string taintedTarget in taintedTargets)
                        {
                            if (taintedTarget != TaintedTargetValue.Return)
                            {
                                IArgumentOperation argumentOperation = visitedArguments.FirstOrDefault(o => o.Parameter.Name == taintedTarget);
                                if (argumentOperation != null)
                                {
                                    this.CacheAbstractValue(argumentOperation, TaintedDataAbstractValue.CreateTainted(argumentOperation.Parameter, argumentOperation.Syntax, method));
                                }
                                else
                                {
                                    Debug.Fail("Are the tainted data sources misconfigured?");
                                }
                            }
                            else
                            {
                                result = TaintedDataAbstractValue.CreateTainted(method, originalOperation.Syntax, this.OwningSymbol);
                            }
                        }
                    }

                    if (this.DataFlowAnalysisContext.SourceInfos.IsSourceTransferMethod(
                            method,
                            visitedArguments,
                            visitedArguments
                            .Where(s => this.GetCachedAbstractValue(s).Kind == TaintedDataAbstractValueKind.Tainted)
                            .Select(s => s.Parameter.Name)
                            .ToImmutableArray(),
                            out taintedParameterPairs))
                    {
                        foreach ((string ifTaintedParameter, string thenTaintedTarget) in taintedParameterPairs)
                        {
                            IArgumentOperation thenTaintedTargetOperation = visitedArguments.FirstOrDefault(o => o.Parameter.Name == thenTaintedTarget);
                            if (thenTaintedTargetOperation != null)
                            {
                                SetTaintedForEntity(
                                    thenTaintedTargetOperation,
                                    this.GetCachedAbstractValue(
                                        visitedArguments.FirstOrDefault(o => o.Parameter.Name == ifTaintedParameter)));
                            }
                            else
                            {
                                Debug.Fail("Are the tainted data sources misconfigured?");
                            }
                        }
                    }
                }
                finally
                {
                    taintedTargets?.Free();
                    taintedParameterPairs?.Free();
                }

                return(result);
            }
        private static void OrderGraph(
            Dictionary <SourceFieldSymbol, Node <SourceFieldSymbol> > graph,
            ArrayBuilder <FieldInfo> order)
        {
            Debug.Assert(graph.Count > 0);

            PooledHashSet <SourceFieldSymbol> lastUpdated = null;

            while (graph.Count > 0)
            {
                // Get the set of fields in the graph that have no dependencies.
                var search = ((IEnumerable <SourceFieldSymbol>)lastUpdated) ?? graph.Keys;
                var set    = ArrayBuilder <SourceFieldSymbol> .GetInstance();

                foreach (var field in search)
                {
                    Node <SourceFieldSymbol> node;
                    if (graph.TryGetValue(field, out node))
                    {
                        if (node.Dependencies.Count == 0)
                        {
                            set.Add(field);
                        }
                    }
                }

                if (lastUpdated != null)
                {
                    lastUpdated.Free();
                    lastUpdated = null;
                }

                if (set.Count > 0)
                {
                    var updated = PooledHashSet <SourceFieldSymbol> .GetInstance();

                    // Remove fields with no dependencies from the graph.
                    foreach (var field in set)
                    {
                        var node = graph[field];

                        // Remove the field from the Dependencies
                        // of each field that depends on it.
                        foreach (var dependedOnBy in node.DependedOnBy)
                        {
                            var n = graph[dependedOnBy];
                            n.Dependencies      = n.Dependencies.Remove(field);
                            graph[dependedOnBy] = n;
                            updated.Add(dependedOnBy);
                        }

                        graph.Remove(field);
                    }

                    CheckGraph(graph);

                    // Add the set to the ordered list.
                    foreach (var item in set)
                    {
                        order.Add(new FieldInfo(item, startsCycle: false));
                    }

                    lastUpdated = updated;
                }
                else
                {
                    // All fields have dependencies which means all fields are involved
                    // in cycles. Break the first cycle found. (Note some fields may have
                    // dependencies but are not strictly part of any cycle. For instance,
                    // B and C in: "enum E { A = A | B, B = C, C = D, D = D }").
                    var field = GetStartOfFirstCycle(graph);

                    // Break the dependencies.
                    var node = graph[field];

                    // Remove the field from the DependedOnBy
                    // of each field it has as a dependency.
                    foreach (var dependency in node.Dependencies)
                    {
                        var n = graph[dependency];
                        n.DependedOnBy    = n.DependedOnBy.Remove(field);
                        graph[dependency] = n;
                    }

                    node = graph[field];
                    node.Dependencies = ImmutableHashSet <SourceFieldSymbol> .Empty;
                    if (node.DependedOnBy.Count == 0)
                    {
                        graph.Remove(field);
                    }
                    else
                    {
                        graph[field] = node;
                    }

                    CheckGraph(graph);

                    // Add the start of the cycle to the ordered list.
                    order.Add(new FieldInfo(field, startsCycle: true));

                    // Need to search the entire graph the next time
                    // through the loop so lastUpdated is not set.
                }

                set.Free();
            }

            if (lastUpdated != null)
            {
                lastUpdated.Free();
            }
        }