Bug #73253 [Opn->Dup]: Incorrect references when inheriting the Serialization interface class

From: Date: Sun, 01 Jan 2017 12:27:59 +0000
Subject: Bug #73253 [Opn->Dup]: Incorrect references when inheriting the Serialization interface class
References: 1  Groups: php.bugs 
Request: Send a blank email to php-bugs+get-206274@lists.php.net to get a copy of this message
Edit report at https://bugs.php.net/bug.php?id=73253&edit=1 ID: 73253 Updated by: nikic@php.net Reported by: illibejiep at gmail dot com Summary: Incorrect references when inheriting the Serialization interface class -Status: Open +Status: Duplicate Type: Bug Package: Scripting Engine problem Operating System: Linux PHP Version: Irrelevant Block user comment: N Private report: N New Comment: The problem here is that in unserialize() you're performing unserializations in a different order than you performing the serializations in serialize(). This is illegal, because references (and object references) in the serialization format are order-dependent. I'm marking this as a duplicate of bug #66052, which is another complaint about this behavior, if from a slightly different angle. Previous Comments: ------------------------------------------------------------------------ [2016-10-05 22:34:20] illibejiep at gmail dot com Description: ------------ The Serialization interface method 'unserialize' incorrectly resolves serialized string references when called from children classes. Test script: --------------- <?php class C { private $c; public function setC($c) { $this->c = $c; } public function getC() { return $this->c; } } class A implements Serializable { private $c; function __construct($c) { $this->c = $c; } public function serialize() { return serialize($this->c); } public function unserialize($serialized) { $this->c = unserialize($serialized); echo "inner child serialized:\n$serialized\n\n"; echo "inner child unserialized:\n"; var_dump($this->c); } } class B extends A implements Serializable { private $str = 'asdf'; public function serialize() { $a = [$this->str, parent::serialize()]; return serialize($a); } public function unserialize($serialized) { echo "inner parent serialized:\n$serialized\n\n"; $a = unserialize($serialized); echo "inner parent unserialized\n"; var_dump($a); $this->str = $a[0]; parent::unserialize($a[1]); } } $c = new C(); $c->setC($c); $a = new A($c); echo "Parent class:\n"; var_dump($a); $s = serialize($a); var_dump($s); echo "Unserializing parent class:\n"; $unsA = unserialize($s); echo "Unserialized parent class:\n"; var_dump($unsA); $b = new B($c); echo "\nChild class:\n"; var_dump($b); $s = serialize($b); var_dump($s); echo "Unserializing child class:\n"; $unsB = unserialize($s); echo "Unserialized child class:\n"; var_dump($unsB); Expected result: ---------------- The unserialized child class should have the same structure. Actual result: -------------- Parent class: object(A)#2 (1) { ["c":"A":private]=> object(C)#1 (1) { ["c":"C":private]=> *RECURSION* } } string(40) "C:1:"A":27:{O:1:"C":1:{s:4:"Cc";r:2;}}" Unserializing parent class: inner child serialized: O:1:"C":1:{s:4:"Cc";r:2;} inner child unserialized: object(C)#4 (1) { ["c":"C":private]=> *RECURSION* } Unserialized parent class: object(A)#3 (1) { ["c":"A":private]=> object(C)#4 (1) { ["c":"C":private]=> *RECURSION* } } Child class: object(B)#5 (2) { ["str":"B":private]=> string(4) "asdf" ["c":"A":private]=> object(C)#1 (1) { ["c":"C":private]=> *RECURSION* } } string(73) "C:1:"B":60:{a:2:{i:0;s:4:"asdf";i:1;s:27:"O:1:"C":1:{s:4:"Cc";r:2;}";}}" Unserializing child class: inner parent serialized: a:2:{i:0;s:4:"asdf";i:1;s:27:"O:1:"C":1:{s:4:"Cc";r:2;}";} inner parent unserialized array(2) { [0]=> string(4) "asdf" [1]=> string(27) "O:1:"C":1:{s:4:"Cc";r:2;}" } inner child serialized: O:1:"C":1:{s:4:"Cc";r:2;} inner child unserialized: object(C)#7 (1) { ["c":"C":private]=> array(2) { [0]=> string(4) "asdf" [1]=> string(27) "O:1:"C":1:{s:4:"Cc";r:2;}" } } Unserialized child class: object(B)#6 (2) { ["str":"B":private]=> string(4) "asdf" ["c":"A":private]=> object(C)#7 (1) { ["c":"C":private]=> array(2) { [0]=> string(4) "asdf" [1]=> string(27) "O:1:"C":1:{s:4:"Cc";r:2;}" } } } ------------------------------------------------------------------------ -- Edit this bug report at https://bugs.php.net/bug.php?id=73253&edit=1

« previous php.bugs (#206274) next »