]> granicus.if.org Git - php/commitdiff
Fixed bug #72229 (Wrong reference when serialize/unserialize an object)
authorXinchen Hui <laruence@gmail.com>
Tue, 17 May 2016 09:40:26 +0000 (17:40 +0800)
committerXinchen Hui <laruence@gmail.com>
Tue, 17 May 2016 09:40:26 +0000 (17:40 +0800)
NEWS
ext/standard/tests/serialize/bug72229.phpt [new file with mode: 0644]
ext/standard/var.c

diff --git a/NEWS b/NEWS
index c75fe55e3fa573a17e0c836dfad02f888159c9c9..295f4a2449cd115895476c6ec572cbea43dda319 100644 (file)
--- a/NEWS
+++ b/NEWS
@@ -21,6 +21,8 @@ PHP                                                                        NEWS
   . Fixed bug #72197 (pg_lo_create arbitrary read). (Anatol)
 
 - Standard:
+  . Fixed bug #72229 (Wrong reference when serialize/unserialize an object).
+    (Laruence)
   . Fixed bug #72193 (dns_get_record returns array containing elements of
     type 'unknown'). (Laruence)
   . Fixed bug #72017 (range() with float step produces unexpected result).
diff --git a/ext/standard/tests/serialize/bug72229.phpt b/ext/standard/tests/serialize/bug72229.phpt
new file mode 100644 (file)
index 0000000..17c393c
--- /dev/null
@@ -0,0 +1,53 @@
+--TEST--
+Bug #72229 (Wrong reference when serialize/unserialize an object)
+--FILE--
+<?php
+class C1
+{
+    public $arr1 = array();
+    public $arr2 = array();
+    public function __construct()
+    {
+        $this->arr1[0] = $this;
+        $this->arr2[0] = $this->arr1[0];
+        $var1 = &$this->arr1[0];  // Set a reference...
+        unset($var1);             // ... and unset it. 
+    }
+}
+$Obj1 = new C1();
+$txt1 = serialize($Obj1);
+$Obj2 = unserialize($txt1);
+$Obj1->arr2[0] = 50;
+print_r($Obj1);
+$Obj2->arr2[0] = 50;
+print_r($Obj2);
+?>
+--EXPECTF--
+C1 Object
+(
+    [arr1] => Array
+        (
+            [0] => C1 Object
+ *RECURSION*
+        )
+
+    [arr2] => Array
+        (
+            [0] => 50
+        )
+
+)
+C1 Object
+(
+    [arr1] => Array
+        (
+            [0] => C1 Object
+ *RECURSION*
+        )
+
+    [arr2] => Array
+        (
+            [0] => 50
+        )
+
+)
index acb1d40c0171c2699035913aa63d153b64ca5270..4f94ec34cb0641e91ec4635a54ebbbc030f2cc92 100644 (file)
@@ -957,6 +957,10 @@ again:
                                                php_var_serialize_string(buf, ZSTR_VAL(key), ZSTR_LEN(key));
                                        }
 
+                                       if (Z_ISREF_P(data) && Z_REFCOUNT_P(data) == 1) {
+                                               ZVAL_UNREF(data);
+                                       }
+
                                        /* we should still add element even if it's not OK,
                                         * since we already wrote the length of the array before */
                                        if ((Z_TYPE_P(data) == IS_ARRAY && Z_TYPE_P(struc) == IS_ARRAY && Z_ARR_P(data) == Z_ARR_P(struc))