public void FunctionCallExtraction_OneArgument(string phpCode)
        {
            var statements = ParseAndGetAstStatementContent(phpCode);

            foreach (XmlNode node in statements)
            {
                if (node.LocalName == AstConstants.Nodes.Expr_FuncCall)
                {
                    FunctionCall fc = new FunctionCallExtractor().ExtractFunctionCall(node);
                    Assert.AreEqual(1, fc.Arguments.Count);
                }
            }
        }
Beispiel #2
0
 public ExpressionInfo AnalyzeFunctionCall(XmlNode node, ExpressionInfo exprInfo, IVariableStorage varStorage, 
                                           IVulnerabilityStorage vulnStorage, IDictionary<uint, ExpressionInfo> argumentInfos, AnalysisStacks analysisStacks)
 {
     var funcCall = new FunctionCallExtractor().ExtractFunctionCall(node);
     if (_getOptionsFunctions.Contains(funcCall.Name) ||
         _addOptionFunctions.Contains(funcCall.Name) ||
         _updateOptionFunctions.Contains(funcCall.Name))
     {
         return HandleOptionsCall(funcCall, node, exprInfo, varStorage, vulnStorage, argumentInfos, analysisStacks);
     }
     else if (_hookFunctions.Contains(funcCall.Name))
     {
         return HandleHookCall(node, exprInfo, varStorage, analysisStacks);
     }
     return exprInfo;
 }
        public void FunctionCallExtration_OneArgumentWhichIsClass()
        {
            string php = @"<?php
            class ClassOne
            {
            private $name;
            function __construct($var1) {
            $this->name = $var1;
            }

            function __toString(){
            return ""ClassOne "" . $this->name;
            }
            }

            function Test($var)
            {
            echo $var;
            }

            Test(new ClassOne('test'));
            ?>";
            var statemets = ParseAndGetAstStatementContent(php);

            foreach (XmlNode node in statemets)
            {
                if (node.LocalName == AstConstants.Nodes.Expr_FuncCall)
                {
                    FunctionCall fc = new FunctionCallExtractor().ExtractFunctionCall(node);
                    Assert.AreEqual("Test", fc.Name);
                    Assert.AreEqual(1, fc.Arguments.Count);
                    Assert.AreEqual(AstConstants.Nodes.Expr_New, fc.Arguments.ElementAt(0).Value.LocalName);

                    //Class value is no longer created.
                    /*var cv = (ClassValue)fc.ArgumentValues.ElementAt(0);
                    Assert.AreEqual("ClassOne", cv.ClassName);
                    Assert.AreEqual(1, cv.ClassValues.Count);
                    Assert.AreEqual("test", cv.ClassValues.ElementAt(0).ValueContent);
                    Assert.AreEqual("string", cv.ClassValues.ElementAt(0).Type);*/
                }
            }
        }
