/** * Handles uncaught exceptions * * @param \Exception $exception * @return boolean */ public function onUncaughtException(\Exception $exception) { if (ob_get_level() > 0) { ob_end_clean(); } if (self::$_isActive === true) { echo $exception->getMessage(); } self::$_isActive = true; /* @note in the original sources the following annotation can be found: Escape the exception's message avoiding possible XSS injections? But then they the value is only copied */ $className = get_class($exception); $message = $exception->getMessage(); $html = '<html><head><meta http-equiv="Content-Type" content="text/html; charset="utf-8" /><title>' . $className . ': ' . $message . '</title>' . $this->getCssSources() . '</head><body>' . $this->getVersion() . '<div align="center"><div class="error-main"><h1>' . $className . ': ' . $message . '</h1><span class="error-file">' . $exception->getFile() . ' (' . $exception->getLine() . ')</span></div>'; if ($this->_showBackTrace === true) { $html .= '<div class="error-info"><div id="tabs"><ul><li><a href="#error-tabs-1">Backtrace</a></li><li><a href="#error-tabs-2">Request</a></li><li><a href="#error-tabs-3">Server</a></li><li><a href="#error-tabs-4">Included Files</a></li><li><a href="#error-tabs-5">Memory</a></li>'; if (is_array($this->_data) === true) { $html .= '<li><a href="error-tabs-6">Variables</a></li>'; } $html .= '</ul><div id="error-tabs-1"><table cellspacing="0" align="center" width="100%">'; $trace = $exception->getTrace(); foreach ($trace as $n => $traceItem) { $html .= $this->showTraceItem($n, $traceItem); } $html .= '</table></div><div id="error-tabs-2"><table cellspacing="0" align="center" class="superglobal-detail"><tr><th>Key</th><th>Value</th></tr>'; //@note $_REQUEST contains unfiltered data, but there is no escaping $r = $_REQUEST; foreach ($r as $keyRequest => $value) { $html .= '<tr><td class="key">' . $keyRequest . '</td><td>' . $value . '</td></tr>'; } $html .= '</table></div><div id="error-tabs-3"><table cellspacing="0" align="center" class="superglobal-detail"><tr><th>Key</th><th>Value</th></tr>'; //@note $_SERVER contains unfiltered data, but there is no escaping $r = $_SERVER; foreach ($r as $keyServer => $value) { $html .= '<tr><td class="key">' . $keyServer . '</td><td>' . $this->_getVarDump($value) . '</td></tr>'; } $html .= '</table></div><div id="error-tabs-4"><table cellspacing="0" align="center" class="superglobal-detail"><tr><th>#</th><th>Path</th></tr>'; //@note paths are not escaped $files = get_included_files(); foreach ($files as $keyFile => $value) { //@note "td" opening element for key was changed to "th" $html .= '<tr><th>' . $keyFile . '</th><td>' . $value . '</td></tr>'; } $html .= '</table></div><div id="error-tabs-5"><table cellspacing="0" align="center" class="superglobal-detail"><tr><th colspan="2">Memory</th></tr><tr><td>Usage</td><td>' . (string) memory_get_usage() . '</td></tr></table></div>'; if (is_array($this->_data) === true) { $html .= '<div id="error-tabs-6"><table cellspacing="0" align="center" class="superglobal-detail"><tr><th>Key</th><th>Value</th></tr>'; foreach ($this->_data as $keyVar => $dataVar) { //@note the c code is wrong, $dataVar is never int but an array! $html .= '<tr><td class="key">' . $keyVar . '</td><td>' . $this->_getVarDump((int) $dataVar) . '</td></tr>'; } $html .= '</table></div>'; } $html .= '</div>'; } //Get javascript sources $html .= $this->getJsSources() . '</div></body></html>'; //Print the HTML //@todo add an option to store the html echo $html; //Unlock the exception renderer self::$_isActive = false; return true; }