Skip to content

Commit

Permalink
[OutputEscaper] fixed output escaping when a variable was decorated w…
Browse files Browse the repository at this point in the history
…ith 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.
  • Loading branch information
fabpot committed Nov 18, 2010
1 parent 3ce745c commit 333504a
Show file tree
Hide file tree
Showing 2 changed files with 19 additions and 1 deletion.
7 changes: 6 additions & 1 deletion src/Symfony/Component/OutputEscaper/Escaper.php
Expand Up @@ -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
Expand Down Expand Up @@ -75,6 +76,10 @@ static public function escape($escaper, $value)
}

if (is_object($value)) {
if (isset(self::$safeObjects[spl_object_hash($value)])) {
return $value;
}

if ($value instanceof BaseEscaper) {
// avoid double decoration
$copy = clone $value;
Expand All @@ -86,7 +91,7 @@ static public function escape($escaper, $value)
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) {
Expand Down
13 changes: 13 additions & 0 deletions tests/Symfony/Tests/Component/OutputEscaper/EscaperTest.php
Expand Up @@ -153,6 +153,19 @@ public function testUnescapeUnescapesMixedArrays()
);
$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
Expand Down

0 comments on commit 333504a

Please sign in to comment.