Bug #76606 [Com]: Widespread regression with Serializable interface and legacy __wakeup method
Edit report at https://bugs.php.net/bug.php?id=76606&edit=1
ID: 76606
Comment by: westie at typefish dot co dot uk
Reported by: westie at typefish dot co dot uk
Summary: Widespread regression with Serializable interface
and legacy __wakeup method
Status: Open
Type: Bug
Package: Class/Object related
Operating System: All tested
PHP Version: Irrelevant
Block user comment: N
Private report: N
New Comment:
https://3v4l.org/rWFHv
To re-iterate, failing on all normal PHP versions yet working as expected on a third party PHP
implementation (HHVM)
Previous Comments:
------------------------------------------------------------------------
[2018-07-10 14:28:37] westie at typefish dot co dot uk
Please reverse the 'expected' and 'actual' results, I swapped them around.
To confirm what the expect result should be:
string(48) "(input) O:15:"Test_TestClassA":1:{s:1:"x";i:4;}"
string(8) "__wakeup"
string(23) "(output) true (passing)"
string(48) "(input) O:15:"Test_TestClassB":1:{s:1:"x";i:4;}"
string(8) "__wakeup"
string(23) "(output) true (passing)"
string(49) "(input) O:16:"Test_TestClassAA":1:{s:1:"x";i:4;}"
string(8) "__wakeup"
string(23) "(output) true (passing)"
string(49) "(input) O:16:"Test_TestClassBB":1:{s:1:"x";i:4;}"
string(8) "__wakeup"
string(23) "(output) true (passing)"
------------------------------------------------------------------------
[2018-07-10 14:26:34] westie at typefish dot co dot uk
Description:
------------
According to the documentation, developers are allowed to intermingle the legacy method of
unserialising an object (using __wakeup) AND using the much more modern and cleaner way, using
methods provided in the Serializable interface.
> Note, that when an old instance of a class that implements this interface
> now, which had been serialized before the class implemeted the interface,
> is unserialized, __wakeup() is called instead of the unserialize method,
> which might be useful for migration purposes.
> ~ http://uk1.php.net/manual/en/class.serializable.php
I appear to have found an interesting regression, where this is no longer the case.
Multiple versions affected (possibly including EOL in this list):
- 5.4.29 (EOL?)
- 5.5.13 (EOL?)
- 5.6.0 - 5.6.30
- 5.6.36 specifically
- 7.0.0 - 7.3.0alpha1 (will literally presume ALL of PHP7)
I was planning to implement this functionality in a new project but yeah, I cannot anymore!
Test script:
---------------
<?php
# author note: please review the code on https://3v4l.org/XRr5t
to see
# the full extent of this regression
# base class
class Test_TestClassBase
{
public $x = 4;
public function __wakeup()
{
var_dump("__wakeup");
}
public function __sleep()
{
return array_keys(get_object_vars($this));
}
public function unserialize($input)
{
var_dump("unserialize");
}
public function serialize()
{
var_dump("serialize");
return serialize(get_object_vars($this));
}
}
# derived classes
class Test_TestClassA extends Test_TestClassBase {}
class Test_TestClassB extends Test_TestClassBase implements Serializable {}
class Test_TestClassAA extends Test_TestClassA implements Serializable {}
class Test_TestClassBB extends Test_TestClassB {}
# run our serialisation
foreach(array("Test_TestClassA", "Test_TestClassB",
"Test_TestClassAA", "Test_TestClassBB") as $class)
{
$serialised =
'O:'.strlen($class).':"'.$class.'":1:{s:1:"x";i:4;}';
var_dump("(input) ".$serialised);
var_dump("(output) ".(unserialize($serialised) instanceof $class ? "true
(passing)" : "false (failing)"));
}
Expected result:
----------------
string(48) "(input) O:15:"Test_TestClassA":1:{s:1:"x";i:4;}"
string(8) "__wakeup"
string(23) "(output) true (passing)"
string(48) "(input) O:15:"Test_TestClassB":1:{s:1:"x";i:4;}"
Warning: Erroneous data format for unserializing 'Test_TestClassB' in /in/XRr5t on line 48
Notice: unserialize(): Error at offset 26 of 39 bytes in /in/XRr5t on line 48
string(24) "(output) false (failing)"
string(49) "(input) O:16:"Test_TestClassAA":1:{s:1:"x";i:4;}"
Warning: Erroneous data format for unserializing 'Test_TestClassAA' in /in/XRr5t on line
48
Notice: unserialize(): Error at offset 27 of 40 bytes in /in/XRr5t on line 48
string(24) "(output) false (failing)"
string(49) "(input) O:16:"Test_TestClassBB":1:{s:1:"x";i:4;}"
Warning: Erroneous data format for unserializing 'Test_TestClassBB' in /in/XRr5t on line
48
Notice: unserialize(): Error at offset 27 of 40 bytes in /in/XRr5t on line 48
string(24) "(output) false (failing)"
Actual result:
--------------
string(48) "(input) O:15:"Test_TestClassA":1:{s:1:"x";i:4;}"
string(8) "__wakeup"
string(23) "(output) true (passing)"
string(48) "(input) O:15:"Test_TestClassB":1:{s:1:"x";i:4;}"
string(8) "__wakeup"
string(23) "(output) true (passing)"
string(49) "(input) O:16:"Test_TestClassAA":1:{s:1:"x";i:4;}"
string(8) "__wakeup"
string(23) "(output) true (passing)"
string(49) "(input) O:16:"Test_TestClassBB":1:{s:1:"x";i:4;}"
string(8) "__wakeup"
string(23) "(output) true (passing)"
------------------------------------------------------------------------
--
Edit this bug report at https://bugs.php.net/bug.php?id=76606&edit=1
Thread (3 messages)