|
php.net | support | documentation | report a bug | advanced search | search howto | statistics | random bug | login |
PatchesPull RequestsHistoryAllCommentsChangesGit/SVN commits
[2017-01-01 12:27 UTC] nikic@php.net
-Status: Open
+Status: Duplicate
[2017-01-01 12:27 UTC] nikic@php.net
|
|||||||||||||||||||||||||||||||||||||
Copyright © 2001-2025 The PHP GroupAll rights reserved. |
Last updated: Mon Nov 17 01:00:01 2025 UTC |
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;}" } } }