Skip to content

Commit 0d7e10c

Browse files
TimWollabwoebi
authored andcommitted
Fix memory leak of function attribute hash table (#8070)
==109253== 280 (56 direct, 224 indirect) bytes in 1 blocks are definitely lost in loss record 4 of 4 ==109253== at 0x483B7F3: malloc (in /usr/lib/x86_64-linux-gnu/valgrind/vgpreload_memcheck-amd64-linux.so) ==109253== by 0x6D9FA2: __zend_malloc (zend_alloc.c:3068) ==109253== by 0x745138: zend_add_attribute (zend_attributes.c:226) ==109253== by 0x6680D1: zend_add_parameter_attribute (zend_attributes.h:102) ==109253== by 0x66B787: zm_startup_zend_test (test.c:478) ==109253== by 0x7224CD: zend_startup_module_ex (zend_API.c:2202) ==109253== by 0x72252C: zend_startup_module_zval (zend_API.c:2217) ==109253== by 0x734288: zend_hash_apply (zend_hash.c:2011) ==109253== by 0x722C30: zend_startup_modules (zend_API.c:2328) ==109253== by 0x67409B: php_module_startup (main.c:2256) ==109253== by 0x88EDDE: php_cli_startup (php_cli.c:409) ==109253== by 0x890F61: main (php_cli.c:1334)
1 parent f095d2c commit 0d7e10c

File tree

3 files changed

+33
-4
lines changed

3 files changed

+33
-4
lines changed

NEWS

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,8 @@ PHP NEWS
44

55
- Core:
66
. Fixed freeing of internal attribute arguments. (Bob)
7+
. Fixed bug GH-8070 (memory leak of internal function attribute hash).
8+
(Tim Düsterhus)
79

810
- Intl:
911
. Fixed bug GH-8142 (Compilation error on cygwin). (David Carlier)

Zend/zend.c

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -624,6 +624,22 @@ static void function_copy_ctor(zval *zv) /* {{{ */
624624
}
625625
func->common.arg_info = new_arg_info + 1;
626626
}
627+
if (old_func->common.attributes) {
628+
zend_attribute *old_attr;
629+
630+
func->common.attributes = NULL;
631+
632+
ZEND_HASH_PACKED_FOREACH_PTR(old_func->common.attributes, old_attr) {
633+
uint32_t i;
634+
zend_attribute *attr;
635+
636+
attr = zend_add_attribute(&func->common.attributes, old_attr->name, old_attr->argc, old_attr->flags, old_attr->offset, old_attr->lineno);
637+
638+
for (i = 0 ; i < old_attr->argc; i++) {
639+
ZVAL_DUP(&attr->args[i].value, &old_attr->args[i].value);
640+
}
641+
} ZEND_HASH_FOREACH_END();
642+
}
627643
}
628644
/* }}} */
629645

Zend/zend_opcode.c

Lines changed: 15 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -153,6 +153,11 @@ ZEND_API void zend_function_dtor(zval *zv)
153153
/* For methods this will be called explicitly. */
154154
if (!function->common.scope) {
155155
zend_free_internal_arg_info(&function->internal_function);
156+
157+
if (function->common.attributes) {
158+
zend_hash_release(function->common.attributes);
159+
function->common.attributes = NULL;
160+
}
156161
}
157162

158163
if (!(function->common.fn_flags & ZEND_ACC_ARENA_ALLOCATED)) {
@@ -394,11 +399,17 @@ ZEND_API void destroy_zend_class(zval *zv)
394399
zend_hash_destroy(&ce->properties_info);
395400
zend_string_release_ex(ce->name, 1);
396401

397-
/* TODO: eliminate this loop for classes without functions with arg_info */
402+
/* TODO: eliminate this loop for classes without functions with arg_info / attributes */
398403
ZEND_HASH_FOREACH_PTR(&ce->function_table, fn) {
399-
if ((fn->common.fn_flags & (ZEND_ACC_HAS_RETURN_TYPE|ZEND_ACC_HAS_TYPE_HINTS)) &&
400-
fn->common.scope == ce) {
401-
zend_free_internal_arg_info(&fn->internal_function);
404+
if (fn->common.scope == ce) {
405+
if (fn->common.fn_flags & (ZEND_ACC_HAS_RETURN_TYPE|ZEND_ACC_HAS_TYPE_HINTS)) {
406+
zend_free_internal_arg_info(&fn->internal_function);
407+
}
408+
409+
if (fn->common.attributes) {
410+
zend_hash_release(fn->common.attributes);
411+
fn->common.attributes = NULL;
412+
}
402413
}
403414
} ZEND_HASH_FOREACH_END();
404415

0 commit comments

Comments
 (0)