php / php/php-src

`unserialize` doesn't respect `class_alias` for properties

Aperta
#18,542 3 commenti 1 reazione 0 assegnatari Vedi su GitHub

Nessuno ha ancora preso questa issue.

Bug Category: Serialization Extension: standard
Lingua principale
C
Stelle
40.4k
Fork
8.1k
Merge medio
2g 13h
PR unite (30g)
96

Descrizione

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

Guida per i contributori

Apri la guida per i contributori

Come iniziare

  1. Leggi tutta la issue e poi la guida ai contributi del progetto.
  2. Commenta sulla issue per dire che te ne occupi tu — evita che due persone facciano lo stesso lavoro.
  3. Fai un fork del repository e lavora su un branch.
  4. Apri una pull request che faccia riferimento al numero della issue.

Direzione di ricerca

Inizia eseguendo gli script forniti serialize.php e unserialize.php su PHP 8.3.20, quindi esamina serialized.bin e l'output di debug di __unserialize per tracciare come viene rappresentato il nome della proprietà aliasato. Il lavoro è completato quando il caso riprodotto restituisce int(42) senza creare una proprietà dinamica né lasciare la proprietà tipizzata non inizializzata.

Scritto dal modello di indicizzazione a partire dal testo della issue.

Valutazione

Stack tecnologico
php
Ambito
backend
Tipo di issue
Bug
Difficoltà
4/5
Tempo stimato
3-5 giorni
Stato di attività
Ferma
Chiarezza
Specificata chiaramente
Idoneità per principianti
35/100

Ricevi le nuove issue nella tua casella

Un breve riepilogo di issue GitHub adatte ai principianti.