xref: /freebsd-src/contrib/libcbor/test/tag_test.c (revision abd872540f24cfc7dbd1ea29b6918c7082a22108)
1 /*
2  * Copyright (c) 2014-2020 Pavel Kalvoda <me@pavelkalvoda.com>
3  *
4  * libcbor is free software; you can redistribute it and/or modify
5  * it under the terms of the MIT license. See LICENSE for details.
6  */
7 
8 #include "assertions.h"
9 #include "cbor.h"
10 #include "test_allocator.h"
11 
12 cbor_item_t *tag;
13 struct cbor_load_result res;
14 
15 unsigned char embedded_tag_data[] = {0xC0, 0x00};
16 
test_refcounting(void ** _CBOR_UNUSED (_state))17 static void test_refcounting(void **_CBOR_UNUSED(_state)) {
18   tag = cbor_load(embedded_tag_data, 2, &res);
19   assert_true(cbor_refcount(tag) == 1);
20   cbor_item_t *item = cbor_tag_item(tag);
21   assert_true(cbor_refcount(item) == 2);
22   cbor_decref(&tag);
23   assert_null(tag);
24   assert_true(cbor_refcount(item) == 1);
25   cbor_decref(&item);
26   assert_null(item);
27 }
28 
29 /* Tag 0 + uint 0 */
test_embedded_tag(void ** _CBOR_UNUSED (_state))30 static void test_embedded_tag(void **_CBOR_UNUSED(_state)) {
31   tag = cbor_load(embedded_tag_data, 2, &res);
32   assert_true(cbor_typeof(tag) == CBOR_TYPE_TAG);
33   assert_true(cbor_tag_value(tag) == 0);
34   assert_uint8(cbor_move(cbor_tag_item(tag)), 0);
35   cbor_decref(&tag);
36   assert_null(tag);
37 }
38 
39 unsigned char int8_tag_data[] = {0xD8, 0xFF, 0x01};
40 
41 /* Tag 255 + uint 1 */
test_int8_tag(void ** _CBOR_UNUSED (_state))42 static void test_int8_tag(void **_CBOR_UNUSED(_state)) {
43   tag = cbor_load(int8_tag_data, 3, &res);
44   assert_true(cbor_typeof(tag) == CBOR_TYPE_TAG);
45   assert_true(cbor_tag_value(tag) == 255);
46   assert_uint8(cbor_move(cbor_tag_item(tag)), 1);
47   cbor_decref(&tag);
48   assert_null(tag);
49 }
50 
51 unsigned char int16_tag_data[] = {0xD9, 0xFF, 0x00, 0x02};
52 
53 /* Tag 255 << 8 + uint 2 */
test_int16_tag(void ** _CBOR_UNUSED (_state))54 static void test_int16_tag(void **_CBOR_UNUSED(_state)) {
55   tag = cbor_load(int16_tag_data, 4, &res);
56   assert_true(cbor_typeof(tag) == CBOR_TYPE_TAG);
57   assert_true(cbor_tag_value(tag) == 255 << 8);
58   assert_uint8(cbor_move(cbor_tag_item(tag)), 2);
59   cbor_decref(&tag);
60   assert_null(tag);
61 }
62 
63 unsigned char int32_tag_data[] = {0xDA, 0xFF, 0x00, 0x00, 0x00, 0x03};
64 
65 /* uint 3 */
test_int32_tag(void ** _CBOR_UNUSED (_state))66 static void test_int32_tag(void **_CBOR_UNUSED(_state)) {
67   tag = cbor_load(int32_tag_data, 6, &res);
68   assert_true(cbor_typeof(tag) == CBOR_TYPE_TAG);
69   assert_true(cbor_tag_value(tag) == 4278190080ULL);
70   assert_uint8(cbor_move(cbor_tag_item(tag)), 3);
71   cbor_decref(&tag);
72   assert_null(tag);
73 }
74 
75 unsigned char int64_tag_data[] = {0xDB, 0xFF, 0x00, 0x00, 0x00,
76                                   0x00, 0x00, 0x00, 0x00, 0x04};
77 
78 /* uint 4 */
test_int64_tag(void ** _CBOR_UNUSED (_state))79 static void test_int64_tag(void **_CBOR_UNUSED(_state)) {
80   tag = cbor_load(int64_tag_data, 10, &res);
81   assert_true(cbor_typeof(tag) == CBOR_TYPE_TAG);
82   assert_true(cbor_tag_value(tag) == 18374686479671623680ULL);
83   assert_uint8(cbor_move(cbor_tag_item(tag)), 4);
84   cbor_decref(&tag);
85   assert_null(tag);
86 }
87 
88 unsigned char nested_tag_data[] = {0xC0, 0xC1, 0x18, 0x2A};
89 
90 /* Tag 0, tag 1 + uint 0 */
test_nested_tag(void ** _CBOR_UNUSED (_state))91 static void test_nested_tag(void **_CBOR_UNUSED(_state)) {
92   tag = cbor_load(nested_tag_data, 4, &res);
93   assert_true(cbor_typeof(tag) == CBOR_TYPE_TAG);
94   assert_true(cbor_tag_value(tag) == 0);
95   cbor_item_t *nested_tag = cbor_tag_item(tag);
96   assert_true(cbor_typeof(nested_tag) == CBOR_TYPE_TAG);
97   assert_true(cbor_tag_value(nested_tag) == 1);
98   assert_uint8(cbor_move(cbor_tag_item(nested_tag)), 42);
99   cbor_decref(&tag);
100   assert_null(tag);
101   cbor_decref(&nested_tag);
102   assert_null(nested_tag);
103 }
104 
test_all_tag_values_supported(void ** _CBOR_UNUSED (_state))105 static void test_all_tag_values_supported(void **_CBOR_UNUSED(_state)) {
106   /* Test all items in the protected range of
107    * https://www.iana.org/assignments/cbor-tags/cbor-tags.xhtml */
108   for (int64_t tag_value = 0; tag_value <= 32767; tag_value++) {
109     cbor_item_t *tag_item =
110         cbor_build_tag(tag_value, cbor_move(cbor_build_uint8(42)));
111     unsigned char *serialized_tag;
112     size_t serialized_tag_size =
113         cbor_serialize_alloc(tag_item, &serialized_tag, NULL);
114     assert_true(serialized_tag_size > 0);
115     tag = cbor_load(serialized_tag, serialized_tag_size, &res);
116     assert_true(res.read == serialized_tag_size);
117     assert_true(cbor_typeof(tag) == CBOR_TYPE_TAG);
118     assert_true(cbor_tag_value(tag) == tag_value);
119     cbor_decref(&tag);
120     assert_null(tag);
121     cbor_decref(&tag_item);
122     assert_null(tag_item);
123     free(serialized_tag);
124   }
125 }
126 
test_build_tag(void ** _CBOR_UNUSED (_state))127 static void test_build_tag(void **_CBOR_UNUSED(_state)) {
128   tag = cbor_build_tag(1, cbor_move(cbor_build_uint8(42)));
129 
130   assert_true(cbor_typeof(tag) == CBOR_TYPE_TAG);
131   assert_size_equal(cbor_tag_value(tag), 1);
132   assert_uint8(cbor_move(cbor_tag_item(tag)), 42);
133 
134   cbor_decref(&tag);
135 }
136 
test_build_tag_failure(void ** _CBOR_UNUSED (_state))137 static void test_build_tag_failure(void **_CBOR_UNUSED(_state)) {
138   cbor_item_t *tagged_item = cbor_build_uint8(42);
139 
140   WITH_FAILING_MALLOC({ assert_null(cbor_build_tag(1, tagged_item)); });
141   assert_size_equal(cbor_refcount(tagged_item), 1);
142 
143   cbor_decref(&tagged_item);
144 }
145 
test_tag_creation(void ** _CBOR_UNUSED (_state))146 static void test_tag_creation(void **_CBOR_UNUSED(_state)) {
147   WITH_FAILING_MALLOC({ assert_null(cbor_new_tag(42)); });
148 }
149 
main(void)150 int main(void) {
151   const struct CMUnitTest tests[] = {
152       cmocka_unit_test(test_refcounting),
153       cmocka_unit_test(test_embedded_tag),
154       cmocka_unit_test(test_int8_tag),
155       cmocka_unit_test(test_int16_tag),
156       cmocka_unit_test(test_int32_tag),
157       cmocka_unit_test(test_int64_tag),
158       cmocka_unit_test(test_nested_tag),
159       cmocka_unit_test(test_all_tag_values_supported),
160       cmocka_unit_test(test_build_tag),
161       cmocka_unit_test(test_build_tag_failure),
162       cmocka_unit_test(test_tag_creation),
163   };
164   return cmocka_run_group_tests(tests, NULL, NULL);
165 }
166