]> granicus.if.org Git - php/commitdiff
Fix arginfo leak in disable_functions
authorNikita Popov <nikita.ppv@gmail.com>
Fri, 28 Jun 2019 14:36:58 +0000 (16:36 +0200)
committerNikita Popov <nikita.ppv@gmail.com>
Fri, 28 Jun 2019 14:38:46 +0000 (16:38 +0200)
Arginfo is allocated if types are used, we need to free it.

Zend/zend_API.c
Zend/zend_compile.h
Zend/zend_opcode.c

index 13c661699fa506b1c34201aa9699df0cafc1b73c..edc2ba7bc91d94f86bce167b5f1469e96095cf31 100644 (file)
@@ -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;
index 6721612b4cf54431ae63645dcd3ab4af06420f22..959c62b81538a4618e4730cfa73108387d88e5ea 100644 (file)
@@ -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);
index dd7c42a0937f8a4f6b0afc17ac472b1d577886b5..403f501dbf369f8bb4473f5bdc39024f42878344 100644 (file)
@@ -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);