8000 bug #13902 [Debug] reintroduce charset param to ExceptionHandler (nic… · symfony/symfony@900558c · GitHub
[go: up one dir, main page]

Skip to content

Commit 900558c

Browse files
committed
bug #13902 [Debug] reintroduce charset param to ExceptionHandler (nicolas-grekas)
This PR was merged into the 2.6 branch. Discussion ---------- [Debug] reintroduce charset param to ExceptionHandler | Q | A | ------------- | --- | Bug fix? | yes | New feature? | no | BC breaks? | no | Deprecations? | no | Tests pass? | yes | Fixed tickets | - | License | MIT | Doc PR | - For some reason, we removed the charset arg of the constructor in 2.5, then used the same position to add fileLinkFormat in 2.6. This is a BC break with 2.3. This PR reintroduces charset at second position, with some heuristic to keep compat with 2.6 Commits ------- c8bd867 [Debug] reintroduce charset param to ExceptionHandler
2 parents 43efb1a + c8bd867 commit 900558c

File tree

1 file changed

+28
-10
lines changed

1 file changed

+28
-10
lines changed

src/Symfony/Component/Debug/ExceptionHandler.php

Lines changed: 28 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -30,27 +30,37 @@
3030
class ExceptionHandler
3131
{
3232
private $debug;
33+
private $charset;
3334
private $handler;
3435
private $caughtBuffer;
3536
private $caughtLength;
3637
private $fileLinkFormat;
3738

38-
public function __construct($debug = true, $fileLinkFormat = null)
39+
public function __construct($debug = true, $charset = null, $fileLinkFormat = null)
3940
{
41+
if (false !== strpos($charset, '%') xor false === strpos($fileLinkFormat, '%')) {
42+
// Swap $charset and $fileLinkFormat for BC reasons
43+
$pivot = $fileLinkFormat;
44+
$fileLinkFormat = $charset;
45+
$charset = $pivot;
46+
}
4047
$this->debug = $debug;
48+
$this->charset = $charset ?: ini_get('default_charset') ?: 'UTF-8';
4149
$this->fileLinkFormat = $fileLinkFormat ?: ini_get('xdebug.file_link_format') ?: get_cfg_var('xdebug.file_link_format');
4250
}
4351

4452
/**
4553
* Registers the exception handler.
4654
*
47-
* @param bool $debug
55+
* @param bool $debug Enable/disable debug mode, where the stack trace is displayed
56+
* @param string|null $charset The charset used by exception messages
57+
* @param string|null $fileLinkFormat The IDE link template
4858
*
4959
* @return ExceptionHandler The registered exception handler
5060
*/
51-
public static function register($debug = true, $fileLinkFormat = null)
61+
public static function register($debug = true, $charset = null, $fileLinkFormat = null)
5262
{
53-
$handler = new static($debug, $fileLinkFormat);
63+
$handler = new static($debug, $charset, $fileLinkFormat);
5464

5565
$prev = set_exception_handler(array($handler, 'handle'));
5666
if (is_array($prev) && $prev[0] instanceof ErrorHandler) {
@@ -224,7 +234,7 @@ public function getContent(FlattenException $exception)
224234
foreach ($exception->toArray() as $position => $e) {
225235
$ind = $count - $position + 1;
226236
$class = $this->formatClass($e['class']);
227-
$message = nl2br(self::utf8Htmlize($e['message']));
237+
$message = nl2br($this->escapeHtml($e['message']));
228238
$content .= sprintf(<<<EOF
229239
<h2 class="block_exception clear_fix">
230240
<span class="exception_counter">%d/%d</span>
@@ -252,7 +262,7 @@ public function getContent(FlattenException $exception)
252262
} catch (\Exception $e) {
253263
// something nasty happened and we cannot throw an exception anymore
254264
if ($this->debug) {
255-
$title = sprintf('Exception thrown when handling an exception (%s: %s)', get_class($e), self::utf8Htmlize($e->getMessage()));
265+
$title = sprintf('Exception thrown when handling an exception (%s: %s)', get_class($e), $this->escapeHtml($e->getMessage()));
256266
} else {
257267
$title = 'Whoops, looks like something went wrong.';
258268
}
@@ -338,7 +348,7 @@ private function decorate($content, $css)
338348
<!DOCTYPE html>
339349
<html>
340350
<head>
341-
<meta charset="UTF-8" />
351+
<meta charset="{$this->charset}" />
342352
<meta name="robots" content="noindex,nofollow" />
343353
<style>
344354
/* Copyright (c) 2010, Yahoo! Inc. All rights reserved. Code licensed under the BSD License: http://developer.yahoo.com/yui/license.html */
@@ -366,7 +376,7 @@ private function formatClass($class)
366376

367377
private function formatPath($path, $line)
368378
{
369-
$path = self::utf8Htmlize($path);
379+
$path = $this->escapeHtml($path);
370380
$file = preg_match('#[^/\\\\]*$#', $path, $file) ? $file[0] : $path;
371381

372382
if ($linkFormat = $this->fileLinkFormat) {
@@ -394,15 +404,15 @@ private function formatArgs(array $args)
394404
} elseif ('array' === $item[0]) {
395405
$formattedValue = sprintf("<em>array</em>(%s)", is_array($item[1]) ? $this->formatArgs($item[1]) : $item[1]);
396406
} elseif ('string' === $item[0]) {
397-
$formattedValue = sprintf("'%s'", self::utf8Htmlize($item[1]));
407+
$formattedValue = sprintf("'%s'", $this->escapeHtml($item[1]));
398408
} elseif ('null' === $item[0]) {
399409
$formattedValue = '<em>null</em>';
400410
} elseif ('boolean' === $item[0]) {
401411
$formattedValue = '<em>'.strtolower(var_export($item[1], true)).'</em>';
402412
} elseif ('resource' === $item[0]) {
403413
$formattedValue = '<em>resource</em>';
404414
} else {
405-
$formattedValue = str_replace("\n", '', var_export(self::utf8Htmlize((string) $item[1]), true));
415+
$formattedValue = str_replace("\n", '', var_export($this->escapeHtml((string) $item[1]), true));
406416
}
407417

408418
$result[] = is_int($key) ? $formattedValue : sprintf("'%s' => %s", $key, $formattedValue);
@@ -430,6 +440,14 @@ protected static function utf8Htmlize($str)
430440
return htmlspecialchars($str, ENT_QUOTES | (PHP_VERSION_ID >= 50400 ? ENT_SUBSTITUTE : 0), 'UTF-8');
431441
}
432442

443+
/**
444+
* HTML-encodes a string
445+
*/
446+
private function escapeHtml($str)
447+
{
448+
return htmlspecialchars($str, ENT_QUOTES | (PHP_VERSION_ID >= 50400 ? ENT_SUBSTITUTE : 0), $this->charset);
449+
}
450+
433451
/**
434452
* @internal
435453
*/

0 commit comments

Comments
 (0)
0