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); } } }
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);*/ } } }
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; }
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; }
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; }
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); } } }
/// <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; }
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 }