30
30
class ExceptionHandler
31
31
{
32
32
private $ debug ;
33
+ private $ charset ;
33
34
private $ handler ;
34
35
private $ caughtBuffer ;
35
36
private $ caughtLength ;
36
37
private $ fileLinkFormat ;
37
38
38
- public function __construct ($ debug = true , $ fileLinkFormat = null )
39
+ public function __construct ($ debug = true , $ charset = null , $ fileLinkFormat = null )
39
40
{
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
+ }
40
47
$ this ->debug = $ debug ;
48
+ $ this ->charset = $ charset ?: ini_get ('default_charset ' ) ?: 'UTF-8 ' ;
41
49
$ this ->fileLinkFormat = $ fileLinkFormat ?: ini_get ('xdebug.file_link_format ' ) ?: get_cfg_var ('xdebug.file_link_format ' );
42
50
}
43
51
44
52
/**
45
53
* Registers the exception handler.
46
54
*
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
48
58
*
49
59
* @return ExceptionHandler The registered exception handler
50
60
*/
51
- public static function register ($ debug = true , $ fileLinkFormat = null )
61
+ public static function register ($ debug = true , $ charset = null , $ fileLinkFormat = null )
52
62
{
53
- $ handler = new static ($ debug , $ fileLinkFormat );
63
+ $ handler = new static ($ debug , $ charset , $ fileLinkFormat );
54
64
55
65
$ prev = set_exception_handler (array ($ handler , 'handle ' ));
56
66
if (is_array ($ prev ) && $ prev [0 ] instanceof ErrorHandler) {
@@ -224,7 +234,7 @@ public function getContent(FlattenException $exception)
224
234
foreach ($ exception ->toArray () as $ position => $ e ) {
225
235
$ ind = $ count - $ position + 1 ;
226
236
$ class = $ this ->formatClass ($ e ['class ' ]);
227
- $ message = nl2br (self :: utf8Htmlize ($ e ['message ' ]));
237
+ $ message = nl2br ($ this -> escapeHtml ($ e ['message ' ]));
228
238
$ content .= sprintf (<<<EOF
229
239
<h2 class="block_exception clear_fix">
230
240
<span class="exception_counter">%d/%d</span>
@@ -252,7 +262,7 @@ public function getContent(FlattenException $exception)
252
262
} catch (\Exception $ e ) {
253
263
// something nasty happened and we cannot throw an exception anymore
254
264
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 ()));
256
266
} else {
257
267
$ title = 'Whoops, looks like something went wrong. ' ;
258
268
}
@@ -338,7 +348,7 @@ private function decorate($content, $css)
338
348
<!DOCTYPE html>
339
349
<html>
340
350
<head>
341
- <meta charset="UTF-8 " />
351
+ <meta charset=" { $ this -> charset } " />
342
352
<meta name="robots" content="noindex,nofollow" />
343
353
<style>
344
354
/* 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)
366
376
367
377
private function formatPath ($ path , $ line )
368
378
{
369
- $ path = self :: utf8Htmlize ($ path );
379
+ $ path = $ this -> escapeHtml ($ path );
370
380
$ file = preg_match ('#[^/ \\\\]*$# ' , $ path , $ file ) ? $ file [0 ] : $ path ;
371
381
372
382
if ($ linkFormat = $ this ->fileLinkFormat ) {
@@ -394,15 +404,15 @@ private function formatArgs(array $args)
394
404
} elseif ('array ' === $ item [0 ]) {
395
405
$ formattedValue = sprintf ("<em>array</em>(%s) " , is_array ($ item [1 ]) ? $ this ->formatArgs ($ item [1 ]) : $ item [1 ]);
396
406
} elseif ('string ' === $ item [0 ]) {
397
- $ formattedValue = sprintf ("'%s' " , self :: utf8Htmlize ($ item [1 ]));
407
+ $ formattedValue = sprintf ("'%s' " , $ this -> escapeHtml ($ item [1 ]));
398
408
} elseif ('null ' === $ item [0 ]) {
399
409
$ formattedValue = '<em>null</em> ' ;
400
410
} elseif ('boolean ' === $ item [0 ]) {
401
411
$ formattedValue = '<em> ' .strtolower (var_export ($ item [1 ], true )).'</em> ' ;
402
412
} elseif ('resource ' === $ item [0 ]) {
403
413
$ formattedValue = '<em>resource</em> ' ;
404
414
} 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 ));
406
416
}
407
417
408
418
$ result [] = is_int ($ key ) ? $ formattedValue : sprintf ("'%s' => %s " , $ key , $ formattedValue );
@@ -430,6 +440,14 @@ protected static function utf8Htmlize($str)
430
440
return htmlspecialchars ($ str , ENT_QUOTES | (PHP_VERSION_ID >= 50400 ? ENT_SUBSTITUTE : 0 ), 'UTF-8 ' );
431
441
}
432
442
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
+
433
451
/**
434
452
* @internal
435
453
*/
0 commit comments