mirror of
https://github.com/php/php-src.git
synced 2025-08-15 21:48:51 +02:00
Fix various bugs related to DNF types
- GH-11958: DNF types in trait properties do not get bound properly - GH-11883: Memory leak in zend_type_release() for non-arena allocated DNF types - Internal trait bound to userland class would not be arena allocated - Property DNF types were not properly deep copied during lazy loading Co-authored-by: Ilija Tovilo <ilija.tovilo@me.com> Co-authored-by: ju1ius <jules.bernable@gmail.com>
This commit is contained in:
parent
0b516aea25
commit
02a80c5b82
7 changed files with 113 additions and 35 deletions
|
@ -57,20 +57,33 @@ static void ZEND_COLD emit_incompatible_method_error(
|
|||
const zend_function *parent, zend_class_entry *parent_scope,
|
||||
inheritance_status status);
|
||||
|
||||
static void zend_type_copy_ctor(zend_type *type, bool persistent) {
|
||||
if (ZEND_TYPE_HAS_LIST(*type)) {
|
||||
zend_type_list *old_list = ZEND_TYPE_LIST(*type);
|
||||
size_t size = ZEND_TYPE_LIST_SIZE(old_list->num_types);
|
||||
zend_type_list *new_list = ZEND_TYPE_USES_ARENA(*type)
|
||||
? zend_arena_alloc(&CG(arena), size) : pemalloc(size, persistent);
|
||||
memcpy(new_list, old_list, ZEND_TYPE_LIST_SIZE(old_list->num_types));
|
||||
ZEND_TYPE_SET_PTR(*type, new_list);
|
||||
static void zend_type_copy_ctor(zend_type *const type, bool use_arena, bool persistent);
|
||||
|
||||
zend_type *list_type;
|
||||
ZEND_TYPE_LIST_FOREACH(new_list, list_type) {
|
||||
ZEND_ASSERT(ZEND_TYPE_HAS_NAME(*list_type));
|
||||
zend_string_addref(ZEND_TYPE_NAME(*list_type));
|
||||
} ZEND_TYPE_LIST_FOREACH_END();
|
||||
static void zend_type_list_copy_ctor(
|
||||
zend_type *const parent_type,
|
||||
bool use_arena,
|
||||
bool persistent
|
||||
) {
|
||||
const zend_type_list *const old_list = ZEND_TYPE_LIST(*parent_type);
|
||||
size_t size = ZEND_TYPE_LIST_SIZE(old_list->num_types);
|
||||
zend_type_list *new_list = use_arena
|
||||
? zend_arena_alloc(&CG(arena), size) : pemalloc(size, persistent);
|
||||
|
||||
memcpy(new_list, old_list, size);
|
||||
ZEND_TYPE_SET_LIST(*parent_type, new_list);
|
||||
if (use_arena) {
|
||||
ZEND_TYPE_FULL_MASK(*parent_type) |= _ZEND_TYPE_ARENA_BIT;
|
||||
}
|
||||
|
||||
zend_type *list_type;
|
||||
ZEND_TYPE_LIST_FOREACH(new_list, list_type) {
|
||||
zend_type_copy_ctor(list_type, use_arena, persistent);
|
||||
} ZEND_TYPE_LIST_FOREACH_END();
|
||||
}
|
||||
|
||||
static void zend_type_copy_ctor(zend_type *const type, bool use_arena, bool persistent) {
|
||||
if (ZEND_TYPE_HAS_LIST(*type)) {
|
||||
zend_type_list_copy_ctor(type, use_arena, persistent);
|
||||
} else if (ZEND_TYPE_HAS_NAME(*type)) {
|
||||
zend_string_addref(ZEND_TYPE_NAME(*type));
|
||||
}
|
||||
|
@ -2401,7 +2414,8 @@ static void zend_do_traits_property_binding(zend_class_entry *ce, zend_class_ent
|
|||
doc_comment = property_info->doc_comment ? zend_string_copy(property_info->doc_comment) : NULL;
|
||||
|
||||
zend_type type = property_info->type;
|
||||
zend_type_copy_ctor(&type, /* persistent */ 0);
|
||||
/* Assumption: only userland classes can use traits, as such the type must be arena allocated */
|
||||
zend_type_copy_ctor(&type, /* use arena */ true, /* persistent */ false);
|
||||
new_prop = zend_declare_typed_property(ce, prop_name, prop_value, flags, doc_comment, type);
|
||||
|
||||
if (property_info->attributes) {
|
||||
|
@ -2789,15 +2803,8 @@ static zend_class_entry *zend_lazy_class_load(zend_class_entry *pce)
|
|||
Z_PTR(p->val) = new_prop_info;
|
||||
memcpy(new_prop_info, prop_info, sizeof(zend_property_info));
|
||||
new_prop_info->ce = ce;
|
||||
if (ZEND_TYPE_HAS_LIST(new_prop_info->type)) {
|
||||
zend_type_list *new_list;
|
||||
zend_type_list *list = ZEND_TYPE_LIST(new_prop_info->type);
|
||||
|
||||
new_list = zend_arena_alloc(&CG(arena), ZEND_TYPE_LIST_SIZE(list->num_types));
|
||||
memcpy(new_list, list, ZEND_TYPE_LIST_SIZE(list->num_types));
|
||||
ZEND_TYPE_SET_PTR(new_prop_info->type, list);
|
||||
ZEND_TYPE_FULL_MASK(new_prop_info->type) |= _ZEND_TYPE_ARENA_BIT;
|
||||
}
|
||||
/* Deep copy the type information */
|
||||
zend_type_copy_ctor(&new_prop_info->type, /* use_arena */ true, /* persistent */ false);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue