]> granicus.if.org Git - php/commitdiff
Fixed Bug #70332 (Wrong behavior while returning reference on object)
authorXinchen Hui <laruence@php.net>
Sun, 23 Aug 2015 12:17:26 +0000 (20:17 +0800)
committerXinchen Hui <laruence@php.net>
Sun, 23 Aug 2015 12:17:51 +0000 (20:17 +0800)
This fix is actually made for array acessing bug fix (#70262) which is
discarded since we have another better fix, anyway now seems this is still useful

NEWS
Zend/tests/bug70332.phpt [new file with mode: 0644]
Zend/zend_vm_def.h
Zend/zend_vm_execute.h

diff --git a/NEWS b/NEWS
index 51006c318516dc668b62af563bc56f3a28813da0..96fb51259499689d05a34dd3493e6eadb2195d01 100644 (file)
--- a/NEWS
+++ b/NEWS
@@ -3,6 +3,8 @@ PHP                                                                        NEWS
 03 Sep 2015, PHP 7.0.0 RC 2
 
 - Core:
+  . Fixed bug #70332 (Wrong behavior while returning reference on object).
+    (Laruence, Dmitry)
   . Fixed bug #70300 (Syntactical inconsistency with new group use syntax).
     (marcio dot web2 at gmail dot com)
   . Fixed bug #70321 (Magic getter breaks reference to array property).
diff --git a/Zend/tests/bug70332.phpt b/Zend/tests/bug70332.phpt
new file mode 100644 (file)
index 0000000..217070f
--- /dev/null
@@ -0,0 +1,24 @@
+--TEST--
+Bug #70332 (Wrong behavior while returning reference on object)
+--FILE--
+<?php
+function & test($arg) {
+       return $arg;
+}
+
+$arg = new Stdclass();
+$arg->name = array();
+
+test($arg)->name[1] = "xxxx";
+
+print_r($arg);
+?>
+--EXPECT--
+stdClass Object
+(
+    [name] => Array
+        (
+            [1] => xxxx
+        )
+
+)
index ff7e0b109c7d7546da12a4321738d02b9e6f80a6..795078085eb47f67f6d9ffd217773c34018ab0e2 100644 (file)
@@ -7247,11 +7247,11 @@ ZEND_VM_HANDLER(156, ZEND_SEPARATE, VAR, UNUSED)
        zval *var_ptr;
 
        var_ptr = EX_VAR(opline->op1.var);
-       if (Z_TYPE_P(var_ptr) != IS_OBJECT &&
-           !Z_ISREF_P(var_ptr) &&
-           Z_REFCOUNTED_P(var_ptr) &&
-           Z_REFCOUNT_P(var_ptr) > 1) {
-
+       if (UNEXPECTED(Z_ISREF_P(var_ptr))) {
+               if (UNEXPECTED(Z_REFCOUNT_P(var_ptr) == 1)) {
+                       ZVAL_UNREF(var_ptr);
+               }
+       } else if (Z_COPYABLE_P(var_ptr) && Z_REFCOUNT_P(var_ptr) > 1) {
                Z_DELREF_P(var_ptr);
                ZVAL_DUP(EX_VAR(opline->op1.var), var_ptr);
        }
index c256966ad840081b8faee23cd06dff2be7bd42c7..3f54a01e8b7b24244943e8a5ff73b14fbb627a25 100644 (file)
@@ -19441,11 +19441,11 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_SEPARATE_SPEC_VAR_UNUSED_HANDL
        zval *var_ptr;
 
        var_ptr = EX_VAR(opline->op1.var);
-       if (Z_TYPE_P(var_ptr) != IS_OBJECT &&
-           !Z_ISREF_P(var_ptr) &&
-           Z_REFCOUNTED_P(var_ptr) &&
-           Z_REFCOUNT_P(var_ptr) > 1) {
-
+       if (UNEXPECTED(Z_ISREF_P(var_ptr))) {
+               if (UNEXPECTED(Z_REFCOUNT_P(var_ptr) == 1)) {
+                       ZVAL_UNREF(var_ptr);
+               }
+       } else if (Z_COPYABLE_P(var_ptr) && Z_REFCOUNT_P(var_ptr) > 1) {
                Z_DELREF_P(var_ptr);
                ZVAL_DUP(EX_VAR(opline->op1.var), var_ptr);
        }