|
php.net | support | documentation | report a bug | advanced search | search howto | statistics | random bug | login |
[2021-11-23 11:45 UTC] joupicky at gmail dot com
Description: ------------ The value of error_reporting() function (and global error reporting setting) gets overridden when a native PHP function such as random_int() or filemtime() gets called with a suppress "@" operator and assigned to a class variable. I am running PHP Version 8.0.13 with the latest Apache2. I was able to reproduce this also when ran as FPM. I was not able to reproduce this when called as CLI. I am using a precompiled binaries from https://launchpad.net/~ondrej/+archive/ubuntu/php/. I was not able to reproduce this on PHP7.4 when install via Ubuntu repos. This might be only relevant to the build from that repository (which is used by many people AFAIK). Test script: --------------- <?php error_reporting(E_ALL); class Foo { public $a; public function bar() { $this->a = (true) ? @random_int(0, 100) : false; } } var_dump(error_reporting()); //int(32767) = E_ALL $c = new Foo(); $c->bar(); var_dump(error_reporting()); //random int Expected result: ---------------- int(32767) int(32767) Actual result: -------------- int(32767) int(5) //random int PatchesPull RequestsHistoryAllCommentsChangesGit/SVN commits
|
|||||||||||||||||||||||||||||||||||||
Copyright © 2001-2025 The PHP GroupAll rights reserved. |
Last updated: Sat Oct 25 11:00:01 2025 UTC |
I doubt this is a valid expression for your ternary operator, also with this code the integer value change for error_reporting occurs? error_reporting(E_ALL); class Foo { public $a; public function seta($a) { $b = @random_int(16, 16); if(is_int($b)) $this->a = $b; return $a; } public function numbera() { return $this->a; } } $c = new Foo(); $c->seta(0); $var = $c->numbera(); if($var != 16) echo 'bug' . PHP_EOL; else echo 'normal' . PHP_EOL; var_dump($var, error_reporting(), @error_reporting()); The @ operator will no longer silence fatal errors (E_ERROR == 1, E_CORE_ERROR == 4, E_COMPILE_ERROR == 64, E_USER_ERROR == 256, E_RECOVERABLE_ERROR == 4096, E_PARSE == 4) https://www.php.net/manual/en/migration80.incompatible.phpI was able to reproduce this in a fresh Ubuntu 20.04 setup, here are reproduction steps which should work starting from spinning up fresh Ubuntu 20.04 on Amazon EC2. Interesting, the issue doesn't always happen if you hit the file immediately after creating it, even if you hit it multiple times immediately after creating it, a small delay is necessary. Test Process -------------------- sudo su add-apt-repository ppa:ondrej/php apt-get update apt-get upgrade apt-get install php8.0-fpm apache2 a2enmod proxy_fcgi rm /etc/apache2/sites-enabled/000-default.conf cat /etc/apache2/sites-available/000-default.conf | grep -v "</VirtualHost>" > /etc/apache2/sites-enabled/000-default.conf cat >>/etc/apache2/sites-enabled/000-default.conf <<'EOF' <FilesMatch "\.php$"> <If "-f %{REQUEST_FILENAME}"> SetHandler "proxy:unix:/var/run/php/php8.0-fpm.sock|fcgi://localhost/" </If> </FilesMatch> </VirtualHost> EOF service apache2 restart cat >/var/www/html/test-1.php <<'EOF' <?php error_reporting(E_ALL); class Foo { public $a; public function bar() { $this->a = (true) ? @random_int(0, 100) : false; } } echo "Should Equal 32767: " . error_reporting() . "\n"; $c = new Foo(); $c->bar(); echo "Should Equal 32767: " . error_reporting() . "\n"; EOF echo "Sleeping 2 seconds to more reliably trigger the issue..." sleep 2 for x in 1 2 3 4 ; do curl http://localhost/test-1.php; done ----------The QM_ASSIGN to T0 is eliminated, even though there is a read of T0 in between: Foo::bar: ; (lines=10, args=0, vars=0, tmps=2, ssa_vars=3, no_loops) ; (after dce pass) ; /home/nikic/php/php-src/t484.php:6-8 ; return [null] RANGE[0..0] BB0: ; start exit lines=[0-9] ; level=0 0000 #0.T0 [long] = BEGIN_SILENCE 0001 INIT_FCALL 2 112 string("random_int") 0002 SEND_VAL int(0) 1 0003 SEND_VAL int(100) 2 0004 #1.V1 [long] = DO_ICALL 0005 END_SILENCE #0.T0 [long] 0006 #2.T0 [long] = QM_ASSIGN #1.V1 [long] 0007 ASSIGN_OBJ THIS string("a") 0008 OP_DATA #2.T0 [long] 0009 RETURN null Foo::bar: ; (lines=9, args=0, vars=0, tmps=2, ssa_vars=3, no_loops) ; (after dfa pass) ; /home/nikic/php/php-src/t484.php:6-8 ; return [null] RANGE[0..0] BB0: ; start exit lines=[0-8] ; level=0 0000 #0.T0 [long] = BEGIN_SILENCE 0001 INIT_FCALL 2 112 string("random_int") 0002 SEND_VAL int(0) 1 0003 SEND_VAL int(100) 2 0004 #2.T0 [long] = DO_ICALL 0005 END_SILENCE #0.T0 [long] 0006 ASSIGN_OBJ THIS string("a") 0007 OP_DATA #2.T0 [long] 0008 RETURN null