diff --git a/Slim/Error/Renderers/HtmlErrorRenderer.php b/Slim/Error/Renderers/HtmlErrorRenderer.php index 58f5b5630..e9064ad0c 100644 --- a/Slim/Error/Renderers/HtmlErrorRenderer.php +++ b/Slim/Error/Renderers/HtmlErrorRenderer.php @@ -14,7 +14,6 @@ use Throwable; use function get_class; -use function htmlentities; use function htmlspecialchars; use function sprintf; @@ -33,11 +32,7 @@ public function __invoke(Throwable $exception, bool $displayErrorDetails): strin $html .= '

Details

'; $html .= $this->renderExceptionFragment($exception); } else { - $description = htmlspecialchars( - $this->getErrorDescription($exception), - ENT_QUOTES | ENT_SUBSTITUTE, - 'UTF-8' - ); + $description = $this->escapeHtml($this->getErrorDescription($exception)); $html = "

{$description}

"; } @@ -46,26 +41,25 @@ public function __invoke(Throwable $exception, bool $displayErrorDetails): strin private function renderExceptionFragment(Throwable $exception): string { - $html = sprintf('
Type: %s
', get_class($exception)); - - $code = $exception->getCode(); - $html .= sprintf('
Code: %s
', $code); - - $html .= sprintf('
Message: %s
', htmlentities($exception->getMessage())); - - $html .= sprintf('
File: %s
', $exception->getFile()); - - $html .= sprintf('
Line: %s
', $exception->getLine()); - + $html = sprintf('
Type: %s
', $this->escapeHtml(get_class($exception))); + $html .= sprintf('
Code: %s
', $this->escapeHtml((string) $exception->getCode())); + $html .= sprintf('
Message: %s
', $this->escapeHtml($exception->getMessage())); + $html .= sprintf('
File: %s
', $this->escapeHtml($exception->getFile())); + $html .= sprintf('
Line: %s
', $this->escapeHtml((string) $exception->getLine())); $html .= '

Trace

'; - $html .= sprintf('
%s
', htmlentities($exception->getTraceAsString())); + $html .= sprintf('
%s
', $this->escapeHtml($exception->getTraceAsString())); return $html; } + private function escapeHtml(string $text): string + { + return htmlspecialchars($text, ENT_QUOTES | ENT_SUBSTITUTE, 'UTF-8'); + } + public function renderHtmlBody(string $title = '', string $html = ''): string { - $title = htmlspecialchars($title, ENT_QUOTES | ENT_SUBSTITUTE, 'UTF-8'); + $title = $this->escapeHtml($title); return sprintf( '' . diff --git a/tests/Error/AbstractErrorRendererTest.php b/tests/Error/AbstractErrorRendererTest.php index f47fee4c8..d0bc97fc1 100644 --- a/tests/Error/AbstractErrorRendererTest.php +++ b/tests/Error/AbstractErrorRendererTest.php @@ -21,10 +21,18 @@ use Slim\Tests\TestCase; use stdClass; +use function bin2hex; +use function file_put_contents; +use function get_class; use function htmlspecialchars; use function json_decode; use function json_encode; +use function mkdir; +use function random_bytes; +use function rmdir; use function simplexml_load_string; +use function sys_get_temp_dir; +use function unlink; use const ENT_QUOTES; use const ENT_SUBSTITUTE; @@ -74,6 +82,72 @@ public function testHTMLErrorRendererRenderFragmentMethod() $this->assertMatchesRegularExpression('/.*Line*/', $output); } + public function testHTMLErrorRendererEscapesQuotesInErrorDetails() + { + $unsafe = "O'Brien