private VariableResolveResult Node_Expr_ArrayDimFetch(XmlNode node)
{
var arrayVarResult = GetVariable(node.GetSubNode(AstConstants.Subnode + ":" + AstConstants.Subnodes.Var));
var dimValueNode = node.GetSubNode(AstConstants.Subnode + ":" + AstConstants.Subnodes.Dim)
.GetSubNodesByPrefix(AstConstants.Node).SingleOrDefault();
if (dimValueNode == null)
{
// This can happen with e.g. $myArray[] = *something*;
return new VariableResolveResult(arrayVarResult.Variable.Unknown, true);
}
if (dimValueNode.LocalName == AstConstants.Nodes.Scalar_String)
{
var keyValue = dimValueNode.GetSubNode(AstConstants.Subnode + ":" + AstConstants.Subnodes.Value).InnerText;
Variable fetchedVar;
if (arrayVarResult.Variable.Info.TryGetVariableByString(keyValue, out fetchedVar))
{
return new VariableResolveResult(fetchedVar);
}
var newVar = new Variable(keyValue, VariableScope.Instance);
var arrayDimension = new VariableTreeDimension() {Key = keyValue};
double numericKeyValue;
if (double.TryParse(keyValue, NumberStyles.AllowDecimalPoint, CultureInfo.InvariantCulture, out numericKeyValue))
{
arrayDimension.Index = (int) numericKeyValue;
}
newVar.Info.Taints = arrayVarResult.Variable.Info.NestedVariableDefaultTaintFactory();
newVar.Info.NestedVariableDefaultTaintFactory = arrayVarResult.Variable.Info.NestedVariableDefaultTaintFactory;
newVar.Info.PossibleStoredTaint = ClonePossibleStored(arrayVarResult.Variable.Info);
newVar.Info.NestedVariablePossibleStoredDefaultTaintFactory = arrayVarResult.Variable.Info.NestedVariablePossibleStoredDefaultTaintFactory;
arrayVarResult.Variable.Info.Variables.Add(arrayDimension, newVar);
return new VariableResolveResult(newVar, true);
}
if (dimValueNode.LocalName == AstConstants.Nodes.Scalar_LNumber ||
dimValueNode.LocalName == AstConstants.Nodes.Scalar_DNumber)
{
var valueNode = dimValueNode.GetSubNode(AstConstants.Subnode + ":" + AstConstants.Subnodes.Value);
int index = (int) Convert.ToDouble(valueNode.InnerText, CultureInfo.InvariantCulture);
Variable fetchedVar;
if (arrayVarResult.Variable.Info.TryGetVariableByIndex(index, out fetchedVar))
{
return new VariableResolveResult(fetchedVar);
}
var newVar = new Variable(index.ToString(CultureInfo.InvariantCulture), VariableScope.Instance)
{
Info = {
Taints = arrayVarResult.Variable.Info.NestedVariableDefaultTaintFactory(),
NestedVariableDefaultTaintFactory = arrayVarResult.Variable.Info.NestedVariableDefaultTaintFactory,
NestedVariablePossibleStoredDefaultTaintFactory = arrayVarResult.Variable.Info.NestedVariablePossibleStoredDefaultTaintFactory,
PossibleStoredTaint = ClonePossibleStored(arrayVarResult.Variable.Info)
}
};
arrayVarResult.Variable.Info.Variables.Add(new VariableTreeDimension() {
Index = index,
Key = index.ToString(CultureInfo.InvariantCulture)
}, newVar);
return new VariableResolveResult(newVar, true);
}
// Couldn't resolve array element.
return new VariableResolveResult(arrayVarResult.Variable.Unknown, true);
}