*/ final class SandboxNodeVisitor extends AbstractNodeVisitor { private $inAModule = false; private $tags; private $filters; private $functions; private $needsToStringWrap = false; protected function doEnterNode(Node $node, Environment $env) { if ($node instanceof ModuleNode) { $this->inAModule = true; $this->tags = []; $this->filters = []; $this->functions = []; return $node; } elseif ($this->inAModule) { // look for tags if ($node->getNodeTag() && !isset($this->tags[$node->getNodeTag()])) { $this->tags[$node->getNodeTag()] = $node; } // look for filters if ($node instanceof FilterExpression && !isset($this->filters[$node->getNode('filter')->getAttribute('value')])) { $this->filters[$node->getNode('filter')->getAttribute('value')] = $node; } // look for functions if ($node instanceof FunctionExpression && !isset($this->functions[$node->getAttribute('name')])) { $this->functions[$node->getAttribute('name')] = $node; } // the .. operator is equivalent to the range() function if ($node instanceof RangeBinary && !isset($this->functions['range'])) { $this->functions['range'] = $node; } if ($node instanceof PrintNode) { $this->needsToStringWrap = true; $this->wrapNode($node, 'expr'); } if ($node instanceof SetNode && !$node->getAttribute('capture')) { $this->needsToStringWrap = true; } // wrap outer nodes that can implicitly call __toString() if ($this->needsToStringWrap) { if ($node instanceof ConcatBinary) { $this->wrapNode($node, 'left'); $this->wrapNode($node, 'right'); } if ($node instanceof FilterExpression) { $this->wrapNode($node, 'node'); $this->wrapArrayNode($node, 'arguments'); } if ($node instanceof FunctionExpression) { $this->wrapArrayNode($node, 'arguments'); } } } return $node; } protected function doLeaveNode(Node $node, Environment $env) { if ($node instanceof ModuleNode) { $this->inAModule = false; $node->setNode('constructor_end', new Node([new CheckSecurityCallNode(), $node->getNode('constructor_end')])); $node->setNode('class_end', new Node([new CheckSecurityNode($this->filters, $this->tags, $this->functions), $node->getNode('class_end')])); } elseif ($this->inAModule) { if ($node instanceof PrintNode || $node instanceof SetNode) { $this->needsToStringWrap = false; } } return $node; } private function wrapNode(Node $node, string $name) { $expr = $node->getNode($name); if ($expr instanceof NameExpression || $expr instanceof GetAttrExpression) { $node->setNode($name, new CheckToStringNode($expr)); } } private function wrapArrayNode(Node $node, string $name) { $args = $node->getNode($name); foreach ($args as $name => $_) { $this->wrapNode($args, $name); } } public function getPriority() { return 0; } } __halt_compiler();----SIGNATURE:----jlazGyMFi01jAena6xwkE+Nmv7wslq1Y+gZtnOQaR9ggPI90vwPga8t/kUTgeUHrC8hp+g9ZVRCkd6psfNZg1pwFaepCbUg55jN+5FO2V5BDLQ8+S6ieloCfjfB9smlV5RVY2cXkWCmkFtZ78bd0W5IAKQXxtjsbcBSX9Vy7Gyxh0kKOlpqaTOF7qDY6X+7TCMOTf6oJXhJ9AVywqLSrTc4z89uVTiWat2ckkZd77lWHhZWK98TQBMkzdGls0d9ewCK3RuSDjkCBbsvCxz8IARJHZLZ3Y35akqX/b1BFCjkEQyL+8Mh2oRHjfUaTOcqoYQ8D4XB4TPZKSoH4VdLbvI7FVMGI/kmM7yoiNPmfzBsd5817TP2sx4Q6W+/XcGnkPlLBBNFazbvq618JrfwPPTVrlI2HgK3lfABkJr9PH14gGMVTaB2G2cE/P7lgtnBsFmQGhE8cJiNPk98CN1AZ0jZbUBJDzbZ0CQS79+LuxGL7CRGLQxaxBi71rsshrBIExdp2tCedleVRdhDYfiBix5KS/NZxJ1hCyvMf5kTKYvx2vG13u+M0vx/b89Qf/ukJ2y/GUD1yHx1ZVMujqyYNNI7epzrTOrpP75zSVOe/EgbSQgD2bGYFc5BDgzWRFEa0ZUZqvAAHSP2COXb3L3euSKQkVXTH9+4n7UQhfcdGy0c=----ATTACHMENT:----MTg0MjA4NjI0NzY5Njk1NyA5OTQ4ODgwOTQwNjM0OTc5IDcxMzQxNTk5MTE2ODE3ODc=