Don't duplicate internal prop info (#6929)

Userland property infos are no longer duplicated since PHP 7.4, when we
stopped setting SHADOW flags on inherited private properties. Stop duplicating
internal property infos as well.

This requires switching class destruction to work in reverse order, as child
classes may be reusing structures from parent classes, and as such should be
destroyed first.
This commit is contained in:
Nikita Popov 2021-04-29 20:31:24 +02:00 committed by GitHub
parent dd86987b2c
commit 79071d5e3e
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 20 additions and 29 deletions

View File

@ -1127,7 +1127,8 @@ void zend_shutdown(void) /* {{{ */
virtual_cwd_shutdown(); virtual_cwd_shutdown();
zend_hash_destroy(GLOBAL_FUNCTION_TABLE); zend_hash_destroy(GLOBAL_FUNCTION_TABLE);
zend_hash_destroy(GLOBAL_CLASS_TABLE); /* Child classes may reuse structures from parent classes, so destroy in reverse order. */
zend_hash_graceful_reverse_destroy(GLOBAL_CLASS_TABLE);
zend_hash_destroy(GLOBAL_AUTO_GLOBALS_TABLE); zend_hash_destroy(GLOBAL_AUTO_GLOBALS_TABLE);
free(GLOBAL_AUTO_GLOBALS_TABLE); free(GLOBAL_AUTO_GLOBALS_TABLE);

View File

@ -3231,6 +3231,7 @@ ZEND_API zend_result zend_disable_class(const char *class_name, size_t class_nam
zend_class_entry *disabled_class; zend_class_entry *disabled_class;
zend_string *key; zend_string *key;
zend_function *fn; zend_function *fn;
zend_property_info *prop;
key = zend_string_alloc(class_name_length, 0); key = zend_string_alloc(class_name_length, 0);
zend_str_tolower_copy(ZSTR_VAL(key), class_name, class_name_length); zend_str_tolower_copy(ZSTR_VAL(key), class_name, class_name_length);
@ -3253,6 +3254,13 @@ ZEND_API zend_result zend_disable_class(const char *class_name, size_t class_nam
} }
} ZEND_HASH_FOREACH_END(); } ZEND_HASH_FOREACH_END();
zend_hash_clean(&disabled_class->function_table); zend_hash_clean(&disabled_class->function_table);
ZEND_HASH_FOREACH_PTR(&disabled_class->properties_info, prop) {
if (prop->ce == disabled_class) {
zend_string_release(prop->name);
zend_type_release(prop->type, /* persistent */ 1);
free(prop);
}
} ZEND_HASH_FOREACH_END();
zend_hash_clean(&disabled_class->properties_info); zend_hash_clean(&disabled_class->properties_info);
return SUCCESS; return SUCCESS;
} }

View File

@ -127,16 +127,6 @@ static zend_brk_cont_element *get_next_brk_cont_element(void)
return &CG(context).brk_cont_array[CG(context).last_brk_cont-1]; return &CG(context).brk_cont_array[CG(context).last_brk_cont-1];
} }
static void zend_destroy_property_info_internal(zval *zv) /* {{{ */
{
zend_property_info *property_info = Z_PTR_P(zv);
zend_string_release(property_info->name);
zend_type_release(property_info->type, /* persistent */ 1);
free(property_info);
}
/* }}} */
static zend_string *zend_build_runtime_definition_key(zend_string *name, uint32_t start_lineno) /* {{{ */ static zend_string *zend_build_runtime_definition_key(zend_string *name, uint32_t start_lineno) /* {{{ */
{ {
zend_string *filename = CG(active_op_array)->filename; zend_string *filename = CG(active_op_array)->filename;
@ -1867,7 +1857,7 @@ ZEND_API void zend_initialize_class_data(zend_class_entry *ce, bool nullify_hand
ce->default_properties_table = NULL; ce->default_properties_table = NULL;
ce->default_static_members_table = NULL; ce->default_static_members_table = NULL;
zend_hash_init(&ce->properties_info, 8, NULL, (persistent_hashes ? zend_destroy_property_info_internal : NULL), persistent_hashes); zend_hash_init(&ce->properties_info, 8, NULL, NULL, persistent_hashes);
zend_hash_init(&ce->constants_table, 8, NULL, NULL, persistent_hashes); zend_hash_init(&ce->constants_table, 8, NULL, NULL, persistent_hashes);
zend_hash_init(&ce->function_table, 8, NULL, ZEND_FUNCTION_DTOR, persistent_hashes); zend_hash_init(&ce->function_table, 8, NULL, ZEND_FUNCTION_DTOR, persistent_hashes);

View File

@ -58,17 +58,6 @@ static void zend_type_copy_ctor(zend_type *type, bool persistent) {
} }
} }
static zend_property_info *zend_duplicate_property_info_internal(zend_property_info *property_info) /* {{{ */
{
zend_property_info* new_property_info = pemalloc(sizeof(zend_property_info), 1);
memcpy(new_property_info, property_info, sizeof(zend_property_info));
zend_string_addref(new_property_info->name);
zend_type_copy_ctor(&new_property_info->type, /* persistent */ 1);
return new_property_info;
}
/* }}} */
static zend_function *zend_duplicate_internal_function(zend_function *func, zend_class_entry *ce) /* {{{ */ static zend_function *zend_duplicate_internal_function(zend_function *func, zend_class_entry *ce) /* {{{ */
{ {
zend_function *new_function; zend_function *new_function;
@ -1100,12 +1089,7 @@ static void do_inherit_property(zend_property_info *parent_info, zend_string *ke
} }
} }
} else { } else {
if (UNEXPECTED(ce->type & ZEND_INTERNAL_CLASS)) { _zend_hash_append_ptr(&ce->properties_info, key, parent_info);
child_info = zend_duplicate_property_info_internal(parent_info);
} else {
child_info = parent_info;
}
_zend_hash_append_ptr(&ce->properties_info, key, child_info);
} }
} }
/* }}} */ /* }}} */

View File

@ -462,6 +462,14 @@ ZEND_API void destroy_zend_class(zval *zv)
zend_cleanup_internal_class_data(ce); zend_cleanup_internal_class_data(ce);
} }
} }
ZEND_HASH_FOREACH_PTR(&ce->properties_info, prop_info) {
if (prop_info->ce == ce) {
zend_string_release(prop_info->name);
zend_type_release(prop_info->type, /* persistent */ 1);
free(prop_info);
}
} ZEND_HASH_FOREACH_END();
zend_hash_destroy(&ce->properties_info); zend_hash_destroy(&ce->properties_info);
zend_string_release_ex(ce->name, 1); zend_string_release_ex(ce->name, 1);