`unserialize` doesn't respect `class_alias` for properties
Nobody has claimed this yet.
- Dominant language
- C
- Stars
- 40.4k
- Forks
- 8.1k
- Avg merge
- 2d 13h
- Merged PRs (30d)
- 96
Description
Description
The following code:
<?php // serialize.php
class Hello {
public function __construct (
private readonly int $answer
) {}
}
$x = serialize(new Hello(42));
file_put_contents('serialized.bin', $x);
<?php // unserialize.php
class HelloAlias {
public function __construct (
public readonly int $answer
) {}
}
class_alias(HelloAlias::class, 'Hello');
$x = file_get_contents('serialized.bin');
$z = unserialize($x);
var_dump($z->answer);
Resulted in this output:
PHP Deprecated: Creation of dynamic property HelloAlias::$answer is deprecated in unserialize-bug/unserialize.php on line 12
Fatal error: Uncaught Error: Typed property HelloAlias::$answer must not be accessed before initialization in unserialize-bug/unserialize.php:13
Stack trace:
#0 {main}
thrown in unserialize-bug/unserialize.php on line 13
But I expected this output instead:
int(42)
If I look at the serialized.bin file, I can see that for the variable "answer", there is {s:13:"�Hello�answer";i:42;} stored (containing the class without alias).
When I add debug for __unserialize
public function __unserialize (array $arr): void {
var_dump($arr);
}
I will get this output. The Helloanswer is actually \0Hello\0answer
➜ unserialize-bug php unserialize.php
array(1) {
["Helloanswer"]=>
int(42)
}
Using this naiive fix will work, but is really ugly:
public function __unserialize (array $arr): void {
foreach ($arr as $k => $v) {
$key = str_replace("\0Hello\0", '', $k);
$this->$key = $v;
}
}
PHP Version
➜ php -v
PHP 8.3.20 (cli) (built: Apr 8 2025 20:21:18) (NTS)
Copyright (c) The PHP Group
Zend Engine v4.3.20, Copyright (c) Zend Technologies
with Zend OPcache v8.3.20, Copyright (c), by Zend Technologies
Operating System
No response
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start by running the provided serialize.php and unserialize.php scripts on PHP 8.3.20, then inspect serialized.bin and the __unserialize debug output to trace how the aliased property name is represented. Done means the reproduced case returns int(42) without creating a dynamic property or leaving the typed property uninitialized.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- php
- Domain
- backend
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Stale
- Clarity
- Clearly specified
- Newbie friendliness
- 35/100