Bug #78410 [Opn]: Cannot "manually" unserialize class that is final and extends an internal one
| From: | nikic@php.net | Date: | Tue, 13 Aug 2019 17:27:20 +0000 |
| Subject: | Bug #78410 [Opn]: Cannot "manually" unserialize class that is final and extends an internal one | ||
| References: | 1 | Groups: | php.bugs |
| Request: | Send a blank email to php-bugs+get-222233@lists.php.net to get a copy of this message | ||
Edit report at https://bugs.php.net/bug.php?id=78410&edit=1
ID: 78410
Updated by: nikic@php.net
Reported by: nicolas dot grekas+php at gmail dot com
Summary: Cannot "manually" unserialize class that is final
and extends an internal one
Status: Open
Type: Bug
Package: *General Issues
PHP Version: 7.4.0beta2
Block user comment: N
Private report: N
New Comment:
I don't really understand what the intent here is ... why is it not possible to provide a
correct O-format string to create the object? It's not going to work with an empty payload, but
then again I don't think it worked with an empty C-payload before either ... right?
> The simplest way I can think of to unlock progress is to allow
> unserialize('O:8:"Foo":0:{}') to work. Doing so *would not call __unserialize*
> but would return an empty object, as it does for classes that don't implement the method.
In that case we should remove the Reflection restriction instead, because that's what this is
effectively doing, just in a more roundabout way. But that restriction exists for a reason.
Previous Comments:
------------------------------------------------------------------------
[2019-08-13 17:19:32] nicolas dot grekas+php at gmail dot com
Description:
------------
I'm trying to make the VarExporter component of Symfony work on PHP 7.4 and I'm in a
dead-end. What the component provides is an implementation of serialize/unserialize using PHP as the
serialization format. This cannot be implemented anymore in PHP 7.4 with the new
__serialize/__unserialize methods.
The case that breaks is when a userland class is made final *and* extends an internal one.
E.g. final class Foo extends extends \ArrayIterator {...}
Because of these two conditions, ReflectionClass::newInstanceWithoutConstructor is forbidden. In PHP
<=7.3, it is possible to work around the limitation by calling serialize() with a proper payload:
either an empty "O:"-one when the class doesn't implement Serializable, or a
"C:"-one when it does.
To implement the semantics of __unserialize, I cannot use "C:"-format.
And PHP 7.4 complains if I unserialize('O:8:"Foo":0:{}'). That's my
dead-end: I cannot create such an instance to call __unserialize in userland.
The simplest way I can think of to unlock progress is to allow
unserialize('O:8:"Foo":0:{}') to work. Doing so *would not call __unserialize*
but would return an empty object, as it does for classes that don't implement the method.
Thank you for your help, this is a critical blocker for us.
------------------------------------------------------------------------
--
Edit this bug report at https://bugs.php.net/bug.php?id=78410&edit=1