/** * Execute a code review after compilation * * @param array $input array($parsedCode, $templateFilepath) * * @throws libs\view\InvalidConfiguration * @throws libs\view\RestrictedException * * @author Damian Kęska <*****@*****.**> * @return array */ public function afterCompile($input) { $collector = new NodeVisitor_pseudoSandboxing(); $traverser = new PhpParser\NodeTraverser(); $traverser->addVisitor($collector); $this->parser = new PhpParser\Parser(new PhpParser\Lexer\Emulative()); $stmts = $this->parser->parse($input[0]); $stmts = $traverser->traverse($stmts); /** * Whitelist support */ if ($this->engine->getConfigurationKey('sandboxMode', 'whitelist') == 'whitelist') { $whitelist = $this->engine->getConfigurationKey('sandboxWhitelist'); if (!is_array($whitelist)) { throw new Rain\InvalidConfiguration('Missing configuration key "sandboxWhitelist", please set it using setConfigurationKey in RainTPL', 2); } foreach ($collector->calledFunctions as $functionName => $count) { if (!in_array($functionName, $whitelist)) { throw new Rain\RestrictedException('Method "' . $functionName . '" was blocked from use in this template', 1); } } } elseif ($this->engine->getConfigurationKey('sandboxMode') == 'blacklist') { $blacklist = $this->engine->getConfigurationKey('sandboxBlacklist'); if (!is_array($blacklist)) { throw new Rain\InvalidConfiguration('Missing configuration key "sandboxBlacklist", please set it using setConfigurationKey in RainTPL', 2); } foreach ($collector->calledFunctions as $functionName => $count) { if (in_array($functionName, $blacklist)) { throw new Rain\RestrictedException('Method "' . $functionName . '" was blocked from use in this template', 1); } } } return $input; }
/** * 通过判断文件中Nodes的数量和class node和 function node数量比较,找出main php files * @param php项目文件夹路径$dirpath * @return multitype: */ public static function mainFileFinder($dirpath) { $files = self::getPHPfile($dirpath); $should2parser = array(); $parser = new PhpParser\Parser(new PhpParser\Lexer\Emulative()); $traverser = new PhpParser\NodeTraverser(); $visitor = new VisitorForLine(); $traverser->addVisitor($visitor); foreach ($files as $file) { $code = file_get_contents($file); try { $stmts = $parser->parse($code); } catch (PhpParser\Error $e) { continue; } $traverser->traverse($stmts); $nodes = $visitor->getNodes(); $sumcount = count($nodes); $count = $visitor->getCount(); if ($sumcount == 0) { continue; } //暂时确定当比值小于0.6,为main php files if ($count / $sumcount < 0.6) { array_push($should2parser, $file); } $visitor->setCount(0); $visitor->setNodes(array()); } return $should2parser; }
/** * 得到一个文件基本信息FileSummary,包括路径,基本块,包含的文件等 * @param string $absPath */ public static function getFileSummary($absPath) { if (!$absPath) { return; } $visitor = new MyVisitor(); $parser = new PhpParser\Parser(new PhpParser\Lexer\Emulative()); $traverser = new PhpParser\NodeTraverser(); $code = file_get_contents($absPath); try { $stmts = $parser->parse($code); } catch (Exception $e) { return; } $traverser->addVisitor($visitor); $traverser->traverse($stmts); $nodes = $visitor->getNodes(); $fileSummary = new FileSummary(); $fileSummary->setPath($absPath); $currBlock = new BasicBlock(); foreach ($nodes as $node) { if (!is_object($node)) { continue; } //不分析函数定义 if ($node->getType() == "Stmt_Function") { continue; } $currBlock->addNode($node); } $fileSummaryGenerator = new FileSummaryGenerator(); $fileSummaryGenerator->simulate($currBlock, $fileSummary); return $fileSummary; }
public function obfuscate() { $content = $this->source; $parser = new PhpParser\Parser(new PhpParser\Lexer\Emulative()); $traverser = new PhpParser\NodeTraverser(); $prettyPrinter = new PhpParser\PrettyPrinter\Obfuscated(); // add your visitors $traverser->addVisitor(new StringNodeVisitor()); $traverser->addVisitor(new VariableNodeVisitor()); $traverser->addVisitor(new DigitNodeVisitor()); $f = new FunctionNodeVisitor(); $traverser->addVisitor($f); try { $stmts = $parser->parse($content); $stmts = $traverser->traverse($stmts); $nodeWithFunctionNames = $f->getNativeFunctionNamesNode(); $userDefinedFunctionNames = $f->getUserDefinedFunctionNames(); $f2 = new Function2NodeVisitor($nodeWithFunctionNames, $userDefinedFunctionNames); $traverser2 = new PhpParser\NodeTraverser(); $traverser2->addVisitor($f2); $stmts = array_merge(array($nodeWithFunctionNames['']), $stmts); $stmts = $traverser2->traverse($stmts); $content = $prettyPrinter->prettyPrintFile($stmts); return $content; } catch (PhpParser\Error $e) { return 'Parse Error: ' . $e->getMessage(); } }
public function parseContent() { $traverser = new \PhpParser\NodeTraverser(); $visitor = new ParsePhpForTrlVisitor(); $traverser->addVisitor($visitor); ini_set('xdebug.max_nesting_level', 200); $statments = $traverser->traverse($this->_parser->parse($this->_codeContent)); return $visitor->getTranslations(); }
/** * @see BaseCheck::check() * @param AnalyzedPhpFile[] $files */ public function check($files) { foreach ($files as $php_file) { $this->current_php_file = $php_file; $traverser = new PhpParser\NodeTraverser(); $traverser->addVisitor($this->visitor); $traverser->traverse($php_file->get_node_tree()); } $this->current_php_file = null; return empty($this->errors); }
/** * 获取concat中的各个成员 * 形如: * (1) "aaaa" . $b . "bbbbbb" ; * 使用时,只需要将最大的一个concat传递过来当做参数$node即可 * @param AST $node */ public function setItemByNode($node) { $type = $node->getType(); if ($type == "Expr_BinaryOp_Concat") { $parser = new PhpParser\Parser(new PhpParser\Lexer\Emulative()); $traverser = new PhpParser\NodeTraverser(); $visitor = new BinaryOpConcatVisitor(); $traverser->addVisitor($visitor); $traverser->traverse(array($node)); $this->items = $visitor->getItems(); } }
public static function patch($source) { $patched = false; self::$replacement = []; $parser = new PhpParser\Parser(new PhpParser\Lexer(['usedAttributes' => ['startTokenPos', 'endTokenPos']])); $traverser = new PhpParser\NodeTraverser(); $traverser->addVisitor(new CIPHPUnitTestFunctionPatcherNodeVisitor()); $ast_orig = $parser->parse($source); $traverser->traverse($ast_orig); if (self::$replacement !== []) { $patched = true; $new_source = self::generateNewSource($source); } else { $new_source = $source; } return [$new_source, $patched]; }
/** * 处理单个文件的静态检测 * 输入PHP文件 * @param string $path */ function load_file($path) { $cfg = new CFGGenerator(); $cfg->getFileSummary()->setPath($path); $visitor = new MyVisitor(); $parser = new PhpParser\Parser(new PhpParser\Lexer\Emulative()); $traverser = new PhpParser\NodeTraverser(); $code = file_get_contents($path); $stmts = $parser->parse($code); $traverser->addVisitor($visitor); $traverser->traverse($stmts); $nodes = $visitor->getNodes(); $pEntryBlock = new BasicBlock(); $pEntryBlock->is_entry = true; //开始分析 $cfg->CFGBuilder($nodes, NULL, NULL, NULL); }
/** * Runs the analyzer on the given $files. * * @param array<AnalyzedFile> $files The files to process */ public function analyze($files) { $total_lines = 0; foreach ($files as $file) { if ($file->get_filetype() !== 'php') { continue; } $element = new FileElement($file); $visitor = new AnalyzerVisitor('CodeElementFactory', $element, $this->elements); $traverser = new PhpParser\NodeTraverser(); $traverser->addVisitor($visitor); $traverser->traverse($file->get_node_tree()); $this->elements['files']->add_child($visitor->get_root()); $total_lines += (int) $element->get_stat('line_count'); } $this->elements['totals']->add_stat('total_lines', $total_lines); }
/** * Analyzes this file. * * @throws PhpParser\Error if the file cannot be parsed. */ protected function analyze_file() { // Load the contents of the file if (is_null($this->filecontents) || !$this->filecontents) { $this->filecontents = file_get_contents($this->filepath); } if (false === $this->filecontents) { return; } // Parse the tokens $parser = new PhpParser\Parser(new PhpParser\Lexer()); $this->node_tree = $parser->parse($this->filecontents); // Pre-process the parsed elements for further usage $traverser = new PhpParser\NodeTraverser(); $traverser->addVisitor(new ScopeVisitor()); $traverser->addVisitor(new InAssignmentVisitor()); $this->node_tree = $traverser->traverse($this->node_tree); }
/** * @param ClassLoader $loader * @return Command */ protected function createCommand(ClassLoader $loader) { $parser = new \PhpParser\Parser(new \PhpParser\Lexer\Emulative()); $collector = new Collector(); $filterTraverser = new \PhpParser\NodeTraverser(); $filterTraverser->addVisitor(new \PhpParser\NodeVisitor\NameResolver()); $filterTraverser->addVisitor($collector); $writerTraverser = new \PhpParser\NodeTraverser(); $writerTraverser->addVisitor(new Converter()); $filter = new Filter($parser, $filterTraverser, $collector, $loader); $writer = new Writer($parser, $writerTraverser, new Printer()); $finder = new Finder(); $finder->files()->name('*.php'); $command = new Command(Message::COMMAND); $command->setHelp(Message::HELP); $command->setDescription(Message::NAME . ' (' . Message::VERSION . ')'); $command->setFinder($finder); $command->setFilter($filter); $command->setWriter($writer); return $command; }
/** * * @param array<AnalyzedFile> $files */ public function analyze($files) { // First we get the list of file metas $file_elements = $this->scanner->elements['files']->get_children(); foreach ($files as $file) { if ($file->get_filetype() !== 'php') { continue; } $filepath = $file->get_filepath(); if (array_key_exists($filepath, $file_elements)) { $file_element = $file_elements[$filepath]; } else { // This is not a file we can handle continue; } $visitor = new AnalyzerVisitor('ResourceElementFactory', $file_element, $this->elements); $traverser = new PhpParser\NodeTraverser(); $traverser->addVisitor($visitor); $traverser->traverse($file->get_node_tree()); } }
/** * Obfuscate a single file's contents * * @param string $source * @return string obfuscated contents **/ public function obfuscateFileContents($source, $file = false) { $traverser = new PhpParser\NodeTraverser(); if (input::get('ReplaceVariables')) { /** * all $vars */ $traverser->addVisitor(new \Controllers\Obfuscator\ScrambleVariable($this)); $traverser->addVisitor(new \Controllers\Obfuscator\ScrambleString($this)); } if (input::get('ReplaceFunctions')) { /** * all OOP functions */ $traverser->addVisitor(new \Controllers\Obfuscator\ScrambleFunction($this)); /** * all NONE OOP functions (NATIVE) */ $traverser->addVisitor(new \Controllers\Obfuscator\ScrambleNativeFunction($this)); } if (input::get('ReplaceVariables')) { /** * all OOP $this->vars */ $traverser->addVisitor(new \Controllers\Obfuscator\ScrambleProperty($this)); } //if( input::get('ReplaceSmart') ) { //$traverser->addVisitor(new \Controllers\Obfuscator\ScrambleSmart($this)); //} $parser = new Parser(new Lexer()); // traverse $stmts = $traverser->traverse($parser->parse($source)); $prettyPrinter = new PrettyPrinter(); $nodeDumper = new PhpParser\NodeDumper(); Debugbar::debug($stmts); // pretty print $code = "<?php\n" . $prettyPrinter->prettyPrint($stmts); if (Input::has('test')) { @header("Content-Type:text/plain"); print_r($this->getFuncPack()); print_r($this->getVarPack()); echo '<pre>'; echo $nodeDumper->dump($stmts), "\n"; echo htmlentities($code); echo '</pre>'; } return $code; }
/** * 净化函数处理函数 * @param funcNode $node * @return null | array(funcName,type) */ public static function SantiniFuncHandler($node, $fileSummary) { global $F_SECURES_ALL; $funcName = NodeUtils::getNodeFunctionName($node); //查看系统净化函数及已查找函数的信息 $ret = self::isSecureFunction($funcName); if ($ret[0]) { $oneFunction = new OneFunction($funcName); $oneFunction->setSanitiType($ret['type']); return $oneFunction; } else { //未查找过函数 $context = Context::getInstance(); $require_array = $fileSummary->getIncludeMap(); $path = $fileSummary->getPath(); $funcBody = $context->getClassMethodBody($funcName, $path, $require_array); if (!$funcBody) { return null; } $visitor = new SanitiFunctionVisitor(); $parser = new PhpParser\Parser(new PhpParser\Lexer\Emulative()); $traverser = new PhpParser\NodeTraverser(); $traverser->addVisitor($visitor); $visitor->funcName = $funcName; $visitor->fileSummary = $fileSummary; $traverser->traverse($funcBody->stmts); if ($visitor->sanitiInfo[0]) { //将净化函数加入净化UserSanitizeFuncContext $oneFunction = new OneFunction($funcName); $oneFunction->setSanitiType($visitor->sanitiInfo['type']); $SanitiFuncContext = UserSanitizeFuncConetxt::getInstance(); $SanitiFuncContext->addFunction($oneFunction); return $oneFunction; } else { return null; } } }
private static function rewriteContents($orig_file, $target_file, $contents) { $traverser = new \PhpParser\NodeTraverser(); $traverser->addVisitor(new SoftMocksTraverser($orig_file)); $prettyPrinter = new SoftMocksPrinter(); $parser = (new \PhpParser\ParserFactory())->create(\PhpParser\ParserFactory::PREFER_PHP7); $stmts = $parser->parse($contents); $stmts = $traverser->traverse($stmts); return $prettyPrinter->prettyPrintFile($stmts); }
$text = $comment->getText(); if (strpos($text, '@since') === false && strpos($text, '@deprecated') === false) { $this->errors[] = '@since or @deprecated tag is needed in PHPDoc for ' . $this->namespace . '\\' . $this->className . '::' . $node->name; return; } } } public function getErrors() { return $this->errors; } } echo 'Parsing all files in lib/public for the presence of @since or @deprecated on each method...' . PHP_EOL . PHP_EOL; $parser = new PhpParser\Parser(new PhpParser\Lexer()); /* iterate over all .php files in lib/public */ $Directory = new RecursiveDirectoryIterator(dirname(__DIR__) . '/lib/public'); $Iterator = new RecursiveIteratorIterator($Directory); $Regex = new RegexIterator($Iterator, '/^.+\\.php$/i', RecursiveRegexIterator::GET_MATCH); $errors = []; foreach ($Regex as $file) { $stmts = $parser->parse(file_get_contents($file[0])); $visitor = new SinceTagCheckVisitor($this->blackListedClassNames); $traverser = new \PhpParser\NodeTraverser(); $traverser->addVisitor($visitor); $traverser->traverse($stmts); $errors = array_merge($errors, $visitor->getErrors()); } if (count($errors)) { echo join(PHP_EOL, $errors) . PHP_EOL . PHP_EOL; exit(1); }
ini_set('xdebug.var_display_max_children', -1); ini_set('xdebug.var_display_max_data', -1); ini_set('xdebug.var_display_max_depth', -1); list($operations, $files) = parseArgs($argv); /* Dump nodes by default */ if (empty($operations)) { $operations[] = 'dump'; } if (empty($files)) { showHelp("Must specify at least one file."); } $parser = new PhpParser\Parser(new PhpParser\Lexer\Emulative()); $dumper = new PhpParser\NodeDumper(); $prettyPrinter = new PhpParser\PrettyPrinter\Standard(); $serializer = new PhpParser\Serializer\XML(); $traverser = new PhpParser\NodeTraverser(); $traverser->addVisitor(new PhpParser\NodeVisitor\NameResolver()); foreach ($files as $file) { if (strpos($file, '<?php') === 0) { $code = $file; echo "====> Code {$code}\n"; } else { if (!file_exists($file)) { die("File {$file} does not exist.\n"); } $code = file_get_contents($file); echo "====> File {$file}:\n"; } try { $stmts = $parser->parse($code); } catch (PhpParser\Error $e) {
/** * 生成基本块摘要,为数据流分析做准备 * 1、处理赋值语句 * 2、记录全局变量定义 * 3、记录全局变量注册 * 4、记录返回值 * 5、记录常量定义 * @param BasicBlock $block */ public function simulate($block) { //获取基本块中所有的节点 $nodes = $block->getContainedNodes(); //循环nodes集合,搜集信息加入到blocksummary中 foreach ($nodes as $node) { if ($node->getType() == 'Expr_ErrorSuppress') { $node = $node->expr; } switch ($node->getType()) { //处理赋值语句 case 'Expr_Assign': $dataFlow = new DataFlow(); $this->assignHandler($node, $block, $dataFlow, "left"); $this->assignHandler($node, $block, $dataFlow, "right"); break; //处理foreach,转换为summary中的赋值 //处理foreach,转换为summary中的赋值 case 'Stmt_Foreach': $this->foreachHandler($block, $node); break; //处理字符串连接赋值 //$sql .= "from users where"生成sql => "from users where" //处理字符串连接赋值 //$sql .= "from users where"生成sql => "from users where" case 'Expr_AssignOp_Concat': $dataFlow = new DataFlow(); $this->assignConcatHandler($node, $block, $dataFlow, "left"); $this->assignConcatHandler($node, $block, $dataFlow, "right"); break; //处理常量,加入至summary中 //应该使用define判断 //处理常量,加入至summary中 //应该使用define判断 case 'Expr_FuncCall' && NodeUtils::getNodeFunctionName($node) == "define": $this->constantHandler($node, $block, "define"); break; //处理const关键定义的常量 //处理const关键定义的常量 case 'Stmt_Const': $this->constantHandler($node, $block, "const"); break; //处理全局变量的定义,global $a //处理全局变量的定义,global $a case 'Stmt_Global': $this->globalDefinesHandler($node, $block); break; //过程内分析时记录 //过程内分析时记录 case 'Stmt_Return': $this->returnValueHandler($node, $block); break; //全局变量的注册extract,import_request_variables //识别净化值 //全局变量的注册extract,import_request_variables //识别净化值 case 'Expr_FuncCall' && (NodeUtils::getNodeFunctionName($node) == "import_request_variables" || NodeUtils::getNodeFunctionName($node) == "extract"): $this->registerGlobalHandler($node, $block); break; //如果$GLOBALS['name'] = 'xxxx' ; 则并入registerGlobal中 //如果$GLOBALS['name'] = 'xxxx' ; 则并入registerGlobal中 case 'Expr_ArrayDimFetch' && substr(NodeUtils::getNodeStringName($node), 0, 7) == "GLOBALS": $this->registerGLOBALSHandler($node, $block); break; //处理函数调用以及类方法的调用 //过程间分析以及污点分析 //处理函数调用以及类方法的调用 //过程间分析以及污点分析 case 'Expr_MethodCall': case 'Expr_Include': case 'Expr_StaticCall': case 'Stmt_Echo': case 'Expr_Print': case 'Expr_FuncCall': case 'Expr_Eval': $this->functionHandler($node, $block, $this->fileSummary); break; default: $traverser = new PhpParser\NodeTraverser(); $visitor = new nodeFunctionVisitor(); $visitor->block = $block; $visitor->fileSummary = $this->fileSummary; $visitor->cfgGen = new CFGGenerator(); $traverser->addVisitor($visitor); $traverser->traverse(array($node)); break; } } }
public function setCache() { //empty the cache folder $this->cleanFolder(); $phpbb_root_path = get_option('wpphpbbu_path', false); $phpEx = 'php'; $GLOBALS['phpbb_root_path'] = get_option('wpphpbbu_path', false); $GLOBALS['phpEx'] = 'php'; $GLOBALS['phpbb_root_path'] = $phpbb_root_path; //fix make_clickable $parser = new \PhpParser\Parser(new \PhpParser\Lexer()); $prettyPrinter = new \PhpParser\PrettyPrinter\Standard(); try { $searched_function[] = "make_clickable"; $traverser_safety = new \PhpParser\NodeTraverser(); $traverser_safety->addVisitor(new \SafeFunction($searched_function)); // parse $raw = file_get_contents($phpbb_root_path . 'includes/functions_content.' . $phpEx); $stmts = $parser->parse($raw); // traverse $stmts = $traverser_safety->traverse($stmts); // pretty print $code = $prettyPrinter->prettyPrint($stmts); file_put_contents(__DIR__ . '/cache/functions_content.' . $phpEx, '<?php ' . $code . ' ?>'); } catch (PhpParser\Error $e) { echo 'Parse Error: ', $e->getMessage(); } try { $searched_function[] = "validate_username"; $traverser_safety = new \PhpParser\NodeTraverser(); $traverser_safety->addVisitor(new \SafeFunction($searched_function)); // parse $raw = file_get_contents($phpbb_root_path . 'includes/functions_user.' . $phpEx); $stmts = $parser->parse($raw); // traverse $stmts = $traverser_safety->traverse($stmts); // pretty print $code = $prettyPrinter->prettyPrint($stmts); file_put_contents(__DIR__ . '/cache/functions_user.' . $phpEx, '<?php ' . $code . ' ?>'); } catch (\PhpParser\Error $e) { echo 'Parse Error: ', $e->getMessage(); } //unicorn code is actually useless, im bored. At least, it was a good exercise try { $traverser_path = new \PhpParser\NodeTraverser(); //dont forget to escape the path, = preq_quote? $mypath = __DIR__; $traverser_path->addVisitor(new \PathFixer("\$phpbb_root_path \\. \\'includes/functions_content.\\' \\. \$phpEx", [new \PhpParser\Node\Scalar\String_($mypath . '/cache/functions_content.'), new \PhpParser\Node\Expr\Variable('phpEx')])); //fix path to functions_content $raw = file_get_contents($phpbb_root_path . 'common.' . $phpEx); // parse $stmts = $parser->parse($raw); // traverse $stmts = $traverser_path->traverse($stmts); // pretty print $code = $prettyPrinter->prettyPrint($stmts); file_put_contents(__DIR__ . '/cache/common.' . $phpEx, '<?php ' . $code . ' ?>'); } catch (\PhpParser\Error $e) { echo 'Parse Error: ', $e->getMessage(); } }
require_once 'include/classes/config.php'; require_once 'include/classes/scrambler.php'; require_once 'include/classes/parser_extensions/my_pretty_printer.php'; require_once 'include/classes/parser_extensions/my_node_visitor.php'; require_once 'include/functions.php'; include 'include/retrieve_config_and_arguments.php'; if ($clean_mode && file_exists("{$target_directory}/yakpro-po/.yakpro-po-directory")) { if (!$conf->silent) { fprintf(STDERR, "Info:\tRemoving directory\t= [%s]%s", "{$target_directory}/yakpro-po", PHP_EOL); } remove_directory("{$target_directory}/yakpro-po"); exit; } $parser = new PhpParser\Parser(new PhpParser\Lexer\Emulative()); // $parser = new PhpParser\Parser(new PhpParser\Lexer); $traverser = new PhpParser\NodeTraverser(); if ($conf->obfuscate_string_literal) { $prettyPrinter = new myPrettyprinter(); } else { $prettyPrinter = new PhpParser\PrettyPrinter\Standard(); } $t_scrambler = array(); foreach (array('variable', 'function', 'method', 'property', 'class', 'class_constant', 'constant', 'namespace', 'label') as $dummy => $scramble_what) { $t_scrambler[$scramble_what] = new Scrambler($scramble_what, $conf, $process_mode == 'directory' ? $target_directory : null); } $traverser->addVisitor(new MyNodeVisitor()); switch ($process_mode) { case 'file': $obfuscated_str = obfuscate($source_file); if ($obfuscated_str === null) { exit;
/** * @param 包含函数的文件路径 $path * @param 函数的信息 $mehod * @return 函数体 */ public function getFunction($path, $method) { //设置code if (!$path) { return null; } $code = file_get_contents($path); //找到了相应的方法名称 if ($method && $code) { $startLine = $method['startLine']; $endLine = $method['endLine']; $parser = new PhpParser\Parser(new PhpParser\Lexer\Emulative()); $visitor = new FunctionBodyVisitor(); $traverser = new PhpParser\NodeTraverser(); $visitor->startLine = $startLine; $visitor->endLine = $endLine; $visitor->funcName = $method['name']; try { $stmts = $parser->parse($code); } catch (Exception $e) { return null; } $traverser->addVisitor($visitor); $traverser->traverse($stmts); return $visitor->getFunctionBody(); } else { return NULL; } }
/** * Parses source code and returns the built graph. * * @param array $source_paths paths containing source code. * @param bool $remove_unreferenced_nodes should nodes with no edges be pruned from the graph as well? * @return GraphBuilder built graph. */ public static function build_graph(array $source_paths, $remove_unreferenced_nodes) { $visitor = new self(); $parser = new \PhpParser\Parser(new \PhpParser\Lexer()); $traverser = new \PhpParser\NodeTraverser(); $traverser->addVisitor($visitor); foreach ($source_paths as $source_path) { foreach (walk_path(realpath($source_path), '/\\.php$/') as $file_path) { $visitor->change_file($file_path); $code = file_get_contents($file_path); try { $statements = $parser->parse($code); $traverser->traverse($statements); } catch (\PhpParser\Error $ex) { error_log("Parse Error in {$file_path}: {$ex->getMessage()}"); } } } $visitor->prune($remove_unreferenced_nodes); return $visitor; }
/** * @param ParseResult $result * * @return \PhpParser\NodeTraverser */ private function getTraverserInstance(ParseResult $result) { $traverser = new \PhpParser\NodeTraverser(); $traverser->addVisitor(new \PhpParser\NodeVisitor\NameResolver()); $traverser->addVisitor(new UnitCollectingVisitor($this->docblockParser, $result)); return $traverser; }
/** * 从传入节点中提取出包含的PHP文件名称 * @param Node $node * @return string */ public static function getNodeIncludeInfo($node) { if (!$node instanceof Node) { return null; } if ($node->getType() == "Expr_Include") { $parser = new PhpParser\Parser(new PhpParser\Lexer\Emulative()); $traverser = new PhpParser\NodeTraverser(); $visitor = new IncludeVisitor(); $traverser->addVisitor($visitor); $traverser->traverse(array($node)); foreach ($visitor->strings as $v) { if (preg_match("/.+?\\.php/i", $v)) { return $v; } } } else { return null; } }
public function leaveNode(PhpParser\Node $node) { if ($node instanceof PhpParser\Node\Stmt\Class_ || $node instanceof PhpParser\Node\Stmt\Trait_) { $this->m_numEnteredClassesOrTraits--; } else { if ($node instanceof PhpParser\Node\Stmt\Interface_) { $this->m_numEnteredInterfaces--; } else { if ($node instanceof PhpParser\Node\Stmt\ClassMethod) { $numEnteredMethods = $this->m_numEnteredMethods; $this->m_numEnteredMethods--; if (!($this->m_numEnteredClassesOrTraits == 1 && $this->m_numEnteredInterfaces == 0 && $numEnteredMethods == 1 && $this->m_numEnteredClosures == 0 && $this->m_numEnteredFunctions == 0)) { return; } $method = $node; if ($method->isProtected() && !$this->m_wrapProtectedMethods && !$this->m_isTrait || $method->isPrivate() && !$this->m_wrapPrivateMethods && !$this->m_isTrait || $method->isAbstract()) { return; } if (!isset($method->stmts) || CMap::isEmpty($method->stmts)) { return; } $hasParams = false; $params = CArray::make(); $hasParamsByRef = false; $paramsByRef = CArray::make(); if (isset($method->params) && !CMap::isEmpty($method->params)) { $hasParams = true; $params = CArray::fromPArray($method->params); $paramsByRef = CArray::filter($params, function ($param) { return $param->byRef; }); $hasParamsByRef = !CArray::isEmpty($paramsByRef); } $method->stmts[0]->setAttribute("_imFirstStmtInMethodOrFunction", true); $method->stmts[CMap::length($method->stmts) - 1]->setAttribute("_imLastStmtInMethodOrFunction", true); $statements = [$method]; $methodFirstLastStmtVisitor = new CMethodOrFunctionFirstLastStmtVisitor($hasParams, $params, $hasParamsByRef, $paramsByRef); $traverser = new PhpParser\NodeTraverser(); $traverser->addVisitor($methodFirstLastStmtVisitor); $statements = $traverser->traverse($statements); $method = $statements[0]; $returnVisitor = new CReturnVisitor($hasParams, $params, $hasParamsByRef, $paramsByRef, $method->byRef, CReturnVisitor::SUBJ_METHOD); $traverser = new PhpParser\NodeTraverser(); $traverser->addVisitor($returnVisitor); $statements = $traverser->traverse($statements); return $statements; } else { if ($node instanceof PhpParser\Node\Expr\Closure) { $this->m_numEnteredClosures--; } else { if ($node instanceof PhpParser\Node\Stmt\Function_) { $this->m_numEnteredFunctions--; } } } } } }
*/ public $int; /** * @var string */ public $string; /** * @var double */ public $double; } EOF; require 'vendor/autoload.php'; $astTraverser = new PhpParser\NodeTraverser(); $astTraverser->addVisitor(new PhpParser\NodeVisitor\NameResolver()); $parser = new PHPCfg\Parser((new ParserFactory())->create(ParserFactory::PREFER_PHP7), $astTraverser); $traverser = new PHPCfg\Traverser(); $traverser->addVisitor(new PHPCfg\Visitor\Simplifier()); $typeReconstructor = new PHPTypes\TypeReconstructor(); $dumper = new PHPCfg\Printer\Text(); $block = $parser->parse($code, __FILE__); $traverser->traverse($block); $state = new PHPTypes\State([$block]); $typeReconstructor->resolve($state); $blocks = $state->blocks; $optimizer = new PHPOptimizer\Optimizer(); //$blocks = $optimizer->optimize($blocks); function rmdir_recursive($dir) {
public function execute() { global $IP; $files = $this->getFiles(); $chunkSize = ceil(count($files) / 72); $parser = new PhpParser\Parser(new PhpParser\Lexer\Emulative()); $traverser = new PhpParser\NodeTraverser(); $finder = new DeprecatedInterfaceFinder(); $traverser->addVisitor($finder); $fileCount = count($files); for ($i = 0; $i < $fileCount; $i++) { $file = $files[$i]; $code = file_get_contents($file); if (strpos($code, '@deprecated') === -1) { continue; } $finder->setCurrentFile(substr($file->getPathname(), strlen($IP) + 1)); $nodes = $parser->parse($code, array('throwOnError' => false)); $traverser->traverse($nodes); if ($i % $chunkSize === 0) { $percentDone = 100 * $i / $fileCount; fprintf(STDERR, "\r[%-72s] %d%%", str_repeat('#', $i / $chunkSize), $percentDone); } } fprintf(STDERR, "\r[%'#-72s] 100%%\n", ''); // Colorize output if STDOUT is an interactive terminal. if (posix_isatty(STDOUT)) { $versionFmt = "\n* Deprecated since [37;1m%s[0m:\n"; $entryFmt = " %s [33;1m%s[0m (%s:%d)\n"; } else { $versionFmt = "\n* Deprecated since %s:\n"; $entryFmt = " %s %s (%s:%d)\n"; } foreach ($finder->getFoundNodes() as $version => $nodes) { printf($versionFmt, $version); foreach ($nodes as $node) { printf($entryFmt, $node['hard'] ? '+' : '-', $node['name'], $node['filename'], $node['line']); } } printf("\nlegend:\n -: soft-deprecated\n +: hard-deprecated (via wfDeprecated())\n"); }
/** * @param string $filepath * @param Parser $parser * @param Context $context */ protected function parserFile($filepath, Parser $parser, Context $context) { $context->setFilepath($filepath); $astTraverser = new \PhpParser\NodeTraverser(); $astTraverser->addVisitor(new \PhpParser\NodeVisitor\NameResolver()); try { if (!is_readable($filepath)) { throw new RuntimeException('File ' . $filepath . ' is not readable'); } $context->debug('<comment>Precompile: ' . $filepath . '.</comment>'); $code = file_get_contents($filepath); $astTree = $parser->parse($code); $astTraverser->traverse($astTree); $aliasManager = new AliasManager(); $namespace = null; /** * Step 1 Precompile */ foreach ($astTree as $topStatement) { if ($topStatement instanceof Node\Stmt\Namespace_) { /** * Namespace block can be created without NS name */ if ($topStatement->name) { $namespace = $topStatement->name->toString(); $aliasManager->setNamespace($namespace); } if ($topStatement->stmts) { $this->parseTopDefinitions($topStatement->stmts, $aliasManager, $filepath); } } else { $this->parseTopDefinitions($topStatement, $aliasManager, $filepath); } } /** * Another Traverser to handler Analyzer Passe(s) */ $analyzeTraverser = new AstTraverser([new \PHPSA\Node\Visitor\FunctionCall()], $context); $analyzeTraverser->traverse($astTree); $context->clear(); } catch (\PhpParser\Error $e) { $context->sytaxError($e, $filepath); } catch (Exception $e) { $context->output->writeln("<error>{$e->getMessage()}</error>"); } }