bool TestDependGraph::TestFunctionCall() { // functions VD4(FunctionCall, "<?php include $_SERVER['PHP_ROOT'].'f2';\n test();", "<?php function test() {}", "test", "test()"); VD4(FunctionCall, "<?php test(); function test() {}", "", "test", "test()"); VD4(FunctionCall, "<?php function test() {} test();", "", "test", "test()"); // methods VD4(FunctionCall, "<?php include $_SERVER['PHP_ROOT'].'f2';\n" "function test() { $a = new C(); $a->test();}", "<?php class C { public function test() {}}", "c::test", "$a->test()"); VD4(FunctionCall, "<?php function test() { $a = new C(); $a->test();} " "class C { public function test() {}}", "", "c::test", "$a->test()"); VD4(FunctionCall, "<?php class C { public function test() {}} " "function test() { $a = new C(); $a->test();}", "", "c::test", "$a->test()"); #ifdef HPHP_NOTE // making sure a "MasterCopy" marked function will always be used for // dependency's parent { Option::IncludeRoots["$_SERVER['PHP_ROOT']"] = ""; AnalysisResultPtr ar(new AnalysisResult()); BuiltinSymbols::Load(ar); Parser::ParseString("<?php function test() {}", ar, "f1"); Parser::ParseString("<?php /*|MasterCopy|*/ function test() {}", ar, "f2"); ar->analyzeProgram(); ar->inferTypes(); DependencyGraphPtr dg = ar->getDependencyGraph(); ConstructPtr parent = dg->getParent(DependencyGraph::KindOfFunctionCall, "test"); if (!parent || strcmp(parent->getLocation()->file, "f2") != 0) { printf("%s:%d: incorrect parent found at %s:%d\n", __FILE__, __LINE__, parent ? parent->getLocation()->file : "", parent ? parent->getLocation()->line0 : 0); return false; } } #endif return true; }
string IncludeExpression::CheckInclude(ConstructPtr includeExp, ExpressionPtr fileExp, bool &documentRoot) { string container = includeExp->getLocation()->file; string var, lit; parse_string_arg(fileExp, var, lit); if (lit.empty()) return lit; if (var == "__DIR__") { var = ""; // get_include_file_path will check relative to the current file's dir // as long as the first char isn't a / if (lit[0] == '/') { lit = lit.substr(1); } } string included = get_include_file_path(container, var, lit, documentRoot); if (!included.empty()) { if (included == container) { Compiler::Error(Compiler::BadPHPIncludeFile, includeExp); } included = Util::canonicalize(included); if (!var.empty()) documentRoot = true; } return included; }
string DependencyGraph::add(KindOf kindOf, ConstructPtr childExp, ExpressionPtr parentExp, CodeErrorPtr codeError, bool documentRoot /* = false */) { string child = childExp->getLocation()->file; string parent; switch (kindOf) { case KindOfPHPInclude: if (!checkInclude(childExp, parentExp, codeError, documentRoot, child, parent)) { return ""; } break; default: if (!m_hookHandler || !m_hookHandler(this, kindOf, childExp, parentExp, codeError, documentRoot, child, parent, beforeDependencyGraphAdd)) { return ""; } break; } string program; // no program is associated add(kindOf, program, child, childExp, parent, ConstructPtr(), codeError); if (m_hookHandler) { m_hookHandler(this, kindOf, childExp, parentExp, codeError, documentRoot, child, parent, afterDependencyGraphAdd); } return parent; }
ExpressionPtr Option::GetValue(VariableTablePtr variables, const char *varName) { ConstructPtr decl = variables->getDeclaration(varName); if (!decl) { return ExpressionPtr(); } AssignmentExpressionPtr assignment = dynamic_pointer_cast<AssignmentExpression>(decl); if (!assignment) { Logger::Error("Line %d: Ignored option %s", decl->getLocation()->line1, varName); return ExpressionPtr(); } return assignment->getValue(); }
bool DependencyGraph::checkInclude(ConstructPtr childExp, ExpressionPtr parentExp, CodeErrorPtr codeError, bool documentRoot, string &child, string &parent) { child = childExp->getLocation()->file; parent = parseInclude(child, parentExp, documentRoot); if ((parent.empty() || parent == child) && Option::AllowedBadPHPIncludes.find(parentExp->getText()) == Option::AllowedBadPHPIncludes.end()) { if (codeError) { codeError->record(CodeError::BadPHPIncludeFile, childExp); } return false; } if (parent.empty()) return false; return true; }
string IncludeExpression::CheckInclude(ConstructPtr includeExp, ExpressionPtr fileExp, bool &documentRoot, bool relative) { string container = includeExp->getLocation()->file; string var, lit; parse_string_arg(fileExp, var, lit); if (lit.empty()) return lit; string included = get_include_file_path(container, var, lit, documentRoot, relative); if (!included.empty()) { if (included == container) { Compiler::Error(Compiler::BadPHPIncludeFile, includeExp); } included = Util::canonicalize(included); if (!var.empty()) documentRoot = true; } return included; }
string IncludeExpression::CheckInclude(ConstructPtr includeExp, ExpressionPtr fileExp, bool documentRoot) { string container = includeExp->getLocation()->file; string var, lit; parse_string_arg(fileExp, var, lit); if (!lit.empty()) { if (!var.empty()) { var += " . "; } var += "'" + lit + "'"; } string included = get_include_file_path(container, var, documentRoot); included = Util::canonicalize(included); if (included.empty() || container == included) { if (!included.empty() && included.find(' ') == string::npos) { Compiler::Error(Compiler::BadPHPIncludeFile, includeExp); } return ""; } return included; }