diff --git a/ext/standard/tests/serialize/007.phpt b/ext/standard/tests/serialize/007.phpt new file mode 100644 index 000000000000..2876ca1570c6 --- /dev/null +++ b/ext/standard/tests/serialize/007.phpt @@ -0,0 +1,38 @@ +--TEST-- +serialize() with __sleep() without props +--FILE-- +a = 2; + } +} + +class FooNull { + public $a = 1; + function __sleep() { + $this->a = 2; + return null; + } +} + +class Bar { + public $a = 1; + function __sleep() { + $this->a = 2; + return 1; + } +} + +var_dump(serialize(new Foo())); +var_dump(serialize(new FooNull())); +var_dump(serialize(new Bar())); +?> +--EXPECTF-- +string(31) "O:3:"Foo":1:{s:6:"%0Foo%0a";i:2;}" +string(30) "O:7:"FooNull":1:{s:1:"a";i:2;}" + +Warning: serialize(): Bar::__sleep() should return an array of property names, or return null/void to delegate to default serialization in %s on line %d +string(26) "O:3:"Bar":1:{s:1:"a";i:2;}" diff --git a/ext/standard/tests/serialize/bug21957.phpt b/ext/standard/tests/serialize/bug21957.phpt index 9d761a6699c9..80bc8cd66184 100644 --- a/ext/standard/tests/serialize/bug21957.phpt +++ b/ext/standard/tests/serialize/bug21957.phpt @@ -40,10 +40,15 @@ array(2) { int(2) } } -a:2:{s:3:"one";s:3:"ABC";s:3:"two";N;} +a:2:{s:3:"one";s:3:"ABC";s:3:"two";O:4:"test":2:{s:1:"a";i:7;s:1:"b";i:0;}} array(2) { ["one"]=> string(3) "ABC" ["two"]=> - NULL + object(test)#2 (2) { + ["a"]=> + int(7) + ["b"]=> + int(0) + } } diff --git a/ext/standard/tests/serialize/bug79526.phpt b/ext/standard/tests/serialize/bug79526.phpt index 440c18772d53..a7307cbcf260 100644 --- a/ext/standard/tests/serialize/bug79526.phpt +++ b/ext/standard/tests/serialize/bug79526.phpt @@ -24,7 +24,7 @@ serialize(new B()); ?> Done --EXPECTF-- -Warning: serialize(): A::__sleep() should return an array only containing the names of instance-variables to serialize in %s on line %d +Warning: serialize(): A::__sleep() should return an array of property names, or return null/void to delegate to default serialization in %s on line %d Warning: serialize(): B::__sleep() should return an array only containing the names of instance-variables to serialize in %s on line %d diff --git a/ext/standard/tests/serialize/bug81163.phpt b/ext/standard/tests/serialize/bug81163.phpt index 855fc1c953ed..fe222a10384f 100644 --- a/ext/standard/tests/serialize/bug81163.phpt +++ b/ext/standard/tests/serialize/bug81163.phpt @@ -18,4 +18,4 @@ class bar extends foo serialize(new bar()); ?> --EXPECTF-- -Warning: serialize(): bar::__sleep() should return an array only containing the names of instance-variables to serialize in %s on line %d +Warning: serialize(): bar::__sleep() should return an array of property names, or return null/void to delegate to default serialization in %s on line %d diff --git a/ext/standard/var.c b/ext/standard/var.c index a1ef60410a33..aeea583ad7bc 100644 --- a/ext/standard/var.c +++ b/ext/standard/var.c @@ -832,14 +832,14 @@ static HashTable* php_var_serialize_call_sleep(zend_object *obj, zend_function * zend_call_known_instance_method(fn, obj, &retval, /* param_count */ 0, /* params */ NULL); BG(serialize_lock)--; - if (Z_ISUNDEF(retval) || EG(exception)) { + if (Z_ISUNDEF(retval) || Z_ISNULL(retval) || EG(exception)) { zval_ptr_dtor(&retval); return NULL; } if (Z_TYPE(retval) != IS_ARRAY) { zval_ptr_dtor(&retval); - php_error_docref(NULL, E_WARNING, "%s::__sleep() should return an array only containing the names of instance-variables to serialize", ZSTR_VAL(obj->ce->name)); + php_error_docref(NULL, E_WARNING, "%s::__sleep() should return an array of property names, or return null/void to delegate to default serialization", ZSTR_VAL(obj->ce->name)); return NULL; } @@ -1215,20 +1215,18 @@ static void php_var_serialize_intern(smart_str *buf, zval *struc, php_serialize_ zval tmp; ZVAL_OBJ_COPY(&tmp, Z_OBJ_P(struc)); - if (!(ht = php_var_serialize_call_sleep(Z_OBJ(tmp), Z_FUNC_P(zv)))) { - if (!EG(exception)) { - /* we should still add element even if it's not OK, - * since we already wrote the length of the array before */ - smart_str_appendl(buf, "N;", 2); - } + ht = php_var_serialize_call_sleep(Z_OBJ(tmp), Z_FUNC_P(zv)); + if (ht) { + php_var_serialize_class(buf, &tmp, ht, var_hash); + zend_array_release(ht); OBJ_RELEASE(Z_OBJ(tmp)); return; } - php_var_serialize_class(buf, &tmp, ht, var_hash); - zend_array_release(ht); OBJ_RELEASE(Z_OBJ(tmp)); - return; + if (EG(exception)) { + return; + } } }