Skip to content

Commit 8d8a55c

Browse files
committed
fix(zend, opcache): refcount strings
Signed-off-by: azjezz <azjezz@protonmail.com>
1 parent 2d9eba6 commit 8d8a55c

3 files changed

Lines changed: 26 additions & 5 deletions

File tree

Zend/zend_inheritance.c

Lines changed: 24 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1934,10 +1934,22 @@ static void do_inherit_property(zend_property_info *parent_info, zend_string *ke
19341934

19351935
uint32_t num_args = orig->op_array.num_args;
19361936
if (orig->op_array.fn_flags & ZEND_ACC_VARIADIC) num_args++;
1937-
size_t arg_info_block = sizeof(zend_arg_info) * (num_args + 1);
1937+
uint32_t total = num_args + 1;
1938+
size_t arg_info_block = sizeof(zend_arg_info) * total;
19381939

19391940
zend_arg_info *new_arg_info = zend_arena_alloc(&CG(arena), arg_info_block);
19401941
memcpy(new_arg_info, orig->op_array.arg_info - 1, arg_info_block);
1942+
1943+
for (uint32_t i = 0; i < total; i++) {
1944+
if (new_arg_info[i].name) {
1945+
zend_string_addref(new_arg_info[i].name);
1946+
}
1947+
1948+
if (new_arg_info[i].doc_comment) {
1949+
zend_string_addref(new_arg_info[i].doc_comment);
1950+
}
1951+
}
1952+
19411953
uint32_t slot = (hi == ZEND_PROPERTY_HOOK_GET) ? 0 : 1;
19421954
new_arg_info[slot].type = sub;
19431955
zend_type_copy_ctor(&new_arg_info[slot].type, true, false);
@@ -2797,6 +2809,17 @@ static void zend_substitute_trait_method_arg_info(
27972809
zend_arg_info *new_block = zend_arena_alloc(&CG(arena), sizeof(zend_arg_info) * total);
27982810
memcpy(new_block, orig_block, sizeof(zend_arg_info) * total);
27992811

2812+
/* The clone shares name/doc_comment string pointers with the parent's arg_info; bump refcount
2813+
* so opcache's interning pass on the parent doesn't release strings the clone still references. */
2814+
for (uint32_t i = 0; i < total; i++) {
2815+
if (new_block[i].name) {
2816+
zend_string_addref(new_block[i].name);
2817+
}
2818+
if (new_block[i].doc_comment) {
2819+
zend_string_addref(new_block[i].doc_comment);
2820+
}
2821+
}
2822+
28002823
uint32_t return_slot_offset = has_return ? 1 : 0;
28012824

28022825
if (has_return && orig_op->generic_types->return_type) {

ext/opcache/zend_persist.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1211,7 +1211,7 @@ zend_class_entry *zend_persist_class_entry(zend_class_entry *orig_ce)
12111211
zend_property_info *xlat_prop = zend_shared_alloc_get_xlat_entry(prop);
12121212
if (xlat_prop) {
12131213
Z_PTR(p->val) = xlat_prop;
1214-
} else if (prop->ce->type == ZEND_USER_CLASS && zend_hash_find_ptr(&prop->ce->properties_info, p->key) != prop) {
1214+
} else if (!zend_accel_in_shm(prop) && prop->ce->type == ZEND_USER_CLASS) {
12151215
Z_PTR(p->val) = zend_persist_substituted_property_info(prop);
12161216
} else {
12171217
/* This can happen if preloading is used and we inherit a property from an

ext/opcache/zend_persist_calc.c

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -662,9 +662,7 @@ void zend_persist_class_entry_calc(zend_class_entry *ce)
662662
ADD_INTERNED_STRING(p->key);
663663
if (prop->ce == ce) {
664664
zend_persist_property_info_calc(prop);
665-
} else if (prop->ce->type == ZEND_USER_CLASS
666-
&& !zend_shared_alloc_get_xlat_entry(prop)
667-
&& zend_hash_find_ptr(&prop->ce->properties_info, p->key) != prop) {
665+
} else if (!zend_accel_in_shm(prop) && prop->ce->type == ZEND_USER_CLASS && !zend_shared_alloc_get_xlat_entry(prop)) {
668666
zend_shared_alloc_register_xlat_entry(prop, prop);
669667
zend_persist_substituted_property_info_calc(prop);
670668
}

0 commit comments

Comments
 (0)