diff --git a/Zend/tests/clone_clone_method_declares_function.phpt.php b/Zend/tests/clone_clone_method_declares_function.phpt.php new file mode 100644 index 0000000000000..1f50b8a09e151 --- /dev/null +++ b/Zend/tests/clone_clone_method_declares_function.phpt.php @@ -0,0 +1,33 @@ +--TEST-- +Lazy objects: clone does not assert when __clone() declares a function causing a fatal error +--FILE-- +p = new stdClass; + } + + public function __clone() + { + // Redeclaring an already-declared function triggers E_ERROR -> bailout. + // The lazy object machinery must not assert during the resulting shutdown. + function f() {} + } +} + +$r = new ReflectionClass(A::class); +clone $r->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 e88ecf9fbe657..97fc7ff0ce2c7 100644 --- a/Zend/zend_lazy_objects.c +++ b/Zend/zend_lazy_objects.c @@ -162,7 +162,7 @@ zend_lazy_object_flags_t zend_lazy_object_get_flags(const zend_object *obj) void zend_lazy_object_del_info(const zend_object *obj) { zend_result res = zend_hash_index_del(&EG(lazy_objects_store).infos, obj->handle); - ZEND_ASSERT(res == SUCCESS); + ZEND_ASSERT(res == SUCCESS || CG(unclean_shutdown)); } bool zend_lazy_object_decr_lazy_props(const zend_object *obj)