Bug #81454 [Com]: error_reporting() and ini_get('error_reporting') can get out of sync using @
| From: | antonino dot spampinato86 at gmail dot com | Date: | Sun, 19 Sep 2021 21:07:11 +0000 |
| Subject: | Bug #81454 [Com]: error_reporting() and ini_get('error_reporting') can get out of sync using @ | ||
| References: | 1 | Groups: | php.bugs |
| Request: | Send a blank email to php-bugs+get-236705@lists.php.net to get a copy of this message | ||
Edit report at https://bugs.php.net/bug.php?id=81454&edit=1
ID: 81454
Comment by: antonino dot spampinato86 at gmail dot com
Reported by: daimona dot wiki at gmail dot com
Summary: error_reporting() and ini_get('error_reporting') can
get out of sync using @
Status: Open
Type: Bug
Package: Scripting Engine problem
Operating System: Any
PHP Version: Irrelevant
Block user comment: N
Private report: N
New Comment:
<?php
# different results for PHP 5.x and 8.x:
//-1 only works in 2s-complement numeric representations, ~0 in 1s-complement numeric
representations
//ini_set('error_reporting', 2);
$a = array();
$a['ini_get'] = @ini_get('error_reporting');
if(is_string($a['ini_get'])) //return ini_get empty string for false or null, if undefined
is default "null" prior 5.3 it's return bool false #42657
$a['ini_get'] = ini_get('error_reporting');
$a['error_reporting'] = @error_reporting();
if(is_int($a['error_reporting']))
$a['error_reporting'] = error_reporting();
$a['bug'] = @error_reporting();
$b = false; //function not work?
$c = null; //function disabled?
var_dump($a, @$b, @$c);
Expected result:
array(3) {
["ini_get"]=>
string(2) "-1"
["error_reporting"]=>
int(-1)
["bug"]=>
int(-1)
}
bool(false)
NULL
php >= 8:
array(3) {
["ini_get"]=>
string(2) "-1"
["error_reporting"]=>
int(-1)
["bug"]=>
int(4437)
}
bool(false)
NULL
php < 8:
array(3) {
["ini_get"]=>
string(2) "-1"
["error_reporting"]=>
int(-1)
["bug"]=>
int(0)
}
bool(false)
NULL
Previous Comments:
------------------------------------------------------------------------
[2021-09-19 15:51:29] antonino dot spampinato86 at gmail dot com
For php >= 8 https://www.php.net/manual/en/migration80.incompatible.php
------------------------------------------------------------------------
[2021-09-19 15:48:38] antonino dot spampinato86 at gmail dot com
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:
For consistency even the value 0, as it previously indicated error suppression. The php constants of
the errors is a numerical sequence, a mask means from the single or the union of them.
------------------------------------------------------------------------
[2021-09-17 19:37:54] daimona dot wiki at gmail dot com
Description:
------------
This bug is a direct consequence of bug #75924. That one essentially states that, starting with PHP
7, the @ operator affects the output of error_reporting(), but not that of
ini_get('error_reporting').
Now, consider the following test case: https://3v4l.org/70QJY
For the PHP 7 examples, I'd expect error_reporting() and ini_get() to return the same value
(-1) in "POST", but this is not the case.
AIUI, it happens because:
- error_reporting() and ini_get() are out of sync when testFunc() starts, per bug #75924
- error_reporting(0) syncs them again, as expected
- Same for error_reporting($orig)
- But then, when the silenced statement ends, only error_reporting() is restored (because only
error_reporting() was changed by @, I guess)
This bug affects all versions of PHP starting from 7.0. PHP 8 is also affected, even though some
numeric values are different.
Test script:
---------------
function testFunc() {
print "INSIDE 1 er=" . error_reporting() . ' ini=' . intval( ini_get(
'error_reporting' ) ) . "\n";
$orig = error_reporting( 0 );
print "INSIDE 2 er=" . error_reporting() . ' ini=' . intval( ini_get(
'error_reporting' ) ) . "\n";
error_reporting( $orig );
print "INSIDE 3 er=" . error_reporting() . ' ini=' . intval( ini_get(
'error_reporting' ) ) . "\n";
}
print "PRE er=" . error_reporting() . ' ini=' . intval( ini_get(
'error_reporting' ) ) . "\n";
@testFunc();
print "POST er=" . error_reporting() . ' ini=' . intval( ini_get(
'error_reporting' ) ) . "\n";
Expected result:
----------------
PRE er=-1 ini=-1
INSIDE 1 er=0 ini=0
INSIDE 2 er=0 ini=0
INSIDE 3 er=0 ini=0
POST er=-1 ini=-1
Actual result:
--------------
PRE er=-1 ini=-1
INSIDE 1 er=0 ini=-1
INSIDE 2 er=0 ini=0
INSIDE 3 er=0 ini=0
POST er=-1 ini=0
------------------------------------------------------------------------
--
Edit this bug report at https://bugs.php.net/bug.php?id=81454&edit=1