`unserialize` doesn't respect `class_alias` for properties
Dieses Issue hat noch niemand übernommen.
- Vorherrschende Sprache
- C
- Sterne
- 40.4k
- Forks
- 8.1k
- Ø Merge
- 2 T. 13 Std.
- Gemergte PRs (30 T.)
- 96
Beschreibung
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
Beitragsleitfaden
Erste Schritte
- Lies das ganze Issue und danach den Beitragsleitfaden des Projekts.
- Schreib ins Issue, dass du es übernimmst — das erspart doppelte Arbeit.
- Forke das Repository und arbeite in einem Branch.
- Öffne einen Pull Request, der die Issue-Nummer nennt.
Rechercherichtung
Beginne damit, die bereitgestellten Skripte serialize.php und unserialize.php unter PHP 8.3.20 auszuführen. Untersuche anschließend serialized.bin und die __unserialize-Debugausgabe, um nachzuverfolgen, wie der Alias-Eigenschaftsname dargestellt wird. Als erledigt gilt die Aufgabe, wenn der reproduzierte Fall int(42) zurückgibt, ohne eine dynamische Eigenschaft zu erstellen oder die typisierte Eigenschaft nicht initialisiert zu lassen.
Vom Indexierungsmodell aus dem Issue-Text verfasst.
Bewertung
- Tech-Stack
- php
- Bereich
- backend
- Issue-Typ
- Bug
- Schwierigkeit
- 4/5
- Geschätzter Aufwand
- 3-5 Tage
- Aktivitätsstatus
- Veraltet
- Klarheit
- Klar beschrieben
- Anfängerfreundlichkeit
- 35/100