Don't silence fatal errors with @

This commit is contained in:
Nikita Popov 2018-11-26 21:20:03 +01:00
parent b65435c986
commit a302d11610
15 changed files with 53 additions and 19 deletions

View file

@ -42,6 +42,30 @@ PHP 8.0 UPGRADE NOTES
. Any array that has a number n as its first numeric key will use n+1 for . Any array that has a number n as its first numeric key will use n+1 for
its next implicit key. Even if n is negative. its next implicit key. Even if n is negative.
RFC: https://wiki.php.net/rfc/negative_array_index RFC: https://wiki.php.net/rfc/negative_array_index
. The @ operator will no longer silence fatal errors (E_ERROR, E_CORE_ERROR,
E_COMPILE_ERROR, E_USER_ERROR, E_RECOVERABLE_ERROR, E_PARSE). Error handlers
that expect error_reporting to be 0 when @ is used, should be adjusted to
use a mask check instead:
// Replace
function my_error_handler($err_no, $err_msg, $filename, $linenum) {
if (error_reporting() == 0)
return; // Silenced
}
// ...
}
// With
function my_error_handler($err_no, $err_msg, $filename, $linenum) {
if (error_reporting() & $err_no)
return; // Silenced
}
// ...
}
Additionally, care should be taken that error messages are not displayed in
production environments, which can result in information leaks. Please
ensure that display_errors=Off is used in conjunction with error logging.
- Date: - Date:
. mktime() and gmmktime() now require at least one argument. time() can be . mktime() and gmmktime() now require at least one argument. time() can be

View file

@ -10,13 +10,13 @@ function bar() {
echo "bar: ".error_reporting()."\n"; echo "bar: ".error_reporting()."\n";
} }
error_reporting(1); error_reporting(E_WARNING);
echo "before: ".error_reporting()."\n"; echo "before: ".error_reporting()."\n";
@foo(1,@bar(),3); @foo(1,@bar(),3);
echo "after: ".error_reporting()."\n"; echo "after: ".error_reporting()."\n";
?> ?>
--EXPECT-- --EXPECT--
before: 1 before: 2
bar: 0 bar: 0
foo: 0 foo: 0
after: 1 after: 2

View file

@ -39,4 +39,9 @@
#define E_ALL (E_ERROR | E_WARNING | E_PARSE | E_NOTICE | E_CORE_ERROR | E_CORE_WARNING | E_COMPILE_ERROR | E_COMPILE_WARNING | E_USER_ERROR | E_USER_WARNING | E_USER_NOTICE | E_RECOVERABLE_ERROR | E_DEPRECATED | E_USER_DEPRECATED | E_STRICT) #define E_ALL (E_ERROR | E_WARNING | E_PARSE | E_NOTICE | E_CORE_ERROR | E_CORE_WARNING | E_COMPILE_ERROR | E_COMPILE_WARNING | E_USER_ERROR | E_USER_WARNING | E_USER_NOTICE | E_RECOVERABLE_ERROR | E_DEPRECATED | E_USER_DEPRECATED | E_STRICT)
#define E_CORE (E_CORE_ERROR | E_CORE_WARNING) #define E_CORE (E_CORE_ERROR | E_CORE_WARNING)
/* Fatal errors that are ignored by the silence operator */
#define E_FATAL_ERRORS (E_ERROR | E_CORE_ERROR | E_COMPILE_ERROR | E_USER_ERROR | E_RECOVERABLE_ERROR | E_PARSE)
#define E_HAS_ONLY_FATAL_ERRORS(mask) !((mask) & ~E_FATAL_ERRORS)
#endif /* ZEND_ERRORS_H */ #endif /* ZEND_ERRORS_H */

View file

@ -3757,7 +3757,8 @@ static void cleanup_live_vars(zend_execute_data *execute_data, uint32_t op_num,
} }
} else if (kind == ZEND_LIVE_SILENCE) { } else if (kind == ZEND_LIVE_SILENCE) {
/* restore previous error_reporting value */ /* restore previous error_reporting value */
if (!EG(error_reporting) && Z_LVAL_P(var) != 0) { if (E_HAS_ONLY_FATAL_ERRORS(EG(error_reporting))
&& !E_HAS_ONLY_FATAL_ERRORS(Z_LVAL_P(var))) {
EG(error_reporting) = Z_LVAL_P(var); EG(error_reporting) = Z_LVAL_P(var);
} }
} }

