Bug #73253 [Opn->Dup]: Incorrect references when inheriting the Serialization interface class
| From: | nikic@php.net | 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