[OutputEscaper] fixed output escaping when a variable was decorated with SafeDecorator and passed to another part of the system where decoration also happens on the same un-decorated variable

This is the case for instance when you pass a variable to a template like this:

new SafeDecorator($var);

and in the template, you pass it again to another embedded template:

$view->render('...', array('var' => $var);

The second time, $var will be escaped as the SafeDecorator wrapper will have been removed
by the escaper.
This commit is contained in:
Fabien Potencier 2010-11-18 19:19:40 +01:00
parent 3ce745cf6e
commit 333504a201
2 changed files with 19 additions and 1 deletions

View File

@ -22,6 +22,7 @@ class Escaper
static protected $charset = 'UTF-8';
static protected $safeClasses = array();
static protected $escapers;
static protected $safeObjects = array();
/**
* Decorates a PHP variable with something that will escape any data obtained
@ -75,6 +76,10 @@ class Escaper
}
if (is_object($value)) {
if (isset(self::$safeObjects[spl_object_hash($value)])) {
return $value;
}
if ($value instanceof BaseEscaper) {
// avoid double decoration
$copy = clone $value;
@ -86,7 +91,7 @@ class Escaper
if ($value instanceof SafeDecorator) {
// do not escape objects marked as safe
// return the original object
return $value->getRawValue();
return self::$safeObjects[spl_object_hash($value->getRawValue())] = $value->getRawValue();
}
if (self::isClassMarkedAsSafe(get_class($value)) || $value instanceof SafeDecoratorInterface) {

View File

@ -153,6 +153,19 @@ class EscaperTest extends \PHPUnit_Framework_TestCase
);
$this->assertEquals($output, Escaper::unescape($input), '::unescape() unescapes values with some escaped and unescaped values');
}
public function testEscaperRememberSafeDecoratedObjects()
{
$object = new \stdClass();
$object->foo = '<br />';
$var = new SafeDecorator($object);
Escaper::escape('entities', $var);
$escaped = Escaper::escape('entities', $object);
$this->assertEquals('<br />', $escaped->foo);
}
}
class OutputEscaperTestClass