1208625Sjkim/* 2208625Sjkim * Copyright (c) 2014-2020 Pavel Kalvoda <me@pavelkalvoda.com> 3208625Sjkim * 4208625Sjkim * libcbor is free software; you can redistribute it and/or modify 5208625Sjkim * it under the terms of the MIT license. See LICENSE for details. 6208625Sjkim */ 7208625Sjkim 8208625Sjkim#include <stdio.h> 9208625Sjkim#include <string.h> 10208625Sjkim 11208625Sjkim#include "assertions.h" 12208625Sjkim#include "cbor.h" 13208625Sjkim 14208625Sjkimvoid assert_describe_result(cbor_item_t *item, char *expected_result) { 15208625Sjkim#if CBOR_PRETTY_PRINTER 16208625Sjkim // We know the expected size based on `expected_result`, but read everything 17208625Sjkim // in order to get the full actual output in a useful error message. 18208625Sjkim const size_t buffer_size = 512; 19208625Sjkim FILE *outfile = tmpfile(); 20208625Sjkim cbor_describe(item, outfile); 21208625Sjkim rewind(outfile); 22208625Sjkim // Treat string as null-terminated since cmocka doesn't have asserts 23208625Sjkim // for explicit length strings. 24208625Sjkim char *output = malloc(buffer_size); 25208625Sjkim assert_non_null(output); 26208625Sjkim size_t output_size = fread(output, sizeof(char), buffer_size, outfile); 27208625Sjkim output[output_size] = '\0'; 28208625Sjkim assert_string_equal(output, expected_result); 29208625Sjkim assert_true(feof(outfile)); 30208625Sjkim free(output); 31208625Sjkim fclose(outfile); 32208625Sjkim#endif 33208625Sjkim} 34208625Sjkim 35208625Sjkimstatic void test_uint(void **_CBOR_UNUSED(_state)) { 36208625Sjkim cbor_item_t *item = cbor_build_uint8(42); 37208625Sjkim assert_describe_result(item, "[CBOR_TYPE_UINT] Width: 1B, Value: 42\n"); 38208625Sjkim cbor_decref(&item); 39208625Sjkim} 40208625Sjkim 41208625Sjkimstatic void test_negint(void **_CBOR_UNUSED(_state)) { 42208625Sjkim cbor_item_t *item = cbor_build_negint16(40); 43208625Sjkim assert_describe_result(item, 44208625Sjkim "[CBOR_TYPE_NEGINT] Width: 2B, Value: -40 - 1\n"); 45208625Sjkim cbor_decref(&item); 46208625Sjkim} 47208625Sjkim 48208625Sjkimstatic void test_definite_bytestring(void **_CBOR_UNUSED(_state)) { 49208625Sjkim unsigned char data[] = {0x01, 0x02, 0x03}; 50208625Sjkim cbor_item_t *item = cbor_build_bytestring(data, 3); 51208625Sjkim assert_describe_result(item, 52208625Sjkim "[CBOR_TYPE_BYTESTRING] Definite, Length: 3B, Data:\n" 53208625Sjkim " 010203\n"); 54208625Sjkim cbor_decref(&item); 55208625Sjkim} 56208625Sjkim 57208625Sjkimstatic void test_indefinite_bytestring(void **_CBOR_UNUSED(_state)) { 58208625Sjkim unsigned char data[] = {0x01, 0x02, 0x03}; 59208625Sjkim cbor_item_t *item = cbor_new_indefinite_bytestring(); 60208625Sjkim assert_true(cbor_bytestring_add_chunk( 61208625Sjkim item, cbor_move(cbor_build_bytestring(data, 3)))); 62208625Sjkim assert_true(cbor_bytestring_add_chunk( 63208625Sjkim item, cbor_move(cbor_build_bytestring(data, 2)))); 64208625Sjkim assert_describe_result( 65208625Sjkim item, 66208625Sjkim "[CBOR_TYPE_BYTESTRING] Indefinite, Chunks: 2, Chunk data:\n" 67208625Sjkim " [CBOR_TYPE_BYTESTRING] Definite, Length: 3B, Data:\n" 68208625Sjkim " 010203\n" 69208625Sjkim " [CBOR_TYPE_BYTESTRING] Definite, Length: 2B, Data:\n" 70208625Sjkim " 0102\n"); 71208625Sjkim cbor_decref(&item); 72208625Sjkim} 73208625Sjkim 74208625Sjkimstatic void test_definite_string(void **_CBOR_UNUSED(_state)) { 75208625Sjkim char *string = "Hello!"; 76208625Sjkim cbor_item_t *item = cbor_build_string(string); 77208625Sjkim assert_describe_result( 78208625Sjkim item, 79208625Sjkim "[CBOR_TYPE_STRING] Definite, Length: 6B, Codepoints: 6, Data:\n" 80208625Sjkim " Hello!\n"); 81208625Sjkim cbor_decref(&item); 82208625Sjkim} 83208625Sjkim 84208625Sjkimstatic void test_indefinite_string(void **_CBOR_UNUSED(_state)) { 85208625Sjkim char *string = "Hello!"; 86208625Sjkim cbor_item_t *item = cbor_new_indefinite_string(); 87208625Sjkim assert_true( 88208625Sjkim cbor_string_add_chunk(item, cbor_move(cbor_build_string(string)))); 89208625Sjkim assert_true( 90208625Sjkim cbor_string_add_chunk(item, cbor_move(cbor_build_string(string)))); 91208625Sjkim assert_describe_result( 92208625Sjkim item, 93208625Sjkim "[CBOR_TYPE_STRING] Indefinite, Chunks: 2, Chunk data:\n" 94208625Sjkim " [CBOR_TYPE_STRING] Definite, Length: 6B, Codepoints: 6, Data:\n" 95208625Sjkim " Hello!\n" 96208625Sjkim " [CBOR_TYPE_STRING] Definite, Length: 6B, Codepoints: 6, Data:\n" 97208625Sjkim " Hello!\n"); 98208625Sjkim cbor_decref(&item); 99208625Sjkim} 100208625Sjkim 101208625Sjkimstatic void test_multibyte_string(void **_CBOR_UNUSED(_state)) { 102208625Sjkim // "��t��st����ko" in UTF-8 103208625Sjkim char *string = "\xc5\xa0t\xc4\x9bst\xc3\xad\xc4\x8dko"; 104208625Sjkim cbor_item_t *item = cbor_build_string(string); 105208625Sjkim assert_describe_result( 106208625Sjkim item, 107208625Sjkim "[CBOR_TYPE_STRING] Definite, Length: 13B, Codepoints: 9, Data:\n" 108208625Sjkim " \xc5\xa0t\xc4\x9bst\xc3\xad\xc4\x8dko\n"); 109208625Sjkim cbor_decref(&item); 110208625Sjkim} 111208625Sjkim 112208625Sjkimstatic void test_definite_array(void **_CBOR_UNUSED(_state)) { 113208625Sjkim cbor_item_t *item = cbor_new_definite_array(2); 114208625Sjkim assert_true(cbor_array_push(item, cbor_move(cbor_build_uint8(1)))); 115208625Sjkim assert_true(cbor_array_push(item, cbor_move(cbor_build_uint8(2)))); 116208625Sjkim assert_describe_result(item, 117208625Sjkim "[CBOR_TYPE_ARRAY] Definite, Size: 2, Contents:\n" 118209746Sjkim " [CBOR_TYPE_UINT] Width: 1B, Value: 1\n" 119209746Sjkim " [CBOR_TYPE_UINT] Width: 1B, Value: 2\n"); 120208625Sjkim cbor_decref(&item); 121208625Sjkim} 122208625Sjkim 123208625Sjkimstatic void test_indefinite_array(void **_CBOR_UNUSED(_state)) { 124208625Sjkim cbor_item_t *item = cbor_new_indefinite_array(); 125208625Sjkim assert_true(cbor_array_push(item, cbor_move(cbor_build_uint8(1)))); 126208625Sjkim assert_true(cbor_array_push(item, cbor_move(cbor_build_uint8(2)))); 127208625Sjkim assert_describe_result(item, 128208625Sjkim "[CBOR_TYPE_ARRAY] Indefinite, Size: 2, Contents:\n" 129208625Sjkim " [CBOR_TYPE_UINT] Width: 1B, Value: 1\n" 130208625Sjkim " [CBOR_TYPE_UINT] Width: 1B, Value: 2\n"); 131208625Sjkim cbor_decref(&item); 132208625Sjkim} 133208625Sjkim 134209734Sjkimstatic void test_definite_map(void **_CBOR_UNUSED(_state)) { 135209734Sjkim cbor_item_t *item = cbor_new_definite_map(1); 136209734Sjkim assert_true(cbor_map_add( 137208625Sjkim item, (struct cbor_pair){.key = cbor_move(cbor_build_uint8(1)), 138208625Sjkim .value = cbor_move(cbor_build_uint8(2))})); 139208625Sjkim assert_describe_result(item, 140208625Sjkim "[CBOR_TYPE_MAP] Definite, Size: 1, Contents:\n" 141208625Sjkim " Map entry 0\n" 142208625Sjkim " [CBOR_TYPE_UINT] Width: 1B, Value: 1\n" 143208625Sjkim " [CBOR_TYPE_UINT] Width: 1B, Value: 2\n"); 144208625Sjkim cbor_decref(&item); 145208625Sjkim} 146208625Sjkim 147208625Sjkimstatic void test_indefinite_map(void **_CBOR_UNUSED(_state)) { 148208625Sjkim cbor_item_t *item = cbor_new_indefinite_map(); 149208625Sjkim assert_true(cbor_map_add( 150208625Sjkim item, (struct cbor_pair){.key = cbor_move(cbor_build_uint8(1)), 151208625Sjkim .value = cbor_move(cbor_build_uint8(2))})); 152208625Sjkim assert_describe_result(item, 153208625Sjkim "[CBOR_TYPE_MAP] Indefinite, Size: 1, Contents:\n" 154208625Sjkim " Map entry 0\n" 155208625Sjkim " [CBOR_TYPE_UINT] Width: 1B, Value: 1\n" 156208625Sjkim " [CBOR_TYPE_UINT] Width: 1B, Value: 2\n"); 157208625Sjkim cbor_decref(&item); 158208625Sjkim} 159208625Sjkim 160208625Sjkimstatic void test_tag(void **_CBOR_UNUSED(_state)) { 161208625Sjkim cbor_item_t *item = cbor_build_tag(42, cbor_move(cbor_build_uint8(1))); 162208625Sjkim assert_describe_result(item, 163208625Sjkim "[CBOR_TYPE_TAG] Value: 42\n" 164208625Sjkim " [CBOR_TYPE_UINT] Width: 1B, Value: 1\n"); 165208625Sjkim cbor_decref(&item); 166208625Sjkim} 167208625Sjkim 168208625Sjkimstatic void test_floats(void **_CBOR_UNUSED(_state)) { 169208625Sjkim cbor_item_t *item = cbor_new_indefinite_array(); 170208625Sjkim assert_true(cbor_array_push(item, cbor_move(cbor_build_bool(true)))); 171208625Sjkim assert_true( 172208625Sjkim cbor_array_push(item, cbor_move(cbor_build_ctrl(CBOR_CTRL_UNDEF)))); 173208625Sjkim assert_true( 174208625Sjkim cbor_array_push(item, cbor_move(cbor_build_ctrl(CBOR_CTRL_NULL)))); 175208625Sjkim assert_true(cbor_array_push(item, cbor_move(cbor_build_ctrl(24)))); 176208625Sjkim assert_true(cbor_array_push(item, cbor_move(cbor_build_float4(3.14f)))); 177208625Sjkim assert_describe_result( 178208625Sjkim item, 179208625Sjkim "[CBOR_TYPE_ARRAY] Indefinite, Size: 5, Contents:\n" 180208625Sjkim " [CBOR_TYPE_FLOAT_CTRL] Bool: true\n" 181208625Sjkim " [CBOR_TYPE_FLOAT_CTRL] Undefined\n" 182208625Sjkim " [CBOR_TYPE_FLOAT_CTRL] Null\n" 183208625Sjkim " [CBOR_TYPE_FLOAT_CTRL] Simple value: 24\n" 184208625Sjkim " [CBOR_TYPE_FLOAT_CTRL] Width: 4B, Value: 3.140000\n"); 185208625Sjkim cbor_decref(&item); 186208625Sjkim} 187208625Sjkim 188208625Sjkimint main(void) { 189208625Sjkim const struct CMUnitTest tests[] = { 190208625Sjkim cmocka_unit_test(test_uint), 191208625Sjkim cmocka_unit_test(test_negint), 192208625Sjkim cmocka_unit_test(test_definite_bytestring), 193208625Sjkim cmocka_unit_test(test_indefinite_bytestring), 194208625Sjkim cmocka_unit_test(test_definite_string), 195208625Sjkim cmocka_unit_test(test_indefinite_string), 196208625Sjkim cmocka_unit_test(test_multibyte_string), 197208625Sjkim cmocka_unit_test(test_definite_array), 198208625Sjkim cmocka_unit_test(test_indefinite_array), 199208625Sjkim cmocka_unit_test(test_definite_map), 200208625Sjkim cmocka_unit_test(test_indefinite_map), 201208625Sjkim cmocka_unit_test(test_tag), 202208625Sjkim cmocka_unit_test(test_floats), 203208625Sjkim }; 204208625Sjkim return cmocka_run_group_tests(tests, NULL, NULL); 205208625Sjkim} 206208625Sjkim