@@ -34,23 +34,27 @@ class ExceptionHandler
34
34
private $ caughtBuffer ;
35
35
private $ caughtLength ;
36
36
private $ fileLinkFormat ;
37
+ private $ charset ;
37
38
38
- public function __construct ($ debug = true , $ fileLinkFormat = null )
39
+ public function __construct ($ debug = true , $ fileLinkFormat = null , $ charset = null )
39
40
{
40
41
$ this ->debug = $ debug ;
41
42
$ this ->fileLinkFormat = $ fileLinkFormat ?: ini_get ('xdebug.file_link_format ' ) ?: get_cfg_var ('xdebug.file_link_format ' );
43
+ $ this ->charset = $ charset ?: ini_get ('default_charset ' ) ?: 'UTF-8 ' ;
42
44
}
43
45
44
46
/**
45
47
* Registers the exception handler.
46
48
*
47
- * @param bool $debug
49
+ * @param bool $debug Enable/disable debug mode, where the stack trace is displayed
50
+ * @param string|null $fileLinkFormat The IDE link template
51
+ * @param string|null $charset The charset used by exception messages
48
52
*
49
53
* @return ExceptionHandler The registered exception handler
50
54
*/
51
- public static function register ($ debug = true , $ fileLinkFormat = null )
55
+ public static function register ($ debug = true , $ fileLinkFormat = null , $ charset = null )
52
56
{
53
- $ handler = new static ($ debug , $ fileLinkFormat );
57
+ $ handler = new static ($ debug , $ fileLinkFormat, $ charset );
54
58
55
59
$ prev = set_exception_handler (array ($ handler , 'handle ' ));
56
60
if (is_array ($ prev ) && $ prev [0 ] instanceof ErrorHandler) {
@@ -177,6 +181,7 @@ public function sendPhpResponse($exception)
177
181
foreach ($ exception ->getHeaders () as $ name => $ value ) {
178
182
header ($ name .': ' .$ value , false );
179
183
}
184
+ header ('Content-Type: text/html; charset= ' .$ this ->charset );
180
185
}
181
186
182
187
echo $ this ->decorate ($ this ->getContent ($ exception ), $ this ->getStylesheet ($ exception ));
@@ -195,7 +200,7 @@ public function createResponse($exception)
195
200
$ exception = FlattenException::create ($ exception );
196
201
}
197
202
198
- return new Response ($ this ->decorate ($ this ->getContent ($ exception ), $ this ->getStylesheet ($ exception )), $ exception ->getStatusCode (), $ exception ->getHeaders ());
203
+ return Response:: create ($ this ->decorate ($ this ->getContent ($ exception ), $ this ->getStylesheet ($ exception )), $ exception ->getStatusCode (), $ exception ->getHeaders ())-> setCharset ( $ this -> charset );
199
204
}
200
205
201
206
/**
@@ -223,7 +228,7 @@ public function getContent(FlattenException $exception)
223
228
foreach ($ exception ->toArray () as $ position => $ e ) {
224
229
$ ind = $ count - $ position + 1 ;
225
230
$ class = $ this ->formatClass ($ e ['class ' ]);
226
- $ message = nl2br (self :: utf8Htmlize ($ e ['message ' ]));
231
+ $ message = nl2br ($ this -> escapeHtml ($ e ['message ' ]));
227
232
$ content .= sprintf (<<<EOF
228
233
<h2 class="block_exception clear_fix">
229
234
<span class="exception_counter">%d/%d</span>
@@ -337,7 +342,7 @@ private function decorate($content, $css)
337
342
<!DOCTYPE html>
338
343
<html>
339
344
<head>
340
- <meta charset="UTF-8 " />
345
+ <meta charset=" { $ this -> charset } " />
341
346
<meta name="robots" content="noindex,nofollow" />
342
347
<style>
343
348
/* Copyright (c) 2010, Yahoo! Inc. All rights reserved. Code licensed under the BSD License: http://developer.yahoo.com/yui/license.html */
@@ -365,7 +370,7 @@ private function formatClass($class)
365
370
366
371
private function formatPath ($ path , $ line )
367
372
{
368
- $ path = self :: utf8Htmlize ($ path );
373
+ $ path = $ this -> escapeHtml ($ path );
369
374
$ file = preg_match ('#[^/ \\\\]*$# ' , $ path , $ file ) ? $ file [0 ] : $ path ;
370
375
371
376
if ($ linkFormat = $ this ->fileLinkFormat ) {
@@ -393,15 +398,15 @@ private function formatArgs(array $args)
393
398
} elseif ('array ' === $ item [0 ]) {
394
399
$ formattedValue = sprintf ("<em>array</em>(%s) " , is_array ($ item [1 ]) ? $ this ->formatArgs ($ item [1 ]) : $ item [1 ]);
395
400
} elseif ('string ' === $ item [0 ]) {
396
- $ formattedValue = sprintf ("'%s' " , self :: utf8Htmlize ($ item [1 ]));
401
+ $ formattedValue = sprintf ("'%s' " , $ this -> escapeHtml ($ item [1 ]));
397
402
} elseif ('null ' === $ item [0 ]) {
398
403
$ formattedValue = '<em>null</em> ' ;
399
404
} elseif ('boolean ' === $ item [0 ]) {
400
405
$ formattedValue = '<em> ' .strtolower (var_export ($ item [1 ], true )).'</em> ' ;
401
406
} elseif ('resource ' === $ item [0 ]) {
402
407
$ formattedValue = '<em>resource</em> ' ;
403
408
} else {
404
- $ formattedValue = str_replace ("\n" , '' , var_export (self :: utf8Htmlize ((string ) $ item [1 ]), true ));
409
+ $ formattedValue = str_replace ("\n" , '' , var_export ($ this -> escapeHtml ((string ) $ item [1 ]), true ));
405
410
}
406
411
407
412
$ result [] = is_int ($ key ) ? $ formattedValue : sprintf ("'%s' => %s " , $ key , $ formattedValue );
@@ -412,23 +417,24 @@ private function formatArgs(array $args)
412
417
413
418
/**
414
419
* Returns an UTF-8 and HTML encoded string
420
+ *
421
+ * @deprecated since version 2.7, to be removed in 3.0.
415
422
*/
416
423
protected static function utf8Htmlize ($ str )
417
424
{
418
- if (!preg_match ('//u ' , $ str ) && function_exists ('iconv ' )) {
419
- set_error_handler ('var_dump ' , 0 );
420
- $ charset = ini_get ('default_charset ' );
421
- if ('UTF-8 ' === $ charset || $ str !== @iconv ($ charset , $ charset , $ str )) {
422
- $ charset = 'CP1252 ' ;
423
- }
424
- restore_error_handler ();
425
-
426
- $ str = iconv ($ charset , 'UTF-8 ' , $ str );
427
- }
425
+ trigger_error ('The ' .__METHOD__ .' method is deprecated since version 2.7 and will be removed in 3.0. ' , E_USER_DEPRECATED );
428
426
429
427
return htmlspecialchars ($ str , ENT_QUOTES | (PHP_VERSION_ID >= 50400 ? ENT_SUBSTITUTE : 0 ), 'UTF-8 ' );
430
428
}
431
429
430
+ /**
431
+ * HTML-encodes a string
432
+ */
433
+ private function escapeHtml ($ str )
434
+ {
435
+ return htmlspecialchars ($ str , ENT_QUOTES | (PHP_VERSION_ID >= 50400 ? ENT_SUBSTITUTE : 0 ), $ this ->charset );
436
+ }
437
+
432
438
/**
433
439
* @internal
434
440
*/
0 commit comments