private ExpressionInfo Stmt_Foreach(XmlNode node)
{
var expr = node.GetSubNode(AstConstants.Subnode + ":" + AstConstants.Subnodes.Expr);
var keyVar = node.GetSubNode(AstConstants.Subnode + ":" + AstConstants.Subnodes.KeyVar);
var byRef = node.GetSubNode(AstConstants.Subnode + ":" + AstConstants.Subnodes.ByRef);
var valueVar = node.GetSubNode(AstConstants.Subnode + ":" + AstConstants.Subnodes.ValueVar);
var exprResult = Analyze(expr);
var keyVarResult = Analyze(keyVar);
var valueVarResult = Analyze(valueVar);
var exprNode = expr.GetSubNodesByPrefix(AstConstants.Node).Single();
Variable exprVariable = new Variable("$UNKNOWN var$ - Just here to prevent null checks.", _analysisScope.ToVariableScope());
if (_varResolver.IsResolvableNode(exprNode))
{
exprVariable = _varResolver.ResolveVariable(exprNode).Variable;
}
var defaultKeyTaint = exprResult.ValueInfo.DefaultDimensionTaintFactory();
var defaultValuePossibleTaint = exprResult.ValueInfo.NestedVariablePossibleStoredDefaultTaintFactory();
var defaultValueTaint = exprResult.ValueInfo.NestedVariableDefaultTaintFactory();
var keyNode = keyVar.GetSubNodesByPrefix(AstConstants.Node).SingleOrDefault(); // Might be a scalar!
if (keyNode != null && this._varResolver.IsResolvableNode(keyNode))
{
var varResolveResult = _varResolver.ResolveVariable(keyNode);
varResolveResult.Variable.Info.Taints = varResolveResult.Variable.Info.Taints.Merge(defaultKeyTaint);
}
var variableTaints = exprResult.ValueInfo.Variables.Select(x => x.Value.Info.Taints).ToList();
TaintSets worstVariableTaint = variableTaints.Any() ? variableTaints.Aggregate((current, next) => current.Merge(next))
: defaultValueTaint;
worstVariableTaint = worstVariableTaint.Merge(defaultValueTaint);
var variablePossibleTaint = exprResult.ValueInfo.Variables.Select(x => x.Value.Info.PossibleStoredTaint.Taint).ToList();
TaintSets worstVariablePossibleTaint = variablePossibleTaint.Any()
? variablePossibleTaint.Aggregate((current, next) => current.Merge(next))
: defaultValuePossibleTaint;
worstVariablePossibleTaint = worstVariablePossibleTaint.Merge(defaultValuePossibleTaint);
var valueNode = valueVar.GetSubNodesByPrefix(AstConstants.Node).Single();
if (this._varResolver.IsResolvableNode(valueNode))
{
var varResolveResult = _varResolver.ResolveVariable(valueNode).Variable;
varResolveResult.Info.Taints = varResolveResult.Info.Taints.Merge(worstVariableTaint);
varResolveResult.Info.Taints = varResolveResult.Info.Taints.Merge(exprVariable.Unknown.Info.Taints);
varResolveResult.Info.PossibleStoredTaint = _varResolver.ClonePossibleStored(exprVariable.Info);
varResolveResult.Info.PossibleStoredTaint.Taint = varResolveResult.Info.PossibleStoredTaint.Taint.Merge(worstVariablePossibleTaint);
varResolveResult.Info.PossibleStoredTaint.Taint = varResolveResult.Info.PossibleStoredTaint.Taint.Merge(exprVariable.Unknown.Info.PossibleStoredTaint.Taint);
varResolveResult.Info.NestedVariablePossibleStoredDefaultTaintFactory = exprResult.ValueInfo.NestedVariablePossibleStoredDefaultTaintFactory;
varResolveResult.Info.NestedVariableDefaultTaintFactory = exprResult.ValueInfo.NestedVariableDefaultTaintFactory;
}
return new ExpressionInfo();
}