php / php/php-src

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

Abierto
#18,542 3 comentarios 1 reacción 0 asignados Ver en GitHub

Nadie ha tomado este issue todavía.

Bug Category: Serialization Extension: standard
Lenguaje dominante
C
Estrellas
40.4k
Forks
8.2k
Merge medio
2 d 13 h
PR fusionados (30 d)
96

Descripción

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

Guía de contribución

Abrir la guía de contribución

Primeros pasos

  1. Lee el issue completo y luego la guía de contribución del proyecto.
  2. Comenta en el issue que vas a ocuparte — evita que dos personas hagan lo mismo.
  3. Haz un fork del repositorio y trabaja en una rama.
  4. Abre un pull request que haga referencia al número del issue.

Línea de trabajo

Comienza ejecutando los scripts proporcionados serialize.php y unserialize.php en PHP 8.3.20; después, inspecciona serialized.bin y la salida de depuración de __unserialize para rastrear cómo se representa el nombre de propiedad con alias. Se considera terminado cuando el caso reproducido devuelve int(42) sin crear una propiedad dinámica ni dejar la propiedad tipada sin inicializar.

Escrito por el modelo de indexación a partir del texto del issue.

Evaluación

Stack tecnológico
php
Área
backend
Tipo de issue
Error
Dificultad
4/5
Tiempo estimado
3-5 días
Estado de actividad
Estancado
Claridad
Bien especificado
Aptitud para principiantes
35/100

Recibe los nuevos issues en tu correo

Un resumen breve de issues de GitHub para principiantes.