From 1f8a3c11e744bbbb2cd7bc304d1c33b2036d013f Mon Sep 17 00:00:00 2001 From: Michael Wallner Date: Fri, 10 Dec 2021 21:14:30 +0100 Subject: [PATCH] simplify Serializable handling --- ion_private.h | 21 ++++++---------- tests/serialize/serializable.phpt | 42 ++++++++++++++++++++----------- 2 files changed, 35 insertions(+), 28 deletions(-) diff --git a/ion_private.h b/ion_private.h index 3fb3233..367f6bf 100644 --- a/ion_private.h +++ b/ion_private.h @@ -1277,12 +1277,12 @@ static inline void php_ion_unserialize_zval(php_ion_unserializer *ser, zval *ret static inline bool can_call_magic_unserialize(php_ion_unserializer *ser, zend_class_entry *ce) { - return (ce->__unserialize && ser->call_magic); + return (ce && ce->__unserialize && ser->call_magic); } static inline bool can_call_iface_unserialize(php_ion_unserializer *ser, zend_class_entry *ce) { - return !!ce->unserialize; + return (ce && ce->unserialize); } static inline bool can_call_custom_unserialize(php_ion_unserializer *ser, zend_object *zobject, zend_function **fn) @@ -1330,27 +1330,22 @@ static inline void php_ion_unserialize_object_enum(php_ion_unserializer *ser, zv static inline void php_ion_unserialize_object_iface(php_ion_unserializer *ser, zval *return_value) { - zend_string *s = zval_get_string(return_value); - ION_CATCH(); - - zval *backref = php_ion_unserialize_class(ser, return_value); - ION_CATCH(zend_string_release(s)); - - zend_class_entry *ce = Z_OBJCE_P(return_value); + zend_class_entry *ce = zend_lookup_class(ser->annotations.object_class); if (can_call_iface_unserialize(ser, ce)) { + zend_string *s = zval_get_string(return_value); + ZVAL_NULL(return_value); + zval *backref = zend_hash_next_index_insert(ser->ids, return_value); if (SUCCESS == ce->unserialize(backref, ce, (BYTE *) s->val, s->len, NULL)) { - // remove all this Serializable crap in PHP-9 - zval_ptr_dtor(return_value); - ZVAL_COPY_VALUE(return_value, backref); + RETVAL_ZVAL(backref, 0, 0); } else if (!EG(exception)) { zend_throw_exception_ex(spl_ce_UnexpectedValueException, IERR_INTERNAL_ERROR, "Failed to unserialize class %s", ce->name->val); } + zend_string_release(s); } else { zend_throw_exception_ex(spl_ce_RuntimeException, IERR_INVALID_TOKEN, "Class %s does not implement Serializable", ser->annotations.object_class->val); } - zend_string_release(s); } static void php_ion_unserialize_props(php_ion_unserializer *ser, zval *return_value) diff --git a/tests/serialize/serializable.phpt b/tests/serialize/serializable.phpt index 623d731..337537c 100644 --- a/tests/serialize/serializable.phpt +++ b/tests/serialize/serializable.phpt @@ -14,11 +14,6 @@ class test implements Serializable { $this->data = $data; } } -$t = new test; -$s = ion\serialize($t); -echo $s, "\n"; -$c = ion\unserialize($s); -var_dump($c); class recursive implements Serializable { private $id; @@ -42,24 +37,41 @@ class recursive implements Serializable { } } } + +echo "\n"; + +$t = new test; +$s = ion\serialize([$t, $t]); +echo $s, "\n"; +$c = ion\unserialize($s); +debug_zval_dump($c); $tree = new recursive(new recursive(null)); var_dump($tree); $s = ion\serialize($tree); echo $s,"\n"; -var_dump(ion\unserialize($s)); +debug_zval_dump(ion\unserialize($s)); ?> DONE --EXPECTF-- TEST Deprecated: test implements the Serializable interface, which is deprecated. Implement __serialize() and __unserialize() instead (or in addition, if support for old PHP versions is necessary) in %sserialize/serializable.php on line %d -PHP::S::test::"foobar" -object(test)#5 (1) { - ["data":protected]=> - string(6) "foobar" -} Deprecated: recursive implements the Serializable interface, which is deprecated. Implement __serialize() and __unserialize() instead (or in addition, if support for old PHP versions is necessary) in %sserialize/serializable.php on line %d + +PHP::[S::test::"foobar",r::1] +array(2) refcount(2){ + [0]=> + object(test)#%d (1) refcount(2){ + ["data":protected]=> + string(6) "foobar" refcount(1) + } + [1]=> + object(test)#%d (1) refcount(2){ + ["data":protected]=> + string(6) "foobar" refcount(1) + } +} object(recursive)#%d (2) { ["id":"recursive":private]=> NULL @@ -72,13 +84,13 @@ object(recursive)#%d (2) { } } PHP::S::recursive::"node:S::recursive::\"leaf\"" -object(recursive)#%d (2) { +object(recursive)#%d (2) refcount(1){ ["id":"recursive":private]=> - string(4) "node" + string(4) "node" refcount(1) ["r":protected]=> - object(recursive)#%d (2) { + object(recursive)#10 (2) refcount(1){ ["id":"recursive":private]=> - string(4) "leaf" + string(4) "leaf" refcount(1) ["r":protected]=> NULL } -- 2.30.2