summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDmitry Stogov <dmitry@zend.com>2020-10-01 13:18:21 +0300
committerDmitry Stogov <dmitry@zend.com>2020-10-01 13:18:21 +0300
commit773f980e00af7ca45488d3c2879f5f6ba78c96e2 (patch)
tree2de06b8a6bce263db861368722767d0b77f9a7e0
parent5733f11ee9464eeb53eb2bf061c8cb3fd5e7b2ec (diff)
downloadphp-git-773f980e00af7ca45488d3c2879f5f6ba78c96e2.tar.gz
Backport of a partial fix for bug Bug #76982 (memory leak declaring closure in included file).
-rw-r--r--Zend/zend_closures.c5
-rw-r--r--Zend/zend_vm_def.h9
-rw-r--r--Zend/zend_vm_execute.h9
3 files changed, 4 insertions, 19 deletions
diff --git a/Zend/zend_closures.c b/Zend/zend_closures.c
index b9d8bd1c75..022df9dabe 100644
--- a/Zend/zend_closures.c
+++ b/Zend/zend_closures.c
@@ -666,6 +666,7 @@ ZEND_API void zend_create_closure(zval *res, zend_function *func, zend_class_ent
if (func->type == ZEND_USER_FUNCTION) {
memcpy(&closure->func, func, sizeof(zend_op_array));
closure->func.common.fn_flags |= ZEND_ACC_CLOSURE;
+ closure->func.common.fn_flags &= ~ZEND_ACC_IMMUTABLE;
if (closure->func.op_array.static_variables) {
closure->func.op_array.static_variables =
zend_array_dup(closure->func.op_array.static_variables);
@@ -676,7 +677,9 @@ ZEND_API void zend_create_closure(zval *res, zend_function *func, zend_class_ent
|| func->common.scope != scope
|| (func->common.fn_flags & ZEND_ACC_NO_RT_ARENA)
) {
- if (!func->op_array.run_time_cache && (func->common.fn_flags & ZEND_ACC_CLOSURE)) {
+ if (!func->op_array.run_time_cache
+ && (func->common.fn_flags & ZEND_ACC_CLOSURE)
+ && !(func->common.fn_flags & ZEND_ACC_IMMUTABLE)) {
/* If a real closure is used for the first time, we create a shared runtime cache
* and remember which scope it is for. */
func->common.scope = scope;
diff --git a/Zend/zend_vm_def.h b/Zend/zend_vm_def.h
index 6f9aca4b55..1b4eb5720d 100644
--- a/Zend/zend_vm_def.h
+++ b/Zend/zend_vm_def.h
@@ -7097,15 +7097,6 @@ ZEND_VM_HANDLER(153, ZEND_DECLARE_LAMBDA_FUNCTION, CONST, UNUSED)
zfunc = zend_hash_find_ex(EG(function_table), Z_STR_P(RT_CONSTANT(opline, opline->op1)), 1);
ZEND_ASSERT(zfunc != NULL && Z_FUNC_P(zfunc)->type == ZEND_USER_FUNCTION);
- fbc = Z_PTR_P(zfunc);
- if (fbc->common.fn_flags & ZEND_ACC_IMMUTABLE) {
- zend_function *new_func = zend_arena_alloc(&CG(arena), sizeof(zend_op_array));
-
- memcpy(new_func, fbc, sizeof(zend_op_array));
- new_func->common.fn_flags &= ~ZEND_ACC_IMMUTABLE;
- Z_PTR_P(zfunc) = fbc = new_func;
- }
-
if (Z_TYPE(EX(This)) == IS_OBJECT) {
called_scope = Z_OBJCE(EX(This));
if (UNEXPECTED((Z_FUNC_P(zfunc)->common.fn_flags & ZEND_ACC_STATIC) ||
diff --git a/Zend/zend_vm_execute.h b/Zend/zend_vm_execute.h
index e5e5a9e1da..be8b2b3a1f 100644
--- a/Zend/zend_vm_execute.h
+++ b/Zend/zend_vm_execute.h
@@ -9209,15 +9209,6 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_DECLARE_LAMBDA_FUNCTION_SPEC_C
zfunc = zend_hash_find_ex(EG(function_table), Z_STR_P(RT_CONSTANT(opline, opline->op1)), 1);
ZEND_ASSERT(zfunc != NULL && Z_FUNC_P(zfunc)->type == ZEND_USER_FUNCTION);
- fbc = Z_PTR_P(zfunc);
- if (fbc->common.fn_flags & ZEND_ACC_IMMUTABLE) {
- zend_function *new_func = zend_arena_alloc(&CG(arena), sizeof(zend_op_array));
-
- memcpy(new_func, fbc, sizeof(zend_op_array));
- new_func->common.fn_flags &= ~ZEND_ACC_IMMUTABLE;
- Z_PTR_P(zfunc) = fbc = new_func;
- }
-
if (Z_TYPE(EX(This)) == IS_OBJECT) {
called_scope = Z_OBJCE(EX(This));
if (UNEXPECTED((Z_FUNC_P(zfunc)->common.fn_flags & ZEND_ACC_STATIC) ||