mirror of
https://github.com/php/php-src.git
synced 2024-09-22 02:17:32 +00:00
Memory leak fix, for arg_info of internal functions with type hints (ZTS build only).
This commit is contained in:
parent
c060d88c36
commit
a7f83f474c
31
Zend/zend.c
31
Zend/zend.c
@ -570,9 +570,34 @@ static void auto_global_dtor(zval *zv) /* {{{ */
|
||||
static void function_copy_ctor(zval *zv) /* {{{ */
|
||||
{
|
||||
zend_function *old_func = Z_FUNC_P(zv);
|
||||
Z_FUNC_P(zv) = pemalloc(sizeof(zend_internal_function), 1);
|
||||
memcpy(Z_FUNC_P(zv), old_func, sizeof(zend_internal_function));
|
||||
function_add_ref(Z_FUNC_P(zv));
|
||||
zend_function *func = pemalloc(sizeof(zend_internal_function), 1);
|
||||
|
||||
Z_FUNC_P(zv) = func;
|
||||
memcpy(func, old_func, sizeof(zend_internal_function));
|
||||
function_add_ref(func);
|
||||
if ((old_func->common.fn_flags & (ZEND_ACC_HAS_RETURN_TYPE|ZEND_ACC_HAS_TYPE_HINTS))
|
||||
&& old_func->common.arg_info) {
|
||||
uint32_t i;
|
||||
uint32_t num_args = old_func->common.num_args + 1;
|
||||
zend_arg_info *arg_info = old_func->common.arg_info - 1;
|
||||
zend_arg_info *new_arg_info;
|
||||
|
||||
if (old_func->common.fn_flags & ZEND_ACC_VARIADIC) {
|
||||
num_args++;
|
||||
}
|
||||
new_arg_info = pemalloc(sizeof(zend_arg_info) * num_args, 1);
|
||||
memcpy(new_arg_info, arg_info, sizeof(zend_arg_info) * num_args);
|
||||
for (i = 0 ; i < num_args; i++) {
|
||||
if (ZEND_TYPE_IS_CLASS(arg_info[i].type)) {
|
||||
zend_string *name = zend_string_dup(ZEND_TYPE_NAME(arg_info[i].type), 1);
|
||||
|
||||
new_arg_info[i].type =
|
||||
ZEND_TYPE_ENCODE_CLASS(
|
||||
name, ZEND_TYPE_ALLOW_NULL(arg_info[i].type));
|
||||
}
|
||||
}
|
||||
func->common.arg_info = new_arg_info + 1;
|
||||
}
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
|
@ -141,7 +141,7 @@ ZEND_API void zend_function_dtor(zval *zv)
|
||||
ZEND_ASSERT(function->type == ZEND_INTERNAL_FUNCTION);
|
||||
ZEND_ASSERT(function->common.function_name);
|
||||
zend_string_release(function->common.function_name);
|
||||
#ifndef ZTS
|
||||
|
||||
if ((function->common.fn_flags & (ZEND_ACC_HAS_RETURN_TYPE|ZEND_ACC_HAS_TYPE_HINTS)) &&
|
||||
!function->common.scope && function->common.arg_info) {
|
||||
|
||||
@ -159,7 +159,7 @@ ZEND_API void zend_function_dtor(zval *zv)
|
||||
}
|
||||
free(arg_info);
|
||||
}
|
||||
#endif
|
||||
|
||||
if (!(function->common.fn_flags & ZEND_ACC_ARENA_ALLOCATED)) {
|
||||
pefree(function, 1);
|
||||
}
|
||||
@ -245,9 +245,7 @@ ZEND_API void destroy_zend_class(zval *zv)
|
||||
{
|
||||
zend_property_info *prop_info;
|
||||
zend_class_entry *ce = Z_PTR_P(zv);
|
||||
#ifndef ZTS
|
||||
zend_function *fn;
|
||||
#endif
|
||||
|
||||
if (--ce->refcount > 0) {
|
||||
return;
|
||||
@ -331,7 +329,8 @@ ZEND_API void destroy_zend_class(zval *zv)
|
||||
}
|
||||
zend_hash_destroy(&ce->properties_info);
|
||||
zend_string_release(ce->name);
|
||||
#ifndef ZTS
|
||||
|
||||
/* TODO: eliminate this loop for classes without functions with arg_info */
|
||||
ZEND_HASH_FOREACH_PTR(&ce->function_table, fn) {
|
||||
if ((fn->common.fn_flags & (ZEND_ACC_HAS_RETURN_TYPE|ZEND_ACC_HAS_TYPE_HINTS)) &&
|
||||
fn->common.scope == ce) {
|
||||
@ -339,7 +338,7 @@ ZEND_API void destroy_zend_class(zval *zv)
|
||||
fn->common.scope = NULL;
|
||||
}
|
||||
} ZEND_HASH_FOREACH_END();
|
||||
#endif
|
||||
|
||||
zend_hash_destroy(&ce->function_table);
|
||||
if (zend_hash_num_elements(&ce->constants_table)) {
|
||||
zend_class_constant *c;
|
||||
|
Loading…
Reference in New Issue
Block a user