fix leak
authorMichael Wallner <mike@php.net>
Wed, 12 Jan 2022 10:37:22 +0000 (11:37 +0100)
committerMichael Wallner <mike@php.net>
Wed, 12 Jan 2022 10:37:22 +0000 (11:37 +0100)
ion_private.h
tests/serialize/serializable.phpt

index aea7c7de7ec97b54d6404441f128ef901ca3c472..c7212298f935527e19a43b597f10fb0efe616b52 100644 (file)
@@ -2052,9 +2052,13 @@ LOCAL void php_ion_unserialize_object_iface(php_ion_unserializer *ser, zval *ret
                zval *backref = zend_hash_next_index_insert(ser->ids, return_value);
                if (SUCCESS == ce->unserialize(backref, ce, (BYTE *) s->val, s->len, NULL)) {
                        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);
+               } else {
+                       zval_ptr_dtor(backref);
+                       ZVAL_NULL(backref);
+                       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 {
index 0a700de0cdfb4e937b7d7dc312095793ae49dc46..5f6622784aab399d6f77a90d87361d43b3cf4257 100644 (file)
@@ -38,6 +38,18 @@ class recursive implements Serializable {
        }
 }
 
+class except implements Serializable {
+       function __construct (public $onserialize = false) {}
+       function serialize() : string {
+               if ($this->onserialize)
+                       throw new Exception("except on serialize");
+               return "<<data>>";
+       }
+       function unserialize(string $data) : void {
+               throw new Exception("except on unserialize");
+       }
+}
+
 echo "\n";
 
 $t = new test;
@@ -50,6 +62,17 @@ var_dump($tree);
 $s = ion\serialize($tree);
 echo $s,"\n";
 debug_zval_dump(ion\unserialize($s));
+
+try {
+       ion\serialize(new except(true));
+} catch (Exception $e) {
+       printf("caught %s: %s\n", get_class($e), $e->getMessage());
+}
+try {
+       ion\unserialize(ion\serialize(new except()));
+} catch (Exception $e) {
+       printf("caught %s: %s\n", get_class($e), $e->getMessage());
+}
 ?>
 DONE
 --EXPECTF--
@@ -59,6 +82,8 @@ Deprecated: test implements the Serializable interface, which is deprecated. Imp
 
 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
 
+Deprecated: except 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
+
 [S::test::{{"foobar"}},r::1]
 array(2) refcount(2){
   [0]=>
@@ -95,4 +120,6 @@ object(recursive)#%d (2) refcount(1){
     NULL
   }
 }
+caught Exception: except on serialize
+caught Exception: except on unserialize
 DONE