mirror of
https://github.com/php/php-src.git
synced 2026-03-24 00:02:20 +01:00
Fix GH-17747: Exception on reading property in register-based FETCH_OBJ_R breaks JIT
When read_property fails, it may return `&EG(uninitialized_zval)`, and the exception is handled in the VM. The VM will try to `zval_ptr_dtor_nogc` the result, but the result was never set, resulting in dtor'ing garbage data. To solve this, we check when a different zval* was returned and initialize the result with UNDEF. We don't need to copy as the slow_ex handler return values are used directly in a register. Closes GH-17749.
This commit is contained in:
2
NEWS
2
NEWS
@@ -42,6 +42,8 @@ PHP NEWS
|
||||
. Fixed bug GH-17654 (Multiple classes using same trait causes function
|
||||
JIT crash). (nielsdos)
|
||||
. Fixed bug GH-17577 (JIT packed type guard crash). (nielsdos, Dmitry)
|
||||
. Fixed bug GH-17747 (Exception on reading property in register-based
|
||||
FETCH_OBJ_R breaks JIT). (Dmitry, nielsdos)
|
||||
|
||||
- PHPDBG:
|
||||
. Partially fixed bug GH-17387 (Trivial crash in phpdbg lexer). (nielsdos)
|
||||
|
||||
@@ -14539,7 +14539,11 @@ result_fetched:
|
||||
}
|
||||
|
||||
if (may_throw) {
|
||||
zend_jit_check_exception(jit);
|
||||
if (Z_MODE(res_addr) == IS_REG) {
|
||||
zend_jit_check_exception_undef_result(jit, opline);
|
||||
} else {
|
||||
zend_jit_check_exception(jit);
|
||||
}
|
||||
}
|
||||
|
||||
return 1;
|
||||
|
||||
23
ext/opcache/tests/jit/gh17747.phpt
Normal file
23
ext/opcache/tests/jit/gh17747.phpt
Normal file
@@ -0,0 +1,23 @@
|
||||
--TEST--
|
||||
GH-17747 (Exception on reading property in register-based FETCH_OBJ_R breaks JIT)
|
||||
--EXTENSIONS--
|
||||
opcache
|
||||
--INI--
|
||||
opcache.jit=function
|
||||
--FILE--
|
||||
<?php
|
||||
class C {
|
||||
public int $a;
|
||||
public function test() {
|
||||
var_dump($this->a);
|
||||
}
|
||||
}
|
||||
$test = new C;
|
||||
$test->test();
|
||||
?>
|
||||
--EXPECTF--
|
||||
Fatal error: Uncaught Error: Typed property C::$a must not be accessed before initialization in %s:%d
|
||||
Stack trace:
|
||||
#0 %s(%d): C->test()
|
||||
#1 {main}
|
||||
thrown in %s on line %d
|
||||
Reference in New Issue
Block a user