Commit f38f74521b6 for php.net

commit f38f74521b61f4a7e74d0124f557fa1d898bf0e2
Author: Ilija Tovilo <ilija.tovilo@me.com>
Date:   Mon Jan 19 15:47:03 2026 +0100

    Fix lazy proxy bailing __clone assertion

    When __clone of the underlying object fails with a bailout, ZEND_ASSERT(res ==
    SUCCESS) in zend_lazy_object_del_info() will fail because the info has not been
    registered yet.

    Only copy OBJ_EXTRA_FLAGS once the info has been successfully registered.

    Fixes GH-20905
    Closes GH-20975

diff --git a/NEWS b/NEWS
index 06ebe601478..80b69c11cf8 100644
--- a/NEWS
+++ b/NEWS
@@ -14,6 +14,7 @@ PHP                                                                        NEWS
     backing value). (ilutov)
   . Fix OSS-Fuzz #438780145 (Nested finally with repeated return type check may
     uaf). (ilutov)
+  . Fixed bug GH-20905 (Lazy proxy bailing __clone assertion). (ilutov)

 - Date:
   . Update timelib to 2022.16. (Derick)
diff --git a/Zend/tests/lazy_objects/gh20905.phpt b/Zend/tests/lazy_objects/gh20905.phpt
new file mode 100644
index 00000000000..48a1360c0a9
--- /dev/null
+++ b/Zend/tests/lazy_objects/gh20905.phpt
@@ -0,0 +1,22 @@
+--TEST--
+GH-20905: Lazy proxy bailing __clone assertion
+--FILE--
+<?php
+
+function test() {
+    function f() {}
+}
+
+class A {
+    public $_;
+    public function __clone() {
+        test();
+    }
+}
+
+test();
+clone (new ReflectionClass(A::class))->newLazyProxy(fn() => new A);
+
+?>
+--EXPECTF--
+Fatal error: Cannot redeclare function f() (previously declared in %s:%d) in %s on line %d
diff --git a/Zend/zend_lazy_objects.c b/Zend/zend_lazy_objects.c
index d1b950160e1..bf76f6e88fe 100644
--- a/Zend/zend_lazy_objects.c
+++ b/Zend/zend_lazy_objects.c
@@ -744,12 +744,11 @@ zend_object *zend_lazy_object_clone(zend_object *old_obj)
 		}
 	}

-	OBJ_EXTRA_FLAGS(new_proxy) = OBJ_EXTRA_FLAGS(old_obj);
-
 	zend_lazy_object_info *new_info = emalloc(sizeof(*info));
 	*new_info = *info;
 	new_info->u.instance = zend_objects_clone_obj(info->u.instance);

+	OBJ_EXTRA_FLAGS(new_proxy) = OBJ_EXTRA_FLAGS(old_obj);
 	zend_lazy_object_set_info(new_proxy, new_info);

 	return new_proxy;