simplify Serializable handling
authorMichael Wallner <mike@php.net>
Fri, 10 Dec 2021 20:14:30 +0000 (21:14 +0100)
committerMichael Wallner <mike@php.net>
Tue, 14 Dec 2021 11:53:56 +0000 (12:53 +0100)
ion_private.h
tests/serialize/serializable.phpt

index 3fb3233a91b2285df310801fe640fcc78f6a2c30..367f6bf65f267aa68516d5ba67cbe9ed66fbad0a 100644 (file)
@@ -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)
index 623d73159c7353f9fe2d92d7e8ca5528d598b567..337537ca487944c72a2043fccf93d6ed0c9f77eb 100644 (file)
@@ -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
   }