Skip to content

Commit 906418c

Browse files
[VarDumper] fix handling of non-UTF8 strings
1 parent f611205 commit 906418c

File tree

1 file changed

+24
-8
lines changed

1 file changed

+24
-8
lines changed

DataCollector/DumpDataCollector.php

Lines changed: 24 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
use Symfony\Component\HttpFoundation\Response;
1616
use Symfony\Component\Stopwatch\Stopwatch;
1717
use Symfony\Component\VarDumper\Cloner\Data;
18+
use Symfony\Component\VarDumper\Cloner\VarCloner;
1819
use Symfony\Component\VarDumper\Dumper\CliDumper;
1920
use Symfony\Component\VarDumper\Dumper\HtmlDumper;
2021
use Symfony\Component\VarDumper\Dumper\DataDumperInterface;
@@ -31,11 +32,13 @@ class DumpDataCollector extends DataCollector implements DataDumperInterface
3132
private $clonesCount = 0;
3233
private $clonesIndex = 0;
3334
private $rootRefs;
35+
private $charset;
3436

35-
public function __construct(Stopwatch $stopwatch = null, $fileLinkFormat = null)
37+
public function __construct(Stopwatch $stopwatch = null, $fileLinkFormat = null, $charset = null)
3638
{
3739
$this->stopwatch = $stopwatch;
3840
$this->fileLinkFormat = $fileLinkFormat ?: ini_get('xdebug.file_link_format') ?: get_cfg_var('xdebug.file_link_format');
41+
$this->charset = $charset ?: ini_get('php.output_encoding') ?: ini_get('default_charset') ?: 'UTF-8';
3942

4043
// All clones share these properties by reference:
4144
$this->rootRefs = array(
@@ -98,7 +101,7 @@ public function dump(Data $data)
98101
$fileExcerpt = array();
99102

100103
for ($i = max($line - 3, 1), $max = min($line + 3, count($src)); $i <= $max; ++$i) {
101-
$fileExcerpt[] = '<li'.($i === $line ? ' class="selected"' : '').'><code>'.htmlspecialchars($src[$i - 1]).'</code></li>';
104+
$fileExcerpt[] = '<li'.($i === $line ? ' class="selected"' : '').'><code>'.$this->htmlEncode($src[$i - 1]).'</code></li>';
102105
}
103106

104107
$fileExcerpt = '<ol start="'.max($line - 3, 1).'">'.implode("\n", $fileExcerpt).'</ol>';
@@ -158,7 +161,7 @@ public function getDumps($format, $maxDepthLimit = -1, $maxItemsPerDepth = -1)
158161
$data = fopen('php://memory', 'r+b');
159162

160163
if ('html' === $format) {
161-
$dumper = new HtmlDumper($data);
164+
$dumper = new HtmlDumper($data, $this->charset);
162165
} else {
163166
throw new \InvalidArgumentException(sprintf('Invalid dump format: %s', $format));
164167
}
@@ -195,19 +198,18 @@ public function __destruct()
195198
}
196199

197200
if ('cli' !== PHP_SAPI && stripos($h[$i], 'html')) {
198-
echo '<meta http-equiv="Content-Type" content="text/html; charset=utf-8">';
199-
$dumper = new HtmlDumper('php://output');
201+
$dumper = new HtmlDumper('php://output', $this->charset);
200202
} else {
201-
$dumper = new CliDumper('php://output');
203+
$dumper = new CliDumper('php://output', $this->charset);
202204
$dumper->setColors(false);
203205
}
204206

205207
foreach ($this->data as $i => $dump) {
206208
$this->data[$i] = null;
207209

208210
if ($dumper instanceof HtmlDumper) {
209-
$dump['name'] = htmlspecialchars($dump['name'], ENT_QUOTES, 'UTF-8');
210-
$dump['file'] = htmlspecialchars($dump['file'], ENT_QUOTES, 'UTF-8');
211+
$dump['name'] = $this->htmlEncode($dump['name']);
212+
$dump['file'] = $this->htmlEncode($dump['file']);
211213
if ('' !== $dump['file']) {
212214
if ($this->fileLinkFormat) {
213215
$link = strtr($this->fileLinkFormat, array('%f' => $dump['file'], '%l' => $dump['line']));
@@ -227,4 +229,18 @@ public function __destruct()
227229
$this->dataCount = 0;
228230
}
229231
}
232+
233+
private function htmlEncode($s)
234+
{
235+
$html = '';
236+
237+
$dumper = new HtmlDumper(function ($line) use (&$html) {$html .= $line;}, $this->charset);
238+
$dumper->setDumpHeader('');
239+
$dumper->setDumpBoundaries('', '');
240+
241+
$cloner = new VarCloner();
242+
$dumper->dump($cloner->cloneVar($s));
243+
244+
return substr(strip_tags($html), 1, -1);
245+
}
230246
}

0 commit comments

Comments
 (0)