From fbab1350eac2a0a026b76f9d9c8fac3f0f3333d7 Mon Sep 17 00:00:00 2001 From: Ilija Tovilo Date: Mon, 19 Jan 2026 15:47:03 +0100 Subject: [PATCH] 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 --- Zend/tests/lazy_objects/gh20905.phpt | 22 ++++++++++++++++++++++ Zend/zend_lazy_objects.c | 3 +-- 2 files changed, 23 insertions(+), 2 deletions(-) create mode 100644 Zend/tests/lazy_objects/gh20905.phpt diff --git a/Zend/tests/lazy_objects/gh20905.phpt b/Zend/tests/lazy_objects/gh20905.phpt new file mode 100644 index 0000000000000..48a1360c0a949 --- /dev/null +++ b/Zend/tests/lazy_objects/gh20905.phpt @@ -0,0 +1,22 @@ +--TEST-- +GH-20905: Lazy proxy bailing __clone assertion +--FILE-- +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 d1b950160e1cc..bf76f6e88fe7d 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;