/usr/share/phpmyadmin/libraries/classes
Edit: /usr/share/phpmyadmin/libraries/classes/ErrorHandler.php (17557B)
errorReporting = error_reporting();
}
/**
* Destructor
*
* stores errors in session
*/
public function __destruct()
{
if (! isset($_SESSION['errors'])) {
$_SESSION['errors'] = [];
}
// remember only not displayed errors
foreach ($this->errors as $key => $error) {
/**
* We don't want to store all errors here as it would
* explode user session.
*/
if (count($_SESSION['errors']) >= 10) {
$error = new Error(
0,
__('Too many error messages, some are not displayed.'),
__FILE__,
__LINE__
);
$_SESSION['errors'][$error->getHash()] = $error;
break;
}
if ((! ($error instanceof Error))
|| $error->isDisplayed()
) {
continue;
}
$_SESSION['errors'][$key] = $error;
}
}
/**
* Toggles location hiding
*
* @param bool $hide Whether to hide
*/
public function setHideLocation(bool $hide): void
{
$this->hideLocation = $hide;
}
/**
* returns array with all errors
*
* @param bool $check Whether to check for session errors
*
* @return Error[]
*/
public function getErrors(bool $check = true): array
{
if ($check) {
$this->checkSavedErrors();
}
return $this->errors;
}
/**
* returns the errors occurred in the current run only.
* Does not include the errors saved in the SESSION
*
* @return Error[]
*/
public function getCurrentErrors(): array
{
return $this->errors;
}
/**
* Pops recent errors from the storage
*
* @param int $count Old error count
*
* @return Error[]
*/
public function sliceErrors(int $count): array
{
$errors = $this->getErrors(false);
$this->errors = array_splice($errors, 0, $count);
return array_splice($errors, $count);
}
/**
* Error handler - called when errors are triggered/occurred
*
* This calls the addError() function, escaping the error string
* Ignores the errors wherever Error Control Operator (@) is used.
*
* @param int $errno error number
* @param string $errstr error string
* @param string $errfile error file
* @param int $errline error line
*/
public function handleError(
int $errno,
string $errstr,
string $errfile,
int $errline
): void {
if (Util::isErrorReportingAvailable()) {
/**
* Check if Error Control Operator (@) was used, but still show
* user errors even in this case.
* See: https://github.com/phpmyadmin/phpmyadmin/issues/16729
*/
$isSilenced = ! (error_reporting() & $errno);
if (PHP_VERSION_ID < 80000) {
$isSilenced = error_reporting() == 0;
}
if ($isSilenced &&
$this->errorReporting != 0 &&
($errno & (E_USER_WARNING | E_USER_ERROR | E_USER_NOTICE | E_USER_DEPRECATED)) == 0
) {
return;
}
} else {
if (($errno & (E_USER_WARNING | E_USER_ERROR | E_USER_NOTICE | E_USER_DEPRECATED)) == 0) {
return;
}
}
$this->addError($errstr, $errno, $errfile, $errline, true);
}
/**
* Add an error; can also be called directly (with or without escaping)
*
* The following error types cannot be handled with a user defined function:
* E_ERROR, E_PARSE, E_CORE_ERROR, E_CORE_WARNING, E_COMPILE_ERROR,
* E_COMPILE_WARNING,
* and most of E_STRICT raised in the file where set_error_handler() is called.
*
* Do not use the context parameter as we want to avoid storing the
* complete $GLOBALS inside $_SESSION['errors']
*
* @param string $errstr error string
* @param int $errno error number
* @param string $errfile error file
* @param int $errline error line
* @param bool $escape whether to escape the error string
*/
public function addError(
string $errstr,
int $errno,
string $errfile,
int $errline,
bool $escape = true
): void {
if ($escape) {
$errstr = htmlspecialchars($errstr);
}
// create error object
$error = new Error(
$errno,
$errstr,
$errfile,
$errline
);
$error->setHideLocation($this->hideLocation);
// do not repeat errors
$this->errors[$error->getHash()] = $error;
switch ($error->getNumber()) {
case E_STRICT:
case E_DEPRECATED:
case E_NOTICE:
case E_WARNING:
case E_CORE_WARNING:
case E_COMPILE_WARNING:
case E_RECOVERABLE_ERROR:
/* Avoid rendering BB code in PHP errors */
$error->setBBCode(false);
break;
case E_USER_NOTICE:
case E_USER_WARNING:
case E_USER_ERROR:
case E_USER_DEPRECATED:
// just collect the error
// display is called from outside
break;
case E_ERROR:
case E_PARSE:
case E_CORE_ERROR:
case E_COMPILE_ERROR:
default:
// FATAL error, display it and exit
$this->dispFatalError($error);
exit;
}
}
/**
* trigger a custom error
*
* @param string $errorInfo error message
* @param int $errorNumber error number
*/
public function triggerError(string $errorInfo, ?int $errorNumber = null): void
{
// we could also extract file and line from backtrace
// and call handleError() directly
trigger_error($errorInfo, $errorNumber);
}
/**
* display fatal error and exit
*
* @param Error $error the error
*/
protected function dispFatalError(Error $error): void
{
if (! headers_sent()) {
$this->dispPageStart($error);
}
echo $error->getDisplay();
$this->dispPageEnd();
exit;
}
/**
* Displays user errors not displayed
*/
public function dispUserErrors(): void
{
echo $this->getDispUserErrors();
}
/**
* Renders user errors not displayed
*/
public function getDispUserErrors(): string
{
$retval = '';
foreach ($this->getErrors() as $error) {
if (! $error->isUserError() || $error->isDisplayed()) {
continue;
}
$retval .= $error->getDisplay();
}
return $retval;
}
/**
* display HTML header
*
* @param Error $error the error
*/
protected function dispPageStart(?Error $error = null): void
{
Response::getInstance()->disable();
echo '
';
if ($error) {
echo $error->getTitle();
} else {
echo 'phpMyAdmin error reporting page';
}
echo '';
}
/**
* display HTML footer
*/
protected function dispPageEnd(): void
{
echo '