diff --git a/src/Symfony/Bridge/Twig/Extension/DumpExtension.php b/src/Symfony/Bridge/Twig/Extension/DumpExtension.php
index 30318ecac6..5e43547ff1 100644
--- a/src/Symfony/Bridge/Twig/Extension/DumpExtension.php
+++ b/src/Symfony/Bridge/Twig/Extension/DumpExtension.php
@@ -67,7 +67,7 @@ class DumpExtension extends \Twig_Extension
}
$dump = fopen('php://memory', 'r+b');
- $dumper = new HtmlDumper($dump);
+ $dumper = new HtmlDumper($dump, $env->getCharset());
foreach ($vars as $value) {
$dumper->dump($this->cloner->cloneVar($value));
diff --git a/src/Symfony/Component/HttpKernel/DataCollector/DumpDataCollector.php b/src/Symfony/Component/HttpKernel/DataCollector/DumpDataCollector.php
index 635402e160..985db4b133 100644
--- a/src/Symfony/Component/HttpKernel/DataCollector/DumpDataCollector.php
+++ b/src/Symfony/Component/HttpKernel/DataCollector/DumpDataCollector.php
@@ -170,6 +170,8 @@ class DumpDataCollector extends DataCollector implements DataDumperInterface
return 'a:0:{}';
}
+ $this->data[] = $this->fileLinkFormat;
+ $this->data[] = $this->charset;
$ser = serialize($this->data);
$this->data = array();
$this->dataCount = 0;
@@ -184,8 +186,10 @@ class DumpDataCollector extends DataCollector implements DataDumperInterface
public function unserialize($data)
{
parent::unserialize($data);
+ $charset = array_pop($this->data);
+ $fileLinkFormat = array_pop($this->data);
$this->dataCount = count($this->data);
- self::__construct($this->stopwatch);
+ self::__construct($this->stopwatch, $fileLinkFormat, $charset);
}
public function getDumpsCount()
diff --git a/src/Symfony/Component/HttpKernel/Tests/DataCollector/DumpDataCollectorTest.php b/src/Symfony/Component/HttpKernel/Tests/DataCollector/DumpDataCollectorTest.php
index 198a03fd28..18824635ea 100644
--- a/src/Symfony/Component/HttpKernel/Tests/DataCollector/DumpDataCollectorTest.php
+++ b/src/Symfony/Component/HttpKernel/Tests/DataCollector/DumpDataCollectorTest.php
@@ -49,9 +49,9 @@ class DumpDataCollectorTest extends \PHPUnit_Framework_TestCase
);
$this->assertSame($xDump, $dump);
- $this->assertStringMatchesFormat('a:1:{i:0;a:5:{s:4:"data";O:39:"Symfony\Component\VarDumper\Cloner\Data":%a', $collector->serialize());
+ $this->assertStringMatchesFormat('a:3:{i:0;a:5:{s:4:"data";O:39:"Symfony\Component\VarDumper\Cloner\Data":%a', $collector->serialize());
$this->assertSame(0, $collector->getDumpsCount());
- $this->assertSame('a:0:{}', $collector->serialize());
+ $this->assertSame('a:2:{i:0;b:0;i:1;s:5:"UTF-8";}', $collector->serialize());
}
public function testCollectDefault()
diff --git a/src/Symfony/Component/VarDumper/Dumper/AbstractDumper.php b/src/Symfony/Component/VarDumper/Dumper/AbstractDumper.php
index 7c3d280ca6..a5f2b35296 100644
--- a/src/Symfony/Component/VarDumper/Dumper/AbstractDumper.php
+++ b/src/Symfony/Component/VarDumper/Dumper/AbstractDumper.php
@@ -82,11 +82,13 @@ abstract class AbstractDumper implements DataDumperInterface, DumperInterface
public function setCharset($charset)
{
$prev = $this->charset;
- $this->charsetConverter = 'fallback';
-
$charset = strtoupper($charset);
$charset = null === $charset || 'UTF-8' === $charset || 'UTF8' === $charset ? 'CP1252' : $charset;
+ if ($prev === $charset) {
+ return $prev;
+ }
+ $this->charsetConverter = 'fallback';
$supported = true;
set_error_handler(function () use (&$supported) {$supported = false;});
diff --git a/src/Symfony/Component/VarDumper/Dumper/HtmlDumper.php b/src/Symfony/Component/VarDumper/Dumper/HtmlDumper.php
index 0b032b71e6..9a47aea7ee 100644
--- a/src/Symfony/Component/VarDumper/Dumper/HtmlDumper.php
+++ b/src/Symfony/Component/VarDumper/Dumper/HtmlDumper.php
@@ -362,7 +362,7 @@ EOHTML;
return '';
}
- $v = htmlspecialchars($value, ENT_QUOTES, 'UTF-8');
+ $v = esc($value);
if ('ref' === $style) {
if (empty($attr['count'])) {
@@ -373,18 +373,18 @@ EOHTML;
return sprintf('%s', $this->dumpId, $r, 1 + $attr['count'], $v);
}
- if ('const' === $style && array_key_exists('value', $attr)) {
- $style .= sprintf(' title="%s"', htmlspecialchars(json_encode($attr['value']), ENT_QUOTES, 'UTF-8'));
+ if ('const' === $style && isset($attr['value'])) {
+ $style .= sprintf(' title="%s"', esc(is_scalar($attr['value']) ? $attr['value'] : json_encode($attr['value'])));
} elseif ('public' === $style) {
$style .= sprintf(' title="%s"', empty($attr['dynamic']) ? 'Public property' : 'Runtime added dynamic property');
} elseif ('str' === $style && 1 < $attr['length']) {
- $style .= sprintf(' title="%s%s characters"', $attr['length'], $attr['binary'] ? ' binary or non-UTF-8' : '');
+ $style .= sprintf(' title="%d%s characters"', $attr['length'], $attr['binary'] ? ' binary or non-UTF-8' : '');
} elseif ('note' === $style && false !== $c = strrpos($v, '\\')) {
return sprintf('%s', $v, $style, substr($v, $c + 1));
} elseif ('protected' === $style) {
$style .= ' title="Protected property"';
} elseif ('private' === $style) {
- $style .= sprintf(' title="Private property defined in class:
`%s`"', $attr['class']);
+ $style .= sprintf(' title="Private property defined in class:
`%s`"', esc($attr['class']));
}
$map = static::$controlCharsMap;
@@ -461,3 +461,8 @@ EOHTML;
AbstractDumper::dumpLine($depth);
}
}
+
+function esc($str)
+{
+ return htmlspecialchars($str, ENT_QUOTES, 'UTF-8');
+}