8000 [VarExporter] fix exporting declared but unset properties when __slee… · symfony/symfony@a557bdc · GitHub
[go: up one dir, main page]

Skip to content

Commit a557bdc

Browse files
[VarExporter] fix exporting declared but unset properties when __sleep() is implemented
1 parent bfc8b1e commit a557bdc

File tree

2 files changed

+21
-17
lines changed

2 files changed

+21
-17
lines changed

src/Symfony/Component/VarExporter/Internal/Exporter.php

Lines changed: 14 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -90,13 +90,12 @@ public static function prepare($values, $objectsPool, &$refsPool, &$objectsCount
9090

9191
$properties = [];
9292
$sleep = null;
93-
$arrayValue = (array) $value;
9493
$proto = Registry::$prototypes[$class];
9594

9695
if (($value instanceof \ArrayIterator || $value instanceof \ArrayObject) && null !== $proto) {
9796
// ArrayIterator and ArrayObject need special care because their "flags"
9897
// option changes the behavior of the (array) casting operator.
99-
$properties = self::getArrayObjectProperties($value, $arrayValue, $proto);
98+
[$arrayValue, $properties] = self::getArrayObjectProperties($value, $proto);
10099

101100
// populates Registry::$prototypes[$class] with a new instance
102101
Registry::getClassReflector($class, Registry::$instantiableWithoutConstructor[$class], Registry::$cloneable[$class]);
@@ -108,25 +107,23 @@ public static function prepare($values, $objectsPool, &$refsPool, &$objectsCount
108107
$properties[] = $value[$v];
109108
}
110109
$properties = ['SplObjectStorage' => ["\0" => $properties]];
110+
$arrayValue = (array) $value;
111111
} elseif ($value instanceof \Serializable || $value instanceof \__PHP_Incomplete_Class) {
112112
++$objectsCount;
113113
$objectsPool[$value] = [$id = \count($objectsPool), serialize($value), [], 0];
114114
$value = new Reference($id);
115115
goto handle_value;
116-
}
117-
118-
if (method_exists($class, '__sleep')) {
119-
if (!\is_array($sleep = $value->__sleep())) {
120-
trigger_error('serialize(): __sleep should return an array only containing the names of instance-variables to serialize', \E_USER_NOTICE);
121-
$value = null;
122-
goto handle_value;
123-
}
124-
foreach ($sleep as $name) {
125-
if (property_exists($value, $name) && !$reflector->hasProperty($name)) {
126-
$arrayValue[$name] = $value->$name;
116+
} else {
117+
if (method_exists($class, '__sleep')) {
118+
if (!\is_array($sleep = $value->__sleep())) {
119+
trigger_error('serialize(): __sleep should return an array only containing the names of instance-variables to serialize', \E_USER_NOTICE);
120+
$value = null;
121+
goto handle_value;
127122
}
123+
$sleep = array_flip($sleep);
128124
}
129-
$sleep = array_flip($sleep);
125+
126+
$arrayValue = (array) $value;
130127
}
131128

132129
$proto = (array) $proto;
@@ -370,13 +367,13 @@ private static function exportHydrator(Hydrator $value, string $indent, string $
370367
* @param \ArrayIterator|\ArrayObject $value
371368
* @param \ArrayIterator|\ArrayObject $proto
372369
*/
373-
private static function getArrayObjectProperties($value, array &$arrayValue, $proto): array
370+
private static function getArrayObjectProperties($value, $proto): array
374371
{
375372
$reflector = $value instanceof \ArrayIterator ? 'ArrayIterator' : 'ArrayObject';
376373
$reflector = Registry::$reflectors[$reflector] ?? Registry::getClassReflector($reflector);
377374

378375
$properties = [
379-
$arrayValue,
376+
$arrayValue = (array) $value,
380377
$reflector->getMethod('getFlags')->invoke($value),
381378
$value instanceof \ArrayObject ? $reflector->getMethod('getIteratorClass')->invoke($value) : 'ArrayIterator',
382379
];
@@ -402,6 +399,6 @@ private static function getArrayObjectProperties($value, array &$arrayValue, $pr
402399
$properties = [$reflector->class => ["\0" => $properties]];
403400
}
404401

405-
return $properties;
402+
return [$arrayValue, $properties];
406403
}
407404
}

src/Symfony/Component/VarExporter/Tests/VarExporterTest.php

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -332,6 +332,13 @@ public function setFlags($flags): void
332332

333333
class GoodNight
334334
{
335+
public $good;
336+
337+
public function __construct()
338+
{
339+
unset($this->good);
340+
}
341+
335342
public function __sleep(): array
336343
{
337344
$this->good = 'night';

0 commit comments

Comments
 (0)
0