Beispiel #4
0
        private ExpressionInfo Node_FuncCall(XmlNode node)
        {
            var functionCallExtractor = new FunctionCallExtractor();
            var functionCall = functionCallExtractor.ExtractFunctionCall(node);

            bool isAlreadyInStack = _analysisStacks.CallStack.Any(x => x.Name == functionCall.Name);
            _analysisStacks.CallStack.Push(functionCall);

            var argInfos = new List<ExpressionInfo>();

            //Actually extract the arguments
            for (uint index = 1; index <= functionCall.Arguments.Count; index++)
            {
                var item = functionCall.Arguments.FirstOrDefault(x => x.Key == index);
                var exprInfo = this.Analyze(item.Value);
                if (_varResolver.IsResolvableNode(item.Value))
                {
                    var variableResolveResult = _varResolver.ResolveVariable(item.Value);
                    exprInfo.ValueInfo = variableResolveResult.Variable.Info;
                }
                argInfos.Add(exprInfo);
            }

            if (functionCall.Name == "")
            {
                var expr_info = new ExpressionInfo();
                _analysisStacks.CallStack.Pop();
                return argInfos.Aggregate(expr_info, (current, info) => current.Merge(info));
            }

            var customFunctionHandler = new CustomFunctionHandler(this._analyzer, _subroutineAnalyzerFactory);
            customFunctionHandler.AnalysisExtensions.AddRange(this.AnalysisExtensions);
            var immutableVariableStorage = ImmutableVariableStorage.CreateFromMutable(_variableStorage);
            var functionMethodAnalyzer = this._subroutineAnalyzerFactory.Create(immutableVariableStorage, _inclusionResolver,
                _analysisStacks, customFunctionHandler, _vulnerabilityStorage);

            var resultTaintSet = new ExpressionInfo();
            if (!isAlreadyInStack)
            {
                resultTaintSet = functionMethodAnalyzer.AnalyzeFunctionCall(functionCall, argInfos);
            }

            FunctionsHandler fh = FunctionsHandler.Instance;
            var sqlSaniFunc = fh.FindSQLSanitizerByName(functionCall.Name);
            var sqlSinkFunc = fh.FindSQLSinkByName(functionCall.Name);
            var xssSaniFunc = fh.FindXSSSanitizerByName(functionCall.Name);
            var xssSinkFunc = fh.FindXSSSinkByName(functionCall.Name);

            if(sqlSaniFunc != null && sqlSaniFunc.DefaultStatus == SQLITaint.None)
            {
                resultTaintSet.ExpressionTaint.SqliTaint.Clear();
                resultTaintSet.ValueInfo.Taints.SqliTaint.Clear();
                resultTaintSet.ExpressionStoredTaint.Taint.SqliTaint.Clear();
            }
            if (xssSaniFunc != null && xssSaniFunc.DefaultStatus == XSSTaint.None)
            {
                resultTaintSet.ExpressionTaint.XssTaint.Clear();
                resultTaintSet.ValueInfo.Taints.XssTaint.Clear();
                resultTaintSet.ExpressionStoredTaint.Taint.XssTaint.Clear();
            }
            if (sqlSinkFunc != null)
            {
                var vulnerableSqlParams = sqlSinkFunc.Parameters.Where(x => x.Value.IsSensitive).ToDictionary(pair => pair.Key);
                var param = functionCall.Arguments.Where(x => vulnerableSqlParams.Keys.Any(z => z.Item1 == x.Key));

                foreach (var parameter in param)
                {
                    var argInfo = argInfos.ElementAt((int) (parameter.Key - 1));
                    CheckForSQLVulnerabilities(argInfo, parameter.Value);
                }
            }
            if (xssSinkFunc != null)
            {
                var vulnerableXssParams = xssSinkFunc.Parameters.Where(x => x.Value.IsSensitive).ToDictionary(pair => pair.Key);
                var param = functionCall.Arguments.Where(x => vulnerableXssParams.Keys.Any(z => z.Item1 == x.Key));

                foreach (var parameter in param)
                {
                    var argInfo = argInfos.ElementAt((int)(parameter.Key - 1));
                    CheckForXssVulnerabilities(argInfo, parameter.Value);
                }
            }
            resultTaintSet = StoredFuncHandler(resultTaintSet, node, argInfos);

            var argumentInfoWithIndex = argInfos.Select((a, i) => new { Info = a, Index = (uint)i + 1 })
                                                .ToDictionary(a => a.Index, a => a.Info);
            resultTaintSet = ApplyAnalysisExtensionsToFuncCall(node, resultTaintSet, argumentInfoWithIndex);

            _analysisStacks.CallStack.Pop();
            return resultTaintSet;
        }
