public static PropertySetAnalysisContext Create(
     AbstractValueDomain <PropertySetAbstractValue> valueDomain,
     WellKnownTypeProvider wellKnownTypeProvider,
     ControlFlowGraph controlFlowGraph,
     ISymbol owningSymbol,
     InterproceduralAnalysisConfiguration interproceduralAnalysisConfig,
     bool pessimisticAnalysis,
     PointsToAnalysisResult pointsToAnalysisResult,
     ValueContentAnalysisResult valueContentAnalysisResultOpt,
     Func <PropertySetAnalysisContext, PropertySetAnalysisResult> getOrComputeAnalysisResult,
     string typeToTrackMetadataName,
     ConstructorMapper constructorMapper,
     PropertyMapperCollection propertyMappers,
     HazardousUsageEvaluatorCollection hazardousUsageEvaluators)
 {
     return(new PropertySetAnalysisContext(
                valueDomain,
                wellKnownTypeProvider,
                controlFlowGraph,
                owningSymbol,
                interproceduralAnalysisConfig,
                pessimisticAnalysis,
                pointsToAnalysisResult,
                valueContentAnalysisResultOpt,
                getOrComputeAnalysisResult,
                parentControlFlowGraphOpt: null,
                interproceduralAnalysisDataOpt: null,
                typeToTrackMetadataName: typeToTrackMetadataName,
                constructorMapper: constructorMapper,
                propertyMappers: propertyMappers,
                hazardousUsageEvaluators: hazardousUsageEvaluators,
                hazardousUsageTypesToNames: hazardousUsageEvaluators.GetTypeToNameMapping(wellKnownTypeProvider)));
 }
#pragma warning disable CA1307 // Specify StringComparison - string.GetHashCode(StringComparison) not available in all projects that reference this shared project
        protected override void ComputeHashCodePartsSpecific(ArrayBuilder <int> builder)
        {
            builder.Add(TypeToTrackMetadataName.GetHashCode());
            builder.Add(ConstructorMapper.GetHashCode());
            builder.Add(PropertyMappers.GetHashCode());
            builder.Add(HazardousUsageEvaluators.GetHashCode());
        }
 public PropertySetAnalysisParameters(string typeToTrack, ConstructorMapper constructorMapper, PropertyMapperCollection propertyMapperCollection, HazardousUsageEvaluatorCollection hazardousUsageEvaluatorCollection)
 {
     TypeToTrack                       = typeToTrack ?? throw new ArgumentNullException(nameof(typeToTrack));
     ConstructorMapper                 = constructorMapper ?? throw new ArgumentNullException(nameof(constructorMapper));
     PropertyMapperCollection          = propertyMapperCollection ?? throw new ArgumentNullException(nameof(propertyMapperCollection));
     HazardousUsageEvaluatorCollection = hazardousUsageEvaluatorCollection ?? throw new ArgumentNullException(nameof(hazardousUsageEvaluatorCollection));
 }
#pragma warning disable CA1307 // Specify StringComparison - string.GetHashCode(StringComparison) not available in all projects that reference this shared project
        protected override void ComputeHashCodePartsSpecific(Action <int> addPart)
        {
            addPart(TypeToTrackMetadataName.GetHashCode());
            addPart(ConstructorMapper.GetHashCode());
            addPart(PropertyMappers.GetHashCode());
            addPart(HazardousUsageEvaluators.GetHashCode());
        }
Ejemplo n.º 5
0
 public bool Equals(ConstructorMapper other)
 {
     return(other != null &&
            this.MapFromValueContentAbstractValue == other.MapFromValueContentAbstractValue &&
            this.MapFromPointsToAbstractValue == other.MapFromPointsToAbstractValue &&
            this.PropertyAbstractValues == other.PropertyAbstractValues);
 }
