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:
2
NEWS
2
NEWS
@@ -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
|
||||
|
||||
35
Zend/tests/attributes/deprecated/functions/gh17866.phpt
Normal file
35
Zend/tests/attributes/deprecated/functions/gh17866.phpt
Normal 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
|
||||
@@ -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
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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; \
|
||||
|
||||
Reference in New Issue
Block a user