From 0981138914a38b2f708f9cb70dd67c4a8d4730e4 Mon Sep 17 00:00:00 2001 From: lazerg Date: Thu, 15 Oct 2026 10:18:18 +0500 Subject: [PATCH 1/2] Fix GH-24337: JIT segfault when decrementing a non-numeric string property --- NEWS | 2 ++ ext/opcache/jit/zend_jit_ir.c | 7 ++-- ext/opcache/tests/jit/gh24337.phpt | 52 ++++++++++++++++++++++++++++++ 3 files changed, 58 insertions(+), 3 deletions(-) create mode 100644 ext/opcache/tests/jit/gh24337.phpt diff --git a/NEWS b/NEWS index e5ff8f8df4d8..189731e6ab1b 100644 --- a/NEWS +++ b/NEWS @@ -56,6 +56,8 @@ PHP NEWS . Fix OSS-Fuzz #568005340 (FETCH_DIM_FUNC_ARG partial conversion). (ndossche) . Fixed bug GH-24218 (Invalid opcode for count() of a literal array when SCCP is disabled). (Lazizbek Ergashev) + . Fixed bug GH-24337 (JIT: segfault when decrementing a non-numeric string + property). (Lazizbek Ergashev) - PDO: . Fixed a duplicate warning when ATTR_STATEMENT_CLASS is rejected on a diff --git a/ext/opcache/jit/zend_jit_ir.c b/ext/opcache/jit/zend_jit_ir.c index 50851d75abb5..92a068dbfaca 100644 --- a/ext/opcache/jit/zend_jit_ir.c +++ b/ext/opcache/jit/zend_jit_ir.c @@ -15823,12 +15823,13 @@ static int zend_jit_incdec_obj(zend_jit_ctx *jit, } if (var_info & (MAY_BE_ANY - MAY_BE_LONG)) { - if (var_info & (MAY_BE_ARRAY|MAY_BE_OBJECT|MAY_BE_RESOURCE)) { - may_throw = 1; - } if (if_long) { ir_IF_FALSE_cold(if_long); } + if (var_info & (MAY_BE_ANY - (MAY_BE_LONG|MAY_BE_DOUBLE))) { + may_throw = 1; + jit_SET_EX_OPLINE(jit, opline); + } if (opline->opcode == ZEND_POST_INC_OBJ || opline->opcode == ZEND_POST_DEC_OBJ) { jit_ZVAL_COPY(jit, res_addr, -1, var_addr, var_info, 1); } diff --git a/ext/opcache/tests/jit/gh24337.phpt b/ext/opcache/tests/jit/gh24337.phpt new file mode 100644 index 000000000000..7be9156d2222 --- /dev/null +++ b/ext/opcache/tests/jit/gh24337.phpt @@ -0,0 +1,52 @@ +--TEST-- +GH-24337 (JIT: segfault in zend_get_executed_lineno when decrementing a non-numeric string property) +--INI-- +opcache.enable=1 +opcache.enable_cli=1 +opcache.file_update_protection=0 +opcache.jit_buffer_size=64M +opcache.jit=tracing +opcache.jit_hot_loop=2 +opcache.jit_hot_func=2 +opcache.jit_hot_return=2 +opcache.jit_hot_side_exit=1 +--EXTENSIONS-- +opcache +--FILE-- +pu--; + } + } +} +class S extends Q { + public $pu = 'u'; + function run() { + parent::run(); + } +} +$objs = [new Q, new S]; +for ($k = 0; $k < 4; $k++) { + foreach ($objs as $o) { + $o->run(); + } +} +var_dump($objs[0]->pu, $objs[1]->pu); +?> +--EXPECT-- +Decrement on non-numeric string has no effect and is deprecated on line 9 +Decrement on non-numeric string has no effect and is deprecated on line 9 +Decrement on non-numeric string has no effect and is deprecated on line 9 +Decrement on non-numeric string has no effect and is deprecated on line 9 +Decrement on non-numeric string has no effect and is deprecated on line 9 +Decrement on non-numeric string has no effect and is deprecated on line 9 +Decrement on non-numeric string has no effect and is deprecated on line 9 +Decrement on non-numeric string has no effect and is deprecated on line 9 +int(-8) +string(1) "u" From 45e4b984a3db5b93aabb0eb7041c8e053a3455b4 Mon Sep 17 00:00:00 2001 From: lazerg Date: Thu, 15 Oct 2026 22:16:04 +0500 Subject: [PATCH 2/2] Extend GH-24337 test with bool and array properties --- ext/opcache/tests/jit/gh24337.phpt | 63 +++++++++++++++++++++++++++--- 1 file changed, 58 insertions(+), 5 deletions(-) diff --git a/ext/opcache/tests/jit/gh24337.phpt b/ext/opcache/tests/jit/gh24337.phpt index 7be9156d2222..3aad4d768e95 100644 --- a/ext/opcache/tests/jit/gh24337.phpt +++ b/ext/opcache/tests/jit/gh24337.phpt @@ -24,6 +24,11 @@ class Q { $this->pu--; } } + function inc() { + for ($i = 0; $i < 2; $i++) { + $this->pu++; + } + } } class S extends Q { public $pu = 'u'; @@ -31,22 +36,70 @@ class S extends Q { parent::run(); } } -$objs = [new Q, new S]; +class B extends Q { + public $pu = true; + function run() { + parent::run(); + } +} +class A extends Q { + public $pu = []; + function run() { + parent::run(); + } +} +$objs = [new Q, new S, new B, new A]; for ($k = 0; $k < 4; $k++) { foreach ($objs as $o) { - $o->run(); + try { + $o->run(); + } catch (TypeError $e) { + echo $e->getMessage(), " on line ", $e->getLine(), "\n"; + } + try { + $o->inc(); + } catch (TypeError $e) { + echo $e->getMessage(), " on line ", $e->getLine(), "\n"; + } } } -var_dump($objs[0]->pu, $objs[1]->pu); +var_dump($objs[0]->pu, $objs[1]->pu, $objs[2]->pu, $objs[3]->pu); ?> --EXPECT-- Decrement on non-numeric string has no effect and is deprecated on line 9 Decrement on non-numeric string has no effect and is deprecated on line 9 +Decrement on type bool has no effect, this will change in the next major version of PHP on line 9 +Decrement on type bool has no effect, this will change in the next major version of PHP on line 9 +Increment on type bool has no effect, this will change in the next major version of PHP on line 14 +Increment on type bool has no effect, this will change in the next major version of PHP on line 14 +Cannot decrement array on line 9 +Cannot increment array on line 14 Decrement on non-numeric string has no effect and is deprecated on line 9 Decrement on non-numeric string has no effect and is deprecated on line 9 +Decrement on type bool has no effect, this will change in the next major version of PHP on line 9 +Decrement on type bool has no effect, this will change in the next major version of PHP on line 9 +Increment on type bool has no effect, this will change in the next major version of PHP on line 14 +Increment on type bool has no effect, this will change in the next major version of PHP on line 14 +Cannot decrement array on line 9 +Cannot increment array on line 14 Decrement on non-numeric string has no effect and is deprecated on line 9 Decrement on non-numeric string has no effect and is deprecated on line 9 +Decrement on type bool has no effect, this will change in the next major version of PHP on line 9 +Decrement on type bool has no effect, this will change in the next major version of PHP on line 9 +Increment on type bool has no effect, this will change in the next major version of PHP on line 14 +Increment on type bool has no effect, this will change in the next major version of PHP on line 14 +Cannot decrement array on line 9 +Cannot increment array on line 14 Decrement on non-numeric string has no effect and is deprecated on line 9 Decrement on non-numeric string has no effect and is deprecated on line 9 -int(-8) -string(1) "u" +Decrement on type bool has no effect, this will change in the next major version of PHP on line 9 +Decrement on type bool has no effect, this will change in the next major version of PHP on line 9 +Increment on type bool has no effect, this will change in the next major version of PHP on line 14 +Increment on type bool has no effect, this will change in the next major version of PHP on line 14 +Cannot decrement array on line 9 +Cannot increment array on line 14 +int(0) +string(2) "ac" +bool(true) +array(0) { +}