View file

@ -6755,9 +6755,10 @@ ZEND_VM_HANDLER(57, ZEND_BEGIN_SILENCE, ANY, ANY)
ZVAL_LONG(EX_VAR(opline->result.var), EG(error_reporting)); ZVAL_LONG(EX_VAR(opline->result.var), EG(error_reporting));
if (EG(error_reporting)) { if (!E_HAS_ONLY_FATAL_ERRORS(EG(error_reporting))) {
do { do {
EG(error_reporting) = 0; /* Do not silence fatal errors */
EG(error_reporting) &= E_FATAL_ERRORS;
if (!EG(error_reporting_ini_entry)) { if (!EG(error_reporting_ini_entry)) {
zval *zv = zend_hash_find_ex(EG(ini_directives), ZSTR_KNOWN(ZEND_STR_ERROR_REPORTING), 1); zval *zv = zend_hash_find_ex(EG(ini_directives), ZSTR_KNOWN(ZEND_STR_ERROR_REPORTING), 1);
if (zv) { if (zv) {
@ -6786,7 +6787,8 @@ ZEND_VM_HANDLER(58, ZEND_END_SILENCE, TMP, ANY)
{ {
USE_OPLINE USE_OPLINE
if (!EG(error_reporting) && Z_LVAL_P(EX_VAR(opline->op1.var)) != 0) { if (E_HAS_ONLY_FATAL_ERRORS(EG(error_reporting))
&& !E_HAS_ONLY_FATAL_ERRORS(Z_LVAL_P(EX_VAR(opline->op1.var)))) {
EG(error_reporting) = Z_LVAL_P(EX_VAR(opline->op1.var)); EG(error_reporting) = Z_LVAL_P(EX_VAR(opline->op1.var));
} }
ZEND_VM_NEXT_OPCODE(); ZEND_VM_NEXT_OPCODE();

View file

@ -1493,9 +1493,10 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_BEGIN_SILENCE_SPEC_HANDLER(ZEN
ZVAL_LONG(EX_VAR(opline->result.var), EG(error_reporting)); ZVAL_LONG(EX_VAR(opline->result.var), EG(error_reporting));
if (EG(error_reporting)) { if (!E_HAS_ONLY_FATAL_ERRORS(EG(error_reporting))) {
do { do {
EG(error_reporting) = 0; /* Do not silence fatal errors */
EG(error_reporting) &= E_FATAL_ERRORS;
if (!EG(error_reporting_ini_entry)) { if (!EG(error_reporting_ini_entry)) {
zval *zv = zend_hash_find_ex(EG(ini_directives), ZSTR_KNOWN(ZEND_STR_ERROR_REPORTING), 1); zval *zv = zend_hash_find_ex(EG(ini_directives), ZSTR_KNOWN(ZEND_STR_ERROR_REPORTING), 1);
if (zv) { if (zv) {
@ -19620,7 +19621,8 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_END_SILENCE_SPEC_TMP_HANDLER(Z
{ {
USE_OPLINE USE_OPLINE
if (!EG(error_reporting) && Z_LVAL_P(EX_VAR(opline->op1.var)) != 0) { if (E_HAS_ONLY_FATAL_ERRORS(EG(error_reporting))
&& !E_HAS_ONLY_FATAL_ERRORS(Z_LVAL_P(EX_VAR(opline->op1.var)))) {
EG(error_reporting) = Z_LVAL_P(EX_VAR(opline->op1.var)); EG(error_reporting) = Z_LVAL_P(EX_VAR(opline->op1.var));
} }
ZEND_VM_NEXT_OPCODE(); ZEND_VM_NEXT_OPCODE();

View file

@ -17,7 +17,7 @@ echo "*** Testing mb_substitute_character() : usage variation ***\n";
// Define error handler // Define error handler
function test_error_handler($err_no, $err_msg, $filename, $linenum) { function test_error_handler($err_no, $err_msg, $filename, $linenum) {
if (error_reporting() != 0) { if (error_reporting() & $err_no) {
// report non-silenced errors // report non-silenced errors
echo "Error: $err_no - $err_msg, $filename($linenum)\n"; echo "Error: $err_no - $err_msg, $filename($linenum)\n";
} }

View file

@ -13,7 +13,7 @@ echo "*** Testing class_implements() : variation ***\n";
// Define error handler // Define error handler
function test_error_handler($err_no, $err_msg, $filename, $linenum) { function test_error_handler($err_no, $err_msg, $filename, $linenum) {
if (error_reporting() != 0) { if (error_reporting() & $err_no) {
// report non-silenced errors // report non-silenced errors
echo "Error: $err_no - $err_msg, $filename($linenum)\n"; echo "Error: $err_no - $err_msg, $filename($linenum)\n";
} }

View file

@ -13,7 +13,7 @@ echo "*** Testing class_uses() : variation ***\n";
// Define error handler // Define error handler
function test_error_handler($err_no, $err_msg, $filename, $linenum) { function test_error_handler($err_no, $err_msg, $filename, $linenum) {
if (error_reporting() != 0) { if (error_reporting() & $err_no) {
// report non-silenced errors // report non-silenced errors
echo "Error: $err_no - $err_msg, $filename($linenum)\n"; echo "Error: $err_no - $err_msg, $filename($linenum)\n";
} }

View file

@ -12,7 +12,7 @@ echo "*** Testing array_multisort() : usage variation ***\n";
// Define error handler // Define error handler
function test_error_handler($err_no, $err_msg, $filename, $linenum) { function test_error_handler($err_no, $err_msg, $filename, $linenum) {
if (error_reporting() != 0) { if (error_reporting() & $err_no) {
// report non-silenced errors // report non-silenced errors
echo "Error: $err_no - $err_msg, $filename($linenum)\n"; echo "Error: $err_no - $err_msg, $filename($linenum)\n";
} }

View file

@ -12,7 +12,7 @@ echo "*** Testing array_multisort() : usage variation ***\n";
// Define error handler // Define error handler
function test_error_handler($err_no, $err_msg, $filename, $linenum) { function test_error_handler($err_no, $err_msg, $filename, $linenum) {
if (error_reporting() != 0) { if (error_reporting() & $err_no) {
// report non-silenced errors // report non-silenced errors
echo "Error: $err_no - $err_msg, $filename($linenum)\n"; echo "Error: $err_no - $err_msg, $filename($linenum)\n";
} }

View file

@ -12,7 +12,7 @@ echo "*** Testing array_multisort() : usage variation ***\n";
// Define error handler // Define error handler
function test_error_handler($err_no, $err_msg, $filename, $linenum) { function test_error_handler($err_no, $err_msg, $filename, $linenum) {
if (error_reporting() != 0) { if (error_reporting() & $err_no) {
// report non-silenced errors // report non-silenced errors
echo "Error: $err_no - $err_msg, $filename($linenum)\n"; echo "Error: $err_no - $err_msg, $filename($linenum)\n";
} }

View file

@ -14,7 +14,7 @@ echo "*** Testing file_put_contents() : usage variation ***\n";
// Define error handler // Define error handler
function test_error_handler($err_no, $err_msg, $filename, $linenum) { function test_error_handler($err_no, $err_msg, $filename, $linenum) {
if (error_reporting() != 0) { if (error_reporting() & $err_no) {
// report non-silenced errors // report non-silenced errors
echo "Error: $err_no - $err_msg, $filename($linenum)\n"; echo "Error: $err_no - $err_msg, $filename($linenum)\n";
} }

View file

@ -14,7 +14,7 @@ echo "*** Testing file_put_contents() : usage variation ***\n";
// Define error handler // Define error handler
function test_error_handler($err_no, $err_msg, $filename, $linenum) { function test_error_handler($err_no, $err_msg, $filename, $linenum) {
if (error_reporting() != 0) { if (error_reporting() & $err_no) {
// report non-silenced errors // report non-silenced errors
echo "Error: $err_no - $err_msg, $filename($linenum)\n"; echo "Error: $err_no - $err_msg, $filename($linenum)\n";
} }

View file

@ -12,7 +12,7 @@ echo "*** Testing intval() : usage variation ***\n";
// Define error handler // Define error handler
function test_error_handler($err_no, $err_msg, $filename, $linenum) { function test_error_handler($err_no, $err_msg, $filename, $linenum) {
if (error_reporting() != 0) { if (error_reporting() & $err_no) {
// report non-silenced errors // report non-silenced errors
echo "Error: $err_no - $err_msg, $filename($linenum)\n"; echo "Error: $err_no - $err_msg, $filename($linenum)\n";
} }