Skip to content

Commit 79071d5

Browse files
authored
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.
1 parent dd86987 commit 79071d5

File tree

5 files changed

+20
-29
lines changed

5 files changed

+20
-29
lines changed

Zend/zend.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1127,7 +1127,8 @@ void zend_shutdown(void) /* {{{ */
11271127
virtual_cwd_shutdown();
11281128

11291129
zend_hash_destroy(GLOBAL_FUNCTION_TABLE);
1130-
zend_hash_destroy(GLOBAL_CLASS_TABLE);
1130+
/* Child classes may reuse structures from parent classes, so destroy in reverse order. */
1131+
zend_hash_graceful_reverse_destroy(GLOBAL_CLASS_TABLE);
11311132

11321133
zend_hash_destroy(GLOBAL_AUTO_GLOBALS_TABLE);
11331134
free(GLOBAL_AUTO_GLOBALS_TABLE);

Zend/zend_API.c

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3231,6 +3231,7 @@ ZEND_API zend_result zend_disable_class(const char *class_name, size_t class_nam
32313231
zend_class_entry *disabled_class;
32323232
zend_string *key;
32333233
zend_function *fn;
3234+
zend_property_info *prop;
32343235

32353236
key = zend_string_alloc(class_name_length, 0);
32363237
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
32533254
}
32543255
} ZEND_HASH_FOREACH_END();
32553256
zend_hash_clean(&disabled_class->function_table);
3257+
ZEND_HASH_FOREACH_PTR(&disabled_class->properties_info, prop) {
3258+
if (prop->ce == disabled_class) {
3259+
zend_string_release(prop->name);
3260+
zend_type_release(prop->type, /* persistent */ 1);
3261+
free(prop);
3262+
}
3263+
} ZEND_HASH_FOREACH_END();
32563264
zend_hash_clean(&disabled_class->properties_info);
32573265
return SUCCESS;
32583266
}

Zend/zend_compile.c

Lines changed: 1 addition & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -127,16 +127,6 @@ static zend_brk_cont_element *get_next_brk_cont_element(void)
127127
return &CG(context).brk_cont_array[CG(context).last_brk_cont-1];
128128
}
129129

130-
static void zend_destroy_property_info_internal(zval *zv) /* {{{ */
131-
{
132-
zend_property_info *property_info = Z_PTR_P(zv);
133-
134-
zend_string_release(property_info->name);
135-
zend_type_release(property_info->type, /* persistent */ 1);
136-
free(property_info);
137-
}
138-
/* }}} */
139-
140130
static zend_string *zend_build_runtime_definition_key(zend_string *name, uint32_t start_lineno) /* {{{ */
141131
{
142132
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
18671857

18681858
ce->default_properties_table = NULL;
18691859
ce->default_static_members_table = NULL;
1870-
zend_hash_init(&ce->properties_info, 8, NULL, (persistent_hashes ? zend_destroy_property_info_internal : NULL), persistent_hashes);
1860+
zend_hash_init(&ce->properties_info, 8, NULL, NULL, persistent_hashes);
18711861
zend_hash_init(&ce->constants_table, 8, NULL, NULL, persistent_hashes);
18721862
zend_hash_init(&ce->function_table, 8, NULL, ZEND_FUNCTION_DTOR, persistent_hashes);
18731863

Zend/zend_inheritance.c

Lines changed: 1 addition & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -58,17 +58,6 @@ static void zend_type_copy_ctor(zend_type *type, bool persistent) {
5858
}
5959
}
6060

61-
static zend_property_info *zend_duplicate_property_info_internal(zend_property_info *property_info) /* {{{ */
62-
{
63-
zend_property_info* new_property_info = pemalloc(sizeof(zend_property_info), 1);
64-
memcpy(new_property_info, property_info, sizeof(zend_property_info));
65-
zend_string_addref(new_property_info->name);
66-
zend_type_copy_ctor(&new_property_info->type, /* persistent */ 1);
67-
68-
return new_property_info;
69-
}
70-
/* }}} */
71-
7261
static zend_function *zend_duplicate_internal_function(zend_function *func, zend_class_entry *ce) /* {{{ */
7362
{
7463
zend_function *new_function;
@@ -1100,12 +1089,7 @@ static void do_inherit_property(zend_property_info *parent_info, zend_string *ke
11001089
}
11011090
}
11021091
} else {
1103-
if (UNEXPECTED(ce->type & ZEND_INTERNAL_CLASS)) {
1104-
child_info = zend_duplicate_property_info_internal(parent_info);
1105-
} else {
1106-
child_info = parent_info;
1107-
}
1108-
_zend_hash_append_ptr(&ce->properties_info, key, child_info);
1092+
_zend_hash_append_ptr(&ce->properties_info, key, parent_info);
11091093
}
11101094
}
11111095
/* }}} */

Zend/zend_opcode.c

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -462,6 +462,14 @@ ZEND_API void destroy_zend_class(zval *zv)
462462
zend_cleanup_internal_class_data(ce);
463463
}
464464
}
465+
466+
ZEND_HASH_FOREACH_PTR(&ce->properties_info, prop_info) {
467+
if (prop_info->ce == ce) {
468+
zend_string_release(prop_info->name);
469+
zend_type_release(prop_info->type, /* persistent */ 1);
470+
free(prop_info);
471+
}
472+
} ZEND_HASH_FOREACH_END();
465473
zend_hash_destroy(&ce->properties_info);
466474
zend_string_release_ex(ce->name, 1);
467475

0 commit comments

Comments
 (0)