Added an option to mark filters as preserving the safeness

Closes #678
This commit is contained in:
Christophe Coevoet
2012-04-20 16:23:51 +02:00
parent 037f86aa55
commit 0cbf5a004c
6 changed files with 71 additions and 2 deletions
+1
View File
@@ -1,5 +1,6 @@
* 1.7.0 (2012-XX-XX)
* added the preserve_safety option for filters
* fixed a PHP notice when trying to access a key on a non-object/array variable
* enhanced error reporting when the template file is an instance of SplFileInfo
* added Twig_Environment::mergeGlobals()
+7 -1
View File
@@ -26,6 +26,7 @@ abstract class Twig_Filter implements Twig_FilterInterface
'needs_environment' => false,
'needs_context' => false,
'pre_escape' => null,
'preserve_safety' => null,
), $options);
}
@@ -59,7 +60,12 @@ abstract class Twig_Filter implements Twig_FilterInterface
return call_user_func($this->options['is_safe_callback'], $filterArgs);
}
return array();
return null;
}
public function getPreserveSafety()
{
return $this->options['preserve_safety'];
}
public function getPreEscape()
+2
View File
@@ -30,6 +30,8 @@ interface Twig_FilterInterface
function getSafe(Twig_Node $filterArgs);
function getPreserveSafety();
function getPreEscape();
function setArguments($arguments);
+5 -1
View File
@@ -61,7 +61,11 @@ class Twig_NodeVisitor_SafeAnalysis implements Twig_NodeVisitorInterface
$name = $node->getNode('filter')->getAttribute('value');
$args = $node->getNode('arguments');
if (false !== $filter = $env->getFilter($name)) {
$this->setSafe($node, $filter->getSafe($args));
$safe = $filter->getSafe($args);
if (null === $safe) {
$safe = $this->intersectSafe($this->getSafe($node->getNode('node')), $filter->getPreserveSafety());
}
$this->setSafe($node, $safe);
} else {
$this->setSafe($node, array());
}
@@ -0,0 +1,50 @@
--TEST--
"autoescape" tag handles filters preserving the safety
--TEMPLATE--
{% autoescape true %}
(preserve_safety is preserving safety for "html")
1. Unsafe values are still unsafe
( var|preserve_safety|escape )
{{ var|preserve_safety }}
2. Safe values are still safe
( var|escape|preserve_safety )
{{ var|escape|preserve_safety }}
3. Re-escape values that are escaped for an other contexts
( var|escape_something|preserve_safety|escape )
{{ var|escape_something|preserve_safety }}
4. Still escape when using filters not declared safe
( var|escape|preserve_safety|replace({'FABIEN': 'FABPOT'})|escape )
{{ var|escape|preserve_safety|replace({'FABIEN': 'FABPOT'}) }}
{% endautoescape %}
--DATA--
return array('var' => "<Fabien>\nTwig")
--EXPECT--
(preserve_safety is preserving safety for "html")
1. Unsafe values are still unsafe
( var|preserve_safety|escape )
&lt;FABIEN&gt;
TWIG
2. Safe values are still safe
( var|escape|preserve_safety )
&LT;FABIEN&GT;
TWIG
3. Re-escape values that are escaped for an other contexts
( var|escape_something|preserve_safety|escape )
&lt;FABIEN&gt;
TWIG
4. Still escape when using filters not declared safe
( var|escape|preserve_safety|replace({'FABIEN': 'FABPOT'})|escape )
&amp;LT;FABPOT&amp;GT;
TWIG
+6
View File
@@ -238,6 +238,7 @@ class TestExtension extends Twig_Extension
'escape_and_nl2br' => new Twig_Filter_Method($this, 'escape_and_nl2br', array('needs_environment' => true, 'is_safe' => array('html'))),
'nl2br' => new Twig_Filter_Method($this, 'nl2br', array('pre_escape' => 'html', 'is_safe' => array('html'))),
'escape_something' => new Twig_Filter_Method($this, 'escape_something', array('is_safe' => array('something'))),
'preserve_safety' => new Twig_Filter_Method($this, 'preserve_safety', array('preserve_safety' => array('html'))),
'*_path' => new Twig_Filter_Method($this, 'dynamic_path'),
'*_foo_*_bar' => new Twig_Filter_Method($this, 'dynamic_foo'),
);
@@ -297,6 +298,11 @@ class TestExtension extends Twig_Extension
return strtoupper($value);
}
public function preserve_safety($value)
{
return strtoupper($value);
}
public function br()
{
return '<br />';