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()); }
public bool Equals(ConstructorMapper other) { return(other != null && this.MapFromValueContentAbstractValue == other.MapFromValueContentAbstractValue && this.MapFromPointsToAbstractValue == other.MapFromPointsToAbstractValue && this.PropertyAbstractValues == other.PropertyAbstractValues); }
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); }