summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNicolas Grekas <nicolas.grekas@gmail.com>2020-04-16 00:11:38 +0200
committerNikita Popov <nikita.ppv@gmail.com>2020-04-23 10:30:33 +0200
commit73d02c3b3eb8b828a1cc7ae04a4cc4f4875c3ddd (patch)
treece843e9b79af1d8feb4c29ef17e3b1183e268c19
parentc705079b12984dab1901a32b4a0609f2ab8f449a (diff)
downloadphp-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--NEWS2
-rw-r--r--ext/standard/tests/serialize/sleep_uninitialized_typed_prop.phpt38
-rw-r--r--ext/standard/var.c4
3 files changed, 16 insertions, 28 deletions
diff --git a/NEWS b/NEWS
index b6f8f162b7..88185d170f 100644
--- a/NEWS
+++ b/NEWS
@@ -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;
}