From f73f3253aa6c8b9a6cfb818d1acfd146f2701627 Mon Sep 17 00:00:00 2001 From: Niels Dossche <7771979+ndossche@users.noreply.github.com> Date: Sat, 10 Jan 2026 17:42:01 +0100 Subject: [PATCH] Fix GH-20890: Segfault in zval_undefined_cv with non-simple property hook with minimal tracing JIT This is similar to f6c2e40a11 but for minimal JIT + tracing JIT. Most of the times the tracing JIT shouldn't rely on going to the VM, but in some cases, like in minimal JIT, it can and then it hits the same bug. --- ext/opcache/jit/zend_jit_trace.c | 8 +++++++ ext/opcache/tests/jit/gh20890.phpt | 37 ++++++++++++++++++++++++++++++ 2 files changed, 45 insertions(+) create mode 100644 ext/opcache/tests/jit/gh20890.phpt diff --git a/ext/opcache/jit/zend_jit_trace.c b/ext/opcache/jit/zend_jit_trace.c index 9d2de55e29499..41393f721cfcf 100644 --- a/ext/opcache/jit/zend_jit_trace.c +++ b/ext/opcache/jit/zend_jit_trace.c @@ -328,6 +328,14 @@ static int zend_jit_trace_may_exit(const zend_op_array *op_array, const zend_op // TODO: recompilation may change target ??? return 0; #endif + case ZEND_FETCH_OBJ_R: + if (opline->op2_type == IS_CONST) { + const zend_class_entry *ce = opline->op1_type == IS_UNUSED ? op_array->scope : NULL; + if (!ce || !(ce->ce_flags & ZEND_ACC_FINAL) || ce->num_hooked_props > 0) { + return 1; + } + } + break; case ZEND_RETURN_BY_REF: case ZEND_RETURN: /* return */ diff --git a/ext/opcache/tests/jit/gh20890.phpt b/ext/opcache/tests/jit/gh20890.phpt new file mode 100644 index 0000000000000..c375c379fcc72 --- /dev/null +++ b/ext/opcache/tests/jit/gh20890.phpt @@ -0,0 +1,37 @@ +--TEST-- +GH-20890 (Segfault in zval_undefined_cv with non-simple property hook with minimal tracing JIT) +--CREDITS-- +Moonster8282 +--EXTENSIONS-- +opcache +--INI-- +opcache.jit=1251 +--FILE-- +readCount++; + return $this->readCount * 2; + } + } +} + +function hook_hot_path($obj, $iterations) { + $sum = 0; + for ($i = 0; $i < $iterations; $i++) { + $sum += $obj->computed; + } + return $sum; +} + +echo "Testing property hook in hot path...\n"; +$obj = new HookJIT(); +$result = hook_hot_path($obj, 100); +echo "Result: $result\n"; +?> +--EXPECT-- +Testing property hook in hot path... +Result: 10100