summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDmitry Stogov <dmitry@zend.com>2019-12-19 23:17:39 +0300
committerDmitry Stogov <dmitry@zend.com>2019-12-19 23:17:39 +0300
commit66d5b0608a40cd21bc20529e82b62c308178530a (patch)
tree501829bb30a2f156f8393306b6b0da4056ea302e
parent7e05f97fa65c124dcc8057ddad2562158eda8608 (diff)
parenteb846939b1ecc45fbc4898f4234fea128e8f9551 (diff)
downloadphp-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--NEWS2
-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, 55 insertions, 0 deletions
diff --git a/NEWS b/NEWS
index f88f6e67df..47e4e05b6a 100644
--- a/NEWS
+++ b/NEWS
@@ -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 {