summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDmitry Stogov <dmitry@zend.com>2019-12-19 23:11:08 +0300
committerDmitry Stogov <dmitry@zend.com>2019-12-19 23:11:08 +0300
commiteb846939b1ecc45fbc4898f4234fea128e8f9551 (patch)
tree9cc6f3b9412e3394139793beb4a9b88b7ae475b6
parent3e35b0898023e3e3c3350c21ed8ca69d0a1d7ec4 (diff)
downloadphp-git-eb846939b1ecc45fbc4898f4234fea128e8f9551.tar.gz
Fixed bug #78999 (Cycle leak when using function result as temporary)
-rw-r--r--NEWS4
-rw-r--r--Zend/tests/bug78999.phpt17
-rw-r--r--Zend/zend_vm_def.h4
-rw-r--r--Zend/zend_vm_execute.h32
4 files changed, 57 insertions, 0 deletions
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--
+<?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 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);