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); }
private Tuple<VariableTreeDimension, ValueInfo> Handle_Expr_ArrayItem(XmlNode node) { VariableTreeDimension arrayKey; var itemInfo = new ValueInfo(); var valueResult = Analyze(node.GetSubNode(AstConstants.Subnode + ":" + AstConstants.Subnodes.Value)); itemInfo.Taints = valueResult.ExpressionTaint; if (valueResult.ValueInfo != null) { itemInfo = valueResult.ValueInfo.AssignmentClone(); } var dimension = node.GetSubNode(AstConstants.Subnode + ":" + AstConstants.Subnodes.Key); Analyze(dimension); // Start dimension resolving - This should probably be refactored! var dimNode = dimension.GetSubNodesByPrefix(AstConstants.Node).SingleOrDefault(); // Rules: // Strings with valid integers are cast // Floats are cast to integer (fraction is truncated) // Bools are cast to integers (true = 1, false = 0) // Null = empty string // Arrays/Objects cannot be used as key. // // Conflict - Last one wins. if (dimNode == null) { arrayKey = new VariableTreeDimension() { Index = -1, Key = "$UKENDT$" }; } else { if (dimNode.Name == AstConstants.Node + ":" + AstConstants.Nodes.Scalar_String) { var stringValue = ScalarNode.GetStringValue(dimNode); arrayKey = new VariableTreeDimension() { Key = stringValue }; double indexValue; if (double.TryParse(stringValue, out indexValue)) { arrayKey.Index = (int)indexValue; } } else if (dimNode.Name == AstConstants.Node + ":" + AstConstants.Nodes.Scalar_LNumber) { var index = ScalarNode.GetLValue(dimNode); arrayKey = new VariableTreeDimension() { Index = index, Key = index.ToString(CultureInfo.InvariantCulture) }; } else if (dimNode.Name == AstConstants.Node + ":" + AstConstants.Nodes.Scalar_DNumber) { var index = (int)ScalarNode.GetDValue(dimNode); arrayKey = new VariableTreeDimension() { Index = index, Key = index.ToString(CultureInfo.InvariantCulture) }; } else { // Default case. ie. Non resolvable dimension arrayKey = new VariableTreeDimension() { Index = -1, Key = "$UKENDT$" }; } } // End dimension resolving. return new Tuple<VariableTreeDimension, ValueInfo>(arrayKey, itemInfo); }
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)); }