Beispiel #5
0
        private ExpressionInfo StoredMethodHandler(ExpressionInfo exprInfo, XmlNode node)
        {
            var functionCallExtractor = new FunctionCallExtractor();
            var methodCall = functionCallExtractor.ExtractMethodCall(node, this._variableStorage, this._analysisScope);
            var fh = FunctionsHandler.Instance;

            foreach (var className in methodCall.ClassNames.Distinct())
            {
                var sqlSinkFunc = fh.FindSQLSinkByName(methodCall.CreateFullMethodName(className));
                if (sqlSinkFunc == null)
                {
                    continue;
                }

                var vulnerableSqlParams = sqlSinkFunc.Parameters.Where(x => x.Value.IsSensitive).ToDictionary(pair => pair.Key);
                var param = methodCall.Arguments.Where(x => vulnerableSqlParams.Keys.Any(z => z.Item1 == x.Key));

                foreach (var parameter in param)
                {
                    ExpressionInfo customParameterAnalysis = Analyze(parameter.Value);
                    if (customParameterAnalysis.ValueInfo.Value == null)
                        continue;
                    if (StringAnalysis.IsSQLInsertionStmt(customParameterAnalysis.ValueInfo.Value))
                    {
                        customParameterAnalysis.ExpressionStoredTaint =
                            new StoredVulnInfo(StringAnalysis.RetrieveSQLTableName(customParameterAnalysis.ValueInfo.Value),
                                AstNode.GetStartLine(node)) {
                                                                Taint = customParameterAnalysis.ExpressionTaint,
                                                                ICantFeelIt = IsItInYet.YesItsGoingIn
                                                            };
                        InsertIntoStoredLocation(customParameterAnalysis, node);
                        customParameterAnalysis = new ExpressionInfo();
                    }
                    else if (StringAnalysis.IsSQLRetrieveStmt(customParameterAnalysis.ValueInfo.Value))
                    {
                        customParameterAnalysis.ExpressionStoredTaint =
                            new StoredVulnInfo(StringAnalysis.RetrieveSQLTableName(customParameterAnalysis.ValueInfo.Value),
                                AstNode.GetStartLine(node)) {
                                                                Taint = new DefaultTaintProvider().GetTaintedTaintSet(),
                                                                ICantFeelIt = IsItInYet.NoImPullingOut
                                                            };
                        exprInfo.ValueInfo.NestedVariablePossibleStoredDefaultTaintFactory = () => new DefaultTaintProvider().GetTaintedTaintSet();
                    }
                    exprInfo.ExpressionStoredTaint = exprInfo.ExpressionStoredTaint.Merge(customParameterAnalysis.ExpressionStoredTaint);
                }
            }
            return exprInfo;
        }
Beispiel #6
0
        private ExpressionInfo StoredFuncHandler(ExpressionInfo exprInfo, XmlNode node, List<ExpressionInfo> argInfos)
        {
            var resultExpr = new ExpressionInfo();
            var functionCallExtractor = new FunctionCallExtractor();
            var functionCall = functionCallExtractor.ExtractFunctionCall(node);
            var fh = FunctionsHandler.Instance;

            var sqlSinkFunc = fh.FindSQLSinkByName(functionCall.Name);

            if (sqlSinkFunc != null)
            {
                var vulnerableSqlParams = sqlSinkFunc.Parameters.Where(x => x.Value.IsSensitive).ToDictionary(pair => pair.Key);
                var param = functionCall.Arguments.Where(x => vulnerableSqlParams.Keys.Any(z => z.Item1 == x.Key));

                foreach (var arg in argInfos)
                {
                    exprInfo = arg;
                    if (exprInfo.ValueInfo.Value == null)
                    {
                        continue;
                    }
                    if (StringAnalysis.IsSQLInsertionStmt(exprInfo.ValueInfo.Value))
                    {
                        exprInfo.ExpressionStoredTaint =
                            new StoredVulnInfo(StringAnalysis.RetrieveSQLTableName(exprInfo.ValueInfo.Value), AstNode.GetStartLine(node))
                            {
                                Taint = exprInfo.ExpressionTaint,
                                ICantFeelIt = IsItInYet.YesItsGoingIn
                            };
                        InsertIntoStoredLocation(exprInfo, node);
                        exprInfo = new ExpressionInfo();
                    }
                    else if(StringAnalysis.IsSQLRetrieveStmt(exprInfo.ValueInfo.Value))
                    {
                        exprInfo.ExpressionStoredTaint =
                            new StoredVulnInfo(StringAnalysis.RetrieveSQLTableName(exprInfo.ValueInfo.Value), AstNode.GetStartLine(node))
                            {
                                Taint = new DefaultTaintProvider().GetTaintedTaintSet(),
                                ICantFeelIt = IsItInYet.NoImPullingOut
                            };
                        resultExpr.ValueInfo.NestedVariablePossibleStoredDefaultTaintFactory = () => new DefaultTaintProvider().GetTaintedTaintSet();
                    }
                    resultExpr.ExpressionStoredTaint = resultExpr.ExpressionStoredTaint.Merge(exprInfo.ExpressionStoredTaint);
                }
            }
            else
            {
                return exprInfo;
            }
            return resultExpr;
        }
