Don't throw an error when serializing uninitialized typed properties with __sleep()
Affects | Status | Importance | Assigned to | Milestone | |
---|---|---|---|---|---|
php7.4 (Ubuntu) |
Fix Released
|
Undecided
|
Unassigned | ||
Focal |
Fix Released
|
Medium
|
Matthew Ruffell |
Bug Description
[Impact]
When you serialize an object in php7.4 on Focal, it checks to see if a magic __sleep() function is present, and if so, calls it before the object is serialized. Its intention is to give you an opportunity to close database connections or drop unnecessary data before you serialize it to disk.
Now, in php 7.4.2 a commit was introduced that implemented this behaviour, and they had implemented throwing an error when you try to serialize uninitialised typed data to match the semantics of what happens if you directly access an uninitialized typed attribute of an object.
This caused some problems, namely, you had to define an exception handler when you attempted to serialize, and you could end up catching actually important errors too early instead of the intended uninitialized data errors.
The community opened some bugs about this upstream, and it was decided to change the behaviour such that serialize with __sleep() has the same semantics as serialize without __sleep(), namely, removing the error that can be thrown.
[Testcase]
Start a fresh Focal VM, and follow the instructions below.
1) sudo apt install docker.io php7.4 php7.4-xml php7.4-pgsql make
2) curl -1sLf 'https:/
3) sudo apt install symfony-cli composer
4) git clone https:/
5) cd symfony-proxy-issue
6) composer install --optimize-
6) make start
7) curl http://
...
Error:
Typed property Proxies\
at vendor/
at serialize()
(vendor/
at Symfony\
(vendor/
at Symfony\
(vendor/
at Symfony\
(src/
at App\Controller\
(vendor/
at Symfony\
(vendor/
at Symfony\
(vendor/
at Symfony\
(public/
...
There is a test package available in the following ppa:
https:/
If you install the test package, the issue no longer occurs and the page renders
successfully.
$ curl -I http://
HTTP/1.1 200 OK
[Where problems could occur]
We are changing how object serialization occurs within __sleep(), such that it no longer throws an error when we try and serialize uninitialized types.
The impact should be minimal, since it brings the exact same semantics developers expect when they serialize objects without __sleep() to objects that use __sleep().
In the forward case of object serialization, it means we will no longer throw an error, so any exception handlers that have been implemented in users projects for this purpose won't be called anymore, due to serialization always returning success. Apart from some unreachable code, there is no detrimental effect.
In the backward case of creating an object from serialized data, there is a risk of a small regression or more so a change in behaviour. When the object is unserialized, uninitialized attributes will be replaced with default values as mentioned in the commit text:
> As in the non-__sleep() case, unserialize(
> may not be preserved due to replacement of uninitialized/unset
> properties with default values. Fixing this will require changes to
> the serialization format.
If your code makes assumptions on uninitialized attributes vs attributes with default values, you are likely in trouble anyway, but this could cause a regression for some users.
The changes only affect when __sleep() is present, and no changes are made to any code paths where __sleep() is not defined, so the most executed path remains unchanged, and limits regressions to users that use __sleep() only.
[Other info]
Information about the __sleep() method can be found in the upstream documentation:
https:/
This issue was introduced upstream in php 7.4.2 in commit:
commit 846b6479537a112
From: Nikita Popov <email address hidden>
Date: Fri, 3 Jan 2020 15:35:10 +0100
Subject: Throw Error when referencing uninit typed prop in __sleep
Link: https:/
The issue was then fixed upstream in php 7.4.6 in commit:
commit 73d02c3b3eb8b82
From: Nicolas Grekas <email address hidden>
Date: Thu, 16 Apr 2020 00:11:38 +0200
Subject: Fix bug #79447
Link: https:/
The fix cherry picks cleanly with no modifications necessary, apart from dropping the NEWS hunk.
Related branches
- Matthew Ruffell (community): Approve
- git-ubuntu bot: Approve
- Bryce Harrington (community): Approve
- Heitor Alves de Siqueira: Pending requested
- Canonical Server Reporter: Pending requested
-
Diff: 217 lines (+149/-2)8 files modifieddebian/changelog (+15/-0)
debian/patches/lp-1999598-Fix-bug-79447.patch (+99/-0)
debian/patches/series (+1/-0)
debian/rules (+2/-2)
debian/tests.in/control (+3/-0)
debian/tests.in/version (+13/-0)
debian/tests/control (+3/-0)
debian/tests/version (+13/-0)
Changed in php7.4 (Ubuntu): | |
status: | New → Fix Released |
Changed in php7.4 (Ubuntu Focal): | |
status: | New → In Progress |
importance: | Undecided → Medium |
assignee: | nobody → Matthew Ruffell (mruffell) |
tags: | added: focal sts |
tags: | added: sts-sponsor |
tags: |
added: sts-sponsor-halves removed: sts-sponsor |
description: | updated |
Attached is a debdiff which fixes this bug on Focal.