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; PooledHashSet <(string, string)>?sanitizedParameterPairs = null; PooledHashSet <string>? taintedParameterNamesCached = null; try { IEnumerable <string> GetTaintedParameterNames() { IEnumerable <string> taintedParameterNames = visitedArguments .Where(s => this.GetCachedAbstractValue(s).Kind == TaintedDataAbstractValueKind.Tainted) .Select(s => s.Parameter.Name); if (visitedInstance != null && this.GetCachedAbstractValue(visitedInstance).Kind == TaintedDataAbstractValueKind.Tainted) { taintedParameterNames = taintedParameterNames.Concat(TaintedTargetValue.This); } return(taintedParameterNames); } taintedParameterNamesCached = PooledHashSet <string> .GetInstance(); taintedParameterNamesCached.UnionWith(GetTaintedParameterNames()); if (this.DataFlowAnalysisContext.SourceInfos.IsSourceMethod( method, visitedArguments, new Lazy <PointsToAnalysisResult?>(() => DataFlowAnalysisContext.PointsToAnalysisResult), new Lazy <(PointsToAnalysisResult?, ValueContentAnalysisResult?)>(() => (DataFlowAnalysisContext.PointsToAnalysisResult, DataFlowAnalysisContext.ValueContentAnalysisResult)), out taintedTargets)) { bool rebuildTaintedParameterNames = false; foreach (string taintedTarget in taintedTargets) { if (taintedTarget != TaintedTargetValue.Return) { IArgumentOperation argumentOperation = visitedArguments.FirstOrDefault(o => o.Parameter.Name == taintedTarget); if (argumentOperation != null) { rebuildTaintedParameterNames = true; 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 (rebuildTaintedParameterNames) { taintedParameterNamesCached.Clear(); taintedParameterNamesCached.UnionWith(GetTaintedParameterNames()); } } if (this.DataFlowAnalysisContext.SourceInfos.IsSourceTransferMethod( method, visitedArguments, taintedParameterNamesCached, out taintedParameterPairs)) { foreach ((string ifTaintedParameter, string thenTaintedTarget) in taintedParameterPairs) { IOperation thenTaintedTargetOperation = visitedInstance != null && thenTaintedTarget == TaintedTargetValue.This ? visitedInstance : visitedArguments.FirstOrDefault(o => o.Parameter.Name == thenTaintedTarget); if (thenTaintedTargetOperation != null) { SetTaintedForEntity( thenTaintedTargetOperation, this.GetCachedAbstractValue( visitedInstance != null && ifTaintedParameter == TaintedTargetValue.This ? visitedInstance : visitedArguments.FirstOrDefault(o => o.Parameter.Name == ifTaintedParameter))); } else { Debug.Fail("Are the tainted data sources misconfigured?"); } } } if (visitedInstance != null && this.IsSanitizingInstanceMethod(method)) { SetTaintedForEntity(visitedInstance, TaintedDataAbstractValue.NotTainted); } if (this.IsSanitizingMethod( method, visitedArguments, taintedParameterNamesCached, out sanitizedParameterPairs)) { if (sanitizedParameterPairs.Count == 0) { // it was either sanitizing constructor or // the short form or registering sanitizer method by just the name result = TaintedDataAbstractValue.NotTainted; } else { foreach ((string ifTaintedParameter, string thenSanitizedTarget) in sanitizedParameterPairs) { if (thenSanitizedTarget == TaintedTargetValue.Return) { result = TaintedDataAbstractValue.NotTainted; continue; } IArgumentOperation thenSanitizedTargetOperation = visitedArguments.FirstOrDefault(o => o.Parameter.Name == thenSanitizedTarget); if (thenSanitizedTargetOperation != null) { SetTaintedForEntity(thenSanitizedTargetOperation, TaintedDataAbstractValue.NotTainted); } else { Debug.Fail("Are the tainted data sanitizers misconfigured?"); } } } } } finally { taintedTargets?.Dispose(); taintedParameterPairs?.Dispose(); sanitizedParameterPairs?.Dispose(); taintedParameterNamesCached?.Dispose(); } return(result); }
private static void Free(PooledHashSet hash_set) { hash_set.Clear(); pool.Free(hash_set); }