Bug #46140 [Opn->Csd]: Unserializing with __wakeup that removes child causes subsequent refs to shift

From: Date: Sun, 24 May 2015 18:06:51 +0000
Subject: Bug #46140 [Opn->Csd]: Unserializing with __wakeup that removes child causes subsequent refs to shift
References: 1  Groups: php.bugs 
Request: Send a blank email to php-bugs+get-192863@lists.php.net to get a copy of this message
Edit report at https://bugs.php.net/bug.php?id=46140&edit=1 ID: 46140 Updated by: cmb@php.net Reported by: ehassler at synapsestudios dot com Summary: Unserializing with __wakeup that removes child causes subsequent refs to shift -Status: Open +Status: Closed Type: Bug Package: Class/Object related Operating System: * PHP Version: 5.2.8 -Assigned To: +Assigned To: cmb Block user comment: N Private report: N New Comment: Fixed as of PHP 5.4.39, 5.5.23 and 5.6.7. Previous Comments: ------------------------------------------------------------------------ [2014-06-02 20:49:43] cmbecker69 at gmx dot de It seems this issue will be solved in PHP 5.7, see <http://3v4l.org/jpqW8>. ------------------------------------------------------------------------ [2008-10-29 00:18:41] ehassler at synapsestudios dot com Very similar problem in PHP_VERSION === '5.2.7RC3-dev' under Windows. I ran my test script and got out: array(3) { [0]=> object(B)#5 (1) { ["value"]=> object(C)#1 (0) { } } [1]=> object(B)#6 (1) { ["value"]=> object(B)#6 (1) { ["value"]=> *RECURSION* } } [2]=> object(B)#7 (1) { ["value"]=> object(B)#6 (1) { ["value"]=> object(B)#6 (1) { ["value"]=> *RECURSION* } } } } ------------------------------------------------------------------------ [2008-09-21 02:33:42] ehassler at synapsestudios dot com After adding static $instance2 to class C, and changing the __wakeup to this: function __wakeup() { if($this->value instanceof C) { C::$instance2 = $this->value; $this->value = C::$instance; } } I get the expected behavior. So, I guess, you know, hope that helps. ------------------------------------------------------------------------ [2008-09-21 02:22:58] ehassler at synapsestudios dot com Description: ------------ During unserialization of a 3 deep non-recursive but not-a-tree data structure (more like a diamond) where, on nodes in level 2 a __wakeup causes all references to a child node of a certain class to be removed, when that child node would occur in subsequent level 2 nodes' child spots, the reference instead now points to the next level 2 node instead of any level 3 node. More specifically, it points to the first level 2 node after the one that removed said child. The sample code makes it more clear. Reproduce code: --------------- class B { public $value; function __construct($value){ $this->value = $value; } function __wakeup() { if($this->value instanceof C) $this->value = C::$instance; } } class C { static public $instance; } C::$instance = new C; $A = array( new B(C::$instance), new B(C::$instance), new B(C::$instance) ); var_dump($A); $A = unserialize(serialize($A)); var_dump($A); Expected result: ---------------- array 0 => object(B)[2] public 'value' => object(C)[1] 1 => object(B)[3] public 'value' => object(C)[1] 2 => object(B)[4] public 'value' => object(C)[1] array 0 => object(B)[5] public 'value' => object(C)[1] 1 => object(B)[7] public 'value' => object(C)[1] 2 => object(B)[8] public 'value' => object(C)[1] Actual result: -------------- array 0 => object(B)[2] public 'value' => object(C)[1] 1 => object(B)[3] public 'value' => object(C)[1] 2 => object(B)[4] public 'value' => object(C)[1] array 0 => object(B)[5] public 'value' => object(C)[1] 1 => object(B)[6] public 'value' => &object(B)[6] 2 => object(B)[7] public 'value' => object(B)[6] public 'value' => &object(B)[6] ------------------------------------------------------------------------ -- Edit this bug report at https://bugs.php.net/bug.php?id=46140&edit=1

« previous php.bugs (#192863) next »