Beispiel #7
0
        private ExpressionInfo Node_MethodCall(XmlNode node)
        {
            var functionCallExtractor = new FunctionCallExtractor();
            var methodCall = functionCallExtractor.ExtractMethodCall(node, this._variableStorage, this._analysisScope);

            bool isAlreadyInStack = _analysisStacks.CallStack.Any(x => x.Name == methodCall.Name);
            _analysisStacks.CallStack.Push(methodCall);

            var argInfos = new List<ExpressionInfo>();

            //Actually analyze the arguments
            for (uint index = 1; index <= methodCall.Arguments.Count; index++)
            {
                var item = methodCall.Arguments.FirstOrDefault(x => x.Key == index);
                var exprInfo = this.Analyze(item.Value);
                if (_varResolver.IsResolvableNode(item.Value))
                {
                    var @var = _varResolver.ResolveVariable(item.Value);
                    exprInfo.ValueInfo = @var.Variable.Info;
                }
                argInfos.Add(exprInfo);
            }

            if (methodCall.Name == "")
            {
                var exprInfo = new ExpressionInfo();
                _analysisStacks.CallStack.Pop();
                return argInfos.Aggregate(exprInfo, (current, info) => current.Merge(info));
            }

            var customFunctionHandler = new CustomFunctionHandler(this._analyzer, _subroutineAnalyzerFactory);
            customFunctionHandler.AnalysisExtensions.AddRange(this.AnalysisExtensions);
            var functionMethodAnalyzer = _subroutineAnalyzerFactory.Create(ImmutableVariableStorage.CreateFromMutable(_variableStorage),
                _inclusionResolver, _analysisStacks, customFunctionHandler, _vulnerabilityStorage);

            var methodCallTaintSet = new ExpressionInfo();
            if(!isAlreadyInStack)
            {
                methodCallTaintSet = functionMethodAnalyzer.AnalyzeMethodCall(methodCall, argInfos);
            }

            FunctionsHandler fh = FunctionsHandler.Instance;
            var resultTaintSet = new ExpressionInfo();
            foreach (var className in methodCall.ClassNames.Distinct())
            {
                var tempResultTaintSet = methodCallTaintSet.AssignmentClone();
                var sqlSaniFunc = fh.FindSQLSanitizerByName(methodCall.CreateFullMethodName(className));
                var sqlSinkFunc = fh.FindSQLSinkByName(methodCall.CreateFullMethodName(className));
                var xssSaniFunc = fh.FindXSSSanitizerByName(methodCall.CreateFullMethodName(className));
                var xssSinkFunc = fh.FindXSSSinkByName(methodCall.CreateFullMethodName(className));

                if (sqlSaniFunc != null && sqlSaniFunc.DefaultStatus == SQLITaint.None)
                {
                    resultTaintSet.ExpressionTaint.SqliTaint.Clear();
                }
                if (xssSaniFunc != null && xssSaniFunc.DefaultStatus == XSSTaint.None)
                {
                    resultTaintSet.ExpressionTaint.XssTaint.Clear();
                }
                if (sqlSinkFunc != null || xssSinkFunc != null)
                {
                    if (sqlSinkFunc != null)
                    {
                        var vulnerableSqlParams = sqlSinkFunc.Parameters.Where(x => x.Value.IsSensitive)
                                                                        .ToDictionary(pair => pair.Key);
                        var parameters = methodCall.Arguments.Where(x => vulnerableSqlParams.Keys.Any(z => z.Item1 == x.Key));

                        foreach (var parameter in parameters)
                        {
                            //var argInfo = Analyze(parameter.Value);
                            var argInfo = argInfos.ElementAt((int)(parameter.Key - 1));
                            CheckForSQLVulnerabilities(argInfo, parameter.Value);
                        }
                        if (sqlSinkFunc.ReturnType == "object" || sqlSinkFunc.ReturnType == "mix")
                        {
                            resultTaintSet.ValueInfo.ClassNames.AddRange(sqlSinkFunc.Classnames);
                        }
                    }
                    if (xssSinkFunc != null)
                    {
                        var vulnerableXssParams = xssSinkFunc.Parameters.Where(x => x.Value.IsSensitive).ToDictionary(pair => pair.Key);
                        var param = methodCall.Arguments.Where(x => vulnerableXssParams.Keys.Any(z => z.Item1 == x.Key));

                        foreach (var parameter in param)
                        {
                            var argInfo = argInfos.ElementAt((int)(parameter.Key - 1));
                            CheckForXssVulnerabilities(argInfo, parameter.Value);
                        }
                    }
                    // Assuming sinks does not return taint.
                    resultTaintSet.ExpressionTaint.ClearTaint();
                    resultTaintSet.ExpressionStoredTaint.Taint.ClearTaint();
                }
                tempResultTaintSet = StoredMethodHandler(tempResultTaintSet, node);
                resultTaintSet = resultTaintSet.Merge(tempResultTaintSet);

                var methodNameWithClass = methodCall.CreateFullMethodName(className);
                bool isStoredProvider = FunctionsHandler.Instance.FindStoredProviderMethods(methodNameWithClass).Any();
                if (isStoredProvider)
                {
                    resultTaintSet.ExpressionStoredTaint = resultTaintSet.ExpressionStoredTaint.Merge(methodCall.Var.Info.PossibleStoredTaint);
                    //TODO: The following is not true in all cases.
                    // What cases?
                    var cloned = resultTaintSet.ExpressionStoredTaint.Taint.DeepClone();
                    resultTaintSet.ValueInfo.NestedVariablePossibleStoredDefaultTaintFactory = () => cloned;
                }
            }

            _analysisStacks.CallStack.Pop();
            return resultTaintSet;
        }
        private TaintSets Node_FuncCall(XmlNode node)
        {
            if (!isConditional)
            {
                return null;
            }

            // We use the True scope as both True and False are the same at this point in time
            var functionCallExtractor = new FunctionCallExtractor();
            var functionCall = functionCallExtractor.ExtractFunctionCall(node);

            FunctionsHandler fh = FunctionsHandler.Instance;

            var condSaniFunc = fh.FindCondSanitizerByName(functionCall.Name);
            if (condSaniFunc != null)
            {
                var parameter = functionCall.Arguments;
                var varResolverFalse = new VariableResolver(_variables[EdgeType.False]);
                if (parameter.Any(x => varResolverFalse.IsResolvableNode(x.Value))
                                    && condSaniFunc.DefaultStatus == MixedStatus.XSSSQL_SAFE)
                {
                    if (isNegated)
                    {
                        var var = varResolverFalse.ResolveVariable(parameter.First(x => varResolverFalse.IsResolvableNode(x.Value)).Value);
                        var.Variable.Info.Taints = new TaintSets().ClearTaint();
                    }
                    else
                    {
                        var varResolverTrue = new VariableResolver(_variables[EdgeType.True]);
                        var var = varResolverTrue.ResolveVariable(parameter.First(x => varResolverTrue.IsResolvableNode(x.Value)).Value);
                        var.Variable.Info.Taints = new TaintSets().ClearTaint();
                    }
                }
            }
            return new TaintSets().ClearTaint();
        }
        public void FunctionCallExtration_OneArgumentWhichIsInstance()
        {
            var phpCode = @"<?php
            function Test($var)
            {
            echo $var;
            }

            Test('test');
            ?>";
            var statements = ParseAndGetAstStatementContent(phpCode);

            foreach (XmlNode node in statements)
            {
                if (node.LocalName == AstConstants.Nodes.Expr_FuncCall)
                {
                    FunctionCall fc = new FunctionCallExtractor().ExtractFunctionCall(node);
                    Assert.AreEqual("Test", fc.Name);
                    Assert.AreEqual(1, fc.Arguments.Count);

                    var constantArg = fc.Arguments.FirstOrDefault(x => x.Key == 1);
                    Assert.IsNotNull(constantArg);
                    Assert.IsNotNull(constantArg.Value);
                    Assert.AreEqual((AstConstants.Scalar + "_" + AstConstants.Scalars.String).ToUpper(), constantArg.Value.LocalName.ToUpper());

                    var value = constantArg.Value.GetSubNode(AstConstants.Subnode + ":" + AstConstants.Subnodes.Value).FirstChild.InnerText;
                    Assert.AreEqual("test", value);
                }
            }
        }
        public void MethodExtration_ExtractMethodCallFromVar()
        {
            var phpCode = @"<?php
            class ClassOne {
            public $var1;

            function __construct($var) {
            $this->var1 = $var;
            }

            function printOut($extra) {
            echo ""ClassOne: "" . $this->var1 . "" "" . $extra . ""\n"";
            }
            }

            $tmp = new ClassOne('test');
            $tmp->printOut('fisk');
            ?>";
            var stmts = ParseAndGetAstStatementContent(phpCode);

            foreach (XmlNode node in stmts)
            {
                if (node.LocalName == AstConstants.Nodes.Expr_MethodCall)
                {
                    MethodCall mc = new FunctionCallExtractor().ExtractMethodCall(node, new Mock<IVariableStorage>().Object);
                    Assert.AreEqual(1, mc.ClassNames.Count, "The expected number of class names was not correct");
                    Assert.AreEqual("ClassOne", mc.ClassNames.First(), "Wrong class name extracted");
                    Assert.AreEqual("printOut", mc.Name, "Wrong method name extracted");
                    Assert.AreEqual(1, mc.Arguments.Count, "Argument list was not 1 as expected");
                }
            }
        }
        public void MethodExtraction_NewExpr()
        {
            var phpCode = @"<?php
            class ClassOne {
            public $var1;

            function __construct($var) {
            $this->var1 = $var;
            }

            function printOut($extra) {
            echo ""ClassOne: "" . $this->var1 . "" "" . $extra . ""\n"";
            }
            }

            (new ClassOne('test'))->printOut('fisk');
            ?>";
            var stmts = ParseAndGetAstStatementContent(phpCode);

            foreach (XmlNode node in stmts)
            {
                if (node.LocalName == AstConstants.Nodes.Expr_MethodCall)
                {
                    MethodCall mc = new FunctionCallExtractor().ExtractMethodCall(node, new Mock<IVariableStorage>().Object);
                    Assert.True(mc.ClassNames.Any(x => x == "ClassOne"));
                    Assert.AreEqual("printOut", mc.Name);
                    Assert.AreEqual(1, mc.Arguments.Count);
                }
            }
        }
        public void FunctionCallExtration_SeveralArguments()
        {
            var phpCode = @"<?php
            function Test($var, $var2, $var3)
            {
            echo $var . $var2 . $var3;
            }

            Test('test', 1, false);
            ?>";
            var statements = ParseAndGetAstStatementContent(phpCode);

            foreach (XmlNode node in statements)
            {
                if (node.LocalName == AstConstants.Nodes.Expr_FuncCall)
                {
                    FunctionCall fc = new FunctionCallExtractor().ExtractFunctionCall(node);
                    Assert.AreEqual("Test", fc.Name);
                    Assert.AreEqual(3, fc.Arguments.Count);
                    /*Assert.AreEqual("test", fc.ArgumentValues.ElementAt(0).ValueContent);
                    Assert.AreEqual("1", fc.ArgumentValues.ElementAt(1).ValueContent);
                    Assert.AreEqual("false", fc.ArgumentValues.ElementAt(2).ValueContent);*/
                }
            }
        }
        public void FunctionCallExtration_OneArgumentWhichIsVar()
        {
            string php = @"<?php function Test($var) { echo $var; } $var2 = 'test'; Test($var2); ?>";
            var statements = ParseAndGetAstStatementContent(php);

            foreach (XmlNode node in statements)
            {
                if (node.LocalName == AstConstants.Nodes.Expr_FuncCall)
                {
                    FunctionCall fc = new FunctionCallExtractor().ExtractFunctionCall(node);
                    Assert.AreEqual(1, fc.Arguments.Count);

                    var variableArg = fc.Arguments.FirstOrDefault(x => x.Key == 1);
                    Assert.IsNotNull(variableArg);
                    Assert.AreEqual(variableArg.Value.LocalName, AstConstants.Nodes.Expr_Variable);

                    var varName = variableArg.Value.GetSubNode(AstConstants.Subnode + ":" + AstConstants.Subnodes.Name).InnerText;
                    Assert.AreEqual("var2", varName);
                    Assert.AreEqual("Test", fc.Name);
                }
            }
        }