Ejemplo n.º 6
0
 private PropertySetAnalysisContext(
     AbstractValueDomain <PropertySetAbstractValue> valueDomain,
     WellKnownTypeProvider wellKnownTypeProvider,
     ControlFlowGraph controlFlowGraph,
     ISymbol owningSymbol,
     InterproceduralAnalysisConfiguration interproceduralAnalysisConfig,
     bool pessimisticAnalysis,
     PointsToAnalysisResult pointsToAnalysisResult,
     ValueContentAnalysisResult valueContentAnalysisResultOpt,
     Func <PropertySetAnalysisContext, PropertySetAnalysisResult> getOrComputeAnalysisResult,
     ControlFlowGraph parentControlFlowGraphOpt,
     InterproceduralPropertySetAnalysisData interproceduralAnalysisDataOpt,
     string typeToTrackMetadataName,
     ConstructorMapper constructorMapper,
     PropertyMapperCollection propertyMappers,
     HazardousUsageEvaluatorCollection hazardousUsageEvaluators,
     ImmutableDictionary <INamedTypeSymbol, string> hazardousUsageTypesToNames)
     : base(valueDomain, wellKnownTypeProvider, controlFlowGraph, owningSymbol, interproceduralAnalysisConfig, pessimisticAnalysis,
            predicateAnalysis: false, exceptionPathsAnalysis: false, copyAnalysisResultOpt: null, pointsToAnalysisResult,
            getOrComputeAnalysisResult, parentControlFlowGraphOpt, interproceduralAnalysisDataOpt, interproceduralAnalysisPredicateOpt: null)
 {
     this.ValueContentAnalysisResultOpt = valueContentAnalysisResultOpt;
     this.TypeToTrackMetadataName       = typeToTrackMetadataName;
     this.ConstructorMapper             = constructorMapper;
     this.PropertyMappers            = propertyMappers;
     this.HazardousUsageEvaluators   = hazardousUsageEvaluators;
     this.HazardousUsageTypesToNames = hazardousUsageTypesToNames;
 }
 private PropertySetAnalysisContext(
     AbstractValueDomain <PropertySetAbstractValue> valueDomain,
     WellKnownTypeProvider wellKnownTypeProvider,
     ControlFlowGraph controlFlowGraph,
     ISymbol owningSymbol,
     AnalyzerOptions analyzerOptions,
     InterproceduralAnalysisConfiguration interproceduralAnalysisConfig,
     bool pessimisticAnalysis,
     PointsToAnalysisResult pointsToAnalysisResult,
     ValueContentAnalysisResult valueContentAnalysisResultOpt,
     Func <PropertySetAnalysisContext, PropertySetAnalysisResult> tryGetOrComputeAnalysisResult,
     ControlFlowGraph parentControlFlowGraphOpt,
     InterproceduralPropertySetAnalysisData interproceduralAnalysisDataOpt,
     ImmutableHashSet <string> typeToTrackMetadataNames,
     ConstructorMapper constructorMapper,
     PropertyMapperCollection propertyMappers,
     HazardousUsageEvaluatorCollection hazardousUsageEvaluators,
     ImmutableDictionary <(INamedTypeSymbol, bool), string> hazardousUsageTypesToNames)
            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);
            }
        /// <summary>
        /// Analyzers should use <see cref="BatchGetOrComputeHazardousUsages"/> instead.  Gets hazardous usages of an object based on a set of its properties.
        /// </summary>
        /// <param name="cfg">Control flow graph of the code.</param>
        /// <param name="compilation">Compilation containing the code.</param>
        /// <param name="owningSymbol">Symbol of the code to examine.</param>
        /// <param name="typeToTrackMetadataName">Name of the type to track.</param>
        /// <param name="constructorMapper">How constructor invocations map to <see cref="PropertySetAbstractValueKind"/>s.</param>
        /// <param name="propertyMappers">How property assignments map to <see cref="PropertySetAbstractValueKind"/>.</param>
        /// <param name="hazardousUsageEvaluators">When and how to evaluate <see cref="PropertySetAbstractValueKind"/>s to for hazardous usages.</param>
        /// <param name="interproceduralAnalysisConfig">Interprocedural dataflow analysis configuration.</param>
        /// <param name="pessimisticAnalysis">Whether to be pessimistic.</param>
        /// <returns>Property set analysis result.</returns>
        internal static PropertySetAnalysisResult GetOrComputeResult(
            ControlFlowGraph cfg,
            Compilation compilation,
            ISymbol owningSymbol,
            AnalyzerOptions analyzerOptions,
            string typeToTrackMetadataName,
            ConstructorMapper constructorMapper,
            PropertyMapperCollection propertyMappers,
            HazardousUsageEvaluatorCollection hazardousUsageEvaluators,
            InterproceduralAnalysisConfiguration interproceduralAnalysisConfig,
            bool pessimisticAnalysis = false)
        {
            if (constructorMapper == null)
            {
                throw new ArgumentNullException(nameof(constructorMapper));
            }

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

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

            constructorMapper.Validate(propertyMappers.PropertyValuesCount);

            var wellKnownTypeProvider = WellKnownTypeProvider.GetOrCreate(compilation);

            PointsToAnalysisResult     pointsToAnalysisResult;
            ValueContentAnalysisResult valueContentAnalysisResultOpt;

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

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

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

            return(result);
        }