Bug #76606 [NEW]: Widespread regression with Serializable interface and legacy __wakeup method
| From: | westie at typefish dot co dot uk | Date: | Tue, 10 Jul 2018 14:26:38 +0000 |
| Subject: | Bug #76606 [NEW]: Widespread regression with Serializable interface and legacy __wakeup method | ||
| Groups: | php.bugs | ||
| Request: | Send a blank email to php-bugs+get-216261@lists.php.net to get a copy of this message | ||
From: westie at typefish dot co dot uk
Operating system: All tested
PHP version: Irrelevant
Package: Class/Object related
Bug Type: Bug
Bug description:Widespread regression with Serializable interface and legacy __wakeup method
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 bug report at https://bugs.php.net/bug.php?id=76606&edit=1
--
Try a snapshot (PHP 5.4): https://bugs.php.net/fix.php?id=76606&r=trysnapshot54
Try a snapshot (PHP 5.5): https://bugs.php.net/fix.php?id=76606&r=trysnapshot55
Try a snapshot (trunk): https://bugs.php.net/fix.php?id=76606&r=trysnapshottrunk
Fixed in SVN: https://bugs.php.net/fix.php?id=76606&r=fixed
Fixed in release: https://bugs.php.net/fix.php?id=76606&r=alreadyfixed
Need backtrace: https://bugs.php.net/fix.php?id=76606&r=needtrace
Need Reproduce Script: https://bugs.php.net/fix.php?id=76606&r=needscript
Try newer version: https://bugs.php.net/fix.php?id=76606&r=oldversion
Not developer issue: https://bugs.php.net/fix.php?id=76606&r=support
Expected behavior: https://bugs.php.net/fix.php?id=76606&r=notwrong
Not enough info: https://bugs.php.net/fix.php?id=76606&r=notenoughinfo
Submitted twice: https://bugs.php.net/fix.php?id=76606&r=submittedtwice
register_globals: https://bugs.php.net/fix.php?id=76606&r=globals
PHP 4 support discontinued: https://bugs.php.net/fix.php?id=76606&r=php4
Daylight Savings: https://bugs.php.net/fix.php?id=76606&r=dst
IIS Stability: https://bugs.php.net/fix.php?id=76606&r=isapi
Install GNU Sed: https://bugs.php.net/fix.php?id=76606&r=gnused
Floating point limitations: https://bugs.php.net/fix.php?id=76606&r=float
No Zend Extensions: https://bugs.php.net/fix.php?id=76606&r=nozend
MySQL Configuration Error: https://bugs.php.net/fix.php?id=76606&r=mysqlcfg