summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNikita Popov <nikita.ppv@gmail.com>2019-06-28 16:36:58 +0200
committerNikita Popov <nikita.ppv@gmail.com>2019-06-28 16:38:46 +0200
commit36983035404fa6a6027addd3589832adb93c92ac (patch)
treec7405021f57fc7d0a848ecf4126be927e931aa6f
parent345a3b277cf2edb37c8235bf18371bf37ab3b121 (diff)
downloadphp-git-36983035404fa6a6027addd3589832adb93c92ac.tar.gz
Fix arginfo leak in disable_functions
Arginfo is allocated if types are used, we need to free it.
-rw-r--r--Zend/zend_API.c1
-rw-r--r--Zend/zend_compile.h1
-rw-r--r--Zend/zend_opcode.c38
3 files changed, 23 insertions, 17 deletions
diff --git a/Zend/zend_API.c b/Zend/zend_API.c
index 13c661699f..edc2ba7bc9 100644
--- a/Zend/zend_API.c
+++ b/Zend/zend_API.c
@@ -2780,6 +2780,7 @@ ZEND_API int zend_disable_function(char *function_name, size_t function_name_len
{
zend_internal_function *func;
if ((func = zend_hash_str_find_ptr(CG(function_table), function_name, function_name_length))) {
+ zend_free_internal_arg_info(func);
func->fn_flags &= ~(ZEND_ACC_VARIADIC | ZEND_ACC_HAS_TYPE_HINTS | ZEND_ACC_HAS_RETURN_TYPE);
func->num_args = 0;
func->arg_info = NULL;
diff --git a/Zend/zend_compile.h b/Zend/zend_compile.h
index 6721612b4c..959c62b815 100644
--- a/Zend/zend_compile.h
+++ b/Zend/zend_compile.h
@@ -790,6 +790,7 @@ ZEND_API ZEND_COLD void zend_user_exception_handler(void);
} \
} while (0)
+void zend_free_internal_arg_info(zend_internal_function *function);
ZEND_API void destroy_zend_function(zend_function *function);
ZEND_API void zend_function_dtor(zval *zv);
ZEND_API void destroy_zend_class(zval *zv);
diff --git a/Zend/zend_opcode.c b/Zend/zend_opcode.c
index dd7c42a093..403f501dbf 100644
--- a/Zend/zend_opcode.c
+++ b/Zend/zend_opcode.c
@@ -102,6 +102,26 @@ ZEND_API void destroy_zend_function(zend_function *function)
zend_function_dtor(&tmp);
}
+void zend_free_internal_arg_info(zend_internal_function *function) {
+ if ((function->fn_flags & (ZEND_ACC_HAS_RETURN_TYPE|ZEND_ACC_HAS_TYPE_HINTS)) &&
+ !function->scope && function->arg_info) {
+
+ uint32_t i;
+ uint32_t num_args = function->num_args + 1;
+ zend_internal_arg_info *arg_info = function->arg_info - 1;
+
+ if (function->fn_flags & ZEND_ACC_VARIADIC) {
+ num_args++;
+ }
+ for (i = 0 ; i < num_args; i++) {
+ if (ZEND_TYPE_IS_CLASS(arg_info[i].type)) {
+ zend_string_release_ex(ZEND_TYPE_NAME(arg_info[i].type), 1);
+ }
+ }
+ free(arg_info);
+ }
+}
+
ZEND_API void zend_function_dtor(zval *zv)
{
zend_function *function = Z_PTR_P(zv);
@@ -115,23 +135,7 @@ ZEND_API void zend_function_dtor(zval *zv)
ZEND_ASSERT(function->common.function_name);
zend_string_release_ex(function->common.function_name, 1);
- if ((function->common.fn_flags & (ZEND_ACC_HAS_RETURN_TYPE|ZEND_ACC_HAS_TYPE_HINTS)) &&
- !function->common.scope && function->common.arg_info) {
-
- uint32_t i;
- uint32_t num_args = function->common.num_args + 1;
- zend_arg_info *arg_info = function->common.arg_info - 1;
-
- if (function->common.fn_flags & ZEND_ACC_VARIADIC) {
- num_args++;
- }
- for (i = 0 ; i < num_args; i++) {
- if (ZEND_TYPE_IS_CLASS(arg_info[i].type)) {
- zend_string_release_ex(ZEND_TYPE_NAME(arg_info[i].type), 1);
- }
- }
- free(arg_info);
- }
+ zend_free_internal_arg_info(&function->internal_function);
if (!(function->common.fn_flags & ZEND_ACC_ARENA_ALLOCATED)) {
pefree(function, 1);