Commit 2f2b421a485 for php.net
commit 2f2b421a485b9b95265b591d90aaabea90d35ec9
Author: Ilija Tovilo <ilija.tovilo@me.com>
Date: Thu Jan 29 00:25:14 2026 +0100
Fix segfault when preloading constant AST closure
Fixes GH-21059
Closes GH-21071
diff --git a/NEWS b/NEWS
index dbf94f74882..8ec869035f0 100644
--- a/NEWS
+++ b/NEWS
@@ -4,6 +4,7 @@ PHP NEWS
- Core:
. Fixed bug GH-21029 (zend_mm_heap corrupted on Aarch64, LTO builds). (Arnaud)
+ . Fixed bug GH-21059 (Segfault when preloading constant AST closure). (ilutov)
- Windows:
. Fixed compilation with clang (missing intrin.h include). (Kévin Dunglas)
diff --git a/Zend/zend_ast.c b/Zend/zend_ast.c
index 9cb3c7aae4a..62a4bfec506 100644
--- a/Zend/zend_ast.c
+++ b/Zend/zend_ast.c
@@ -1154,6 +1154,12 @@ ZEND_API zend_result ZEND_FASTCALL zend_ast_evaluate_inner(
}
case ZEND_AST_OP_ARRAY:
{
+ // Preloading will attempt to resolve constants but objects can't be stored in shm
+ // Aborting here to store the const AST instead
+ if (CG(in_compilation)) {
+ return FAILURE;
+ }
+
zend_function *func = (zend_function *)zend_ast_get_op_array(ast)->op_array;
zend_create_closure(result, func, scope, scope, NULL);
diff --git a/ext/opcache/tests/preload_gh21059.inc b/ext/opcache/tests/preload_gh21059.inc
new file mode 100644
index 00000000000..8f93bb45020
--- /dev/null
+++ b/ext/opcache/tests/preload_gh21059.inc
@@ -0,0 +1,7 @@
+<?php
+
+class Foo {
+ public const C = static function() {
+ echo "Hello world\n";
+ };
+}
diff --git a/ext/opcache/tests/preload_gh21059.phpt b/ext/opcache/tests/preload_gh21059.phpt
new file mode 100644
index 00000000000..39e7aceae94
--- /dev/null
+++ b/ext/opcache/tests/preload_gh21059.phpt
@@ -0,0 +1,18 @@
+--TEST--
+GH-21059: Segfault when preloading constant AST closure
+--INI--
+opcache.enable=1
+opcache.enable_cli=1
+opcache.preload={PWD}/preload_gh21059.inc
+--EXTENSIONS--
+opcache
+--SKIPIF--
+<?php
+if (PHP_OS_FAMILY == 'Windows') die('skip Preloading is not supported on Windows');
+?>
+--FILE--
+<?php
+(Foo::C)();
+?>
+--EXPECT--
+Hello world