Skip to content

Commit 9f692c6

Browse files
committed
bug #53906 [VarDumper] Fix serialization of stubs with null or uninitialized values (derrabus)
This PR was merged into the 6.4 branch. Discussion ---------- [VarDumper] Fix serialization of stubs with null or uninitialized values | Q | A | ------------- | --- | Branch? | 6.4 | Bug fix? | yes | New feature? | no | Deprecations? | no | Issues | Fix #53905 | License | MIT The`Stub::__sleep()` implementation excludes properties from the serialized representation that are set to their defaults, but it cannot tell apart properties with a null value from properties that don't have a default. This is an issue for typed properties that are uninitialized by default. Commits ------- 3ffd495 [VarDumper] Fix serialization of stubs with null or uninitialized values
2 parents 29df289 + 3ffd495 commit 9f692c6

File tree

3 files changed

+89
-4
lines changed

3 files changed

+89
-4
lines changed
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
<?php
2+
3+
/*
4+
* This file is part of the Symfony package.
5+
*
6+
* (c) Fabien Potencier <fabien@symfony.com>
7+
*
8+
* For the full copyright and license information, please view the LICENSE
9+
* file that was distributed with this source code.
10+
*/
11+
12+
namespace Symfony\Component\VarDumper\Cloner\Internal;
13+
14+
/**
15+
* Flags a typed property that has no default value.
16+
*
17+
* This dummy object is used to distinguish a property with a default value of null
18+
* from a property that is uninitialized by default.
19+
*
20+
* @internal
21+
*/
22+
enum NoDefault
23+
{
24+
case NoDefault;
25+
}

src/Symfony/Component/VarDumper/Cloner/Stub.php

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,8 @@
1111

1212
namespace Symfony\Component\VarDumper\Cloner;
1313

14+
use Symfony\Component\VarDumper\Cloner\Internal\NoDefault;
15+
1416
/**
1517
* Represents the main properties of a PHP variable.
1618
*
@@ -50,15 +52,20 @@ public function __sleep(): array
5052
$properties = [];
5153

5254
if (!isset(self::$defaultProperties[$c = static::class])) {
53-
self::$defaultProperties[$c] = get_class_vars($c);
55+
$reflection = new \ReflectionClass($c);
56+
self::$defaultProperties[$c] = [];
57+
58+
foreach ($reflection->getProperties() as $p) {
59+
if ($p->isStatic()) {
60+
continue;
61+
}
5462

55-
foreach ((new \ReflectionClass($c))->getStaticProperties() as $k => $v) {
56-
unset(self::$defaultProperties[$c][$k]);
63+
self::$defaultProperties[$c][$p->name] = $p->hasDefaultValue() ? $p->getDefaultValue() : ($p->hasType() ? NoDefault::NoDefault : null);
5764
}
5865
}
5966

6067
foreach (self::$defaultProperties[$c] as $k => $v) {
61-
if ($this->$k !== $v) {
68+
if (NoDefault::NoDefault === $v || $this->$k !== $v) {
6269
$properties[] = $k;
6370
}
6471
}
Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
<?php
2+
3+
/*
4+
* This file is part of the Symfony package.
5+
*
6+
* (c) Fabien Potencier <fabien@symfony.com>
7+
*
8+
* For the full copyright and license information, please view the LICENSE
9+
* file that was distributed with this source code.
10+
*/
11+
12+
namespace Symfony\Component\VarDumper\Tests\Cloner;
13+
14+
use PHPUnit\Framework\TestCase;
15+
use Symfony\Component\VarDumper\Cloner\Stub;
16+
17+
final class StubTest extends TestCase
18+
{
19+
public function testUnserializeNullValue()
20+
{
21+
$stub = new Stub();
22+
$stub->value = null;
23+
24+
$stub = unserialize(serialize($stub));
25+
26+
self::assertNull($stub->value);
27+
}
28+
29+
public function testUnserializeNullInTypedProperty()
30+
{
31+
$stub = new MyStub();
32+
$stub->myProp = null;
33+
34+
$stub = unserialize(serialize($stub));
35+
36+
self::assertNull($stub->myProp);
37+
}
38+
39+
public function testUninitializedStubPropertiesAreLeftUninitialized()
40+
{
41+
$stub = new MyStub();
42+
43+
$stub = unserialize(serialize($stub));
44+
45+
$r = new \ReflectionProperty(MyStub::class, 'myProp');
46+
self::assertFalse($r->isInitialized($stub));
47+
}
48+
}
49+
50+
final class MyStub extends Stub
51+
{
52+
public mixed $myProp;
53+
}

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy