`unserialize` doesn't respect `class_alias` for properties
Personne n'a encore pris cette issue.
- Langage dominant
- C
- Étoiles
- 40.4k
- Forks
- 8.1k
- Merge moyen
- 2 j 13 h
- PR mergées (30 j)
- 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
Guide de contribution
Ouvrir le guide de contribution
Par où commencer
- Lisez l'issue en entier, puis le guide de contribution du projet.
- Signalez en commentaire que vous la prenez — cela évite que deux personnes fassent le même travail.
- Forkez le dépôt et travaillez sur une branche.
- Ouvrez une pull request qui référence le numéro de l'issue.
Piste de recherche
Commencez par exécuter les scripts fournis serialize.php et unserialize.php avec PHP 8.3.20, puis inspectez serialized.bin et la sortie de débogage de __unserialize afin de suivre la représentation du nom de propriété aliasé. Le travail est terminé lorsque le cas reproduit renvoie int(42) sans créer de propriété dynamique ni laisser la propriété typée non initialisée.
Rédigé par le modèle d'indexation à partir du texte de l'issue.
Évaluation
- Stack technique
- php
- Domaine
- backend
- Type d'issue
- Bug
- Difficulté
- 4/5
- Temps estimé
- 3-5 jours
- Activité
- À l'abandon
- Clarté
- Clairement spécifiée
- Accessibilité débutants
- 35/100