1
0
mirror of https://github.com/php/php-src.git synced 2026-03-24 00:02:20 +01:00

Fix GH-17866: zend_mm_heap corrupted error after upgrading from 8.4.3 to 8.4.4

This regressed in GH-17592.
The function is with its attributes HashTable* is copied in
zend_get_closure_invoke_method() but its refcount is not increased.
This caused a crash in the Symfony demo page.

Closes GH-17880.
This commit is contained in:
Niels Dossche
2025-02-21 21:01:46 +01:00
parent c0857e0d8a
commit 2542357b6d
5 changed files with 40 additions and 11 deletions

2
NEWS
View File

@@ -19,6 +19,8 @@ PHP NEWS
may call hooks of overridden properties). (Arnaud)
. Fixed bug GH-17916 (Final abstract properties should error).
(DanielEScherzer)
. Fixed bug GH-17866 (zend_mm_heap corrupted error after upgrading from
8.4.3 to 8.4.4). (nielsdos)
- DOM:
. Fixed bug GH-17609 (Typo in error message: Dom\NO_DEFAULT_NS instead of

View File

@@ -0,0 +1,35 @@
--TEST--
GH-17866 (zend_mm_heap corrupted error after upgrading from 8.4.3 to 8.4.4)
--FILE--
<?php
class Foo {
#[Deprecated("xyzzy")]
public function __invoke() {
echo "In __invoke\n";
}
}
$foo = new Foo;
$closure = Closure::fromCallable($foo);
$test = $closure->__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

View File

@@ -464,7 +464,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

View File

@@ -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;
}

View File

@@ -339,10 +339,6 @@ ZEND_API bool ZEND_FASTCALL zend_asymmetric_property_has_set_access(const zend_p
} while (0)
#define zend_free_trampoline(func) do { \
HashTable *attributes = (func)->common.attributes; \
if (attributes && !(GC_FLAGS(attributes) & GC_IMMUTABLE) && !GC_DELREF(attributes)) { \
zend_array_destroy(attributes); \
} \
if ((func) == &EG(trampoline)) { \
EG(trampoline).common.attributes = NULL; \
EG(trampoline).common.function_name = NULL; \