tests++
authorMichael Wallner <mike@php.net>
Mon, 10 Jan 2022 22:05:21 +0000 (23:05 +0100)
committerMichael Wallner <mike@php.net>
Mon, 10 Jan 2022 22:05:21 +0000 (23:05 +0100)
ion_private.h
tests/Symbol/Enum.phpt [new file with mode: 0644]
tests/Symbol/ImportLocation.phpt [new file with mode: 0644]
tests/Symbol/Table.phpt
tests/Symbol/Table/Shared/roundtrip.phpt
tests/unserialize/argtype.phpt [new file with mode: 0644]
tests/unserialize/invalid_annotation.phpt [new file with mode: 0644]

index 4f49088d8365df4d3acf84379e385e3bf547bce5..7233f464c4ec2b89b3b58068f4d519568782223e 100644 (file)
@@ -2027,6 +2027,8 @@ LOCAL zval *php_ion_unserialize_class(php_ion_unserializer *ser, zval *return_va
 LOCAL void php_ion_unserialize_object_enum(php_ion_unserializer *ser, zval *return_value)
 {
        zend_string *zs_case = zval_get_string(return_value);
+       zend_hash_next_index_insert(ser->tmp, return_value);
+       ZVAL_NULL(return_value);
        ION_CATCH();
 
        zend_class_entry *ce = zend_lookup_class(ser->annotations.object_class);
@@ -2050,6 +2052,7 @@ LOCAL void php_ion_unserialize_object_iface(php_ion_unserializer *ser, zval *ret
        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);
+               zend_hash_next_index_insert(ser->tmp, 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)) {
@@ -2222,7 +2225,7 @@ LOCAL void php_ion_unserialize_object(php_ion_unserializer *ser, zval *return_va
 {
        // backup possible backref to array returned by magic/custom __serialize()
        zval *input = zend_hash_next_index_insert(ser->tmp, return_value);
-
+       ZVAL_NULL(return_value);
        php_ion_unserialize_class(ser, return_value);
        ION_CATCH();
 
@@ -2554,7 +2557,6 @@ LOCAL void php_ion_unserialize_zval(php_ion_unserializer *ser, zval *return_valu
                ION_CHECK(ion_reader_read_ion_symbol(ser->reader, &sym));
                php_ion_symbol_zval(&sym, return_value);
                if (ser->annotations.object_type) {
-                       zend_hash_next_index_insert(ser->tmp, return_value);
                        goto unserialize_struct;
                }
                zend_hash_next_index_insert(ser->ids, return_value);
@@ -2565,7 +2567,6 @@ LOCAL void php_ion_unserialize_zval(php_ion_unserializer *ser, zval *return_valu
                ION_CHECK(ion_reader_read_string(ser->reader, &str));
                RETVAL_STRINGL((char *) str.value, str.length);
                if (ser->annotations.object_type) {
-                       zend_hash_next_index_insert(ser->tmp, return_value);
                        goto unserialize_struct;
                }
                zend_hash_next_index_insert(ser->ids, return_value);
@@ -2575,7 +2576,6 @@ LOCAL void php_ion_unserialize_zval(php_ion_unserializer *ser, zval *return_valu
        case tid_BLOB_INT:
                php_ion_reader_read_lob(ser->reader, return_value);
                if (ser->annotations.object_type) {
-                       zend_hash_next_index_insert(ser->tmp, return_value);
                        goto unserialize_struct;
                }
                zend_hash_next_index_insert(ser->ids, return_value);
@@ -2661,7 +2661,8 @@ void php_ion_unserialize(php_ion_unserializer *ser, zval *zdata, zval *return_va
                reader->buffer = zval_get_string(zdata);
        } else {
                zend_throw_exception_ex(spl_ce_InvalidArgumentException, IERR_INVALID_ARG,
-                               "Invalid source to unserialize; expected string or resource");
+                               "Invalid source to unserialize: expected string or resource, got %s",
+                                                               zend_zval_type_name(zdata));
                if (zo_ser) {
                        OBJ_RELEASE(zo_ser);
                }
diff --git a/tests/Symbol/Enum.phpt b/tests/Symbol/Enum.phpt
new file mode 100644 (file)
index 0000000..2478b0f
--- /dev/null
@@ -0,0 +1,26 @@
+--TEST--
+ion\Symbol\Enum
+--EXTENSIONS--
+ion
+--FILE--
+TEST
+<?php
+$t = ion\Symbol\Table\PHP::PHP;
+var_dump($t instanceof ion\Symbol\Enum);
+var_dump($t->toSymbol(), $t->toSID(), $t->toString());
+?>
+DONE
+--EXPECTF--
+TEST
+bool(true)
+object(ion\Symbol)#2 (3) {
+  ["value"]=>
+  string(3) "PHP"
+  ["sid"]=>
+  int(10)
+  ["importLocation"]=>
+  NULL
+}
+int(10)
+string(3) "PHP"
+DONE
diff --git a/tests/Symbol/ImportLocation.phpt b/tests/Symbol/ImportLocation.phpt
new file mode 100644 (file)
index 0000000..78c9945
--- /dev/null
@@ -0,0 +1,34 @@
+--TEST--
+ion\Symbol\ImportLocation
+--EXTENSIONS--
+ion
+--FILE--
+TEST
+<?php
+var_dump($iloc = new ion\Symbol\ImportLocation("table", 123));
+var_dump(clone $iloc);
+unset($iloc);
+var_dump(clone new ion\Symbol\ImportLocation("table", 123));
+?>
+DONE
+--EXPECTF--
+TEST
+object(ion\Symbol\ImportLocation)#%d (2) {
+  ["name"]=>
+  string(5) "table"
+  ["location"]=>
+  int(123)
+}
+object(ion\Symbol\ImportLocation)#%d (2) {
+  ["name"]=>
+  string(5) "table"
+  ["location"]=>
+  int(123)
+}
+object(ion\Symbol\ImportLocation)#%d (2) {
+  ["name"]=>
+  string(5) "table"
+  ["location"]=>
+  int(123)
+}
+DONE
index 86d4b05915db07b9c572079af823b50754bb30e4..12c70e9d8d3980ef89c4ad24f23420616cbeb8ef 100644 (file)
@@ -43,6 +43,7 @@ echo "add, find, local sym4\n";
 var_dump($local->add("sym4"));
 var_dump($local->find("sym4"));
 var_dump($local->findLocal("sym4"));
+var_dump($local->getMaxId());
 ?>
 DONE
 --EXPECTF--
@@ -157,4 +158,5 @@ object(ion\Symbol)#%d (3) {
   ["importLocation"]=>
   NULL
 }
+int(23)
 DONE
index c9e2b93eee58581a48883e726678cd4b51f3d89c..d538c054ca0c18c3aea0133ec7360533bc7dc2bf 100644 (file)
@@ -1,5 +1,5 @@
 --TEST--
-Symbol\Table\Shared/roundtrip
+ion\Symbol\Table\Shared/roundtrip
 --EXTENSIONS--
 ion
 --FILE--
diff --git a/tests/unserialize/argtype.phpt b/tests/unserialize/argtype.phpt
new file mode 100644 (file)
index 0000000..1c99b03
--- /dev/null
@@ -0,0 +1,20 @@
+--TEST--
+ion\unserialize/argtype
+--EXTENSIONS--
+ion
+--FILE--
+TEST
+<?php
+$a=[];
+foreach ([&$a,  $a, (object) $a] as $s) {
+       try { var_dump(ion\unserialize($s)); }
+       catch (Throwable $e) { printf("caught %s: %s\n", get_class($e), $e->getMessage()); }
+}
+?>
+DONE
+--EXPECT--
+TEST
+caught InvalidArgumentException: Invalid source to unserialize: expected string or resource, got array
+caught InvalidArgumentException: Invalid source to unserialize: expected string or resource, got array
+caught InvalidArgumentException: Invalid source to unserialize: expected string or resource, got stdClass
+DONE
diff --git a/tests/unserialize/invalid_annotation.phpt b/tests/unserialize/invalid_annotation.phpt
new file mode 100644 (file)
index 0000000..3e8aea6
--- /dev/null
@@ -0,0 +1,31 @@
+--TEST--
+ion\unserialize/invalid annotation
+--EXTENSIONS--
+ion
+--FILE--
+TEST
+<?php
+foreach (["r::r::1", "R::R::1", "p::p::1", "p::foo::p::1", "c::c::1", "c::1", "E::foo::E::1",
+                       "E::1", "S::1", "S::S::foo123", "O::O::O::1", "O::1", "C::C::C::1", "C::1"] as $s) {
+       try { var_dump(ion\unserialize($s)); }
+       catch (Throwable $e) { printf("caught %s: %s\n", get_class($e), $e->getMessage()); }
+}
+?>
+DONE
+--EXPECT--
+TEST
+caught RuntimeException: Invalid multiple back reference annotations
+caught RuntimeException: Invalid multiple reference annotations
+int(1)
+caught RuntimeException: Invalid multiple object property annotations
+caught RuntimeException: Invalid object type annotation: c::1
+caught RuntimeException: IERR_INVALID_ARG: ion_reader_get_an_annotation(ser->reader, ++i, &class_name)
+caught RuntimeException: Invalid multiple object type annotations: E::E
+caught RuntimeException: IERR_INVALID_ARG: ion_reader_get_an_annotation(ser->reader, ++i, &class_name)
+caught RuntimeException: IERR_INVALID_ARG: ion_reader_get_an_annotation(ser->reader, ++i, &class_name)
+caught RuntimeException: Class S does not implement Serializable
+caught RuntimeException: Invalid multiple object type annotations: O::O
+caught RuntimeException: IERR_INVALID_ARG: ion_reader_get_an_annotation(ser->reader, ++i, &class_name)
+caught RuntimeException: Invalid multiple object type annotations: C::C
+caught RuntimeException: IERR_INVALID_ARG: ion_reader_get_an_annotation(ser->reader, ++i, &class_name)
+DONE