Exemplo n.º 1
0
 static function construct_cfg($stmts)
 {
     $prettyPrinter = new PhpParser\PrettyPrinter\Standard();
     // Creating an empty entry node.
     $cfg = new CFG();
     $entry = new CFGNode();
     $cfg->entry = $entry;
     $current_node = $entry;
     foreach ($stmts as $stmt) {
         print "Processing statement:\n";
         printStmts(array($stmt));
         // Assignment statement.
         if ($stmt instanceof PhpParser\Node\Expr\Assign) {
             print "Found assignment statement\n";
             $assign_node = CFG::processExprAssign($stmt);
             $current_node->successors[] = $assign_node;
             $assign_node->parents[] = $current_node;
             $current_node = $assign_node;
             print "Constructed assignment node\n";
         } else {
             if ($stmt instanceof PhpParser\Node\Expr\AssignOp) {
                 print "Found assignment with operation statement\n";
                 $assign_op_node = CFG::processExprAssignOp($stmt);
                 $current_node->successors[] = $assign_op_node;
                 $assign_op_node->parents[] = $current_node;
                 $current_node = $assign_op_node;
                 print "Constructed assignment with operation node\n";
             } else {
                 if ($stmt instanceof PhpParser\Node\Expr\PreDec) {
                     print "Found a pre-decrement expression\n";
                     $predec_node = CFG::processExprPreDec($stmt);
                     $current_node->successors[] = $predec_node;
                     $predec_node->parents[] = $current_node;
                     $current_node = $predec_node;
                     print "Constructed pre-decrement expression.\n";
                 } else {
                     if ($stmt instanceof PhpParser\Node\Stmt\Unset_) {
                         print "Found unset statement\n";
                         $unset_node = CFG::processStmtUnset($stmt);
                         $current_node->successors[] = $unset_node;
                         $unset_node->parents[] = $current_node;
                         $current_node = $unset_node;
                         print "Constructed unset node\n";
                     } else {
                         if ($stmt instanceof PhpParser\Node\Stmt\Global_) {
                             print "Found global statement\n";
                             $global_node = CFG::processStmtGlobal($stmt);
                             $current_node->successors[] = $global_node;
                             $global_node->parents[] = $current_node;
                             $current_node = $global_node;
                             print "Constructed global node\n";
                         } else {
                             if ($stmt instanceof PhpParser\Node\Stmt\Break_) {
                                 print "Found break statement\n";
                                 $break_node = CFG::processStmtBreak($stmt);
                                 $current_node->successors[] = $break_node;
                                 $break_node->parents[] = $current_node;
                                 $current_node = $break_node;
                                 print "Constructed break node\n";
                             } else {
                                 if ($stmt instanceof PhpParser\Node\Stmt\Return_) {
                                     print "Found return statement\n";
                                     $return_node = CFG::processStmtReturn($stmt);
                                     $current_node->successors[] = $return_node;
                                     $return_node->parents[] = $current_node;
                                     $current_node = $return_node;
                                     print "Constructed return node\n";
                                 } else {
                                     if ($stmt instanceof PhpParser\Node\Stmt\If_) {
                                         // Note: What happens on if-elsif-elsif-else ?
                                         print "Found conditional statement\n";
                                         $if_nodes = CFG::processStmtIf($stmt);
                                         // Connect the current node with the
                                         // conditional node of the if.
                                         $current_node->successors[] = $if_nodes[0];
                                         // The previously processed node is the parent of
                                         // the conditional node.
                                         $if_nodes[0]->parents[] = $current_node;
                                         // Make the current node, the node that
                                         // joins the branches of the if.
                                         $current_node = $if_nodes[1];
                                         print "Constructed conditional node\n";
                                         // Method call statement.
                                     } else {
                                         if ($stmt instanceof PhpParser\Node\Expr\MethodCall) {
                                             print "Found method call statement\n";
                                             $method_call_node = CFG::processExprMethodCall($stmt);
                                             $current_node->successors[] = $method_call_node;
                                             $method_call_node->parents[] = $current_node;
                                             $current_node = $method_call_node;
                                             print "Constructed method call node\n";
                                             // Function call statement.
                                         } else {
                                             if ($stmt instanceof PhpParser\Node\Expr\FuncCall) {
                                                 print "Found function call statement\n";
                                                 $function_call_node = CFG::processExprFuncCall($stmt);
                                                 $current_node->successors[] = $function_call_node;
                                                 $function_call_node->parents[] = $current_node;
                                                 $current_node = $function_call_node;
                                                 print "Constructed function call node\n";
                                                 // Static function call statement.
                                             } else {
                                                 if ($stmt instanceof PhpParser\Node\Expr\StaticCall) {
                                                     print "Found static call statement\n";
                                                     $static_call_node = CFG::processExprStaticCall($stmt);
                                                     $current_node->successors[] = $static_call_node;
                                                     $static_call_node->parents[] = $current_node;
                                                     $current_node = $static_call_node;
                                                     print "Constructed static call node\n";
                                                     // Loops: Foreach, For or While statement.
                                                 } else {
                                                     if ($stmt instanceof PhpParser\Node\Stmt\Foreach_ || $stmt instanceof PhpParser\Node\Stmt\For_ || $stmt instanceof PhpParser\Node\Stmt\While_) {
                                                         print "Found " . gettype($stmt) . " statement\n";
                                                         // Returns a pair with the loop header
                                                         // and a dummy exit node that follows the
                                                         // loop.
                                                         $loop_nodes = CFG::processStmtLoop($stmt);
                                                         // Connect the current node to the loop header.
                                                         $current_node->successors[] = $loop_nodes[0];
                                                         $loop_nodes[0]->parents[] = $current_node;
                                                         // Make the dummy exit node of the loop
                                                         // the current node.
                                                         $current_node = $loop_nodes[1];
                                                         print "Constructed " . gettype($stmt) . " node\n";
                                                     } else {
                                                         print "WARNING: Couldn't construct CFG node.\n";
                                                         print "The statement is of class " . get_class($stmt) . "\n";
                                                         print "Has keys\n";
                                                         /*
                                                         		  	  foreach($stmt as $key => $value) {
                                                         	print "Key=".($key)."\n";
                                                         		   	  }
                                                         */
                                                         // Constructing dummy node.
                                                         $dummy_node = new CFGNode();
                                                         $current_node->successors[] = $dummy_node;
                                                         $dummy_node->parents[] = $current_node;
                                                         $current_node = $dummy_node;
                                                     }
                                                 }
                                             }
                                         }
                                     }
                                 }
                             }
                         }
                     }
                 }
             }
         }
     }
     // Create a dummy exit node, and make a pointer
     // from the last processed node to the exit node.
     $cfg->exit = new CFGNode();
     $current_node->successors[] = $cfg->exit;
     $cfg->exit->parents[] = $current_node;
     return $cfg;
 }