Пример #1
0
        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);
        }
Пример #2
0
        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);
        }
Пример #3
0
        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));
        }