diff --git a/src/Symfony/Component/OutputEscaper/Escaper.php b/src/Symfony/Component/OutputEscaper/Escaper.php
index 1ef1a53280ea..a4292e71909f 100644
--- a/src/Symfony/Component/OutputEscaper/Escaper.php
+++ b/src/Symfony/Component/OutputEscaper/Escaper.php
@@ -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 @@ 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;
@@ -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) {
diff --git a/tests/Symfony/Tests/Component/OutputEscaper/EscaperTest.php b/tests/Symfony/Tests/Component/OutputEscaper/EscaperTest.php
index b7336da947eb..95fc86bb382f 100644
--- a/tests/Symfony/Tests/Component/OutputEscaper/EscaperTest.php
+++ b/tests/Symfony/Tests/Component/OutputEscaper/EscaperTest.php
@@ -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 = '
';
+
+ $var = new SafeDecorator($object);
+ Escaper::escape('entities', $var);
+
+ $escaped = Escaper::escape('entities', $object);
+
+ $this->assertEquals('
', $escaped->foo);
+ }
}
class OutputEscaperTestClass