private ExpressionInfo Node_Expr_Assign(XmlNode node)
{
var rhsExpr = node.GetSubNode(AstConstants.Subnode + ":" + AstConstants.Subnodes.Expr);
var rhsTaint = Analyze(rhsExpr);
var lhsExpr = node.GetSubNode(AstConstants.Subnode + ":" + AstConstants.Subnodes.Var);
Variable variable;
if (_varResolver.IsResolvableNode(lhsExpr.FirstChild))
{
variable = _varResolver.ResolveVariable(lhsExpr.FirstChild).Variable;
}
else
{
// LHS of assignment is not necessarily something we support. E.g. list(..,..) = ...
// In that case we use a "dummy" variable
variable = new Variable("$UNKNOWN$", _analysisScope.ToVariableScope());
}
var rhsExprNodes = rhsExpr.GetSubNodesByPrefix(AstConstants.Node);
if (rhsExprNodes.Any())
{
var rhsExprNode = rhsExprNodes.Single();
if (_varResolver.IsResolvableNode(rhsExprNode))
{
// If simple var to var assignment, move relevant var info to lhs variabel
var rhsVariable = _varResolver.ResolveVariable(rhsExprNode).Variable;
variable.Info = rhsVariable.Info.AssignmentClone();
return rhsTaint;
}
if (rhsTaint.ValueInfo.Value != null)
{
variable.Info.Value = rhsTaint.ValueInfo.Value;
variable.Info.Type = rhsTaint.ValueInfo.Type;
variable.Info.ClassNames.AddRange(rhsTaint.ValueInfo.ClassNames);
}
}
variable.Info = variable.Info.Merge(rhsTaint.ValueInfo);
if (rhsTaint.ValueInfo.Equals(new ValueInfo())) // HACK - Hacky way of determining if it hasn't been changed.
{
variable.Info.Taints = rhsTaint.ExpressionTaint;
variable.Info.PossibleStoredTaint = rhsTaint.ExpressionStoredTaint;
variable.Info.Type = rhsTaint.ValueInfo.Type;
variable.Info.ClassNames.AddRange(rhsTaint.ValueInfo.ClassNames);
return rhsTaint;
}
variable.Info = rhsTaint.ValueInfo.AssignmentClone();
return rhsTaint;
}