diff options
| author | Benjamin Southall <applemansigloo@gmail.com> | 2019-02-26 10:11:12 +1000 |
|---|---|---|
| committer | Benjamin Southall <applemansigloo@gmail.com> | 2019-02-26 10:11:12 +1000 |
| commit | f79395851b044689567e0e6c9504acbcaa742782 (patch) | |
| tree | ee539aee9ffa90e8accd6f130b30a8ebed7a232e /inc/lib/Twig/NodeVisitor | |
| parent | 28f32baf0125ca5085266e73dc5071e5814d8e3b (diff) | |
Twig update to latest Twig 1.x legacy as per vichan
Diffstat (limited to 'inc/lib/Twig/NodeVisitor')
| -rw-r--r-- | inc/lib/Twig/NodeVisitor/Escaper.php | 39 | ||||
| -rw-r--r-- | inc/lib/Twig/NodeVisitor/Optimizer.php | 101 | ||||
| -rw-r--r-- | inc/lib/Twig/NodeVisitor/SafeAnalysis.php | 43 | ||||
| -rw-r--r-- | inc/lib/Twig/NodeVisitor/Sandbox.php | 52 |
4 files changed, 118 insertions, 117 deletions
diff --git a/inc/lib/Twig/NodeVisitor/Escaper.php b/inc/lib/Twig/NodeVisitor/Escaper.php index cc4b3d71..1a1ae66f 100644 --- a/inc/lib/Twig/NodeVisitor/Escaper.php +++ b/inc/lib/Twig/NodeVisitor/Escaper.php @@ -3,7 +3,7 @@ /* * This file is part of Twig. * - * (c) 2009 Fabien Potencier + * (c) Fabien Potencier * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. @@ -12,9 +12,11 @@ /** * Twig_NodeVisitor_Escaper implements output escaping. * + * @final + * * @author Fabien Potencier <fabien@symfony.com> */ -class Twig_NodeVisitor_Escaper implements Twig_NodeVisitorInterface +class Twig_NodeVisitor_Escaper extends Twig_BaseNodeVisitor { protected $statusStack = array(); protected $blocks = array(); @@ -28,21 +30,14 @@ class Twig_NodeVisitor_Escaper implements Twig_NodeVisitorInterface $this->safeAnalysis = new Twig_NodeVisitor_SafeAnalysis(); } - /** - * Called before child nodes are visited. - * - * @param Twig_NodeInterface $node The node to visit - * @param Twig_Environment $env The Twig environment instance - * - * @return Twig_NodeInterface The modified node - */ - public function enterNode(Twig_NodeInterface $node, Twig_Environment $env) + protected function doEnterNode(Twig_Node $node, Twig_Environment $env) { if ($node instanceof Twig_Node_Module) { - if ($env->hasExtension('escaper') && $defaultStrategy = $env->getExtension('escaper')->getDefaultStrategy($node->getAttribute('filename'))) { + if ($env->hasExtension('Twig_Extension_Escaper') && $defaultStrategy = $env->getExtension('Twig_Extension_Escaper')->getDefaultStrategy($node->getTemplateName())) { $this->defaultStrategy = $defaultStrategy; } $this->safeVars = array(); + $this->blocks = array(); } elseif ($node instanceof Twig_Node_AutoEscape) { $this->statusStack[] = $node->getAttribute('value'); } elseif ($node instanceof Twig_Node_Block) { @@ -54,19 +49,12 @@ class Twig_NodeVisitor_Escaper implements Twig_NodeVisitorInterface return $node; } - /** - * Called after child nodes are visited. - * - * @param Twig_NodeInterface $node The node to visit - * @param Twig_Environment $env The Twig environment instance - * - * @return Twig_NodeInterface The modified node - */ - public function leaveNode(Twig_NodeInterface $node, Twig_Environment $env) + protected function doLeaveNode(Twig_Node $node, Twig_Environment $env) { if ($node instanceof Twig_Node_Module) { $this->defaultStrategy = false; $this->safeVars = array(); + $this->blocks = array(); } elseif ($node instanceof Twig_Node_Expression_Filter) { return $this->preEscapeFilterNode($node, $env); } elseif ($node instanceof Twig_Node_Print) { @@ -98,7 +86,7 @@ class Twig_NodeVisitor_Escaper implements Twig_NodeVisitorInterface return new $class( $this->getEscaperFilter($type, $expression), - $node->getLine() + $node->getTemplateLine() ); } @@ -150,18 +138,17 @@ class Twig_NodeVisitor_Escaper implements Twig_NodeVisitorInterface protected function getEscaperFilter($type, Twig_NodeInterface $node) { - $line = $node->getLine(); + $line = $node->getTemplateLine(); $name = new Twig_Node_Expression_Constant('escape', $line); $args = new Twig_Node(array(new Twig_Node_Expression_Constant((string) $type, $line), new Twig_Node_Expression_Constant(null, $line), new Twig_Node_Expression_Constant(true, $line))); return new Twig_Node_Expression_Filter($node, $name, $args, $line); } - /** - * {@inheritdoc} - */ public function getPriority() { return 0; } } + +class_alias('Twig_NodeVisitor_Escaper', 'Twig\NodeVisitor\EscaperNodeVisitor', false); diff --git a/inc/lib/Twig/NodeVisitor/Optimizer.php b/inc/lib/Twig/NodeVisitor/Optimizer.php index a254def7..c55e40ff 100644 --- a/inc/lib/Twig/NodeVisitor/Optimizer.php +++ b/inc/lib/Twig/NodeVisitor/Optimizer.php @@ -3,7 +3,7 @@ /* * This file is part of Twig. * - * (c) 2010 Fabien Potencier + * (c) Fabien Potencier * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. @@ -17,48 +17,46 @@ * You can configure which optimizations you want to activate via the * optimizer mode. * + * @final + * * @author Fabien Potencier <fabien@symfony.com> */ -class Twig_NodeVisitor_Optimizer implements Twig_NodeVisitorInterface +class Twig_NodeVisitor_Optimizer extends Twig_BaseNodeVisitor { - const OPTIMIZE_ALL = -1; - const OPTIMIZE_NONE = 0; - const OPTIMIZE_FOR = 2; - const OPTIMIZE_RAW_FILTER = 4; - const OPTIMIZE_VAR_ACCESS = 8; + const OPTIMIZE_ALL = -1; + const OPTIMIZE_NONE = 0; + const OPTIMIZE_FOR = 2; + const OPTIMIZE_RAW_FILTER = 4; + const OPTIMIZE_VAR_ACCESS = 8; protected $loops = array(); + protected $loopsTargets = array(); protected $optimizers; protected $prependedNodes = array(); protected $inABody = false; /** - * Constructor. - * - * @param integer $optimizers The optimizer mode + * @param int $optimizers The optimizer mode */ public function __construct($optimizers = -1) { - if (!is_int($optimizers) || $optimizers > 2) { + if (!is_int($optimizers) || $optimizers > (self::OPTIMIZE_FOR | self::OPTIMIZE_RAW_FILTER | self::OPTIMIZE_VAR_ACCESS)) { throw new InvalidArgumentException(sprintf('Optimizer mode "%s" is not valid.', $optimizers)); } $this->optimizers = $optimizers; } - /** - * {@inheritdoc} - */ - public function enterNode(Twig_NodeInterface $node, Twig_Environment $env) + protected function doEnterNode(Twig_Node $node, Twig_Environment $env) { if (self::OPTIMIZE_FOR === (self::OPTIMIZE_FOR & $this->optimizers)) { $this->enterOptimizeFor($node, $env); } - if (!version_compare(phpversion(), '5.4.0RC1', '>=') && self::OPTIMIZE_VAR_ACCESS === (self::OPTIMIZE_VAR_ACCESS & $this->optimizers) && !$env->isStrictVariables() && !$env->hasExtension('sandbox')) { + if (PHP_VERSION_ID < 50400 && self::OPTIMIZE_VAR_ACCESS === (self::OPTIMIZE_VAR_ACCESS & $this->optimizers) && !$env->isStrictVariables() && !$env->hasExtension('Twig_Extension_Sandbox')) { if ($this->inABody) { if (!$node instanceof Twig_Node_Expression) { - if (get_class($node) !== 'Twig_Node') { + if ('Twig_Node' !== get_class($node)) { array_unshift($this->prependedNodes, array()); } } else { @@ -72,10 +70,7 @@ class Twig_NodeVisitor_Optimizer implements Twig_NodeVisitorInterface return $node; } - /** - * {@inheritdoc} - */ - public function leaveNode(Twig_NodeInterface $node, Twig_Environment $env) + protected function doLeaveNode(Twig_Node $node, Twig_Environment $env) { $expression = $node instanceof Twig_Node_Expression; @@ -89,14 +84,14 @@ class Twig_NodeVisitor_Optimizer implements Twig_NodeVisitorInterface $node = $this->optimizePrintNode($node, $env); - if (self::OPTIMIZE_VAR_ACCESS === (self::OPTIMIZE_VAR_ACCESS & $this->optimizers) && !$env->isStrictVariables() && !$env->hasExtension('sandbox')) { + if (self::OPTIMIZE_VAR_ACCESS === (self::OPTIMIZE_VAR_ACCESS & $this->optimizers) && !$env->isStrictVariables() && !$env->hasExtension('Twig_Extension_Sandbox')) { if ($node instanceof Twig_Node_Body) { $this->inABody = false; } elseif ($this->inABody) { - if (!$expression && get_class($node) !== 'Twig_Node' && $prependedNodes = array_shift($this->prependedNodes)) { + if (!$expression && 'Twig_Node' !== get_class($node) && $prependedNodes = array_shift($this->prependedNodes)) { $nodes = array(); foreach (array_unique($prependedNodes) as $name) { - $nodes[] = new Twig_Node_SetTemp($name, $node->getLine()); + $nodes[] = new Twig_Node_SetTemp($name, $node->getTemplateLine()); } $nodes[] = $node; @@ -108,12 +103,12 @@ class Twig_NodeVisitor_Optimizer implements Twig_NodeVisitorInterface return $node; } - protected function optimizeVariables($node, $env) + protected function optimizeVariables(Twig_NodeInterface $node, Twig_Environment $env) { if ('Twig_Node_Expression_Name' === get_class($node) && $node->isSimple()) { $this->prependedNodes[0][] = $node->getAttribute('name'); - return new Twig_Node_Expression_TempName($node->getAttribute('name'), $node->getLine()); + return new Twig_Node_Expression_TempName($node->getAttribute('name'), $node->getTemplateLine()); } return $node; @@ -126,22 +121,22 @@ class Twig_NodeVisitor_Optimizer implements Twig_NodeVisitorInterface * * * "echo $this->render(Parent)Block()" with "$this->display(Parent)Block()" * - * @param Twig_NodeInterface $node A Node - * @param Twig_Environment $env The current Twig environment + * @return Twig_NodeInterface */ - protected function optimizePrintNode($node, $env) + protected function optimizePrintNode(Twig_NodeInterface $node, Twig_Environment $env) { if (!$node instanceof Twig_Node_Print) { return $node; } + $exprNode = $node->getNode('expr'); if ( - $node->getNode('expr') instanceof Twig_Node_Expression_BlockReference || - $node->getNode('expr') instanceof Twig_Node_Expression_Parent + $exprNode instanceof Twig_Node_Expression_BlockReference || + $exprNode instanceof Twig_Node_Expression_Parent ) { - $node->getNode('expr')->setAttribute('output', true); + $exprNode->setAttribute('output', true); - return $node->getNode('expr'); + return $exprNode; } return $node; @@ -150,10 +145,9 @@ class Twig_NodeVisitor_Optimizer implements Twig_NodeVisitorInterface /** * Removes "raw" filters. * - * @param Twig_NodeInterface $node A Node - * @param Twig_Environment $env The current Twig environment + * @return Twig_NodeInterface */ - protected function optimizeRawFilter($node, $env) + protected function optimizeRawFilter(Twig_NodeInterface $node, Twig_Environment $env) { if ($node instanceof Twig_Node_Expression_Filter && 'raw' == $node->getNode('filter')->getAttribute('value')) { return $node->getNode('node'); @@ -164,16 +158,15 @@ class Twig_NodeVisitor_Optimizer implements Twig_NodeVisitorInterface /** * Optimizes "for" tag by removing the "loop" variable creation whenever possible. - * - * @param Twig_NodeInterface $node A Node - * @param Twig_Environment $env The current Twig environment */ - protected function enterOptimizeFor($node, $env) + protected function enterOptimizeFor(Twig_NodeInterface $node, Twig_Environment $env) { if ($node instanceof Twig_Node_For) { // disable the loop variable by default $node->setAttribute('with_loop', false); array_unshift($this->loops, $node); + array_unshift($this->loopsTargets, $node->getNode('value_target')->getAttribute('name')); + array_unshift($this->loopsTargets, $node->getNode('key_target')->getAttribute('name')); } elseif (!$this->loops) { // we are outside a loop return; @@ -183,9 +176,15 @@ class Twig_NodeVisitor_Optimizer implements Twig_NodeVisitorInterface // the loop variable is referenced for the current loop elseif ($node instanceof Twig_Node_Expression_Name && 'loop' === $node->getAttribute('name')) { + $node->setAttribute('always_defined', true); $this->addLoopToCurrent(); } + // optimize access to loop targets + elseif ($node instanceof Twig_Node_Expression_Name && in_array($node->getAttribute('name'), $this->loopsTargets)) { + $node->setAttribute('always_defined', true); + } + // block reference elseif ($node instanceof Twig_Node_BlockReference || $node instanceof Twig_Node_Expression_BlockReference) { $this->addLoopToCurrent(); @@ -196,6 +195,16 @@ class Twig_NodeVisitor_Optimizer implements Twig_NodeVisitorInterface $this->addLoopToAll(); } + // include function without the with_context=false parameter + elseif ($node instanceof Twig_Node_Expression_Function + && 'include' === $node->getAttribute('name') + && (!$node->getNode('arguments')->hasNode('with_context') + || false !== $node->getNode('arguments')->getNode('with_context')->getAttribute('value') + ) + ) { + $this->addLoopToAll(); + } + // the loop variable is referenced via an attribute elseif ($node instanceof Twig_Node_Expression_GetAttr && (!$node->getNode('attribute') instanceof Twig_Node_Expression_Constant @@ -213,14 +222,13 @@ class Twig_NodeVisitor_Optimizer implements Twig_NodeVisitorInterface /** * Optimizes "for" tag by removing the "loop" variable creation whenever possible. - * - * @param Twig_NodeInterface $node A Node - * @param Twig_Environment $env The current Twig environment */ - protected function leaveOptimizeFor($node, $env) + protected function leaveOptimizeFor(Twig_NodeInterface $node, Twig_Environment $env) { if ($node instanceof Twig_Node_For) { array_shift($this->loops); + array_shift($this->loopsTargets); + array_shift($this->loopsTargets); } } @@ -236,11 +244,10 @@ class Twig_NodeVisitor_Optimizer implements Twig_NodeVisitorInterface } } - /** - * {@inheritdoc} - */ public function getPriority() { return 255; } } + +class_alias('Twig_NodeVisitor_Optimizer', 'Twig\NodeVisitor\OptimizerNodeVisitor', false); diff --git a/inc/lib/Twig/NodeVisitor/SafeAnalysis.php b/inc/lib/Twig/NodeVisitor/SafeAnalysis.php index b0c658cd..ca31c8fc 100644 --- a/inc/lib/Twig/NodeVisitor/SafeAnalysis.php +++ b/inc/lib/Twig/NodeVisitor/SafeAnalysis.php @@ -1,6 +1,18 @@ <?php -class Twig_NodeVisitor_SafeAnalysis implements Twig_NodeVisitorInterface +/* + * This file is part of Twig. + * + * (c) Fabien Potencier + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +/** + * @final + */ +class Twig_NodeVisitor_SafeAnalysis extends Twig_BaseNodeVisitor { protected $data = array(); protected $safeVars = array(); @@ -13,12 +25,20 @@ class Twig_NodeVisitor_SafeAnalysis implements Twig_NodeVisitorInterface public function getSafe(Twig_NodeInterface $node) { $hash = spl_object_hash($node); - if (isset($this->data[$hash])) { - foreach ($this->data[$hash] as $bucket) { - if ($bucket['key'] === $node) { - return $bucket['value']; - } + if (!isset($this->data[$hash])) { + return; + } + + foreach ($this->data[$hash] as $bucket) { + if ($bucket['key'] !== $node) { + continue; } + + if (in_array('html_attr', $bucket['value'])) { + $bucket['value'][] = 'html'; + } + + return $bucket['value']; } } @@ -40,12 +60,12 @@ class Twig_NodeVisitor_SafeAnalysis implements Twig_NodeVisitorInterface ); } - public function enterNode(Twig_NodeInterface $node, Twig_Environment $env) + protected function doEnterNode(Twig_Node $node, Twig_Environment $env) { return $node; } - public function leaveNode(Twig_NodeInterface $node, Twig_Environment $env) + protected function doLeaveNode(Twig_Node $node, Twig_Environment $env) { if ($node instanceof Twig_Node_Expression_Constant) { // constants are marked safe for all @@ -89,8 +109,6 @@ class Twig_NodeVisitor_SafeAnalysis implements Twig_NodeVisitorInterface } else { $this->setSafe($node, array()); } - } elseif ($node instanceof Twig_Node_Expression_MacroCall) { - $this->setSafe($node, array('all')); } elseif ($node instanceof Twig_Node_Expression_GetAttr && $node->getNode('node') instanceof Twig_Node_Expression_Name) { $name = $node->getNode('node')->getAttribute('name'); // attributes on template instances are safe @@ -123,11 +141,10 @@ class Twig_NodeVisitor_SafeAnalysis implements Twig_NodeVisitorInterface return array_intersect($a, $b); } - /** - * {@inheritdoc} - */ public function getPriority() { return 0; } } + +class_alias('Twig_NodeVisitor_SafeAnalysis', 'Twig\NodeVisitor\SafeAnalysisNodeVisitor', false); diff --git a/inc/lib/Twig/NodeVisitor/Sandbox.php b/inc/lib/Twig/NodeVisitor/Sandbox.php index fb27045b..71aa4f02 100644 --- a/inc/lib/Twig/NodeVisitor/Sandbox.php +++ b/inc/lib/Twig/NodeVisitor/Sandbox.php @@ -3,7 +3,7 @@ /* * This file is part of Twig. * - * (c) 2009 Fabien Potencier + * (c) Fabien Potencier * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. @@ -12,24 +12,18 @@ /** * Twig_NodeVisitor_Sandbox implements sandboxing. * + * @final + * * @author Fabien Potencier <fabien@symfony.com> */ -class Twig_NodeVisitor_Sandbox implements Twig_NodeVisitorInterface +class Twig_NodeVisitor_Sandbox extends Twig_BaseNodeVisitor { protected $inAModule = false; protected $tags; protected $filters; protected $functions; - /** - * Called before child nodes are visited. - * - * @param Twig_NodeInterface $node The node to visit - * @param Twig_Environment $env The Twig environment instance - * - * @return Twig_NodeInterface The modified node - */ - public function enterNode(Twig_NodeInterface $node, Twig_Environment $env) + protected function doEnterNode(Twig_Node $node, Twig_Environment $env) { if ($node instanceof Twig_Node_Module) { $this->inAModule = true; @@ -40,53 +34,49 @@ class Twig_NodeVisitor_Sandbox implements Twig_NodeVisitorInterface return $node; } elseif ($this->inAModule) { // look for tags - if ($node->getNodeTag()) { - $this->tags[] = $node->getNodeTag(); + if ($node->getNodeTag() && !isset($this->tags[$node->getNodeTag()])) { + $this->tags[$node->getNodeTag()] = $node; } // look for filters - if ($node instanceof Twig_Node_Expression_Filter) { - $this->filters[] = $node->getNode('filter')->getAttribute('value'); + if ($node instanceof Twig_Node_Expression_Filter && !isset($this->filters[$node->getNode('filter')->getAttribute('value')])) { + $this->filters[$node->getNode('filter')->getAttribute('value')] = $node; } // look for functions - if ($node instanceof Twig_Node_Expression_Function) { - $this->functions[] = $node->getAttribute('name'); + if ($node instanceof Twig_Node_Expression_Function && !isset($this->functions[$node->getAttribute('name')])) { + $this->functions[$node->getAttribute('name')] = $node; + } + + // the .. operator is equivalent to the range() function + if ($node instanceof Twig_Node_Expression_Binary_Range && !isset($this->functions['range'])) { + $this->functions['range'] = $node; } // wrap print to check __toString() calls if ($node instanceof Twig_Node_Print) { - return new Twig_Node_SandboxedPrint($node->getNode('expr'), $node->getLine(), $node->getNodeTag()); + return new Twig_Node_SandboxedPrint($node->getNode('expr'), $node->getTemplateLine(), $node->getNodeTag()); } } return $node; } - /** - * Called after child nodes are visited. - * - * @param Twig_NodeInterface $node The node to visit - * @param Twig_Environment $env The Twig environment instance - * - * @return Twig_NodeInterface The modified node - */ - public function leaveNode(Twig_NodeInterface $node, Twig_Environment $env) + protected function doLeaveNode(Twig_Node $node, Twig_Environment $env) { if ($node instanceof Twig_Node_Module) { $this->inAModule = false; - return new Twig_Node_SandboxedModule($node, array_unique($this->filters), array_unique($this->tags), array_unique($this->functions)); + $node->setNode('display_start', new Twig_Node(array(new Twig_Node_CheckSecurity($this->filters, $this->tags, $this->functions), $node->getNode('display_start')))); } return $node; } - /** - * {@inheritdoc} - */ public function getPriority() { return 0; } } + +class_alias('Twig_NodeVisitor_Sandbox', 'Twig\NodeVisitor\SandboxNodeVisitor', false); |
