From f2375073707da99d86d4dc2b2f90d96bd6057734 Mon Sep 17 00:00:00 2001 From: Midah Pasche Date: Wed, 13 Sep 2023 09:20:39 +0200 Subject: [PATCH] refactored html building in Horde_ErrorHandler and return status 500 --- lib/Horde/ErrorHandler.php | 129 ++++++++++++++++++++++++------------- 1 file changed, 86 insertions(+), 43 deletions(-) diff --git a/lib/Horde/ErrorHandler.php b/lib/Horde/ErrorHandler.php index 43e22a36..ce264a32 100644 --- a/lib/Horde/ErrorHandler.php +++ b/lib/Horde/ErrorHandler.php @@ -87,57 +87,19 @@ public static function fatal($error) if (!headers_sent()) { header('Content-type: text/html; charset=UTF-8'); + header('HTTP/1.1 500: Internal Server Error'); } - echo <<< HTML - -Horde :: Fatal Error - -HTML; - - ob_start(); + try { $admin = (isset($registry) && $registry->isAdmin()); - - echo '

' . Horde_Core_Translation::t("A fatal error has occurred") . '

'; - - if (is_object($error) && method_exists($error, 'getMessage')) { - echo '

' . htmlspecialchars($error->getMessage()) . '

'; - } elseif (is_string($error)) { - echo '

' . htmlspecialchars($error) . '

'; - } - - if ($admin) { - if ($error instanceof Throwable || - $error instanceof Exception) { - $trace = $error; - $file = $error->getFile(); - $line = $error->getLine(); - } else { - $trace = debug_backtrace(); - $calling = array_shift($trace); - $file = $calling['file']; - $line = $calling['line']; - } - printf(Horde_Core_Translation::t("in %s:%d"), $file, $line); - echo '
' .
-                    strval(new Horde_Support_Backtrace($trace)) .
-                    '
'; - if (is_object($error)) { - echo '

' . Horde_Core_Translation::t("Details") . '

'; - echo '

' . Horde_Core_Translation::t("The full error message is logged in Horde's log file, and is shown below only to administrators. Non-administrative users will not see error details.") . '

'; - ob_flush(); - flush(); - echo '
' . htmlspecialchars(print_r($error, true)) . '
'; - } - } else { - echo '

' . Horde_Core_Translation::t("Details have been logged for the administrator.") . '

'; - } + $errorHtml = self::getHtmlForError($error, $admin); } catch (Exception $e) { die($e); } + ob_start(); + echo $errorHtml; ob_end_flush(); - echo ''; exit(1); } @@ -209,4 +171,85 @@ public static function catchFatalError() } } + /** + * Returns html for an error + * + * @param string|Throwable $error The error as string message or Throwable + * @param bool $isAdmin If true will also output the complete trace + * If $error is a Throwable its complete content will also be included in the output + * @return string The full html page for that error as a string + */ + public static function getHtmlForError($error, bool $isAdmin = false): string + { + if ($error instanceof Throwable) { + $message = htmlspecialchars($error->getMessage()); + + } else { + $message = $error; + } + $fatalErrorHasOccoured = Horde_Core_Translation::t('A fatal error has occurred'); + if ($isAdmin){ + $detailsHtml = self::getErrorDetailsAsHtml($error); + } else { + $detailsHtml = '

' . Horde_Core_Translation::t("Details have been logged for the administrator.") . '

'; + } + return << + + Horde :: Fatal Error + + + +

{$fatalErrorHasOccoured}

+

{$message}

+ {$detailsHtml} + + + HTMLDELIM; + + } + + /** + * Get the details of an error as html. This should usually only be output to admin users + * + * @param string|Throwable $error The error as string message or Throwable + * @return string The details of that error as html + */ + protected static function getErrorDetailsAsHtml($error): string + { + if ($error instanceof Throwable) { + $trace = strval(new Horde_Support_Backtrace($error)); + $fileName = $error->getFile(); + $lineNo = $error->getLine(); + + $translateDetails = Horde_Core_Translation::t('Details'); + $translateLogInfo = Horde_Core_Translation::t('The full error message is logged in Horde\'s log file, and is shown below only to administrators. Non-administrative users will not see error details.'); + $fullErrorAsHtml = htmlspecialchars(print_r($error, true)); + $fullDetailsHtml = <<$translateDetails +

{$translateLogInfo}

+
+
$fullErrorAsHtml
+
+ HTMLDELIM; + } else { + $trace = debug_backtrace(); + $calling = array_shift($trace); + $trace = strval(new Horde_Support_Backtrace($trace)); + $fileName = $calling['file']; + $lineNo = $calling['line']; + $fullDetailsHtml = ''; + } + $translateIn = sprintf(Horde_Core_Translation::t('in %s:%d'), $fileName, $lineNo); + + return << +
+            {$trace}
+            
+ + {$fullDetailsHtml} + HTMLDELIM; + } }