diff --git a/Zend/tests/attributes/deprecated/functions/gh17866.phpt b/Zend/tests/attributes/deprecated/functions/gh17866.phpt new file mode 100644 index 00000000000..8786b49c602 --- /dev/null +++ b/Zend/tests/attributes/deprecated/functions/gh17866.phpt @@ -0,0 +1,35 @@ +--TEST-- +GH-17866 (zend_mm_heap corrupted error after upgrading from 8.4.3 to 8.4.4) +--FILE-- +__invoke(...); + +$rc = new ReflectionMethod($test, '__invoke'); +var_dump($rc->getAttributes()); +var_dump($rc->isDeprecated()); + +$test(); + +?> +--EXPECTF-- +array(1) { + [0]=> + object(ReflectionAttribute)#%d (1) { + ["name"]=> + string(10) "Deprecated" + } +} +bool(true) + +Deprecated: Method Foo::__invoke() is deprecated, xyzzy in %s on line %d +In __invoke diff --git a/Zend/zend_closures.c b/Zend/zend_closures.c index e7eb47a38bd..7b2621275dc 100644 --- a/Zend/zend_closures.c +++ b/Zend/zend_closures.c @@ -469,7 +469,7 @@ ZEND_API zend_function *zend_get_closure_invoke_method(zend_object *object) /* { zend_closure *closure = (zend_closure *)object; zend_function *invoke = (zend_function*)emalloc(sizeof(zend_function)); const uint32_t keep_flags = - ZEND_ACC_RETURN_REFERENCE | ZEND_ACC_VARIADIC | ZEND_ACC_HAS_RETURN_TYPE; + ZEND_ACC_RETURN_REFERENCE | ZEND_ACC_VARIADIC | ZEND_ACC_HAS_RETURN_TYPE | ZEND_ACC_DEPRECATED; invoke->common = closure->func.common; /* We return ZEND_INTERNAL_FUNCTION, but arg_info representation is the diff --git a/Zend/zend_object_handlers.c b/Zend/zend_object_handlers.c index b6d17a1149d..56bea759226 100644 --- a/Zend/zend_object_handlers.c +++ b/Zend/zend_object_handlers.c @@ -1618,12 +1618,8 @@ ZEND_API zend_function *zend_get_call_trampoline_func(const zend_class_entry *ce | ZEND_ACC_PUBLIC | ZEND_ACC_VARIADIC | (fbc->common.fn_flags & (ZEND_ACC_RETURN_REFERENCE|ZEND_ACC_ABSTRACT|ZEND_ACC_DEPRECATED)); - if (fbc->common.attributes) { - func->attributes = fbc->common.attributes; - GC_TRY_ADDREF(func->attributes); - } else { - func->attributes = NULL; - } + /* Attributes outlive the trampoline because they are created by the compiler. */ + func->attributes = fbc->common.attributes; if (is_static) { func->fn_flags |= ZEND_ACC_STATIC; } diff --git a/Zend/zend_object_handlers.h b/Zend/zend_object_handlers.h index 130e84b5c58..7e7d3df37a6 100644 --- a/Zend/zend_object_handlers.h +++ b/Zend/zend_object_handlers.h @@ -341,9 +341,6 @@ ZEND_API bool ZEND_FASTCALL zend_asymmetric_property_has_set_access(const zend_p } while (0) #define zend_free_trampoline(func) do { \ - if ((func)->common.attributes) { \ - zend_array_release((func)->common.attributes); \ - } \ if ((func) == &EG(trampoline)) { \ EG(trampoline).common.attributes = NULL; \ EG(trampoline).common.function_name = NULL; \