From eb846939b1ecc45fbc4898f4234fea128e8f9551 Mon Sep 17 00:00:00 2001 From: Dmitry Stogov Date: Thu, 19 Dec 2019 23:11:08 +0300 Subject: [PATCH] Fixed bug #78999 (Cycle leak when using function result as temporary) --- NEWS | 4 ++++ Zend/tests/bug78999.phpt | 17 +++++++++++++++++ Zend/zend_vm_def.h | 4 ++++ Zend/zend_vm_execute.h | 32 ++++++++++++++++++++++++++++++++ 4 files changed, 57 insertions(+) create mode 100644 Zend/tests/bug78999.phpt diff --git a/NEWS b/NEWS index ea94f1f7bf..60e91f19df 100644 --- a/NEWS +++ b/NEWS @@ -2,6 +2,10 @@ PHP NEWS ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||| ?? ??? ????, PHP 7.3.14 +- Core + . Fixed bug #78999 (Cycle leak when using function result as temporary). + (Dmitry) + - CURL: . Implemented FR #77711 (CURLFile should support UNICODE filenames). (cmb) diff --git a/Zend/tests/bug78999.phpt b/Zend/tests/bug78999.phpt new file mode 100644 index 0000000000..d4ec16b972 --- /dev/null +++ b/Zend/tests/bug78999.phpt @@ -0,0 +1,17 @@ +--TEST-- +Bug #78999 (Cycle leak when using function result as temporary) +--FILE-- +prop = $t; + return $t; +} +var_dump(get()); +var_dump(gc_collect_cycles()); +--EXPECT-- +object(stdClass)#1 (1) { + ["prop"]=> + *RECURSION* +} +int(1) diff --git a/Zend/zend_vm_def.h b/Zend/zend_vm_def.h index 1963760112..62a9ad8bed 100644 --- a/Zend/zend_vm_def.h +++ b/Zend/zend_vm_def.h @@ -3860,6 +3860,10 @@ ZEND_VM_HOT_HANDLER(62, ZEND_RETURN, CONST|TMP|VAR|CV, ANY) if (EXPECTED(!Z_OPT_ISREF_P(retval_ptr))) { ZVAL_COPY_VALUE(return_value, retval_ptr); if (EXPECTED(!(EX_CALL_INFO() & ZEND_CALL_CODE))) { + zend_refcounted *ref = Z_COUNTED_P(retval_ptr); + if (GC_MAY_LEAK(ref)) { + gc_possible_root(ref); + } ZVAL_NULL(retval_ptr); } else { Z_ADDREF_P(return_value); diff --git a/Zend/zend_vm_execute.h b/Zend/zend_vm_execute.h index d80a5f704d..e893e35b6d 100644 --- a/Zend/zend_vm_execute.h +++ b/Zend/zend_vm_execute.h @@ -2727,6 +2727,10 @@ static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_RETURN_SPEC_CONST_ if (EXPECTED(!Z_OPT_ISREF_P(retval_ptr))) { ZVAL_COPY_VALUE(return_value, retval_ptr); if (EXPECTED(!(EX_CALL_INFO() & ZEND_CALL_CODE))) { + zend_refcounted *ref = Z_COUNTED_P(retval_ptr); + if (GC_MAY_LEAK(ref)) { + gc_possible_root(ref); + } ZVAL_NULL(retval_ptr); } else { Z_ADDREF_P(return_value); @@ -17665,6 +17669,10 @@ static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_RETURN_SPEC_TMP_HA if (EXPECTED(!Z_OPT_ISREF_P(retval_ptr))) { ZVAL_COPY_VALUE(return_value, retval_ptr); if (EXPECTED(!(EX_CALL_INFO() & ZEND_CALL_CODE))) { + zend_refcounted *ref = Z_COUNTED_P(retval_ptr); + if (GC_MAY_LEAK(ref)) { + gc_possible_root(ref); + } ZVAL_NULL(retval_ptr); } else { Z_ADDREF_P(return_value); @@ -20433,6 +20441,10 @@ static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_RETURN_SPEC_VAR_HA if (EXPECTED(!Z_OPT_ISREF_P(retval_ptr))) { ZVAL_COPY_VALUE(return_value, retval_ptr); if (EXPECTED(!(EX_CALL_INFO() & ZEND_CALL_CODE))) { + zend_refcounted *ref = Z_COUNTED_P(retval_ptr); + if (GC_MAY_LEAK(ref)) { + gc_possible_root(ref); + } ZVAL_NULL(retval_ptr); } else { Z_ADDREF_P(return_value); @@ -36875,6 +36887,10 @@ static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_RETURN_SPEC_CV_HAN if (EXPECTED(!Z_OPT_ISREF_P(retval_ptr))) { ZVAL_COPY_VALUE(return_value, retval_ptr); if (EXPECTED(!(EX_CALL_INFO() & ZEND_CALL_CODE))) { + zend_refcounted *ref = Z_COUNTED_P(retval_ptr); + if (GC_MAY_LEAK(ref)) { + gc_possible_root(ref); + } ZVAL_NULL(retval_ptr); } else { Z_ADDREF_P(return_value); @@ -55714,6 +55730,10 @@ zend_leave_helper_SPEC_LABEL: if (EXPECTED(!Z_OPT_ISREF_P(retval_ptr))) { ZVAL_COPY_VALUE(return_value, retval_ptr); if (EXPECTED(!(EX_CALL_INFO() & ZEND_CALL_CODE))) { + zend_refcounted *ref = Z_COUNTED_P(retval_ptr); + if (GC_MAY_LEAK(ref)) { + gc_possible_root(ref); + } ZVAL_NULL(retval_ptr); } else { Z_ADDREF_P(return_value); @@ -57328,6 +57348,10 @@ zend_leave_helper_SPEC_LABEL: if (EXPECTED(!Z_OPT_ISREF_P(retval_ptr))) { ZVAL_COPY_VALUE(return_value, retval_ptr); if (EXPECTED(!(EX_CALL_INFO() & ZEND_CALL_CODE))) { + zend_refcounted *ref = Z_COUNTED_P(retval_ptr); + if (GC_MAY_LEAK(ref)) { + gc_possible_root(ref); + } ZVAL_NULL(retval_ptr); } else { Z_ADDREF_P(return_value); @@ -57614,6 +57638,10 @@ zend_leave_helper_SPEC_LABEL: if (EXPECTED(!Z_OPT_ISREF_P(retval_ptr))) { ZVAL_COPY_VALUE(return_value, retval_ptr); if (EXPECTED(!(EX_CALL_INFO() & ZEND_CALL_CODE))) { + zend_refcounted *ref = Z_COUNTED_P(retval_ptr); + if (GC_MAY_LEAK(ref)) { + gc_possible_root(ref); + } ZVAL_NULL(retval_ptr); } else { Z_ADDREF_P(return_value); @@ -59256,6 +59284,10 @@ zend_leave_helper_SPEC_LABEL: if (EXPECTED(!Z_OPT_ISREF_P(retval_ptr))) { ZVAL_COPY_VALUE(return_value, retval_ptr); if (EXPECTED(!(EX_CALL_INFO() & ZEND_CALL_CODE))) { + zend_refcounted *ref = Z_COUNTED_P(retval_ptr); + if (GC_MAY_LEAK(ref)) { + gc_possible_root(ref); + } ZVAL_NULL(retval_ptr); } else { Z_ADDREF_P(return_value); -- 2.40.0