diff --git a/RevPHPNodeVisitor.php b/RevPHPNodeVisitor.php index 858976c..04c9839 100644 --- a/RevPHPNodeVisitor.php +++ b/RevPHPNodeVisitor.php @@ -171,6 +171,12 @@ public function findValue(PhpParser\Node $node, &$value) { } else { } } else + if ($node instanceof PhpParser\Node\Expr\BinaryOp\BitwiseXor) { + if ($this->xorStrings($node, $value)) { + $found_value = TRUE; + } else { + } + } else if ($node instanceof PhpParser\Node\Expr\Variable) { $variable_value = null; if ($node->name instanceof PhpParser\Node) @@ -276,6 +282,10 @@ public function findName(PhpParser\Node $node, &$varname) { if ($this->concatStrings($node, $varname)) $found_string = TRUE; } else + if ($node instanceof PhpParser\Node\Expr\BinaryOp\BitwiseXor) { + if ($this->xorStrings($node, $varname)) + $found_string = TRUE; + } else if ($node instanceof PhpParser\Node\Scalar\String_) { $varname = $node->value; # XXX - ??? $found_string = TRUE; @@ -317,7 +327,7 @@ public function findName(PhpParser\Node $node, &$varname) { $varname = $node->name; $found_string = TRUE; } else { - debug_print_backtrace(); + ob_start(); debug_print_backtrace(); fwrite(STDERR, rtrim(ob_get_clean() ?: "failed to dump backtrace") . PHP_EOL); } } else if ($node instanceof PhpParser\Node\Expr\List_) { @@ -334,7 +344,7 @@ public function findName(PhpParser\Node $node, &$varname) { # Something dreadfully wrong. This is pretty much the # very last thing it could be. fwrite(STDERR, "Problem in findName(), no name, line {$node->getLine()}: ".print_r($node, TRUE)."\n"); - debug_print_backtrace(); + ob_start(); debug_print_backtrace(); fwrite(STDERR, rtrim(ob_get_clean() ?: "failed to dump backtrace") . PHP_EOL); } } #fwrite(STDERR, "leave findName, {$node->getType()}, name: \"$varname\"\n"); @@ -393,6 +403,26 @@ public function concatStrings(PhpParser\Node\Expr\BinaryOp\Concat $concat, &$con return $found_string; } + public function xorStrings(PhpParser\Node\Expr\BinaryOp\BitwiseXor $xorstring, &$xoredstring) { + $found_string = FALSE; + if ($this->findValue($xorstring->left, $leftstring) + && $this->findValue($xorstring->right, $rightstring)) { + $xoredstring = $leftstring ^ $rightstring; + $found_string = TRUE; + } else { + # Replace left or right nodes with statically-determinable values, if possible + if ($this->findValue($xorstring->left, $leftvalue)) { + if (is_string($leftvalue)) + $xorstring->left = $this->newNodeAsType($leftvalue, false); + } + if ($this->findValue($xorstring->right, $rightvalue)) { + if (is_string($rightvalue)) + $xorstring->right = $this->newNodeAsType($rightvalue, false); + } + } + return $found_string; + } + public function enterNode(PhpParser\Node $node) { if ($node instanceof PhpParser\Node\Stmt\Function_) { $this->symtbl->pushScope(); @@ -826,6 +856,31 @@ public function leaveNode(PhpParser\Node $node) { $node->left = $this->newNodeAsType($leftvalue, false); } } else + if ($node instanceof PhpParser\Node\Expr\BinaryOp\BitwiseXor) { + # Roll up any substrings. This can be computationally inefficient. + $left_is_string = false; + if ($this->findValue($node->left, $leftvalue)) { + if (is_string($leftvalue)) + $left_is_string = true; + } + if ($this->findValue($node->right, $rightvalue)) { + if (is_string($rightvalue)) { + if ($node->left instanceof PhpParser\Node\Expr\BinaryOp\BitwiseXor) { + if ($this->findValue($node->left->right, $othervalue)) { + if (is_string($othervalue)) { + $node->right = $this->newNodeAsType($othervalue ^ $rightvalue); + $node->left = $node->left->left; + } + } + } else { + $node->right = $this->newNodeAsType($rightvalue, false); + } + } + } else { + if ($left_is_string) + $node->left = $this->newNodeAsType($leftvalue, false); + } + } else if ($node instanceof PhpParser\Node\Stmt\Function_) { $this->substituteFunctionName($node); $this->symtbl->popScope(); diff --git a/SymbolTable.php b/SymbolTable.php index c4f31da..b6d592a 100644 --- a/SymbolTable.php +++ b/SymbolTable.php @@ -115,11 +115,11 @@ public function isSymbol($candidate_string) { public function globalSymbolValue($name, &$value) { $found_value = FALSE; if (is_object($name)) { - debug_print_backtrace(); + ob_start(); debug_print_backtrace(); fwrite(STDERR, rtrim(ob_get_clean() ?: "failed to dump backtrace") . PHP_EOL); } #fwrite(STDERR, "+++++\nglobalSymbolValue: ".print_r($name, TRUE)."\n-------\n"); if (!is_string($name) && !is_int($name)) { - debug_print_backtrace(); + ob_start(); debug_print_backtrace(); fwrite(STDERR, rtrim(ob_get_clean() ?: "failed to dump backtrace") . PHP_EOL); fwrite(STDERR, "Bad array name in globalSymbolValue:\n"); fwrite(STDERR, print_r($name, true)); }