Beispiel #14
0
        /// <summary>
        /// Make sure that hardcoded callback functions are analyzed.
        /// </summary>
        private ExpressionInfo HandleHookCall(XmlNode node, ExpressionInfo exprInfo, IVariableStorage currentStorage, AnalysisStacks analysisStacks)
        {
            var functionCall = new FunctionCallExtractor().ExtractFunctionCall(node);
            var result = new ExpressionInfo();

            foreach (var argument in functionCall.Arguments.Where(a => a.Value.LocalName == AstConstants.Nodes.Scalar_String))
            {
                var stringValue = ScalarNode.GetStringValue(argument.Value);
                var functions = FunctionsHandler.Instance.LookupFunction(stringValue);
                if (functions.Any())
                {
                    //Console.WriteLine("FOUND " + functions.Count() + " functions with name: " + stringValue);
                    var functionAnalyzer = this.FunctionMethodAnalyzerFactory(currentStorage);
                    var call = new FunctionCall(stringValue, null, AstNode.GetStartLine(node), AstNode.GetEndLine(node));

                    if (analysisStacks.CallStack.Any(c => c.Name == call.Name))
                    {
                        // Avoid recursive registrations.
                        continue;
                    }
                    analysisStacks.CallStack.Push(call);
                    var funcCallResult = functionAnalyzer.AnalyzeFunctionCall(call, new ExpressionInfo[0]);
                    analysisStacks.CallStack.Pop();

                    result = result.Merge(funcCallResult);
                }

                // https://codex.wordpress.org/Function_Reference/add_submenu_page
                // If a method is called, it is called with: array( $this, 'function_name' ) or array( __CLASS__, 'function_name' )

            }
            return result;
        }
