[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:
parent
3ce745cf6e
commit
333504a201
@ -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) {
|
||||
|
@ -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
|
||||
|
Reference in New Issue
Block a user