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 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 */ 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 */ 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 */ 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 */ 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 */ 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 */ 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 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 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 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 146 static void test_tag_creation(void **_CBOR_UNUSED(_state)) { 147 WITH_FAILING_MALLOC({ assert_null(cbor_new_tag(42)); }); 148 } 149 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