protected override DisposeAbstractValue HandleInstanceCreation(IOperation creation, PointsToAbstractValue instanceLocation, DisposeAbstractValue defaultValue) { if (ExecutingExceptionPathsAnalysisPostPass) { base.HandlePossibleThrowingOperation(creation); } defaultValue = DisposeAbstractValue.NotDisposable; var instanceType = creation.Type; if (!IsDisposable(instanceType) || !IsCurrentBlockReachable()) { return(defaultValue); } // Special case: Do not track System.Threading.Tasks.Task as you are not required to dispose them. if (TaskNamedType != null && instanceType.DerivesFrom(TaskNamedType, baseTypesOnly: true)) { return(defaultValue); } // StringReader doesn't need to be disposed: https://docs.microsoft.com/en-us/dotnet/api/system.io.stringreader?view=netframework-4.8 if (StringReaderType != null && instanceType.Equals(StringReaderType)) { return(defaultValue); } // Special case: MemoryStream doesn't need to be disposed. Subclasses *might* need to be disposed, but that is the less common case, and the common case is a huge source of noisy warnings. if (MemoryStreamNamedType != null && instanceType.Equals(MemoryStreamNamedType)) { return(defaultValue); } // Handle user option for additional excluded types if (DataFlowAnalysisContext.IsConfiguredToSkipAnalysis(instanceType)) { return(defaultValue); } SetAbstractValue(instanceLocation, DisposeAbstractValue.NotDisposed); return(DisposeAbstractValue.NotDisposed); }
public override FlightEnabledAbstractValue VisitInvocation_NonLambdaOrDelegateOrLocalFunction( IMethodSymbol method, IOperation?visitedInstance, ImmutableArray <IArgumentOperation> visitedArguments, bool invokedAsDelegate, IOperation originalOperation, FlightEnabledAbstractValue defaultValue) { var value = base.VisitInvocation_NonLambdaOrDelegateOrLocalFunction(method, visitedInstance, visitedArguments, invokedAsDelegate, originalOperation, defaultValue); if (DataFlowAnalysisContext.FlightEnablingMethods.Contains(method)) { var context = new FlightEnabledAnalysisCallbackContext(method, visitedArguments, DataFlowAnalysisContext.PointsToAnalysisResultOpt, DataFlowAnalysisContext.ValueContentAnalysisResultOpt); return(DataFlowAnalysisContext.GetValueForFlightEnablingMethodInvocation(context)); } else if (IsAnyAssertMethod(method)) { var argumentValue = GetCachedAbstractValue(visitedArguments[0]); EnableFlightsGlobally(argumentValue, negate: false); } return(GetValueOrDefault(value)); }
private void ProcessRegularInvocationOrCreation(IMethodSymbol targetMethod, ImmutableArray <IArgumentOperation> arguments, IOperation operation) { Debug.Assert(!targetMethod.IsLambdaOrLocalFunctionOrDelegate()); if (targetMethod.IsArgumentNullCheckMethod()) { if (arguments.Length == 1) { // "static bool SomeType.IsNullXXX(obj)" check. MarkValidatedLocations(arguments[0]); } } else if (targetMethod.Parameters.Length > 0 && arguments.Length > 0 && WellKnownTypeProvider.Exception != null && targetMethod.ContainingType.DerivesFrom(WellKnownTypeProvider.Exception)) { // FxCop compat: special cases handled by FxCop. // 1. First argument of type System.Runtime.Serialization.SerializationInfo to System.Exception.GetObjectData or its override is validated. // 2. First argument of type System.Runtime.Serialization.SerializationInfo to constructor of System.Exception or its subtype is validated. if (Equals(targetMethod.Parameters[0].Type, WellKnownTypeProvider.SerializationInfo)) { switch (targetMethod.MethodKind) { case MethodKind.Ordinary: if (targetMethod.Name.Equals("GetObjectData", StringComparison.OrdinalIgnoreCase)) { MarkValidatedLocations(arguments[0]); } break; case MethodKind.Constructor: MarkValidatedLocations(arguments[0]); break; } } } else if (_hazardousParameterUsageBuilderOpt != null && !targetMethod.IsExternallyVisible() && TryGetInterproceduralAnalysisResult(operation, out var invokedMethodAnalysisResult)) { // Check if this private/interal method that has hazardous usages of non-validated argument. Debug.Assert(!targetMethod.IsVirtual && !targetMethod.IsOverride); var hazardousParameterUsagesInInvokedMethod = invokedMethodAnalysisResult.HazardousParameterUsages; if (hazardousParameterUsagesInInvokedMethod.Count > 0) { foreach (var argument in arguments) { var notValidatedLocations = GetNotValidatedLocations(argument); foreach (var location in notValidatedLocations) { var parameter = (IParameterSymbol)location.SymbolOpt; if (hazardousParameterUsagesInInvokedMethod.ContainsKey(parameter)) { HandlePotentiallyHazardousOperation(argument, notValidatedLocations); break; } } } } } // Mark arguments passed to parameters of null check validation methods as validated. // Also mark arguments passed to parameters with ValidatedNotNullAttribute as validated. var isNullCheckValidationMethod = DataFlowAnalysisContext.IsNullCheckValidationMethod(targetMethod.OriginalDefinition); foreach (var argument in arguments) { var notValidatedLocations = GetNotValidatedLocations(argument); if (notValidatedLocations.Any()) { if (isNullCheckValidationMethod || HasValidatedNotNullAttribute(argument.Parameter)) { MarkValidatedLocations(argument); } } } }