diff options
author | Xinchen Hui <laruence@php.net> | 2015-03-05 18:16:39 +0800 |
---|---|---|
committer | Xinchen Hui <laruence@php.net> | 2015-03-05 18:39:50 +0800 |
commit | f039225597b51f2ee02a050391d497ae68d63b39 (patch) | |
tree | 9cb4427f51218a5d5e8ffaa8010f85edb039063a /Zend/zend_compile.c | |
parent | 837eeefee9e01156b364a4b0e9cff8d9f0a1a1d5 (diff) | |
download | php-git-f039225597b51f2ee02a050391d497ae68d63b39.tar.gz |
Fixed bug #69174 (leaks when unused inner class use traits precedence)
Diffstat (limited to 'Zend/zend_compile.c')
-rw-r--r-- | Zend/zend_compile.c | 17 |
1 files changed, 16 insertions, 1 deletions
diff --git a/Zend/zend_compile.c b/Zend/zend_compile.c index 1b0ba89eff..edd45bfccc 100644 --- a/Zend/zend_compile.c +++ b/Zend/zend_compile.c @@ -4204,16 +4204,20 @@ static void zend_do_traits_method_binding(zend_class_entry *ce TSRMLS_DC) /* {{{ for (i = 0; i < ce->num_traits; i++) { if (ce->trait_precedences) { HashTable exclude_table; + zend_trait_precedence **precedences; /* TODO: revisit this start size, may be its not optimal */ zend_hash_init_ex(&exclude_table, 2, NULL, NULL, 0, 0); - zend_traits_compile_exclude_table(&exclude_table, ce->trait_precedences, ce->traits[i]); + precedences = ce->trait_precedences; + ce->trait_precedences = NULL; + zend_traits_compile_exclude_table(&exclude_table, precedences, ce->traits[i]); /* copies functions, applies defined aliasing, and excludes unused trait methods */ zend_hash_apply_with_arguments(&ce->traits[i]->function_table TSRMLS_CC, (apply_func_args_t)zend_traits_copy_functions, 3, ce, &overriden, &exclude_table); zend_hash_destroy(&exclude_table); + ce->trait_precedences = precedences; } else { zend_hash_apply_with_arguments(&ce->traits[i]->function_table TSRMLS_CC, (apply_func_args_t)zend_traits_copy_functions, 3, ce, &overriden, NULL); } @@ -4221,6 +4225,17 @@ static void zend_do_traits_method_binding(zend_class_entry *ce TSRMLS_DC) /* {{{ zend_hash_apply_with_argument(&ce->function_table, (apply_func_arg_t)zend_fixup_trait_method, ce TSRMLS_CC); + if (ce->trait_precedences) { + i = 0; + while (ce->trait_precedences[i]) { + if (ce->trait_precedences[i]->exclude_from_classes) { + efree(ce->trait_precedences[i]->exclude_from_classes); + ce->trait_precedences[i]->exclude_from_classes = NULL; + } + i++; + } + } + if (overriden) { zend_hash_destroy(overriden); FREE_HASHTABLE(overriden); |