Skip to content

Commit 8807889

Browse files
committed
Fix arginfo leak when using disabled_classes
Also remove the hack where scope is set to NULL in order to make free_internal_arg_info work. Instead explicitly call it for class methods. This fixes the asan build for Zend/tests/bug77494.phpt.
1 parent 7910f12 commit 8807889

File tree

2 files changed

+15
-4
lines changed

2 files changed

+15
-4
lines changed

Zend/zend_API.c

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2856,6 +2856,7 @@ ZEND_API int zend_disable_class(char *class_name, size_t class_name_length) /* {
28562856
{
28572857
zend_class_entry *disabled_class;
28582858
zend_string *key;
2859+
zend_function *fn;
28592860

28602861
key = zend_string_alloc(class_name_length, 0);
28612862
zend_str_tolower_copy(ZSTR_VAL(key), class_name, class_name_length);
@@ -2864,8 +2865,16 @@ ZEND_API int zend_disable_class(char *class_name, size_t class_name_length) /* {
28642865
if (!disabled_class) {
28652866
return FAILURE;
28662867
}
2868+
28672869
INIT_CLASS_ENTRY_INIT_METHODS((*disabled_class), disabled_class_new);
28682870
disabled_class->create_object = display_disabled_class;
2871+
2872+
ZEND_HASH_FOREACH_PTR(&disabled_class->function_table, fn) {
2873+
if ((fn->common.fn_flags & (ZEND_ACC_HAS_RETURN_TYPE|ZEND_ACC_HAS_TYPE_HINTS)) &&
2874+
fn->common.scope == disabled_class) {
2875+
zend_free_internal_arg_info(&fn->internal_function);
2876+
}
2877+
} ZEND_HASH_FOREACH_END();
28692878
zend_hash_clean(&disabled_class->function_table);
28702879
return SUCCESS;
28712880
}

Zend/zend_opcode.c

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -104,7 +104,7 @@ ZEND_API void destroy_zend_function(zend_function *function)
104104

105105
void zend_free_internal_arg_info(zend_internal_function *function) {
106106
if ((function->fn_flags & (ZEND_ACC_HAS_RETURN_TYPE|ZEND_ACC_HAS_TYPE_HINTS)) &&
107-
!function->scope && function->arg_info) {
107+
function->arg_info) {
108108

109109
uint32_t i;
110110
uint32_t num_args = function->num_args + 1;
@@ -135,7 +135,10 @@ ZEND_API void zend_function_dtor(zval *zv)
135135
ZEND_ASSERT(function->common.function_name);
136136
zend_string_release_ex(function->common.function_name, 1);
137137

138-
zend_free_internal_arg_info(&function->internal_function);
138+
/* For methods this will be called explicitly. */
139+
if (!function->common.scope) {
140+
zend_free_internal_arg_info(&function->internal_function);
141+
}
139142

140143
if (!(function->common.fn_flags & ZEND_ACC_ARENA_ALLOCATED)) {
141144
pefree(function, 1);
@@ -352,8 +355,7 @@ ZEND_API void destroy_zend_class(zval *zv)
352355
ZEND_HASH_FOREACH_PTR(&ce->function_table, fn) {
353356
if ((fn->common.fn_flags & (ZEND_ACC_HAS_RETURN_TYPE|ZEND_ACC_HAS_TYPE_HINTS)) &&
354357
fn->common.scope == ce) {
355-
/* reset function scope to allow arg_info removing */
356-
fn->common.scope = NULL;
358+
zend_free_internal_arg_info(&fn->internal_function);
357359
}
358360
} ZEND_HASH_FOREACH_END();
359361

0 commit comments

Comments
 (0)