public override int Compare(PropertySetAbstractValue oldValue, PropertySetAbstractValue newValue, bool assertMonotonicity) { if (Object.ReferenceEquals(oldValue, newValue)) { return(0); } // The PropertySetAbstractValue indexer allows accessing beyond KnownValuesCount (returns Unknown), // so looping through the max of the two KnownValuesCount. int maxKnownCount = Math.Max(oldValue.KnownValuesCount, newValue.KnownValuesCount); int result = 0; for (int i = 0; i < maxKnownCount; i++) { if (oldValue[i] == newValue[i]) { continue; } else if (oldValue[i] < newValue[i]) { result = -1; } else { FireNonMonotonicAssertIfNeeded(assertMonotonicity); return(1); } } return(result); }
protected override void SetAbstractValue(AbstractLocation location, PropertySetAbstractValue value) { if (value != PropertySetAbstractValue.Unknown || this.CurrentAnalysisData.ContainsKey(location)) { this.CurrentAnalysisData[location] = value; } }
public override PropertySetAbstractValue Merge(PropertySetAbstractValue value1, PropertySetAbstractValue value2) { // The PropertySetAbstractValue indexer allows accessing beyond KnownValuesCount (returns Unknown), // so looping through the max of the two KnownValuesCount. int maxKnownCount = Math.Max(value1.KnownValuesCount, value2.KnownValuesCount); using ArrayBuilder <PropertySetAbstractValueKind> builder = ArrayBuilder <PropertySetAbstractValueKind> .GetInstance(maxKnownCount); for (int i = 0; i < maxKnownCount; i++) { builder.Add(MergeKind(value1[i], value2[i])); } return(PropertySetAbstractValue.GetInstance(builder)); }
/// <summary> /// A <see cref="HazardousUsageEvaluator.EvaluationCallback"/> for all properties flagged being hazardous. /// </summary> /// <param name="propertySetAbstractValue">PropertySetAbstract value.</param> /// <returns>If all properties are flagged, then flagged; if at least one property is unflagged, then unflagged; otherwise (including all unknown) maybe flagged.</returns> private static HazardousUsageEvaluationResult HazardousIfAllFlagged( PropertySetAbstractValue propertySetAbstractValue, bool assumeAllUnknownInsecure) { if (propertySetAbstractValue.KnownValuesCount == 0) { // No known values implies all properties are PropertySetAbstractValueKind.Unknown. return(assumeAllUnknownInsecure ? HazardousUsageEvaluationResult.MaybeFlagged : HazardousUsageEvaluationResult.Unflagged); } bool allFlagged = true; bool atLeastOneUnflagged = false; for (int i = 0; i < propertySetAbstractValue.KnownValuesCount; i++) { if (propertySetAbstractValue[i] != PropertySetAbstractValueKind.Flagged) { allFlagged = false; } if (propertySetAbstractValue[i] == PropertySetAbstractValueKind.Unflagged) { atLeastOneUnflagged = true; break; } } if (allFlagged) { return(HazardousUsageEvaluationResult.Flagged); } else if (atLeastOneUnflagged) { return(HazardousUsageEvaluationResult.Unflagged); } else { // Mix of flagged and unknown. return(HazardousUsageEvaluationResult.MaybeFlagged); } }
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); }
protected override void SetAbstractValueForTupleElementAssignment(AnalysisEntity tupleElementEntity, IOperation assignedValueOperation, PropertySetAbstractValue assignedValue) { }
protected override void SetAbstractValueForAssignment(IOperation target, IOperation?assignedValueOperation, PropertySetAbstractValue assignedValue, bool mayBeAssignment = false) { }
protected override void SetAbstractValueForArrayElementInitializer(IArrayCreationOperation arrayCreation, ImmutableArray <AbstractIndex> indices, ITypeSymbol elementType, IOperation initializer, PropertySetAbstractValue value) { }
private static bool TryGetPooledInstance(IReadOnlyList <PropertySetAbstractValueKind> values, out PropertySetAbstractValue instance) { if (values.Count == 0) { instance = Unknown; return(true); } else if (values.Count == 1) { instance = Pool.GetInstance(values[0]); return(true); } else if (values.Count == 2) { instance = Pool.GetInstance(values[0], values[1]); return(true); } else { for (int i = 2; i < values.Count; i++) { if (values[i] != PropertySetAbstractValueKind.Unknown) { instance = null; return(false); } } instance = Pool.GetInstance(values[0], values[1]); return(true); } }
public static HazardousUsageEvaluationResult HazardousIfAllFlaggedAndAtLeastOneKnown( IMethodSymbol methodSymbol, PropertySetAbstractValue propertySetAbstractValue) { return(HazardousIfAllFlagged(propertySetAbstractValue, assumeAllUnknownInsecure: false)); }
/// <summary> /// A <see cref="HazardousUsageEvaluator.EvaluationCallback"/> for all properties flagged being hazardous, treating all /// unknown as maybe flagged. /// </summary> /// <param name="propertySetAbstractValue">PropertySetAbstract value.</param> /// <returns>If all properties are flagged, then flagged; if at least one property is unflagged, then unflagged; /// otherwise (including all unknown) maybe flagged.</returns> public static HazardousUsageEvaluationResult HazardousIfAllFlaggedOrAllUnknown( PropertySetAbstractValue propertySetAbstractValue) { return(HazardousIfAllFlagged(propertySetAbstractValue, assumeAllUnknownInsecure: true)); }