From: Xinchen Hui Date: Tue, 17 May 2016 09:40:26 +0000 (+0800) Subject: Fixed bug #72229 (Wrong reference when serialize/unserialize an object) X-Git-Tag: php-7.0.8RC1~48 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=7989db975f325d83b461a46c3dc75a81fcc27795;p=php Fixed bug #72229 (Wrong reference when serialize/unserialize an object) --- diff --git a/NEWS b/NEWS index c75fe55e3f..295f4a2449 100644 --- 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 index 0000000000..17c393c7d4 --- /dev/null +++ b/ext/standard/tests/serialize/bug72229.phpt @@ -0,0 +1,53 @@ +--TEST-- +Bug #72229 (Wrong reference when serialize/unserialize an object) +--FILE-- +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 + ) + +) diff --git a/ext/standard/var.c b/ext/standard/var.c index acb1d40c01..4f94ec34cb 100644 --- a/ext/standard/var.c +++ b/ext/standard/var.c @@ -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))