Path: blob/main/contrib/libcbor/test/string_test.c
39507 views
/*1* Copyright (c) 2014-2020 Pavel Kalvoda <[email protected]>2*3* libcbor is free software; you can redistribute it and/or modify4* it under the terms of the MIT license. See LICENSE for details.5*/67#include <string.h>8#include "assertions.h"9#include "cbor.h"10#include "test_allocator.h"1112cbor_item_t *string;13struct cbor_load_result res;1415unsigned char empty_string_data[] = {0x60};1617static void test_empty_string(void **_CBOR_UNUSED(_state)) {18string = cbor_load(empty_string_data, 1, &res);19assert_non_null(string);20assert_true(cbor_typeof(string) == CBOR_TYPE_STRING);21assert_true(cbor_isa_string(string));22assert_size_equal(cbor_string_length(string), 0);23assert_size_equal(cbor_string_codepoint_count(string), 0);24assert_true(res.read == 1);25cbor_decref(&string);26assert_null(string);27}2829unsigned char short_string_data[] = {0x6C, 0x48, 0x65, 0x6C, 0x6C, 0x6F, 0x20,300x77, 0x6F, 0x72, 0x6C, 0x64, 0x21};3132/* 0x60 + 12 | Hello world! */33static void test_short_string(void **_CBOR_UNUSED(_state)) {34string = cbor_load(short_string_data, 13, &res);35assert_non_null(string);36assert_true(cbor_typeof(string) == CBOR_TYPE_STRING);37assert_true(cbor_isa_string(string));38assert_size_equal(cbor_string_length(string), 12);39assert_size_equal(cbor_string_codepoint_count(string), 12);40assert_memory_equal(&"Hello world!", cbor_string_handle(string), 12);41assert_true(res.read == 13);42cbor_decref(&string);43assert_null(string);44}4546unsigned char short_multibyte_string_data[] = {470x6F, 0xC4, 0x8C, 0x61, 0x75, 0x65, 0x73, 0x20,480xC3, 0x9F, 0x76, 0xC4, 0x9B, 0x74, 0x65, 0x21};4950/* 0x60 + 15 | Čaues ßvěte! */51static void test_short_multibyte_string(void **_CBOR_UNUSED(_state)) {52string = cbor_load(short_multibyte_string_data, 16, &res);53assert_non_null(string);54assert_true(cbor_typeof(string) == CBOR_TYPE_STRING);55assert_true(cbor_isa_string(string));56assert_size_equal(cbor_string_length(string), 15);57assert_size_equal(cbor_string_codepoint_count(string), 12);58assert_memory_equal(&"Čaues ßvěte!", cbor_string_handle(string), 15);59assert_true(res.read == 16);60cbor_decref(&string);61assert_null(string);62}6364unsigned char int8_string_data[] = {650x78, 0x96, 0x4C, 0x6F, 0x72, 0x65, 0x6D, 0x20, 0x69, 0x70, 0x73, 0x75,660x6D, 0x20, 0x64, 0x6F, 0x6C, 0x6F, 0x72, 0x20, 0x73, 0x69, 0x74, 0x20,670x61, 0x6D, 0x65, 0x74, 0x2C, 0x20, 0x63, 0x6F, 0x6E, 0x73, 0x65, 0x63,680x74, 0x65, 0x74, 0x75, 0x72, 0x20, 0x61, 0x64, 0x69, 0x70, 0x69, 0x73,690x63, 0x69, 0x6E, 0x67, 0x20, 0x65, 0x6C, 0x69, 0x74, 0x2E, 0x20, 0x44,700x6F, 0x6E, 0x65, 0x63, 0x20, 0x6D, 0x69, 0x20, 0x74, 0x65, 0x6C, 0x6C,710x75, 0x73, 0x2C, 0x20, 0x69, 0x61, 0x63, 0x75, 0x6C, 0x69, 0x73, 0x20,720x6E, 0x65, 0x63, 0x20, 0x76, 0x65, 0x73, 0x74, 0x69, 0x62, 0x75, 0x6C,730x75, 0x6D, 0x20, 0x71, 0x75, 0x69, 0x73, 0x2C, 0x20, 0x66, 0x65, 0x72,740x6D, 0x65, 0x6E, 0x74, 0x75, 0x6D, 0x20, 0x6E, 0x6F, 0x6E, 0x20, 0x66,750x65, 0x6C, 0x69, 0x73, 0x2E, 0x20, 0x4D, 0x61, 0x65, 0x63, 0x65, 0x6E,760x61, 0x73, 0x20, 0x75, 0x74, 0x20, 0x6A, 0x75, 0x73, 0x74, 0x6F, 0x20,770x70, 0x6F, 0x73, 0x75, 0x65, 0x72, 0x65, 0x2E};7879/* 150 | Lorem ....*/80static void test_int8_string(void **_CBOR_UNUSED(_state)) {81string = cbor_load(int8_string_data, 152, &res);82assert_non_null(string);83assert_true(cbor_typeof(string) == CBOR_TYPE_STRING);84assert_true(cbor_isa_string(string));85assert_size_equal(cbor_string_length(string), 150);86assert_size_equal(cbor_string_codepoint_count(string), 150);87assert_memory_equal(88&"Lorem ipsum dolor sit amet, consectetur adipiscing elit. Donec mi tellus, iaculis nec vestibulum quis, fermentum non felis. Maecenas ut justo posuere.",89cbor_string_handle(string),9015091);92assert_true(res.read == 152);93cbor_decref(&string);94assert_null(string);95}9697unsigned char int16_string_data[] = {980x79, 0x00, 0x96, 0x4C, 0x6F, 0x72, 0x65, 0x6D, 0x20, 0x69, 0x70, 0x73,990x75, 0x6D, 0x20, 0x64, 0x6F, 0x6C, 0x6F, 0x72, 0x20, 0x73, 0x69, 0x74,1000x20, 0x61, 0x6D, 0x65, 0x74, 0x2C, 0x20, 0x63, 0x6F, 0x6E, 0x73, 0x65,1010x63, 0x74, 0x65, 0x74, 0x75, 0x72, 0x20, 0x61, 0x64, 0x69, 0x70, 0x69,1020x73, 0x63, 0x69, 0x6E, 0x67, 0x20, 0x65, 0x6C, 0x69, 0x74, 0x2E, 0x20,1030x44, 0x6F, 0x6E, 0x65, 0x63, 0x20, 0x6D, 0x69, 0x20, 0x74, 0x65, 0x6C,1040x6C, 0x75, 0x73, 0x2C, 0x20, 0x69, 0x61, 0x63, 0x75, 0x6C, 0x69, 0x73,1050x20, 0x6E, 0x65, 0x63, 0x20, 0x76, 0x65, 0x73, 0x74, 0x69, 0x62, 0x75,1060x6C, 0x75, 0x6D, 0x20, 0x71, 0x75, 0x69, 0x73, 0x2C, 0x20, 0x66, 0x65,1070x72, 0x6D, 0x65, 0x6E, 0x74, 0x75, 0x6D, 0x20, 0x6E, 0x6F, 0x6E, 0x20,1080x66, 0x65, 0x6C, 0x69, 0x73, 0x2E, 0x20, 0x4D, 0x61, 0x65, 0x63, 0x65,1090x6E, 0x61, 0x73, 0x20, 0x75, 0x74, 0x20, 0x6A, 0x75, 0x73, 0x74, 0x6F,1100x20, 0x70, 0x6F, 0x73, 0x75, 0x65, 0x72, 0x65, 0x2E};111/* 150 | Lorem ....*/112/* This valid but not realistic - length 150 could be encoded in a single113* uint8_t (but we need to keep the test files reasonably compact) */114static void test_int16_string(void **_CBOR_UNUSED(_state)) {115string = cbor_load(int16_string_data, 153, &res);116assert_non_null(string);117assert_true(cbor_typeof(string) == CBOR_TYPE_STRING);118assert_true(cbor_isa_string(string));119assert_size_equal(cbor_string_length(string), 150);120assert_size_equal(cbor_string_codepoint_count(string), 150);121assert_memory_equal(122&"Lorem ipsum dolor sit amet, consectetur adipiscing elit. Donec mi tellus, iaculis nec vestibulum quis, fermentum non felis. Maecenas ut justo posuere.",123cbor_string_handle(string),124150125);126assert_true(res.read == 153);127cbor_decref(&string);128assert_null(string);129}130131unsigned char int32_string_data[] = {1320x7A, 0x00, 0x00, 0x00, 0x96, 0x4C, 0x6F, 0x72, 0x65, 0x6D, 0x20, 0x69,1330x70, 0x73, 0x75, 0x6D, 0x20, 0x64, 0x6F, 0x6C, 0x6F, 0x72, 0x20, 0x73,1340x69, 0x74, 0x20, 0x61, 0x6D, 0x65, 0x74, 0x2C, 0x20, 0x63, 0x6F, 0x6E,1350x73, 0x65, 0x63, 0x74, 0x65, 0x74, 0x75, 0x72, 0x20, 0x61, 0x64, 0x69,1360x70, 0x69, 0x73, 0x63, 0x69, 0x6E, 0x67, 0x20, 0x65, 0x6C, 0x69, 0x74,1370x2E, 0x20, 0x44, 0x6F, 0x6E, 0x65, 0x63, 0x20, 0x6D, 0x69, 0x20, 0x74,1380x65, 0x6C, 0x6C, 0x75, 0x73, 0x2C, 0x20, 0x69, 0x61, 0x63, 0x75, 0x6C,1390x69, 0x73, 0x20, 0x6E, 0x65, 0x63, 0x20, 0x76, 0x65, 0x73, 0x74, 0x69,1400x62, 0x75, 0x6C, 0x75, 0x6D, 0x20, 0x71, 0x75, 0x69, 0x73, 0x2C, 0x20,1410x66, 0x65, 0x72, 0x6D, 0x65, 0x6E, 0x74, 0x75, 0x6D, 0x20, 0x6E, 0x6F,1420x6E, 0x20, 0x66, 0x65, 0x6C, 0x69, 0x73, 0x2E, 0x20, 0x4D, 0x61, 0x65,1430x63, 0x65, 0x6E, 0x61, 0x73, 0x20, 0x75, 0x74, 0x20, 0x6A, 0x75, 0x73,1440x74, 0x6F, 0x20, 0x70, 0x6F, 0x73, 0x75, 0x65, 0x72, 0x65, 0x2E};145146/* 150 | Lorem ....*/147static void test_int32_string(void **_CBOR_UNUSED(_state)) {148string = cbor_load(int32_string_data, 155, &res);149assert_non_null(string);150assert_true(cbor_typeof(string) == CBOR_TYPE_STRING);151assert_true(cbor_isa_string(string));152assert_size_equal(cbor_string_length(string), 150);153assert_size_equal(cbor_string_codepoint_count(string), 150);154assert_memory_equal(155&"Lorem ipsum dolor sit amet, consectetur adipiscing elit. Donec mi tellus, iaculis nec vestibulum quis, fermentum non felis. Maecenas ut justo posuere.",156cbor_string_handle(string),157150158);159assert_true(res.read == 155);160cbor_decref(&string);161assert_null(string);162}163164unsigned char int64_string_data[] = {1650x7B, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x96, 0x4C, 0x6F, 0x72,1660x65, 0x6D, 0x20, 0x69, 0x70, 0x73, 0x75, 0x6D, 0x20, 0x64, 0x6F, 0x6C,1670x6F, 0x72, 0x20, 0x73, 0x69, 0x74, 0x20, 0x61, 0x6D, 0x65, 0x74, 0x2C,1680x20, 0x63, 0x6F, 0x6E, 0x73, 0x65, 0x63, 0x74, 0x65, 0x74, 0x75, 0x72,1690x20, 0x61, 0x64, 0x69, 0x70, 0x69, 0x73, 0x63, 0x69, 0x6E, 0x67, 0x20,1700x65, 0x6C, 0x69, 0x74, 0x2E, 0x20, 0x44, 0x6F, 0x6E, 0x65, 0x63, 0x20,1710x6D, 0x69, 0x20, 0x74, 0x65, 0x6C, 0x6C, 0x75, 0x73, 0x2C, 0x20, 0x69,1720x61, 0x63, 0x75, 0x6C, 0x69, 0x73, 0x20, 0x6E, 0x65, 0x63, 0x20, 0x76,1730x65, 0x73, 0x74, 0x69, 0x62, 0x75, 0x6C, 0x75, 0x6D, 0x20, 0x71, 0x75,1740x69, 0x73, 0x2C, 0x20, 0x66, 0x65, 0x72, 0x6D, 0x65, 0x6E, 0x74, 0x75,1750x6D, 0x20, 0x6E, 0x6F, 0x6E, 0x20, 0x66, 0x65, 0x6C, 0x69, 0x73, 0x2E,1760x20, 0x4D, 0x61, 0x65, 0x63, 0x65, 0x6E, 0x61, 0x73, 0x20, 0x75, 0x74,1770x20, 0x6A, 0x75, 0x73, 0x74, 0x6F, 0x20, 0x70, 0x6F, 0x73, 0x75, 0x65,1780x72, 0x65, 0x2E};179180/* 150 | Lorem ....*/181static void test_int64_string(void **_CBOR_UNUSED(_state)) {182string = cbor_load(int64_string_data, 159, &res);183assert_non_null(string);184assert_true(cbor_typeof(string) == CBOR_TYPE_STRING);185assert_true(cbor_isa_string(string));186assert_size_equal(cbor_string_length(string), 150);187assert_size_equal(cbor_string_codepoint_count(string), 150);188assert_memory_equal(189&"Lorem ipsum dolor sit amet, consectetur adipiscing elit. Donec mi tellus, iaculis nec vestibulum quis, fermentum non felis. Maecenas ut justo posuere.",190cbor_string_handle(string),191150192);193assert_true(res.read == 159);194cbor_decref(&string);195assert_null(string);196}197198unsigned char short_indef_string_data[] = {0x7F, 0x78, 0x01, 0x65, 0xFF, 0xFF};199200/* start | string | break| extra201*/202203static void test_short_indef_string(void **_CBOR_UNUSED(_state)) {204string = cbor_load(short_indef_string_data, 6, &res);205assert_non_null(string);206assert_true(cbor_typeof(string) == CBOR_TYPE_STRING);207assert_true(cbor_isa_string(string));208assert_true(cbor_string_length(string) == 0);209assert_true(cbor_string_is_indefinite(string));210assert_true(cbor_string_chunk_count(string) == 1);211assert_true(res.read == 5);212assert_true(cbor_isa_string(cbor_string_chunks_handle(string)[0]));213assert_true(cbor_string_length(cbor_string_chunks_handle(string)[0]) == 1);214assert_true(*cbor_string_handle(cbor_string_chunks_handle(string)[0]) == 'e');215cbor_decref(&string);216assert_null(string);217}218219static void test_invalid_utf(void **_CBOR_UNUSED(_state)) {220/* 0x60 + 1 | 0xC5 (invalid unfinished 2B codepoint) */221unsigned char string_data[] = {0x61, 0xC5};222string = cbor_load(string_data, 2, &res);223224assert_non_null(string);225assert_true(cbor_typeof(string) == CBOR_TYPE_STRING);226assert_true(cbor_isa_string(string));227assert_size_equal(cbor_string_length(string), 1);228assert_size_equal(cbor_string_codepoint_count(string), 0);229assert_true(cbor_string_is_definite(string));230assert_true(res.read == 2);231232cbor_decref(&string);233}234235static void test_inline_creation(void **_CBOR_UNUSED(_state)) {236string = cbor_build_string("Hello!");237assert_memory_equal(cbor_string_handle(string), "Hello!", strlen("Hello!"));238cbor_decref(&string);239}240241static void test_string_creation(void **_CBOR_UNUSED(_state)) {242WITH_FAILING_MALLOC({ assert_null(cbor_new_definite_string()); });243244WITH_FAILING_MALLOC({ assert_null(cbor_new_indefinite_string()); });245WITH_MOCK_MALLOC({ assert_null(cbor_new_indefinite_string()); }, 2, MALLOC,246MALLOC_FAIL);247248WITH_FAILING_MALLOC({ assert_null(cbor_build_string("Test")); });249WITH_MOCK_MALLOC({ assert_null(cbor_build_string("Test")); }, 2, MALLOC,250MALLOC_FAIL);251252WITH_FAILING_MALLOC({ assert_null(cbor_build_stringn("Test", 4)); });253WITH_MOCK_MALLOC({ assert_null(cbor_build_stringn("Test", 4)); }, 2, MALLOC,254MALLOC_FAIL);255}256257static void test_string_add_chunk(void **_CBOR_UNUSED(_state)) {258WITH_MOCK_MALLOC(259{260cbor_item_t *string = cbor_new_indefinite_string();261cbor_item_t *chunk = cbor_build_string("Hello!");262263assert_false(cbor_string_add_chunk(string, chunk));264assert_size_equal(cbor_string_chunk_count(string), 0);265assert_size_equal(((struct cbor_indefinite_string_data *)string->data)266->chunk_capacity,2670);268269cbor_decref(&chunk);270cbor_decref(&string);271},2725, MALLOC, MALLOC, MALLOC, MALLOC, REALLOC_FAIL);273}274275static void test_add_chunk_reallocation_overflow(void **_CBOR_UNUSED(_state)) {276string = cbor_new_indefinite_string();277cbor_item_t *chunk = cbor_build_string("Hello!");278struct cbor_indefinite_string_data *metadata =279(struct cbor_indefinite_string_data *)string->data;280// Pretend we already have many chunks allocated281metadata->chunk_count = SIZE_MAX;282metadata->chunk_capacity = SIZE_MAX;283284assert_false(cbor_string_add_chunk(string, chunk));285assert_size_equal(cbor_refcount(chunk), 1);286287metadata->chunk_count = 0;288metadata->chunk_capacity = 0;289cbor_decref(&chunk);290cbor_decref(&string);291}292293static void test_set_handle(void **_CBOR_UNUSED(_state)) {294string = cbor_new_definite_string();295char *test_string = "Hello";296unsigned char *string_data = malloc(strlen(test_string));297memcpy(string_data, test_string, strlen(test_string));298assert_ptr_not_equal(string_data, NULL);299cbor_string_set_handle(string, string_data, strlen(test_string));300301assert_ptr_equal(cbor_string_handle(string), string_data);302assert_size_equal(cbor_string_length(string), 5);303assert_size_equal(cbor_string_codepoint_count(string), 5);304305cbor_decref(&string);306}307308static void test_set_handle_multibyte_codepoint(void **_CBOR_UNUSED(_state)) {309string = cbor_new_definite_string();310// "Štěstíčko" in UTF-8311char *test_string = "\xc5\xa0t\xc4\x9bst\xc3\xad\xc4\x8dko";312unsigned char *string_data = malloc(strlen(test_string));313memcpy(string_data, test_string, strlen(test_string));314assert_ptr_not_equal(string_data, NULL);315cbor_string_set_handle(string, string_data, strlen(test_string));316317assert_ptr_equal(cbor_string_handle(string), string_data);318assert_size_equal(cbor_string_length(string), 13);319assert_size_equal(cbor_string_codepoint_count(string), 9);320321cbor_decref(&string);322}323324static void test_set_handle_invalid_utf(void **_CBOR_UNUSED(_state)) {325string = cbor_new_definite_string();326// Invalid multi-byte character (missing the second byte).327char *test_string = "Test: \xc5";328unsigned char *string_data = malloc(strlen(test_string));329memcpy(string_data, test_string, strlen(test_string));330assert_ptr_not_equal(string_data, NULL);331cbor_string_set_handle(string, string_data, strlen(test_string));332333assert_ptr_equal(cbor_string_handle(string), string_data);334assert_size_equal(cbor_string_length(string), 7);335assert_size_equal(cbor_string_codepoint_count(string), 0);336337cbor_decref(&string);338}339340int main(void) {341const struct CMUnitTest tests[] = {342cmocka_unit_test(test_empty_string),343cmocka_unit_test(test_short_string),344cmocka_unit_test(test_short_multibyte_string),345cmocka_unit_test(test_int8_string),346cmocka_unit_test(test_int16_string),347cmocka_unit_test(test_int32_string),348cmocka_unit_test(test_int64_string),349cmocka_unit_test(test_short_indef_string),350cmocka_unit_test(test_invalid_utf),351cmocka_unit_test(test_inline_creation),352cmocka_unit_test(test_string_creation),353cmocka_unit_test(test_string_add_chunk),354cmocka_unit_test(test_add_chunk_reallocation_overflow),355cmocka_unit_test(test_set_handle),356cmocka_unit_test(test_set_handle_multibyte_codepoint),357cmocka_unit_test(test_set_handle_invalid_utf),358};359return cmocka_run_group_tests(tests, NULL, NULL);360}361362363