diff options
author | Dmitry Stogov <dmitry@zend.com> | 2019-12-19 23:17:39 +0300 |
---|---|---|
committer | Dmitry Stogov <dmitry@zend.com> | 2019-12-19 23:17:39 +0300 |
commit | 66d5b0608a40cd21bc20529e82b62c308178530a (patch) | |
tree | 501829bb30a2f156f8393306b6b0da4056ea302e | |
parent | 7e05f97fa65c124dcc8057ddad2562158eda8608 (diff) | |
parent | eb846939b1ecc45fbc4898f4234fea128e8f9551 (diff) | |
download | php-git-66d5b0608a40cd21bc20529e82b62c308178530a.tar.gz |
Merge branch 'PHP-7.3' into PHP-7.4
* PHP-7.3:
Fixed bug #78999 (Cycle leak when using function result as temporary)
-rw-r--r-- | NEWS | 2 | ||||
-rw-r--r-- | Zend/tests/bug78999.phpt | 17 | ||||
-rw-r--r-- | Zend/zend_vm_def.h | 4 | ||||
-rw-r--r-- | Zend/zend_vm_execute.h | 32 |
4 files changed, 55 insertions, 0 deletions
@@ -10,6 +10,8 @@ PHP NEWS never saved). (Nikita) . Fixed bug #78776 (Abstract method implementation from trait does not check "static"). (Nikita) + . Fixed bug #78999 (Cycle leak when using function result as temporary). + (Dmitry) - OPcache: . Fixed bug #78961 (erroneous optimization of re-assigned $GLOBALS). (Dmitry) 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-- +<?php +function get() { + $t = new stdClass; + $t->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 d041d16893..66a4c6be31 100644 --- a/Zend/zend_vm_def.h +++ b/Zend/zend_vm_def.h @@ -4328,7 +4328,11 @@ ZEND_VM_INLINE_HANDLER(62, ZEND_RETURN, CONST|TMP|VAR|CV, ANY) if (Z_OPT_REFCOUNTED_P(retval_ptr)) { if (EXPECTED(!Z_OPT_ISREF_P(retval_ptr))) { if (EXPECTED(!(EX_CALL_INFO() & ZEND_CALL_CODE))) { + zend_refcounted *ref = Z_COUNTED_P(retval_ptr); ZVAL_COPY_VALUE(return_value, retval_ptr); + if (GC_MAY_LEAK(ref)) { + gc_possible_root(ref); + } ZVAL_NULL(retval_ptr); break; } else { diff --git a/Zend/zend_vm_execute.h b/Zend/zend_vm_execute.h index b015558084..f5346d0d57 100644 --- a/Zend/zend_vm_execute.h +++ b/Zend/zend_vm_execute.h @@ -3523,7 +3523,11 @@ static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_RETURN_SPEC_CONST_ if (Z_OPT_REFCOUNTED_P(retval_ptr)) { if (EXPECTED(!Z_OPT_ISREF_P(retval_ptr))) { if (EXPECTED(!(EX_CALL_INFO() & ZEND_CALL_CODE))) { + zend_refcounted *ref = Z_COUNTED_P(retval_ptr); ZVAL_COPY_VALUE(return_value, retval_ptr); + if (GC_MAY_LEAK(ref)) { + gc_possible_root(ref); + } ZVAL_NULL(retval_ptr); break; } else { @@ -17798,7 +17802,11 @@ static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_RETURN_SPEC_TMP_HA if (Z_OPT_REFCOUNTED_P(retval_ptr)) { if (EXPECTED(!Z_OPT_ISREF_P(retval_ptr))) { if (EXPECTED(!(EX_CALL_INFO() & ZEND_CALL_CODE))) { + zend_refcounted *ref = Z_COUNTED_P(retval_ptr); ZVAL_COPY_VALUE(return_value, retval_ptr); + if (GC_MAY_LEAK(ref)) { + gc_possible_root(ref); + } ZVAL_NULL(retval_ptr); break; } else { @@ -20634,7 +20642,11 @@ static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_RETURN_SPEC_VAR_HA if (Z_OPT_REFCOUNTED_P(retval_ptr)) { if (EXPECTED(!Z_OPT_ISREF_P(retval_ptr))) { if (EXPECTED(!(EX_CALL_INFO() & ZEND_CALL_CODE))) { + zend_refcounted *ref = Z_COUNTED_P(retval_ptr); ZVAL_COPY_VALUE(return_value, retval_ptr); + if (GC_MAY_LEAK(ref)) { + gc_possible_root(ref); + } ZVAL_NULL(retval_ptr); break; } else { @@ -37001,7 +37013,11 @@ static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_RETURN_SPEC_CV_HAN if (Z_OPT_REFCOUNTED_P(retval_ptr)) { if (EXPECTED(!Z_OPT_ISREF_P(retval_ptr))) { if (EXPECTED(!(EX_CALL_INFO() & ZEND_CALL_CODE))) { + zend_refcounted *ref = Z_COUNTED_P(retval_ptr); ZVAL_COPY_VALUE(return_value, retval_ptr); + if (GC_MAY_LEAK(ref)) { + gc_possible_root(ref); + } ZVAL_NULL(retval_ptr); break; } else { @@ -53788,7 +53804,11 @@ zend_leave_helper_SPEC_LABEL: if (Z_OPT_REFCOUNTED_P(retval_ptr)) { if (EXPECTED(!Z_OPT_ISREF_P(retval_ptr))) { if (EXPECTED(!(EX_CALL_INFO() & ZEND_CALL_CODE))) { + zend_refcounted *ref = Z_COUNTED_P(retval_ptr); ZVAL_COPY_VALUE(return_value, retval_ptr); + if (GC_MAY_LEAK(ref)) { + gc_possible_root(ref); + } ZVAL_NULL(retval_ptr); break; } else { @@ -55262,7 +55282,11 @@ zend_leave_helper_SPEC_LABEL: if (Z_OPT_REFCOUNTED_P(retval_ptr)) { if (EXPECTED(!Z_OPT_ISREF_P(retval_ptr))) { if (EXPECTED(!(EX_CALL_INFO() & ZEND_CALL_CODE))) { + zend_refcounted *ref = Z_COUNTED_P(retval_ptr); ZVAL_COPY_VALUE(return_value, retval_ptr); + if (GC_MAY_LEAK(ref)) { + gc_possible_root(ref); + } ZVAL_NULL(retval_ptr); break; } else { @@ -55548,7 +55572,11 @@ zend_leave_helper_SPEC_LABEL: if (Z_OPT_REFCOUNTED_P(retval_ptr)) { if (EXPECTED(!Z_OPT_ISREF_P(retval_ptr))) { if (EXPECTED(!(EX_CALL_INFO() & ZEND_CALL_CODE))) { + zend_refcounted *ref = Z_COUNTED_P(retval_ptr); ZVAL_COPY_VALUE(return_value, retval_ptr); + if (GC_MAY_LEAK(ref)) { + gc_possible_root(ref); + } ZVAL_NULL(retval_ptr); break; } else { @@ -56630,7 +56658,11 @@ zend_leave_helper_SPEC_LABEL: if (Z_OPT_REFCOUNTED_P(retval_ptr)) { if (EXPECTED(!Z_OPT_ISREF_P(retval_ptr))) { if (EXPECTED(!(EX_CALL_INFO() & ZEND_CALL_CODE))) { + zend_refcounted *ref = Z_COUNTED_P(retval_ptr); ZVAL_COPY_VALUE(return_value, retval_ptr); + if (GC_MAY_LEAK(ref)) { + gc_possible_root(ref); + } ZVAL_NULL(retval_ptr); break; } else { |