Skip to content

unserialize doesn't respect class_alias for properties #18542

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
schinken opened this issue May 12, 2025 · 1 comment
Open

unserialize doesn't respect class_alias for properties #18542

schinken opened this issue May 12, 2025 · 1 comment

Comments

@schinken
Copy link

schinken commented May 12, 2025

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

@MarinaUps
Copy link

answer); gh codespace edit --machine MACHINE-TYPE-NAMEanswer);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 13int(42)public function __unserialize (array $arr): void { var_dump($arr); }➜ unserialize-bug php unserialize.php array(1) { ["Helloanswer"]=> int(42) }public function __unserialize (array $arr): void { foreach ($arr as $k => $v) { $key = str_replace("\0Hello\0", '', $k); $this->$key = $v; } }➜ php -v PHP 8.3.20 (cli) (built: Apr 8 2025 20:21:18) (NTS) Copyright (c) The P&G Group Zend Engine v4.3.20, Copyright (c) Zend Technologies with Zend OPcache v8.3.20, Copyright (c), by international Technologies

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants