From 46a49be6c866103ebcb95e03b2b96460bec16b7b Mon Sep 17 00:00:00 2001 From: Nikita Popov Date: Thu, 3 Sep 2020 17:10:34 +0200 Subject: [PATCH] Fixed bug #80049 Type checking may convert to refcounted values, so force freeing of extra args. --- NEWS | 2 ++ Zend/tests/bug80049.phpt | 14 ++++++++++++++ Zend/zend_vm_def.h | 1 + Zend/zend_vm_execute.h | 1 + 4 files changed, 18 insertions(+) create mode 100644 Zend/tests/bug80049.phpt diff --git a/NEWS b/NEWS index 0800e83e0f9..d3e40604783 100644 --- a/NEWS +++ b/NEWS @@ -4,6 +4,8 @@ PHP NEWS - Core: . Fixed bug #80048 (Bug #69100 has not been fixed for Windows). (cmb) + . Fixed bug #80049 (Memleak when coercing integers to string via variadic + argument). (Nikita) - Calendar: . Fixed bug #80007 (Potential type confusion in unixtojd() parameter parsing). diff --git a/Zend/tests/bug80049.phpt b/Zend/tests/bug80049.phpt new file mode 100644 index 00000000000..852b71feaab --- /dev/null +++ b/Zend/tests/bug80049.phpt @@ -0,0 +1,14 @@ +--TEST-- +Bug #80049: Memleak when coercing integers to string via variadic argument +--FILE-- + +--EXPECT-- +array(1) { + [0]=> + string(3) "123" +} diff --git a/Zend/zend_vm_def.h b/Zend/zend_vm_def.h index 70e33039da0..6f9aca4b551 100644 --- a/Zend/zend_vm_def.h +++ b/Zend/zend_vm_def.h @@ -4819,6 +4819,7 @@ ZEND_VM_HANDLER(164, ZEND_RECV_VARIADIC, NUM, UNUSED|CACHE_SLOT) ZEND_HASH_FILL_PACKED(Z_ARRVAL_P(params)) { param = EX_VAR_NUM(EX(func)->op_array.last_var + EX(func)->op_array.T); if (UNEXPECTED((EX(func)->op_array.fn_flags & ZEND_ACC_HAS_TYPE_HINTS) != 0)) { + ZEND_ADD_CALL_FLAG(execute_data, ZEND_CALL_FREE_EXTRA_ARGS); do { zend_verify_arg_type(EX(func), arg_num, param, NULL, CACHE_ADDR(opline->op2.num)); if (Z_OPT_REFCOUNTED_P(param)) Z_ADDREF_P(param); diff --git a/Zend/zend_vm_execute.h b/Zend/zend_vm_execute.h index 9d7515e9d05..e5e5a9e1da8 100644 --- a/Zend/zend_vm_execute.h +++ b/Zend/zend_vm_execute.h @@ -2375,6 +2375,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_RECV_VARIADIC_SPEC_UNUSED_HAND ZEND_HASH_FILL_PACKED(Z_ARRVAL_P(params)) { param = EX_VAR_NUM(EX(func)->op_array.last_var + EX(func)->op_array.T); if (UNEXPECTED((EX(func)->op_array.fn_flags & ZEND_ACC_HAS_TYPE_HINTS) != 0)) { + ZEND_ADD_CALL_FLAG(execute_data, ZEND_CALL_FREE_EXTRA_ARGS); do { zend_verify_arg_type(EX(func), arg_num, param, NULL, CACHE_ADDR(opline->op2.num)); if (Z_OPT_REFCOUNTED_P(param)) Z_ADDREF_P(param);