Beispiel #15
0
        private void FunctionMethodEnter(XmlNode node)
        {
            var ext = new FunctionCallExtractor ();
            Function f = null;
            string methodName = ext.ExtractFunctionCall (node).Name;
            string functionName = null;

            if (node.LocalName == AstConstants.Nodes.Expr_FuncCall)
                f = FunctionsHandler.Instance.CustomFunctions.Find (x => x.Name == ext.ExtractFunctionCall (node).Name || x.Aliases.Any (y => y == ext.ExtractFunctionCall (node).Name));
            else if (node.LocalName == AstConstants.Nodes.Expr_MethodCall) {
                var varNode = node.GetSubNode (AstConstants.Subnode + ":" + AstConstants.Subnodes.Var);
                string className = "";

                //PHP: (new ClassName(args))->MethodName(args);
                //Extract the ClassName directly, in this case there can be only one ClassName!
                if (varNode.FirstChild.LocalName == AstConstants.Nodes.Expr_New) {
                    className = varNode.FirstChild
                        .GetSubNode (AstConstants.Subnode + ":" + AstConstants.Subnodes.Class)
                        .GetSubNode (AstConstants.Node + ":" + AstConstants.Nodes.Name)
                        .GetSubNode (AstConstants.Subnode + ":" + AstConstants.Subnodes.Parts).FirstChild.FirstChild.InnerText;
                }

                //Look up the function name in the list of variables
                else {
                    try {classVarList.TryGetValue (varNode.FirstChild
                        .GetSubNode (AstConstants.Subnode + ":" + AstConstants.Subnodes.Name).InnerText, out className);} catch {}
                }

                methodName = node.GetSubNode (AstConstants.Subnode + ":" + AstConstants.Subnodes.Name).FirstChild.InnerText;

                functionName = className + "->" + methodName;
                f = FunctionsHandler.Instance.CustomFunctions.Find (x => x.Name == functionName || x.Aliases.Any (y => y == functionName));
            }

            if (CurrentBlock.BreaksOutOfScope) {
                CurrentBlock = new CFGBlock ();
                Graph.AddVertex (CurrentBlock);
            } else {
                CurrentBlock = ConnectNewBlockTo (CurrentBlock, EdgeType.Normal);
            }
            CurrentBlock.AstEntryNode = node;

            if (f==null)

                f = HandleWPFunctions(methodName, node, functionName);

            if (f != null && !inFunctions.Contains(f)) {
                inFunctions.Add(f);
                foreach (XmlNode n in f.AstNode.ChildNodes) {
                    if (n.LocalName == "stmts")
                        foreach (XmlNode s in n.FirstChild.ChildNodes) {
                                DepthFirstImpl (s);
                        }
                }
                inFunctions.Remove(f);
            }
            //else throw new NullReferenceException("The function did not exist"); //This should never happen
        }