diff options
| author | Michael Wallner <mike@php.net> | 2013-10-04 16:16:15 +0200 |
|---|---|---|
| committer | Michael Wallner <mike@php.net> | 2013-10-04 16:16:15 +0200 |
| commit | 8973390541faaadfdfc0f838421f037060188e5e (patch) | |
| tree | 25997ffd4caba5a588028109cc8547ef41f4b118 | |
| parent | e8ae795529eff83482797dff0d1a1de7f0a84c8d (diff) | |
| download | php-git-8973390541faaadfdfc0f838421f037060188e5e.tar.gz | |
fix bug #64146 (serialize incorrectly saving objects when they are
cloned)
| -rw-r--r-- | ext/standard/tests/serialize/bug64146.phpt | 60 | ||||
| -rw-r--r-- | ext/standard/var.c | 6 |
2 files changed, 62 insertions, 4 deletions
diff --git a/ext/standard/tests/serialize/bug64146.phpt b/ext/standard/tests/serialize/bug64146.phpt new file mode 100644 index 0000000000..18ae78d0ce --- /dev/null +++ b/ext/standard/tests/serialize/bug64146.phpt @@ -0,0 +1,60 @@ +--TEST-- +Bug #64146 (serialize incorrectly saving objects when they are cloned) +--FILE-- +<?php + +echo "Test\n"; + +class A +{ + public $a = array(); + + public function __construct() + { + $this->a[] = new B(1); + $this->a[] = new B(2); + } +} + +class B implements Serializable +{ + public $b; + + public function __construct($c) + { + $this->b = new C($c); + } + + public function serialize() + { + return serialize(clone $this->b); + } + + public function unserialize($data) + { + $this->b = unserialize($data); + } +} + +class C +{ + public $c; + + public function __construct($c) + { + $this->c = $c; + } +} + +$a = unserialize(serialize(new A())); + +print $a->a[0]->b->c . "\n"; +print $a->a[1]->b->c . "\n"; + +?> +Done +--EXPECT-- +Test +1 +2 +Done diff --git a/ext/standard/var.c b/ext/standard/var.c index f76a14cfa6..f71c4a4fdc 100644 --- a/ext/standard/var.c +++ b/ext/standard/var.c @@ -549,11 +549,9 @@ static inline int php_add_var_hash(HashTable *var_hash, zval *var, void *var_old char id[32], *p; register int len; - /* relies on "(long)" being a perfect hash function for data pointers, - * however the actual identity of an object has had to be determined - * by its object handle since 5.0. */ if ((Z_TYPE_P(var) == IS_OBJECT) && Z_OBJ_HT_P(var)->get_class_entry) { - p = smart_str_print_long(id + sizeof(id) - 1, (long) Z_OBJ_HANDLE_P(var)); + p = smart_str_print_long(id + sizeof(id) - 1, + (long) zend_objects_get_address(var TSRMLS_CC)); *(--p) = 'O'; len = id + sizeof(id) - 1 - p; } else { |
