Commit e0eea65aa44 for php
commit e0eea65aa447805c677a9fb0a33bbc65cd79eb68
Author: lazerg <lazerg2@gmail.com>
Date: Tue Sep 22 16:21:45 2026 +0500
Fix GH-23842: skipLazyInitialization() copies unresolved constant defaults
Closes GH-23843.
diff --git a/NEWS b/NEWS
index e5441fe6bc2..0ec3c10f0a1 100644
--- a/NEWS
+++ b/NEWS
@@ -404,6 +404,8 @@ PHP NEWS
parent slot when a child class hooks an inherited property. (iliaal)
. Fixed segfault in ReflectionMethod::createFromMethodName() on an
uninstantiable subclass. (iliaal)
+ . Fixed bug GH-23842 (ReflectionProperty::skipLazyInitialization() copies
+ invalid constant defaults with OPcache). (DirkTrunkstar, Lazizbek Ergashev)
- Readline:
. Fixed class constant completion in the interactive shell. (Weilin Du)
diff --git a/Zend/tests/lazy_objects/gh23842.phpt b/Zend/tests/lazy_objects/gh23842.phpt
new file mode 100644
index 00000000000..fe791dde685
--- /dev/null
+++ b/Zend/tests/lazy_objects/gh23842.phpt
@@ -0,0 +1,32 @@
+--TEST--
+GH-23842: skipLazyInitialization() copies an unresolved constant default with opcache
+--CREDITS--
+DirkTrunkstar
+--EXTENSIONS--
+opcache
+--INI--
+opcache.enable=1
+opcache.enable_cli=1
+opcache.file_cache_only=0
+--FILE--
+<?php
+
+class Currency {
+ public const string EUR = 'EUR';
+}
+
+class Product {
+ public string $currency = Currency::EUR;
+}
+
+$reflector = new ReflectionClass(Product::class);
+$product = $reflector->newLazyGhost(function () {
+ throw new \Exception('initializer');
+});
+$reflector->getProperty('currency')->skipLazyInitialization($product);
+
+var_dump($product->currency);
+
+?>
+--EXPECT--
+string(3) "EUR"
diff --git a/ext/reflection/php_reflection.c b/ext/reflection/php_reflection.c
index c7b15c63a0c..2c94a6e80d1 100644
--- a/ext/reflection/php_reflection.c
+++ b/ext/reflection/php_reflection.c
@@ -6461,7 +6461,7 @@ ZEND_METHOD(ReflectionProperty, skipLazyInitialization)
RETURN_THROWS();
}
- zval *src = &object->ce->default_properties_table[OBJ_PROP_TO_NUM(prop->offset)];
+ zval *src = &CE_DEFAULT_PROPERTIES_TABLE(object->ce)[OBJ_PROP_TO_NUM(prop->offset)];
zval *dst = OBJ_PROP(object, prop->offset);
if (!(Z_PROP_FLAG_P(dst) & IS_PROP_LAZY)) {