[php-src] master: Merge branch 'PHP-8.4' into PHP-8.5

Ilia Alshanetsky <[email protected]>
Newsgroups gmane.comp.php.cvs.general
Message-ID <[email protected]>
Author: Ilia Alshanetsky (iliaal)
Date: 2026-07-01T08:01:23-04:00

Commit: https://github.com/php/php-src/commit/1e89e47376d7465039448fa67c75db17c92fb5fb
Raw diff: https://github.com/php/php-src/commit/1e89e47376d7465039448fa67c75db17c92fb5fb.diff

Merge branch 'PHP-8.4' into PHP-8.5

* PHP-8.4:
  Fix infinite recursion in property hook getter in opcache preloaded trait

Changed paths:
  A  ext/opcache/tests/gh21770.phpt
  A  ext/opcache/tests/preload_gh21770.inc
  M  NEWS
  M  ext/opcache/ZendAccelerator.c


Diff:

diff --git a/NEWS b/NEWS
index a08132d60b54..7cabb876d208 100644
--- a/NEWS
+++ b/NEWS
@@ -18,6 +18,8 @@ PHP                                                                        NEWS
     iliaal)
   . Fixed bug GH-22443 (Tracing JIT SIGSEGV on megamorphic dynamic calls from
     an undereferenced run_time_cache map_ptr offset). (iliaal)
+  . Fixed bug GH-21770 (Infinite recursion in property hook getter in opcache
+    preloaded trait). (iliaal)
 
 - OpenSSL:
   . Fixed timeout for supplemental read at end of a blocking stream in SSL
diff --git a/ext/opcache/ZendAccelerator.c b/ext/opcache/ZendAccelerator.c
index 904a9c2ae08f..62a33c451056 100644
--- a/ext/opcache/ZendAccelerator.c
+++ b/ext/opcache/ZendAccelerator.c
@@ -4368,12 +4368,14 @@ static void preload_fix_trait_op_array(zend_op_array *op_array)
 	uint32_t fn_flags = op_array->fn_flags;
 	zend_function *prototype = op_array->prototype;
 	HashTable *ht = op_array->static_variables;
+	const zend_property_info *prop_info = op_array->prop_info;
 	*op_array = *orig_op_array;
 	op_array->function_name = function_name;
 	op_array->scope = scope;
 	op_array->fn_flags = fn_flags;
 	op_array->prototype = prototype;
 	op_array->static_variables = ht;
+	op_array->prop_info = prop_info;
 }
 
 static void preload_fix_trait_methods(zend_class_entry *ce)
diff --git a/ext/opcache/tests/gh21770.phpt b/ext/opcache/tests/gh21770.phpt
new file mode 100644
index 000000000000..d2fd52a4712b
--- /dev/null
+++ b/ext/opcache/tests/gh21770.phpt
@@ -0,0 +1,25 @@
+--TEST--
+GH-21770 (Infinite recursion in property hook getter in opcache preloaded trait)
+--INI--
+opcache.enable=1
+opcache.enable_cli=1
+opcache.optimization_level=-1
+opcache.preload={PWD}/preload_gh21770.inc
+--EXTENSIONS--
+opcache
+--SKIPIF--
+<?php
+if (PHP_OS_FAMILY == 'Windows') die('skip Preloading is not supported on Windows');
+?>
+--FILE--
+<?php
+$b = new B();
+echo $b->a, "\n";
+
+$c = new C();
+$c->x = 42;
+var_dump($c->x);
+?>
+--EXPECT--
+a
+int(42)
diff --git a/ext/opcache/tests/preload_gh21770.inc b/ext/opcache/tests/preload_gh21770.inc
new file mode 100644
index 000000000000..7433a15eca92
--- /dev/null
+++ b/ext/opcache/tests/preload_gh21770.inc
@@ -0,0 +1,20 @@
+<?php
+trait A {
+    public ?string $a = 'a' {
+        get => $this->a;
+    }
+}
+
+trait X {
+    public int $x = 0 {
+        set(int $value) => $value;
+    }
+}
+
+class B {
+    use A;
+}
+
+class C {
+    use X;
+}
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.