This commit is contained in:
Fabien Potencier
2010-11-07 09:17:24 +01:00
parent 4087d087a1
commit 36489263d5
4 changed files with 50 additions and 52 deletions
+5 -2
View File
@@ -246,21 +246,24 @@ function twig_escape_filter(Twig_Environment $env, $string, $type = 'html')
case 'html':
return htmlspecialchars($string, ENT_QUOTES, $env->getCharset());
default:
throw new Exception("Invalid escape type $type");
throw new Exception(sprintf('Invalid escape type "%s".', $type));
}
}
function twig_escape_filter_is_safe(Twig_Node $filterArgs)
{
foreach($filterArgs as $arg) {
foreach ($filterArgs as $arg) {
if ($arg instanceof Twig_Node_Expression_Constant) {
return array($arg->getAttribute('value'));
} else {
return array();
}
break;
}
return array('html');
}
+2
View File
@@ -42,9 +42,11 @@ abstract class Twig_Filter implements Twig_FilterInterface
if (isset($this->options['is_safe'])) {
return $this->options['is_safe'];
}
if (isset($this->options['is_safe_callback'])) {
return call_user_func($this->options['is_safe_callback'], $filterArgs);
}
return array();
}
}
+19 -19
View File
@@ -26,7 +26,7 @@ class Twig_NodeVisitor_Escaper implements Twig_NodeVisitorInterface
function __construct()
{
$this->safeAnalysis = new Twig_NodeVisitor_SafeAnalysis;
$this->safeAnalysis = new Twig_NodeVisitor_SafeAnalysis();
}
/**
@@ -79,47 +79,47 @@ class Twig_NodeVisitor_Escaper implements Twig_NodeVisitorInterface
$safe = $this->safeAnalysis->getSafe($expression);
if ($safe === null) {
if ($this->traverser === null) {
if (null === $safe) {
if (null === $this->traverser) {
$this->traverser = new Twig_NodeTraverser($env, array($this->safeAnalysis));
}
$this->traverser->traverse($expression);
$safe = $this->safeAnalysis->getSafe($expression);
}
if (in_array($type, $safe) !== false || in_array('all', $safe) !== false) {
if (false !== in_array($type, $safe) || false !== in_array('all', $safe)) {
return $node;
}
// escape
if ($expression instanceof Twig_Node_Expression_Filter) {
$filter = $this->getEscaperFilter($type, $expression->getLine());
$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())
, $node->getLine()
);
} else {
return new Twig_Node_Expression_Filter($node, new Twig_Node($this->getEscaperFilter($type, $node->getLine())), $node->getLine());
}
if ($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()),
$node->getLine()
);
}
return new Twig_Node_Expression_Filter($node, new Twig_Node($this->getEscaperFilter($type, $node->getLine())), $node->getLine());
}
protected function needEscaping(Twig_Environment $env)
{
if (count($this->statusStack)) {
return $this->statusStack[count($this->statusStack) - 1];
} else {
if ($env->hasExtension('escaper') && $env->getExtension('escaper')->isGlobal()) {
return 'html';
} else {
return false;
}
}
if ($env->hasExtension('escaper') && $env->getExtension('escaper')->isGlobal()) {
return 'html';
}
return false;
}
protected function getEscaperFilter($type, $line)
+24 -31
View File
@@ -7,6 +7,7 @@ class Twig_NodeVisitor_SafeAnalysis implements Twig_NodeVisitorInterface
public function getSafe(Twig_NodeInterface $node)
{
$hash = spl_object_hash($node);
return isset($this->data[$hash]) ? $this->data[$hash] : null;
}
@@ -16,45 +17,22 @@ class Twig_NodeVisitor_SafeAnalysis implements Twig_NodeVisitorInterface
$this->data[$hash] = $safe;
}
protected function intersectSafe(array $a = null, array $b = null)
{
if ($a === null || $b === null) {
return array();
}
if (in_array('all', $a)) {
return $b;
}
if (in_array('all', $b)) {
return $a;
}
return array_intersect($a, $b);
}
public function enterNode(Twig_NodeInterface $node, Twig_Environment $env)
{
return $node;
}
public function leaveNode(Twig_NodeInterface $node, Twig_Environment $env)
{
// constants are marked safe for all
if ($node instanceof Twig_Node_Expression_Constant) {
// constants are marked safe for all
$this->setSafe($node, array('all'));
// instersect safeness of both operands
} else if ($node instanceof Twig_Node_Expression_Conditional) {
} elseif ($node instanceof Twig_Node_Expression_Conditional) {
// instersect safeness of both operands
$safe = $this->intersectSafe($this->getSafe($node->getNode('expr2')), $this->getSafe($node->getNode('expr3')));
$this->setSafe($node, $safe);
// filter expression is safe when the last filter is safe
} else if ($node instanceof Twig_Node_Expression_Filter) {
} elseif ($node instanceof Twig_Node_Expression_Filter) {
// filter expression is safe when the last filter is safe
$filterMap = $env->getFilters();
$filters = $node->getNode('filters');
$i = count($filters) - 2;
@@ -65,12 +43,27 @@ class Twig_NodeVisitor_SafeAnalysis implements Twig_NodeVisitorInterface
} else {
$this->setSafe($node, array());
}
} else {
$this->setSafe($node, array());
}
return $node;
}
protected function intersectSafe(array $a = null, array $b = null)
{
if (null === $a || null === $b) {
return array();
}
if (in_array('all', $a)) {
return $b;
}
if (in_array('all', $b)) {
return $a;
}
return array_intersect($a, $b);
}
}