Skip to content

Commit 73d02c3

Browse files
nicolas-grekasnikic
authored andcommitted
Fix bug #79447
Partially reverts 846b647: instead of throwing, this skips uninitialized typed properties when serializing objects. This makes serialize with __sleep() behave the same as serialize() without __sleep(). As in the non-__sleep() case, unserialize(serialize($x)) identity may not be preserved due to replacement of uninitialized/unset properties with default values. Fixing this will require changes to the serialization format. Closes GH-5396.
1 parent c705079 commit 73d02c3

File tree

3 files changed

+16
-28
lines changed

3 files changed

+16
-28
lines changed

NEWS

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,8 @@ PHP NEWS
4040
- Standard:
4141
. Fixed bug #79468 (SIGSEGV when closing stream handle with a stream filter
4242
appended). (dinosaur)
43+
. Fixed bug #79447 (Serializing uninitialized typed properties with __sleep
44+
should not throw). (nicolas-grekas)
4345

4446
?? ??? ????, PHP 7.4.5
4547

ext/standard/tests/serialize/sleep_uninitialized_typed_prop.phpt

Lines changed: 13 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
--TEST--
2-
Referencing an uninitialized typed property in __sleep() should result in Error
2+
Referencing an uninitialized typed property in __sleep() should be skipped
33
--FILE--
44
<?php
55

@@ -18,39 +18,27 @@ class Test {
1818
}
1919

2020
$t = new Test;
21-
try {
22-
serialize($t);
23-
} catch (Error $e) {
24-
echo $e->getMessage(), "\n";
25-
}
21+
var_dump(serialize($t));
22+
var_dump(unserialize(serialize($t)) == $t);
2623

2724
$t->x = 1;
28-
try {
29-
serialize($t);
30-
} catch (Error $e) {
31-
echo $e->getMessage(), "\n";
32-
}
25+
var_dump(unserialize(serialize($t)) == $t);
3326

3427
$t->y = 2;
35-
try {
36-
serialize($t);
37-
} catch (Error $e) {
38-
echo $e->getMessage(), "\n";
39-
}
28+
var_dump(unserialize(serialize($t)) == $t);
4029

4130
$t->z = 3;
42-
try {
43-
var_dump(unserialize(serialize($t)));
44-
} catch (Error $e) {
45-
echo $e->getMessage(), "\n";
46-
}
31+
var_dump(unserialize(serialize($t)) == $t);
4732

33+
var_dump($t);
4834
?>
4935
--EXPECT--
50-
Typed property Test::$x must not be accessed before initialization (in __sleep)
51-
Typed property Test::$y must not be accessed before initialization (in __sleep)
52-
Typed property Test::$z must not be accessed before initialization (in __sleep)
53-
object(Test)#3 (3) {
36+
string(15) "O:4:"Test":0:{}"
37+
bool(true)
38+
bool(true)
39+
bool(true)
40+
bool(true)
41+
object(Test)#1 (3) {
5442
["x"]=>
5543
int(1)
5644
["y":protected]=>

ext/standard/var.c

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -784,9 +784,7 @@ static int php_var_serialize_try_add_sleep_prop(
784784
if (Z_TYPE_P(val) == IS_UNDEF) {
785785
zend_property_info *info = zend_get_typed_property_info_for_slot(Z_OBJ_P(struc), val);
786786
if (info) {
787-
zend_throw_error(NULL,
788-
"Typed property %s::$%s must not be accessed before initialization (in __sleep)",
789-
ZSTR_VAL(Z_OBJCE_P(struc)->name), ZSTR_VAL(error_name));
787+
return SUCCESS;
790788
}
791789
return FAILURE;
792790
}

0 commit comments

Comments
 (0)