Edit report at https://bugs.php.net/bug.php?id=64206&edit=1
ID: 64206
Updated by: mike@php.net
Reported by: cameron dot junge at sella dot co dot nz
Summary: Serialized object becomes r:2, which breaks
unserialization
Status: Verified
Type: Bug
Package: Scripting Engine problem
Operating System: Ubuntu 12.10
PHP Version: 5.4.11
Assigned To: mike
Block user comment: N
Private report: N
New Comment:
What dynamic check?
I guess a differentiated BG(serialize_lock)/BG(unserialize_lock) should do it.
Previous Comments:
------------------------------------------------------------------------
[2013-02-20 14:47:32] laruence@php.net
I think deny unserialize in serialize is not a choice. it need a dynamic check and
make no sense.
reseting one need to be test with...
------------------------------------------------------------------------
[2013-02-20 10:42:39] mike@php.net
As the var_hash is kept between recursive serialize() calls, the serializer
thinks the object is already serialized, but in fact, your hacky code replaces
the previously serialized object.
I see two options:
- deny unserialize() in serialize()
- reset the serialize var_hash on unserialize() (which may break other things)
------------------------------------------------------------------------
[2013-02-20 09:07:19] mike@php.net
After a quick look, I think the problem is rather the unserialize() call in the
serialize() callback and vice-versa.
------------------------------------------------------------------------
[2013-02-20 03:33:16] laruence@php.net
I tried to fix this by lock the serialize hash before calling ce->serialize, but
it break #36424, result a stack overflow segfault.
------------------------------------------------------------------------
[2013-02-13 22:17:34] cameron dot junge at sella dot co dot nz
Description:
------------
When trying to serialize an inherited object, PHP 5.4 serializes the inherited object as a reference
to the parent object, when there is no parent object to reference.
This works fine in PHP 5.3.
See test script for an example.
Test script:
---------------
class A implements \Serializable {
public function serialize()
{
$s = new \stdClass();
$s->id = 1;
var_dump($s);
return serialize($s);
}
public function unserialize($s)
{
}
}
class B extends A {
public function serialize()
{
$p = parent::serialize();
$s = unserialize($p);
$s->foo = 'bar';
$s2 = serialize($s);
var_dump($p, $s, $s2); // $s2 = 'r:2'
//var_dump(unserialize($s2)); // will throw error as can't unserialize
die;
//return serialize($s);
}
}
$b = new B;
serialize($b);
Expected result:
----------------
// PHP5.3.6
object(stdClass)[794]
public 'id' => int 1
string 'O:8:"stdClass":1:{s:2:"id";i:1;}' (length=32)
object(stdClass)[794]
public 'id' => int 1
public 'foo' => string 'bar' (length=3)
string
'O:8:"stdClass":2:{s:2:"id";i:1;s:3:"foo";s:3:"bar";}'
(length=52)
Actual result:
--------------
// PHP 5.4.11
object(stdClass)[794]
public 'id' => int 1
string 'O:8:"stdClass":1:{s:2:"id";i:1;}' (length=32)
object(stdClass)[794]
public 'id' => int 1
public 'foo' => string 'bar' (length=3)
string 'r:2;' (length=4)
------------------------------------------------------------------------
--
Edit this bug report at https://bugs.php.net/bug.php?id=64206&edit=1