$expression = $node instanceof Twig_Node_Print ? $node->getNode('expr') : $node;
+ if ($expression instanceof Twig_Node_Expression_Constant) {
+
+ return $node;
+ }
+
if ($expression instanceof Twig_Node_Expression_Filter) {
- // don't escape if the primary node of the filter is not a variable
- if (!$expression->getNode('node') instanceof Twig_Node_Expression_GetAttr && !$expression->getNode('node') instanceof Twig_Node_Expression_Name) {
- return $node;
- }
- // don't escape if there is already an "escaper" in the filter chain
+ // don't escape if the last filter in the chain is an "escaper"
$filterMap = $env->getFilters();
- for ($i = 0; $i < count($expression->getNode('filters')); $i += 2) {
- $name = $expression->getNode('filters')->getNode($i)->getAttribute('value');
- if (isset($filterMap[$name]) && $filterMap[$name]->isEscaper()) {
- return $node;
- }
+ $i = count($expression->getNode('filters')) - 2;
+ $name = $expression->getNode('filters')->getNode($i)->getAttribute('value');
+ if (isset($filterMap[$name]) && $filterMap[$name]->isEscaper()) {
+ return $node;
}
- } elseif (!$expression instanceof Twig_Node_Expression_GetAttr && !$expression instanceof Twig_Node_Expression_Name) {
- // don't escape if the node is not a variable
- return $node;
}
// escape
if ($expression instanceof Twig_Node_Expression_Filter) {
- // escape all variables in filters arguments
- for ($i = 0; $i < count($expression->getNode('filters')); $i += 2) {
- foreach ($expression->getNode('filters')->getNode($i + 1) as $j => $n) {
- $expression->getNode('filters')->getNode($i + 1)->setNode($j, $this->escapeNode($n, $env, $type));
- }
- }
$filter = $this->getEscaperFilter($type, $expression->getLine());
- $expression->prependFilter($filter[0], $filter[1]);
+ $expression->appendFilter($filter[0], $filter[1]);
return $node;
+
} elseif ($node instanceof Twig_Node_Print) {
return new Twig_Node_Print(
new Twig_Node_Expression_Filter($expression, new Twig_Node($this->getEscaperFilter($type, $node->getLine())), $node->getLine())
--TEST--
-"autoescape" tag applies escaping before calling filters
+"autoescape" tag applies escaping after calling filters
--TEMPLATE--
{% autoescape on %}
+
+(nl2br is an escaper filter)
+
+1. Don't escape escaper filter output
+( var is escaped by |nl2br, line-breaks are added,
+ the output is not escaped )
{{ var|nl2br }}
+
+2. Don't escape escaper filter output
+( var is escaped by |nl2br, line-breaks are added,
+ the output is not escaped, |raw is redundant )
+{{ var|nl2br|raw }}
+
+3. Explicit escape
+( var is escaped by |nl2br, line-breaks are added,
+ the output is explicitly escaped by |escape )
{{ var|nl2br|escape }}
+
+4. Escape non-escaper filter output
+( var is upper-cased by |upper,
+ the output is auto-escaped )
+{{ var|upper }}
+
+5. Escape if last filter is not an escaper
+( var is escaped by |nl2br, line-breaks are added,
+ the output is upper-cased by |upper,
+ the output is auto-escaped as |upper is not an escaper )
+{{ var|nl2br|upper }}
+
+6. Don't escape escaper filter output
+( var is upper cased by upper,
+ the output is escaped by |nl2br, line-breaks are added,
+ the output is not escaped as |nl2br is an escaper )
+{{ var|upper|nl2br }}
+
+7. Escape if last filter is not an escaper
+( the output of |format is "<b>" ~ var ~ "</b>",
+ the output is auto-escaped )
+{{ "<b>%s</b>"|format(var) }}
+
+8. Escape if last filter is not an escaper
+( the output of |format is "<b>" ~ var ~ "</b>",
+ |raw is redundant,
+ the output is auto-escaped )
+{{ "<b>%s</b>"|raw|format(var) }}
+
+9. Don't escape escaper filter output
+( the output of |format is "<b>" ~ var ~ "</b>",
+ the output is not escaped due to |raw filter at the end )
+{{ "<b>%s</b>"|format(var)|raw }}
+
+10. Don't escape escaper filter output
+( the output of |format is "<b>" ~ var ~ "</b>",
+ the output is not escaped due to |raw filter at the end,
+ the |raw filter on var is redundant )
+{{ "<b>%s</b>"|format(var|raw)|raw }}
+
{% endautoescape %}
--DATA--
return array('var' => "<Fabien>\nTwig")
--EXPECT--
+
+(nl2br is an escaper filter)
+
+1. Don't escape escaper filter output
+( var is escaped by |nl2br, line-breaks are added,
+ the output is not escaped )
<Fabien><br />
Twig
-<Fabien><br />
+
+2. Don't escape escaper filter output
+( var is escaped by |nl2br, line-breaks are added,
+ the output is not escaped, |raw is redundant )
+<Fabien><br />
+Twig
+
+3. Explicit escape
+( var is escaped by |nl2br, line-breaks are added,
+ the output is explicitly escaped by |escape )
+&lt;Fabien&gt;<br />
Twig
+
+4. Escape non-escaper filter output
+( var is upper-cased by |upper,
+ the output is auto-escaped )
+<FABIEN>
+TWIG
+
+5. Escape if last filter is not an escaper
+( var is escaped by |nl2br, line-breaks are added,
+ the output is upper-cased by |upper,
+ the output is auto-escaped as |upper is not an escaper )
+&LT;FABIEN&GT;<BR />
+TWIG
+
+6. Don't escape escaper filter output
+( var is upper cased by upper,
+ the output is escaped by |nl2br, line-breaks are added,
+ the output is not escaped as |nl2br is an escaper )
+<FABIEN><br />
+TWIG
+
+7. Escape if last filter is not an escaper
+( the output of |format is "<b>" ~ var ~ "</b>",
+ the output is auto-escaped )
+<b><Fabien>
+Twig</b>
+
+8. Escape if last filter is not an escaper
+( the output of |format is "<b>" ~ var ~ "</b>",
+ |raw is redundant,
+ the output is auto-escaped )
+<b><Fabien>
+Twig</b>
+
+9. Don't escape escaper filter output
+( the output of |format is "<b>" ~ var ~ "</b>",
+ the output is not escaped due to |raw filter at the end )
+<b><Fabien>
+Twig</b>
+
+10. Don't escape escaper filter output
+( the output of |format is "<b>" ~ var ~ "</b>",
+ the output is not escaped due to |raw filter at the end,
+ the |raw filter on var is redundant )
+<b><Fabien>
+Twig</b>