From f38f74521b61f4a7e74d0124f557fa1d898bf0e2 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 Closes GH-20975 --- NEWS | 1 + Zend/tests/lazy_objects/gh20905.phpt | 22 ++++++++++++++++++++++ Zend/zend_lazy_objects.c | 3 +-- 3 files changed, 24 insertions(+), 2 deletions(-) create mode 100644 Zend/tests/lazy_objects/gh20905.phpt 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-- +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;