/**
  * 得到一个文件基本信息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;
 }
 /**
  * 初始化fileSummaryContext
  * @param string $project_path
  */
 private function initFileSummaryContext($project_path, $allFiles)
 {
     global $project_path;
     $fileName = str_replace('/', '_', $project_path);
     $fileName = str_replace(':', '_', $fileName);
     $serialPath = CURR_PATH . "/data/fileSummaryConetxtSerialData/" . $fileName;
     if (!is_file($serialPath)) {
         //创建文件
         $fileHandler = fopen($serialPath, 'w');
         fclose($fileHandler);
     }
     //判断本地序列化文件中是否存在UserSanitizeFuncConetxt
     if (($serial_str = file_get_contents($serialPath)) != '') {
         $fileSummaryMap = unserialize($serial_str);
         $fileSummaryContext = FileSummaryContext::getInstance();
         $fileSummaryContext->setFileSummaryMap($fileSummaryMap);
         return;
     }
     //没有序列化,则获取fileSummary
     $fileSummaryContext = FileSummaryContext::getInstance();
     foreach ($allFiles as $fileAbsPath) {
         $ret = FileSummaryGenerator::getFileSummary($fileAbsPath);
         if ($ret) {
             $fileSummaryContext->addSummaryToMap($ret);
         }
     }
     //对FileSummaryContext进行序列化,加快下次读取速度
     $this->serializeContext($serialPath, $fileSummaryContext->getFileSummaryMap());
 }
 private static function sanitiSameVarMultiFileHandler($varName, $block, $dataFlows, $fileSummary)
 {
     $includeFileSummaryMap = FileSummaryGenerator::getIncludeFilesDataFlows($fileSummary);
     if (!$includeFileSummaryMap) {
         return array(false);
     }
     $includeFileSummaryMap = array_reverse($includeFileSummaryMap);
     foreach ($includeFileSummaryMap as $includeFileSummary) {
         if (!$includeFileSummary instanceof FileSummary) {
             continue;
         }
         $fileDataFlows = $includeFileSummary->getFlowsMap();
         $fileDataFlows = array_reverse($fileDataFlows);
         foreach ($fileDataFlows as $flow) {
             if ($flow->getName() == $varName) {
                 if ($flow->getlocation()) {
                     $ret = $flow->getlocation()->getSanitization();
                     if ($ret) {
                         return array(true, 'funcs' => $ret);
                     } else {
                         return array(false);
                     }
                 }
             }
         }
     }
 }
 /**
  * 多文件间分析
  * @param BasicBlock $block  当前基本块
  * @param string $argName 漏洞变量
  * @param Node $node 调用sink的node
  * @param array $fileSummaryMap 要分析的require文件的summary的list
  */
 public function multiFileHandler($block, $argName, $node, $fileSummary, $flowNum = 0)
 {
     //首先根据fileSummary获取到fileSummaryMap
     $fileSummaryMap = FileSummaryGenerator::getIncludeFilesDataFlows($fileSummary);
     if (!$fileSummaryMap) {
         return;
     }
     $node_path = $fileSummary->getPath();
     foreach ($fileSummaryMap as $fsummary) {
         if ($fsummary instanceof FileSummary) {
             $flows = $fsummary->getFlowsMap();
             $tempNum = $flowNum;
             while ($tempNum) {
                 $tempNum--;
                 array_shift($flows);
             }
             foreach ($flows as $flow) {
                 $flowNum++;
                 if ($flow->getName() == $argName) {
                     //处理净化信息,如果被编码或者净化则返回safe
                     //被isSanitization函数取代
                     if (is_object($flow->getLocation())) {
                         $target = $flow->getLocation();
                         $type = TypeUtils::getTypeByFuncName(NodeUtils::getNodeFunctionName($node));
                         $encodingArr = $target->getEncoding();
                         $saniArr = $target->getSanitization();
                         $res = $this->isSanitization($type, $target, $saniArr, $encodingArr);
                         if ($res == true) {
                             return "safe";
                         }
                     }
                     //获取flow中的右边赋值变量
                     //得到flow->getValue()的变量node
                     //$sql = $a . $b ;  =>  array($a,$b)
                     $vars = $this->getVarsByFlow($flow);
                     foreach ($vars as $var) {
                         $varName = $this->getVarName($var);
                         //如果var右边有source项
                         if (in_array($varName, $this->sourcesArr)) {
                             //报告漏洞
                             $var_path = $fsummary->getPath();
                             $this->report($node_path, $var_path, $node, $flow->getLocation(), $type);
                         }
                     }
                 }
             }
         }
     }
 }