xref: /freebsd-src/contrib/libcbor/test/string_test.c (revision abd872540f24cfc7dbd1ea29b6918c7082a22108)
15d3e7166SEd Maste /*
25d3e7166SEd Maste  * Copyright (c) 2014-2020 Pavel Kalvoda <me@pavelkalvoda.com>
35d3e7166SEd Maste  *
45d3e7166SEd Maste  * libcbor is free software; you can redistribute it and/or modify
55d3e7166SEd Maste  * it under the terms of the MIT license. See LICENSE for details.
65d3e7166SEd Maste  */
75d3e7166SEd Maste 
85d3e7166SEd Maste #include <string.h>
95d3e7166SEd Maste #include "assertions.h"
105d3e7166SEd Maste #include "cbor.h"
115d3e7166SEd Maste #include "test_allocator.h"
125d3e7166SEd Maste 
135d3e7166SEd Maste cbor_item_t *string;
145d3e7166SEd Maste struct cbor_load_result res;
155d3e7166SEd Maste 
165d3e7166SEd Maste unsigned char empty_string_data[] = {0x60};
175d3e7166SEd Maste 
test_empty_string(void ** _CBOR_UNUSED (_state))185d3e7166SEd Maste static void test_empty_string(void **_CBOR_UNUSED(_state)) {
195d3e7166SEd Maste   string = cbor_load(empty_string_data, 1, &res);
205d3e7166SEd Maste   assert_non_null(string);
215d3e7166SEd Maste   assert_true(cbor_typeof(string) == CBOR_TYPE_STRING);
225d3e7166SEd Maste   assert_true(cbor_isa_string(string));
235d3e7166SEd Maste   assert_size_equal(cbor_string_length(string), 0);
245d3e7166SEd Maste   assert_size_equal(cbor_string_codepoint_count(string), 0);
255d3e7166SEd Maste   assert_true(res.read == 1);
265d3e7166SEd Maste   cbor_decref(&string);
275d3e7166SEd Maste   assert_null(string);
285d3e7166SEd Maste }
295d3e7166SEd Maste 
305d3e7166SEd Maste unsigned char short_string_data[] = {0x6C, 0x48, 0x65, 0x6C, 0x6C, 0x6F, 0x20,
315d3e7166SEd Maste                                      0x77, 0x6F, 0x72, 0x6C, 0x64, 0x21};
325d3e7166SEd Maste 
335d3e7166SEd Maste /*                              0x60 + 12 | Hello world! */
test_short_string(void ** _CBOR_UNUSED (_state))345d3e7166SEd Maste static void test_short_string(void **_CBOR_UNUSED(_state)) {
355d3e7166SEd Maste   string = cbor_load(short_string_data, 13, &res);
365d3e7166SEd Maste   assert_non_null(string);
375d3e7166SEd Maste   assert_true(cbor_typeof(string) == CBOR_TYPE_STRING);
385d3e7166SEd Maste   assert_true(cbor_isa_string(string));
395d3e7166SEd Maste   assert_size_equal(cbor_string_length(string), 12);
405d3e7166SEd Maste   assert_size_equal(cbor_string_codepoint_count(string), 12);
415d3e7166SEd Maste   assert_memory_equal(&"Hello world!", cbor_string_handle(string), 12);
425d3e7166SEd Maste   assert_true(res.read == 13);
435d3e7166SEd Maste   cbor_decref(&string);
445d3e7166SEd Maste   assert_null(string);
455d3e7166SEd Maste }
465d3e7166SEd Maste 
475d3e7166SEd Maste unsigned char short_multibyte_string_data[] = {
485d3e7166SEd Maste     0x6F, 0xC4, 0x8C, 0x61, 0x75, 0x65, 0x73, 0x20,
495d3e7166SEd Maste     0xC3, 0x9F, 0x76, 0xC4, 0x9B, 0x74, 0x65, 0x21};
505d3e7166SEd Maste 
515d3e7166SEd Maste /*                              0x60 + 15 | Čaues ßvěte! */
test_short_multibyte_string(void ** _CBOR_UNUSED (_state))525d3e7166SEd Maste static void test_short_multibyte_string(void **_CBOR_UNUSED(_state)) {
535d3e7166SEd Maste   string = cbor_load(short_multibyte_string_data, 16, &res);
545d3e7166SEd Maste   assert_non_null(string);
555d3e7166SEd Maste   assert_true(cbor_typeof(string) == CBOR_TYPE_STRING);
565d3e7166SEd Maste   assert_true(cbor_isa_string(string));
575d3e7166SEd Maste   assert_size_equal(cbor_string_length(string), 15);
585d3e7166SEd Maste   assert_size_equal(cbor_string_codepoint_count(string), 12);
595d3e7166SEd Maste   assert_memory_equal(&"Čaues ßvěte!", cbor_string_handle(string), 15);
605d3e7166SEd Maste   assert_true(res.read == 16);
615d3e7166SEd Maste   cbor_decref(&string);
625d3e7166SEd Maste   assert_null(string);
635d3e7166SEd Maste }
645d3e7166SEd Maste 
655d3e7166SEd Maste unsigned char int8_string_data[] = {
665d3e7166SEd Maste     0x78, 0x96, 0x4C, 0x6F, 0x72, 0x65, 0x6D, 0x20, 0x69, 0x70, 0x73, 0x75,
675d3e7166SEd Maste     0x6D, 0x20, 0x64, 0x6F, 0x6C, 0x6F, 0x72, 0x20, 0x73, 0x69, 0x74, 0x20,
685d3e7166SEd Maste     0x61, 0x6D, 0x65, 0x74, 0x2C, 0x20, 0x63, 0x6F, 0x6E, 0x73, 0x65, 0x63,
695d3e7166SEd Maste     0x74, 0x65, 0x74, 0x75, 0x72, 0x20, 0x61, 0x64, 0x69, 0x70, 0x69, 0x73,
705d3e7166SEd Maste     0x63, 0x69, 0x6E, 0x67, 0x20, 0x65, 0x6C, 0x69, 0x74, 0x2E, 0x20, 0x44,
715d3e7166SEd Maste     0x6F, 0x6E, 0x65, 0x63, 0x20, 0x6D, 0x69, 0x20, 0x74, 0x65, 0x6C, 0x6C,
725d3e7166SEd Maste     0x75, 0x73, 0x2C, 0x20, 0x69, 0x61, 0x63, 0x75, 0x6C, 0x69, 0x73, 0x20,
735d3e7166SEd Maste     0x6E, 0x65, 0x63, 0x20, 0x76, 0x65, 0x73, 0x74, 0x69, 0x62, 0x75, 0x6C,
745d3e7166SEd Maste     0x75, 0x6D, 0x20, 0x71, 0x75, 0x69, 0x73, 0x2C, 0x20, 0x66, 0x65, 0x72,
755d3e7166SEd Maste     0x6D, 0x65, 0x6E, 0x74, 0x75, 0x6D, 0x20, 0x6E, 0x6F, 0x6E, 0x20, 0x66,
765d3e7166SEd Maste     0x65, 0x6C, 0x69, 0x73, 0x2E, 0x20, 0x4D, 0x61, 0x65, 0x63, 0x65, 0x6E,
775d3e7166SEd Maste     0x61, 0x73, 0x20, 0x75, 0x74, 0x20, 0x6A, 0x75, 0x73, 0x74, 0x6F, 0x20,
785d3e7166SEd Maste     0x70, 0x6F, 0x73, 0x75, 0x65, 0x72, 0x65, 0x2E};
795d3e7166SEd Maste 
805d3e7166SEd Maste /*                                          150 | Lorem ....*/
test_int8_string(void ** _CBOR_UNUSED (_state))815d3e7166SEd Maste static void test_int8_string(void **_CBOR_UNUSED(_state)) {
825d3e7166SEd Maste   string = cbor_load(int8_string_data, 152, &res);
835d3e7166SEd Maste   assert_non_null(string);
845d3e7166SEd Maste   assert_true(cbor_typeof(string) == CBOR_TYPE_STRING);
855d3e7166SEd Maste   assert_true(cbor_isa_string(string));
865d3e7166SEd Maste   assert_size_equal(cbor_string_length(string), 150);
875d3e7166SEd Maste   assert_size_equal(cbor_string_codepoint_count(string), 150);
885d3e7166SEd Maste   assert_memory_equal(
895d3e7166SEd Maste 		&"Lorem ipsum dolor sit amet, consectetur adipiscing elit. Donec mi tellus, iaculis nec vestibulum quis, fermentum non felis. Maecenas ut justo posuere.",
905d3e7166SEd Maste 		cbor_string_handle(string),
915d3e7166SEd Maste 		150
925d3e7166SEd Maste 	);
935d3e7166SEd Maste   assert_true(res.read == 152);
945d3e7166SEd Maste   cbor_decref(&string);
955d3e7166SEd Maste   assert_null(string);
965d3e7166SEd Maste }
975d3e7166SEd Maste 
985d3e7166SEd Maste unsigned char int16_string_data[] = {
995d3e7166SEd Maste     0x79, 0x00, 0x96, 0x4C, 0x6F, 0x72, 0x65, 0x6D, 0x20, 0x69, 0x70, 0x73,
1005d3e7166SEd Maste     0x75, 0x6D, 0x20, 0x64, 0x6F, 0x6C, 0x6F, 0x72, 0x20, 0x73, 0x69, 0x74,
1015d3e7166SEd Maste     0x20, 0x61, 0x6D, 0x65, 0x74, 0x2C, 0x20, 0x63, 0x6F, 0x6E, 0x73, 0x65,
1025d3e7166SEd Maste     0x63, 0x74, 0x65, 0x74, 0x75, 0x72, 0x20, 0x61, 0x64, 0x69, 0x70, 0x69,
1035d3e7166SEd Maste     0x73, 0x63, 0x69, 0x6E, 0x67, 0x20, 0x65, 0x6C, 0x69, 0x74, 0x2E, 0x20,
1045d3e7166SEd Maste     0x44, 0x6F, 0x6E, 0x65, 0x63, 0x20, 0x6D, 0x69, 0x20, 0x74, 0x65, 0x6C,
1055d3e7166SEd Maste     0x6C, 0x75, 0x73, 0x2C, 0x20, 0x69, 0x61, 0x63, 0x75, 0x6C, 0x69, 0x73,
1065d3e7166SEd Maste     0x20, 0x6E, 0x65, 0x63, 0x20, 0x76, 0x65, 0x73, 0x74, 0x69, 0x62, 0x75,
1075d3e7166SEd Maste     0x6C, 0x75, 0x6D, 0x20, 0x71, 0x75, 0x69, 0x73, 0x2C, 0x20, 0x66, 0x65,
1085d3e7166SEd Maste     0x72, 0x6D, 0x65, 0x6E, 0x74, 0x75, 0x6D, 0x20, 0x6E, 0x6F, 0x6E, 0x20,
1095d3e7166SEd Maste     0x66, 0x65, 0x6C, 0x69, 0x73, 0x2E, 0x20, 0x4D, 0x61, 0x65, 0x63, 0x65,
1105d3e7166SEd Maste     0x6E, 0x61, 0x73, 0x20, 0x75, 0x74, 0x20, 0x6A, 0x75, 0x73, 0x74, 0x6F,
1115d3e7166SEd Maste     0x20, 0x70, 0x6F, 0x73, 0x75, 0x65, 0x72, 0x65, 0x2E};
1125d3e7166SEd Maste /*                                          150 | Lorem ....*/
1135d3e7166SEd Maste /* This valid but not realistic - length 150 could be encoded in a single
1145d3e7166SEd Maste  * uint8_t (but we need to keep the test files reasonably compact) */
test_int16_string(void ** _CBOR_UNUSED (_state))1155d3e7166SEd Maste static void test_int16_string(void **_CBOR_UNUSED(_state)) {
1165d3e7166SEd Maste   string = cbor_load(int16_string_data, 153, &res);
1175d3e7166SEd Maste   assert_non_null(string);
1185d3e7166SEd Maste   assert_true(cbor_typeof(string) == CBOR_TYPE_STRING);
1195d3e7166SEd Maste   assert_true(cbor_isa_string(string));
1205d3e7166SEd Maste   assert_size_equal(cbor_string_length(string), 150);
1215d3e7166SEd Maste   assert_size_equal(cbor_string_codepoint_count(string), 150);
1225d3e7166SEd Maste   assert_memory_equal(
1235d3e7166SEd Maste 		&"Lorem ipsum dolor sit amet, consectetur adipiscing elit. Donec mi tellus, iaculis nec vestibulum quis, fermentum non felis. Maecenas ut justo posuere.",
1245d3e7166SEd Maste 		cbor_string_handle(string),
1255d3e7166SEd Maste 		150
1265d3e7166SEd Maste 	);
1275d3e7166SEd Maste   assert_true(res.read == 153);
1285d3e7166SEd Maste   cbor_decref(&string);
1295d3e7166SEd Maste   assert_null(string);
1305d3e7166SEd Maste }
1315d3e7166SEd Maste 
1325d3e7166SEd Maste unsigned char int32_string_data[] = {
1335d3e7166SEd Maste     0x7A, 0x00, 0x00, 0x00, 0x96, 0x4C, 0x6F, 0x72, 0x65, 0x6D, 0x20, 0x69,
1345d3e7166SEd Maste     0x70, 0x73, 0x75, 0x6D, 0x20, 0x64, 0x6F, 0x6C, 0x6F, 0x72, 0x20, 0x73,
1355d3e7166SEd Maste     0x69, 0x74, 0x20, 0x61, 0x6D, 0x65, 0x74, 0x2C, 0x20, 0x63, 0x6F, 0x6E,
1365d3e7166SEd Maste     0x73, 0x65, 0x63, 0x74, 0x65, 0x74, 0x75, 0x72, 0x20, 0x61, 0x64, 0x69,
1375d3e7166SEd Maste     0x70, 0x69, 0x73, 0x63, 0x69, 0x6E, 0x67, 0x20, 0x65, 0x6C, 0x69, 0x74,
1385d3e7166SEd Maste     0x2E, 0x20, 0x44, 0x6F, 0x6E, 0x65, 0x63, 0x20, 0x6D, 0x69, 0x20, 0x74,
1395d3e7166SEd Maste     0x65, 0x6C, 0x6C, 0x75, 0x73, 0x2C, 0x20, 0x69, 0x61, 0x63, 0x75, 0x6C,
1405d3e7166SEd Maste     0x69, 0x73, 0x20, 0x6E, 0x65, 0x63, 0x20, 0x76, 0x65, 0x73, 0x74, 0x69,
1415d3e7166SEd Maste     0x62, 0x75, 0x6C, 0x75, 0x6D, 0x20, 0x71, 0x75, 0x69, 0x73, 0x2C, 0x20,
1425d3e7166SEd Maste     0x66, 0x65, 0x72, 0x6D, 0x65, 0x6E, 0x74, 0x75, 0x6D, 0x20, 0x6E, 0x6F,
1435d3e7166SEd Maste     0x6E, 0x20, 0x66, 0x65, 0x6C, 0x69, 0x73, 0x2E, 0x20, 0x4D, 0x61, 0x65,
1445d3e7166SEd Maste     0x63, 0x65, 0x6E, 0x61, 0x73, 0x20, 0x75, 0x74, 0x20, 0x6A, 0x75, 0x73,
1455d3e7166SEd Maste     0x74, 0x6F, 0x20, 0x70, 0x6F, 0x73, 0x75, 0x65, 0x72, 0x65, 0x2E};
1465d3e7166SEd Maste 
1475d3e7166SEd Maste /*                                          150 | Lorem ....*/
test_int32_string(void ** _CBOR_UNUSED (_state))1485d3e7166SEd Maste static void test_int32_string(void **_CBOR_UNUSED(_state)) {
1495d3e7166SEd Maste   string = cbor_load(int32_string_data, 155, &res);
1505d3e7166SEd Maste   assert_non_null(string);
1515d3e7166SEd Maste   assert_true(cbor_typeof(string) == CBOR_TYPE_STRING);
1525d3e7166SEd Maste   assert_true(cbor_isa_string(string));
1535d3e7166SEd Maste   assert_size_equal(cbor_string_length(string), 150);
1545d3e7166SEd Maste   assert_size_equal(cbor_string_codepoint_count(string), 150);
1555d3e7166SEd Maste   assert_memory_equal(
1565d3e7166SEd Maste 		&"Lorem ipsum dolor sit amet, consectetur adipiscing elit. Donec mi tellus, iaculis nec vestibulum quis, fermentum non felis. Maecenas ut justo posuere.",
1575d3e7166SEd Maste 		cbor_string_handle(string),
1585d3e7166SEd Maste 		150
1595d3e7166SEd Maste 	);
1605d3e7166SEd Maste   assert_true(res.read == 155);
1615d3e7166SEd Maste   cbor_decref(&string);
1625d3e7166SEd Maste   assert_null(string);
1635d3e7166SEd Maste }
1645d3e7166SEd Maste 
1655d3e7166SEd Maste unsigned char int64_string_data[] = {
1665d3e7166SEd Maste     0x7B, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x96, 0x4C, 0x6F, 0x72,
1675d3e7166SEd Maste     0x65, 0x6D, 0x20, 0x69, 0x70, 0x73, 0x75, 0x6D, 0x20, 0x64, 0x6F, 0x6C,
1685d3e7166SEd Maste     0x6F, 0x72, 0x20, 0x73, 0x69, 0x74, 0x20, 0x61, 0x6D, 0x65, 0x74, 0x2C,
1695d3e7166SEd Maste     0x20, 0x63, 0x6F, 0x6E, 0x73, 0x65, 0x63, 0x74, 0x65, 0x74, 0x75, 0x72,
1705d3e7166SEd Maste     0x20, 0x61, 0x64, 0x69, 0x70, 0x69, 0x73, 0x63, 0x69, 0x6E, 0x67, 0x20,
1715d3e7166SEd Maste     0x65, 0x6C, 0x69, 0x74, 0x2E, 0x20, 0x44, 0x6F, 0x6E, 0x65, 0x63, 0x20,
1725d3e7166SEd Maste     0x6D, 0x69, 0x20, 0x74, 0x65, 0x6C, 0x6C, 0x75, 0x73, 0x2C, 0x20, 0x69,
1735d3e7166SEd Maste     0x61, 0x63, 0x75, 0x6C, 0x69, 0x73, 0x20, 0x6E, 0x65, 0x63, 0x20, 0x76,
1745d3e7166SEd Maste     0x65, 0x73, 0x74, 0x69, 0x62, 0x75, 0x6C, 0x75, 0x6D, 0x20, 0x71, 0x75,
1755d3e7166SEd Maste     0x69, 0x73, 0x2C, 0x20, 0x66, 0x65, 0x72, 0x6D, 0x65, 0x6E, 0x74, 0x75,
1765d3e7166SEd Maste     0x6D, 0x20, 0x6E, 0x6F, 0x6E, 0x20, 0x66, 0x65, 0x6C, 0x69, 0x73, 0x2E,
1775d3e7166SEd Maste     0x20, 0x4D, 0x61, 0x65, 0x63, 0x65, 0x6E, 0x61, 0x73, 0x20, 0x75, 0x74,
1785d3e7166SEd Maste     0x20, 0x6A, 0x75, 0x73, 0x74, 0x6F, 0x20, 0x70, 0x6F, 0x73, 0x75, 0x65,
1795d3e7166SEd Maste     0x72, 0x65, 0x2E};
1805d3e7166SEd Maste 
1815d3e7166SEd Maste /*                                          150 | Lorem ....*/
test_int64_string(void ** _CBOR_UNUSED (_state))1825d3e7166SEd Maste static void test_int64_string(void **_CBOR_UNUSED(_state)) {
1835d3e7166SEd Maste   string = cbor_load(int64_string_data, 159, &res);
1845d3e7166SEd Maste   assert_non_null(string);
1855d3e7166SEd Maste   assert_true(cbor_typeof(string) == CBOR_TYPE_STRING);
1865d3e7166SEd Maste   assert_true(cbor_isa_string(string));
1875d3e7166SEd Maste   assert_size_equal(cbor_string_length(string), 150);
1885d3e7166SEd Maste   assert_size_equal(cbor_string_codepoint_count(string), 150);
1895d3e7166SEd Maste   assert_memory_equal(
1905d3e7166SEd Maste 		&"Lorem ipsum dolor sit amet, consectetur adipiscing elit. Donec mi tellus, iaculis nec vestibulum quis, fermentum non felis. Maecenas ut justo posuere.",
1915d3e7166SEd Maste 		cbor_string_handle(string),
1925d3e7166SEd Maste 		150
1935d3e7166SEd Maste 	);
1945d3e7166SEd Maste   assert_true(res.read == 159);
1955d3e7166SEd Maste   cbor_decref(&string);
1965d3e7166SEd Maste   assert_null(string);
1975d3e7166SEd Maste }
1985d3e7166SEd Maste 
1995d3e7166SEd Maste unsigned char short_indef_string_data[] = {0x7F, 0x78, 0x01, 0x65, 0xFF, 0xFF};
2005d3e7166SEd Maste 
2015d3e7166SEd Maste /*                                         start |   string      | break| extra
2025d3e7166SEd Maste  */
2035d3e7166SEd Maste 
test_short_indef_string(void ** _CBOR_UNUSED (_state))2045d3e7166SEd Maste static void test_short_indef_string(void **_CBOR_UNUSED(_state)) {
2055d3e7166SEd Maste   string = cbor_load(short_indef_string_data, 6, &res);
2065d3e7166SEd Maste   assert_non_null(string);
2075d3e7166SEd Maste   assert_true(cbor_typeof(string) == CBOR_TYPE_STRING);
2085d3e7166SEd Maste   assert_true(cbor_isa_string(string));
2095d3e7166SEd Maste   assert_true(cbor_string_length(string) == 0);
2105d3e7166SEd Maste   assert_true(cbor_string_is_indefinite(string));
2115d3e7166SEd Maste   assert_true(cbor_string_chunk_count(string) == 1);
2125d3e7166SEd Maste   assert_true(res.read == 5);
2135d3e7166SEd Maste   assert_true(cbor_isa_string(cbor_string_chunks_handle(string)[0]));
2145d3e7166SEd Maste   assert_true(cbor_string_length(cbor_string_chunks_handle(string)[0]) == 1);
2155d3e7166SEd Maste   assert_true(*cbor_string_handle(cbor_string_chunks_handle(string)[0]) == 'e');
2165d3e7166SEd Maste   cbor_decref(&string);
2175d3e7166SEd Maste   assert_null(string);
2185d3e7166SEd Maste }
2195d3e7166SEd Maste 
test_invalid_utf(void ** _CBOR_UNUSED (_state))220*abd87254SEd Maste static void test_invalid_utf(void **_CBOR_UNUSED(_state)) {
221*abd87254SEd Maste   /* 0x60 + 1 | 0xC5 (invalid unfinished 2B codepoint) */
222*abd87254SEd Maste   unsigned char string_data[] = {0x61, 0xC5};
223*abd87254SEd Maste   string = cbor_load(string_data, 2, &res);
224*abd87254SEd Maste 
225*abd87254SEd Maste   assert_non_null(string);
226*abd87254SEd Maste   assert_true(cbor_typeof(string) == CBOR_TYPE_STRING);
227*abd87254SEd Maste   assert_true(cbor_isa_string(string));
228*abd87254SEd Maste   assert_size_equal(cbor_string_length(string), 1);
229*abd87254SEd Maste   assert_size_equal(cbor_string_codepoint_count(string), 0);
230*abd87254SEd Maste   assert_true(cbor_string_is_definite(string));
231*abd87254SEd Maste   assert_true(res.read == 2);
232*abd87254SEd Maste 
233*abd87254SEd Maste   cbor_decref(&string);
234*abd87254SEd Maste }
235*abd87254SEd Maste 
test_inline_creation(void ** _CBOR_UNUSED (_state))2365d3e7166SEd Maste static void test_inline_creation(void **_CBOR_UNUSED(_state)) {
2375d3e7166SEd Maste   string = cbor_build_string("Hello!");
2385d3e7166SEd Maste   assert_memory_equal(cbor_string_handle(string), "Hello!", strlen("Hello!"));
2395d3e7166SEd Maste   cbor_decref(&string);
2405d3e7166SEd Maste }
2415d3e7166SEd Maste 
test_string_creation(void ** _CBOR_UNUSED (_state))2425d3e7166SEd Maste static void test_string_creation(void **_CBOR_UNUSED(_state)) {
2435d3e7166SEd Maste   WITH_FAILING_MALLOC({ assert_null(cbor_new_definite_string()); });
2445d3e7166SEd Maste 
2455d3e7166SEd Maste   WITH_FAILING_MALLOC({ assert_null(cbor_new_indefinite_string()); });
2465d3e7166SEd Maste   WITH_MOCK_MALLOC({ assert_null(cbor_new_indefinite_string()); }, 2, MALLOC,
2475d3e7166SEd Maste                    MALLOC_FAIL);
2485d3e7166SEd Maste 
2495d3e7166SEd Maste   WITH_FAILING_MALLOC({ assert_null(cbor_build_string("Test")); });
2505d3e7166SEd Maste   WITH_MOCK_MALLOC({ assert_null(cbor_build_string("Test")); }, 2, MALLOC,
2515d3e7166SEd Maste                    MALLOC_FAIL);
2525d3e7166SEd Maste 
2535d3e7166SEd Maste   WITH_FAILING_MALLOC({ assert_null(cbor_build_stringn("Test", 4)); });
2545d3e7166SEd Maste   WITH_MOCK_MALLOC({ assert_null(cbor_build_stringn("Test", 4)); }, 2, MALLOC,
2555d3e7166SEd Maste                    MALLOC_FAIL);
2565d3e7166SEd Maste }
2575d3e7166SEd Maste 
test_string_add_chunk(void ** _CBOR_UNUSED (_state))2585d3e7166SEd Maste static void test_string_add_chunk(void **_CBOR_UNUSED(_state)) {
2595d3e7166SEd Maste   WITH_MOCK_MALLOC(
2605d3e7166SEd Maste       {
2615d3e7166SEd Maste         cbor_item_t *string = cbor_new_indefinite_string();
2625d3e7166SEd Maste         cbor_item_t *chunk = cbor_build_string("Hello!");
2635d3e7166SEd Maste 
2645d3e7166SEd Maste         assert_false(cbor_string_add_chunk(string, chunk));
2655d3e7166SEd Maste         assert_size_equal(cbor_string_chunk_count(string), 0);
2665d3e7166SEd Maste         assert_size_equal(((struct cbor_indefinite_string_data *)string->data)
2675d3e7166SEd Maste                               ->chunk_capacity,
2685d3e7166SEd Maste                           0);
2695d3e7166SEd Maste 
2705d3e7166SEd Maste         cbor_decref(&chunk);
2715d3e7166SEd Maste         cbor_decref(&string);
2725d3e7166SEd Maste       },
2735d3e7166SEd Maste       5, MALLOC, MALLOC, MALLOC, MALLOC, REALLOC_FAIL);
2745d3e7166SEd Maste }
2755d3e7166SEd Maste 
test_add_chunk_reallocation_overflow(void ** _CBOR_UNUSED (_state))2765d3e7166SEd Maste static void test_add_chunk_reallocation_overflow(void **_CBOR_UNUSED(_state)) {
2775d3e7166SEd Maste   string = cbor_new_indefinite_string();
2785d3e7166SEd Maste   cbor_item_t *chunk = cbor_build_string("Hello!");
2795d3e7166SEd Maste   struct cbor_indefinite_string_data *metadata =
2805d3e7166SEd Maste       (struct cbor_indefinite_string_data *)string->data;
2815d3e7166SEd Maste   // Pretend we already have many chunks allocated
2825d3e7166SEd Maste   metadata->chunk_count = SIZE_MAX;
2835d3e7166SEd Maste   metadata->chunk_capacity = SIZE_MAX;
2845d3e7166SEd Maste 
2855d3e7166SEd Maste   assert_false(cbor_string_add_chunk(string, chunk));
2865d3e7166SEd Maste   assert_size_equal(cbor_refcount(chunk), 1);
2875d3e7166SEd Maste 
2885d3e7166SEd Maste   metadata->chunk_count = 0;
2895d3e7166SEd Maste   metadata->chunk_capacity = 0;
2905d3e7166SEd Maste   cbor_decref(&chunk);
2915d3e7166SEd Maste   cbor_decref(&string);
2925d3e7166SEd Maste }
2935d3e7166SEd Maste 
test_set_handle(void ** _CBOR_UNUSED (_state))294*abd87254SEd Maste static void test_set_handle(void **_CBOR_UNUSED(_state)) {
295*abd87254SEd Maste   string = cbor_new_definite_string();
296*abd87254SEd Maste   char *test_string = "Hello";
297*abd87254SEd Maste   unsigned char *string_data = malloc(strlen(test_string));
298*abd87254SEd Maste   memcpy(string_data, test_string, strlen(test_string));
299*abd87254SEd Maste   assert_ptr_not_equal(string_data, NULL);
300*abd87254SEd Maste   cbor_string_set_handle(string, string_data, strlen(test_string));
301*abd87254SEd Maste 
302*abd87254SEd Maste   assert_ptr_equal(cbor_string_handle(string), string_data);
303*abd87254SEd Maste   assert_size_equal(cbor_string_length(string), 5);
304*abd87254SEd Maste   assert_size_equal(cbor_string_codepoint_count(string), 5);
305*abd87254SEd Maste 
306*abd87254SEd Maste   cbor_decref(&string);
307*abd87254SEd Maste }
308*abd87254SEd Maste 
test_set_handle_multibyte_codepoint(void ** _CBOR_UNUSED (_state))309*abd87254SEd Maste static void test_set_handle_multibyte_codepoint(void **_CBOR_UNUSED(_state)) {
310*abd87254SEd Maste   string = cbor_new_definite_string();
311*abd87254SEd Maste   // "Štěstíčko" in UTF-8
312*abd87254SEd Maste   char *test_string = "\xc5\xa0t\xc4\x9bst\xc3\xad\xc4\x8dko";
313*abd87254SEd Maste   unsigned char *string_data = malloc(strlen(test_string));
314*abd87254SEd Maste   memcpy(string_data, test_string, strlen(test_string));
315*abd87254SEd Maste   assert_ptr_not_equal(string_data, NULL);
316*abd87254SEd Maste   cbor_string_set_handle(string, string_data, strlen(test_string));
317*abd87254SEd Maste 
318*abd87254SEd Maste   assert_ptr_equal(cbor_string_handle(string), string_data);
319*abd87254SEd Maste   assert_size_equal(cbor_string_length(string), 13);
320*abd87254SEd Maste   assert_size_equal(cbor_string_codepoint_count(string), 9);
321*abd87254SEd Maste 
322*abd87254SEd Maste   cbor_decref(&string);
323*abd87254SEd Maste }
324*abd87254SEd Maste 
test_set_handle_invalid_utf(void ** _CBOR_UNUSED (_state))325*abd87254SEd Maste static void test_set_handle_invalid_utf(void **_CBOR_UNUSED(_state)) {
326*abd87254SEd Maste   string = cbor_new_definite_string();
327*abd87254SEd Maste   // Invalid multi-byte character (missing the second byte).
328*abd87254SEd Maste   char *test_string = "Test: \xc5";
329*abd87254SEd Maste   unsigned char *string_data = malloc(strlen(test_string));
330*abd87254SEd Maste   memcpy(string_data, test_string, strlen(test_string));
331*abd87254SEd Maste   assert_ptr_not_equal(string_data, NULL);
332*abd87254SEd Maste   cbor_string_set_handle(string, string_data, strlen(test_string));
333*abd87254SEd Maste 
334*abd87254SEd Maste   assert_ptr_equal(cbor_string_handle(string), string_data);
335*abd87254SEd Maste   assert_size_equal(cbor_string_length(string), 7);
336*abd87254SEd Maste   assert_size_equal(cbor_string_codepoint_count(string), 0);
337*abd87254SEd Maste 
338*abd87254SEd Maste   cbor_decref(&string);
339*abd87254SEd Maste }
340*abd87254SEd Maste 
main(void)3415d3e7166SEd Maste int main(void) {
3425d3e7166SEd Maste   const struct CMUnitTest tests[] = {
3435d3e7166SEd Maste       cmocka_unit_test(test_empty_string),
3445d3e7166SEd Maste       cmocka_unit_test(test_short_string),
3455d3e7166SEd Maste       cmocka_unit_test(test_short_multibyte_string),
3465d3e7166SEd Maste       cmocka_unit_test(test_int8_string),
3475d3e7166SEd Maste       cmocka_unit_test(test_int16_string),
3485d3e7166SEd Maste       cmocka_unit_test(test_int32_string),
3495d3e7166SEd Maste       cmocka_unit_test(test_int64_string),
3505d3e7166SEd Maste       cmocka_unit_test(test_short_indef_string),
351*abd87254SEd Maste       cmocka_unit_test(test_invalid_utf),
3525d3e7166SEd Maste       cmocka_unit_test(test_inline_creation),
3535d3e7166SEd Maste       cmocka_unit_test(test_string_creation),
3545d3e7166SEd Maste       cmocka_unit_test(test_string_add_chunk),
3555d3e7166SEd Maste       cmocka_unit_test(test_add_chunk_reallocation_overflow),
356*abd87254SEd Maste       cmocka_unit_test(test_set_handle),
357*abd87254SEd Maste       cmocka_unit_test(test_set_handle_multibyte_codepoint),
358*abd87254SEd Maste       cmocka_unit_test(test_set_handle_invalid_utf),
3595d3e7166SEd Maste   };
3605d3e7166SEd Maste   return cmocka_run_group_tests(tests, NULL, NULL);
3615d3e7166SEd Maste }
362