Bug #79031 [Ver->Csd]: Session unserialization problem
| From: | nikic@php.net | Date: | Mon, 30 Dec 2019 11:29:32 +0000 |
| Subject: | Bug #79031 [Ver->Csd]: Session unserialization problem | ||
| References: | 1 | Groups: | php.bugs |
| Request: | Send a blank email to php-bugs+get-224612@lists.php.net to get a copy of this message | ||
Edit report at https://bugs.php.net/bug.php?id=79031&edit=1
ID: 79031
Updated by: nikic@php.net
Reported by: syberon at gmail dot com
Summary: Session unserialization problem
-Status: Verified
+Status: Closed
Type: Bug
Package: Session related
Operating System: Windows 10 1909
PHP Version: 7.4.1
Assigned To: nikic
Block user comment: N
Private report: N
New Comment:
The commit is reverted for 7.4, so I'm closing this issue as fixed.
I've also prepared a fix for the underlying problem targeting PHP 8 here: https://github.com/php/php-src/pull/5039
Previous Comments:
------------------------------------------------------------------------
[2019-12-30 10:21:41] nikic@php.net
Looks like this is a general bug in how serialization locking is handled. Here's a case without
using sessions: https://3v4l.org/cZqVf The inner objects should
be the same, but they're different.
------------------------------------------------------------------------
[2019-12-27 16:53:17] cmb@php.net
This regression has apparently been introduced with commit
b8ef7c3[1]. Nikita, could you have a look please?
[1] <http://git.php.net/?p=php-src.git;a=commit;h=b8ef7c35abd31666d9fb317db4b09a9eef0ede6c>
------------------------------------------------------------------------
[2019-12-27 09:24:53] aleksey at xerkus dot pro
https://3v4l.org/NPt2R This slightly modified example from
comment above showcases the issue
https://3v4l.org/HeLT4 This example uses
php_serialize session serializer and exhibits exactly the same behavior.
------------------------------------------------------------------------
[2019-12-27 08:20:29] syberon at gmail dot com
From observable behavior it appears that unserialize implementation when called by session extension
C code does not set context for unserialize, resulting in relative numbered references being wrong
when used in nested unserialize calls.
------------------------------------------------------------------------
[2019-12-27 04:12:43] syberon at gmail dot com
I found that this problem is related to PHP 7.4 session unserializing. I made some tests and found
that if some class (Zend\Stdlib\ArrayObject in my case) implements Serializable interface and has
some property (object of stdClass for example) it failed to decode if stored in session.
I made a minimal reproducible example:
<?php
class SerializableClass implements Serializable {
public $sharedProp;
public function __construct($prop)
{
$this->sharedProp = $prop;
}
public function __set($key, $value)
{
$this->$key = $value;
}
public function serialize()
{
return serialize(get_object_vars($this));
}
public function unserialize($data)
{
$ar = unserialize($data);
foreach ($ar as $k => $v) {
$this->__set($k, $v);
}
}
}
// Shared object that acts as property of two another objects stored in session
$testPropertyObj = new stdClass();
$testPropertyObj->name = 'test';
// Two instances of \SerializableClass that shares property
$sessionObject = [
'obj1' => new SerializableClass($testPropertyObj),
'obj2' => new SerializableClass($testPropertyObj),
];
session_start();
$_SESSION = $sessionObject;
On first run it creates array with two instances of object with one shared property and store it in
session.
On second run it tries to start session and fail to parse the second object stored in session
because the it loses reference to property 'name'.
This script runs without any problems on PHP 7.3, and rises the parse errors on PHP 7.4.
------------------------------------------------------------------------
The remainder of the comments for this report are too long. To view
the rest of the comments, please view the bug report online at
https://bugs.php.net/bug.php?id=79031
--
Edit this bug report at https://bugs.php.net/bug.php?id=79031&edit=1