diff --git a/Zend/tests/gh24631.phpt b/Zend/tests/gh24631.phpt new file mode 100644 index 000000000000..8a667a67c16a --- /dev/null +++ b/Zend/tests/gh24631.phpt @@ -0,0 +1,32 @@ +--TEST-- +GH-24631: Delayed OOM raised during compilation is reported even when compilation fails +--SKIPIF-- + +--FILE-- +&1'); +@unlink($inc); + +// The real error (OOM) must be reported, and the spurious parse error must not. +var_dump( + str_contains($out, 'Allowed memory size'), + str_contains($out, 'Parse error') +); +?> +--EXPECT-- +bool(true) +bool(false) +--CLEAN-- + diff --git a/Zend/zend.c b/Zend/zend.c index 216056511215..84b4ae5307c8 100644 --- a/Zend/zend.c +++ b/Zend/zend.c @@ -1981,6 +1981,17 @@ ZEND_API zend_result zend_execute_script(int type, zval *retval, zend_file_handl zend_hash_add_empty_element(&EG(included_files), file_handle->opened_path); } + /* GH-24631: a delayed OOM raised during compilation must be reported even + * when compilation produced no op_array. Any pending exception here (e.g. a + * parse error from the OOM-truncated source) is a downstream artifact of the + * OOM, so discard it and let the OOM be the reported error. */ + if (ZEND_HAS_OOM()) { + if (EG(exception)) { + zend_clear_exception(); + } + zend_handle_delayed_oom(); + } + zend_result ret = SUCCESS; if (op_array) { zend_execute(op_array, retval);