From 8832b660b8b191b930bef3ca4a4d34a581d85ff3 Mon Sep 17 00:00:00 2001 From: Fabien Potencier Date: Sat, 21 Jul 2012 23:20:56 +0200 Subject: [PATCH] optimized macro calls when auto-escaping is on (closes #779) --- CHANGELOG | 1 + lib/Twig/Node/Macro.php | 2 +- lib/Twig/NodeVisitor/Escaper.php | 8 ++++++++ lib/Twig/NodeVisitor/SafeAnalysis.php | 14 ++++++++++++++ test/Twig/Tests/Node/MacroTest.php | 2 +- 5 files changed, 25 insertions(+), 2 deletions(-) diff --git a/CHANGELOG b/CHANGELOG index ddf2ff2..1777748 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -1,5 +1,6 @@ * 1.9.1 (2012-XX-XX) + * optimized macro calls when auto-escaping is on * fixed wrong parent class for Twig_Function_Node * made Twig_Loader_Chain more explicit about problems diff --git a/lib/Twig/Node/Macro.php b/lib/Twig/Node/Macro.php index 823131e..e0c3dca 100644 --- a/lib/Twig/Node/Macro.php +++ b/lib/Twig/Node/Macro.php @@ -76,7 +76,7 @@ class Twig_Node_Macro extends Twig_Node ->write("throw \$e;\n") ->outdent() ->write("}\n\n") - ->write("return ('' === \$tmp = ob_get_clean()) ? '' : new Twig_Markup(\$tmp, \$this->env->getCharset());\n") + ->write("return ob_get_clean();\n") ->outdent() ->write("}\n\n") ; diff --git a/lib/Twig/NodeVisitor/Escaper.php b/lib/Twig/NodeVisitor/Escaper.php index 5b1249d..cc9a58b 100644 --- a/lib/Twig/NodeVisitor/Escaper.php +++ b/lib/Twig/NodeVisitor/Escaper.php @@ -22,6 +22,7 @@ class Twig_NodeVisitor_Escaper implements Twig_NodeVisitorInterface protected $safeAnalysis; protected $traverser; protected $defaultStrategy = false; + protected $safeVars = array(); public function __construct() { @@ -42,10 +43,13 @@ class Twig_NodeVisitor_Escaper implements Twig_NodeVisitorInterface if ($env->hasExtension('escaper') && $defaultStrategy = $env->getExtension('escaper')->getDefaultStrategy($node->getAttribute('filename'))) { $this->defaultStrategy = $defaultStrategy; } + $this->safeVars = array(); } elseif ($node instanceof Twig_Node_AutoEscape) { $this->statusStack[] = $node->getAttribute('value'); } elseif ($node instanceof Twig_Node_Block) { $this->statusStack[] = isset($this->blocks[$node->getAttribute('name')]) ? $this->blocks[$node->getAttribute('name')] : $this->needEscaping($env); + } elseif ($node instanceof Twig_Node_Import) { + $this->safeVars[] = $node->getNode('var')->getAttribute('name'); } return $node; @@ -63,6 +67,7 @@ class Twig_NodeVisitor_Escaper implements Twig_NodeVisitorInterface { if ($node instanceof Twig_Node_Module) { $this->defaultStrategy = false; + $this->safeVars = array(); } elseif ($node instanceof Twig_Node_Expression_Filter) { return $this->preEscapeFilterNode($node, $env); } elseif ($node instanceof Twig_Node_Print) { @@ -129,6 +134,9 @@ class Twig_NodeVisitor_Escaper implements Twig_NodeVisitorInterface if (null === $this->traverser) { $this->traverser = new Twig_NodeTraverser($env, array($this->safeAnalysis)); } + + $this->safeAnalysis->setSafeVars($this->safeVars); + $this->traverser->traverse($expression); $safe = $this->safeAnalysis->getSafe($expression); } diff --git a/lib/Twig/NodeVisitor/SafeAnalysis.php b/lib/Twig/NodeVisitor/SafeAnalysis.php index 7cc2e22..7dc65c0 100644 --- a/lib/Twig/NodeVisitor/SafeAnalysis.php +++ b/lib/Twig/NodeVisitor/SafeAnalysis.php @@ -3,6 +3,12 @@ class Twig_NodeVisitor_SafeAnalysis implements Twig_NodeVisitorInterface { protected $data = array(); + protected $safeVars = array(); + + public function setSafeVars($safeVars) + { + $this->safeVars = $safeVars; + } public function getSafe(Twig_NodeInterface $node) { @@ -85,6 +91,14 @@ class Twig_NodeVisitor_SafeAnalysis implements Twig_NodeVisitorInterface } else { $this->setSafe($node, array()); } + } 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 + if ('_self' == $name || in_array($name, $this->safeVars)) { + $this->setSafe($node, array('all')); + } else { + $this->setSafe($node, array()); + } } else { $this->setSafe($node, array()); } diff --git a/test/Twig/Tests/Node/MacroTest.php b/test/Twig/Tests/Node/MacroTest.php index 5930728..3dd57a6 100644 --- a/test/Twig/Tests/Node/MacroTest.php +++ b/test/Twig/Tests/Node/MacroTest.php @@ -61,7 +61,7 @@ public function getfoo(\$foo = null) throw \$e; } - return ('' === \$tmp = ob_get_clean()) ? '' : new Twig_Markup(\$tmp, \$this->env->getCharset()); + return ob_get_clean(); } EOF ), -- 1.7.2.5