diff options
author | Nicolas Grekas <nicolas.grekas@gmail.com> | 2020-04-16 00:11:38 +0200 |
---|---|---|
committer | Nikita Popov <nikita.ppv@gmail.com> | 2020-04-23 10:30:33 +0200 |
commit | 73d02c3b3eb8b828a1cc7ae04a4cc4f4875c3ddd (patch) | |
tree | ce843e9b79af1d8feb4c29ef17e3b1183e268c19 | |
parent | c705079b12984dab1901a32b4a0609f2ab8f449a (diff) | |
download | php-git-73d02c3b3eb8b828a1cc7ae04a4cc4f4875c3ddd.tar.gz |
Fix bug #79447
Partially reverts 846b6479537a112d1ded725e6484e46462048b35: 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.
-rw-r--r-- | NEWS | 2 | ||||
-rw-r--r-- | ext/standard/tests/serialize/sleep_uninitialized_typed_prop.phpt | 38 | ||||
-rw-r--r-- | ext/standard/var.c | 4 |
3 files changed, 16 insertions, 28 deletions
@@ -40,6 +40,8 @@ PHP NEWS - Standard: . Fixed bug #79468 (SIGSEGV when closing stream handle with a stream filter appended). (dinosaur) + . Fixed bug #79447 (Serializing uninitialized typed properties with __sleep + should not throw). (nicolas-grekas) ?? ??? ????, PHP 7.4.5 diff --git a/ext/standard/tests/serialize/sleep_uninitialized_typed_prop.phpt b/ext/standard/tests/serialize/sleep_uninitialized_typed_prop.phpt index 3d78e11f28..ebef92ca18 100644 --- a/ext/standard/tests/serialize/sleep_uninitialized_typed_prop.phpt +++ b/ext/standard/tests/serialize/sleep_uninitialized_typed_prop.phpt @@ -1,5 +1,5 @@ --TEST-- -Referencing an uninitialized typed property in __sleep() should result in Error +Referencing an uninitialized typed property in __sleep() should be skipped --FILE-- <?php @@ -18,39 +18,27 @@ class Test { } $t = new Test; -try { - serialize($t); -} catch (Error $e) { - echo $e->getMessage(), "\n"; -} +var_dump(serialize($t)); +var_dump(unserialize(serialize($t)) == $t); $t->x = 1; -try { - serialize($t); -} catch (Error $e) { - echo $e->getMessage(), "\n"; -} +var_dump(unserialize(serialize($t)) == $t); $t->y = 2; -try { - serialize($t); -} catch (Error $e) { - echo $e->getMessage(), "\n"; -} +var_dump(unserialize(serialize($t)) == $t); $t->z = 3; -try { - var_dump(unserialize(serialize($t))); -} catch (Error $e) { - echo $e->getMessage(), "\n"; -} +var_dump(unserialize(serialize($t)) == $t); +var_dump($t); ?> --EXPECT-- -Typed property Test::$x must not be accessed before initialization (in __sleep) -Typed property Test::$y must not be accessed before initialization (in __sleep) -Typed property Test::$z must not be accessed before initialization (in __sleep) -object(Test)#3 (3) { +string(15) "O:4:"Test":0:{}" +bool(true) +bool(true) +bool(true) +bool(true) +object(Test)#1 (3) { ["x"]=> int(1) ["y":protected]=> diff --git a/ext/standard/var.c b/ext/standard/var.c index 3fa1afcb72..6e59eab419 100644 --- a/ext/standard/var.c +++ b/ext/standard/var.c @@ -784,9 +784,7 @@ static int php_var_serialize_try_add_sleep_prop( if (Z_TYPE_P(val) == IS_UNDEF) { zend_property_info *info = zend_get_typed_property_info_for_slot(Z_OBJ_P(struc), val); if (info) { - zend_throw_error(NULL, - "Typed property %s::$%s must not be accessed before initialization (in __sleep)", - ZSTR_VAL(Z_OBJCE_P(struc)->name), ZSTR_VAL(error_name)); + return SUCCESS; } return FAILURE; } |