Path: blob/main/contrib/libcbor/test/callbacks_test.c
39535 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*/6#include "assertions.h"7#include "cbor.h"8#include "cbor/internal/builder_callbacks.h"9#include "cbor/internal/stack.h"10#include "test_allocator.h"1112unsigned char data[] = {130x93, 0x01, 0x19, 0x01, 0x01, 0x1A, 0x00, 0x01, 0x05, 0xB8, 0x1B, 0x00,140x00, 0x00, 0x01, 0x8F, 0x5A, 0xE8, 0xB8, 0x20, 0x39, 0x01, 0x00, 0x3A,150x00, 0x01, 0x05, 0xB7, 0x3B, 0x00, 0x00, 0x00, 0x01, 0x8F, 0x5A, 0xE8,160xB7, 0x5F, 0x41, 0x01, 0x41, 0x02, 0xFF, 0x7F, 0x61, 0x61, 0x61, 0x62,170xFF, 0x9F, 0xFF, 0xA1, 0x61, 0x61, 0x61, 0x62, 0xC0, 0xBF, 0xFF, 0xF9,180x3C, 0x00, 0xFA, 0x47, 0xC3, 0x50, 0x00, 0xFB, 0x7E, 0x37, 0xE4, 0x3C,190x88, 0x00, 0x75, 0x9C, 0xF6, 0xF7, 0xF5};2021/* Exercise the default callbacks */22static void test_default_callbacks(void** _CBOR_UNUSED(_state)) {23size_t read = 0;24while (read < 79) {25struct cbor_decoder_result result =26cbor_stream_decode(data + read, 79 - read, &cbor_empty_callbacks, NULL);27read += result.read;28}29}3031unsigned char bytestring_data[] = {0x01, 0x02, 0x03};32static void test_builder_byte_string_callback_append(33void** _CBOR_UNUSED(_state)) {34struct _cbor_stack stack = _cbor_stack_init();35assert_non_null(36_cbor_stack_push(&stack, cbor_new_indefinite_bytestring(), 0));37struct _cbor_decoder_context context = {38.creation_failed = false,39.syntax_error = false,40.root = NULL,41.stack = &stack,42};4344cbor_builder_byte_string_callback(&context, bytestring_data, 3);4546assert_false(context.creation_failed);47assert_false(context.syntax_error);48assert_size_equal(context.stack->size, 1);4950cbor_item_t* bytestring = stack.top->item;51assert_size_equal(cbor_refcount(bytestring), 1);52assert_true(cbor_typeof(bytestring) == CBOR_TYPE_BYTESTRING);53assert_true(cbor_isa_bytestring(bytestring));54assert_size_equal(cbor_bytestring_length(bytestring), 0);55assert_true(cbor_bytestring_is_indefinite(bytestring));56assert_size_equal(cbor_bytestring_chunk_count(bytestring), 1);5758cbor_item_t* chunk = cbor_bytestring_chunks_handle(bytestring)[0];59assert_size_equal(cbor_refcount(chunk), 1);60assert_true(cbor_typeof(bytestring) == CBOR_TYPE_BYTESTRING);61assert_true(cbor_isa_bytestring(chunk));62assert_true(cbor_bytestring_is_definite(chunk));63assert_size_equal(cbor_bytestring_length(chunk), 3);64assert_memory_equal(cbor_bytestring_handle(chunk), bytestring_data, 3);65// Data is copied66assert_ptr_not_equal(cbor_bytestring_handle(chunk), bytestring_data);6768cbor_decref(&bytestring);69_cbor_stack_pop(&stack);70}7172static void test_builder_byte_string_callback_append_alloc_failure(73void** _CBOR_UNUSED(_state)) {74struct _cbor_stack stack = _cbor_stack_init();75assert_non_null(76_cbor_stack_push(&stack, cbor_new_indefinite_bytestring(), 0));77struct _cbor_decoder_context context = {78.creation_failed = false,79.syntax_error = false,80.root = NULL,81.stack = &stack,82};8384WITH_FAILING_MALLOC(85{ cbor_builder_byte_string_callback(&context, bytestring_data, 3); });8687assert_true(context.creation_failed);88assert_false(context.syntax_error);89assert_size_equal(context.stack->size, 1);9091// The stack remains unchanged92cbor_item_t* bytestring = stack.top->item;93assert_size_equal(cbor_refcount(bytestring), 1);94assert_true(cbor_typeof(bytestring) == CBOR_TYPE_BYTESTRING);95assert_true(cbor_isa_bytestring(bytestring));96assert_size_equal(cbor_bytestring_length(bytestring), 0);97assert_true(cbor_bytestring_is_indefinite(bytestring));98assert_size_equal(cbor_bytestring_chunk_count(bytestring), 0);99100cbor_decref(&bytestring);101_cbor_stack_pop(&stack);102}103104static void test_builder_byte_string_callback_append_item_alloc_failure(105void** _CBOR_UNUSED(_state)) {106struct _cbor_stack stack = _cbor_stack_init();107assert_non_null(108_cbor_stack_push(&stack, cbor_new_indefinite_bytestring(), 0));109struct _cbor_decoder_context context = {110.creation_failed = false,111.syntax_error = false,112.root = NULL,113.stack = &stack,114};115116// Allocate new data block, but fail to allocate a new item with it117WITH_MOCK_MALLOC(118{ cbor_builder_byte_string_callback(&context, bytestring_data, 3); }, 2,119MALLOC, MALLOC_FAIL);120121assert_true(context.creation_failed);122assert_false(context.syntax_error);123assert_size_equal(context.stack->size, 1);124125// The stack remains unchanged126cbor_item_t* bytestring = stack.top->item;127assert_size_equal(cbor_refcount(bytestring), 1);128assert_true(cbor_typeof(bytestring) == CBOR_TYPE_BYTESTRING);129assert_true(cbor_isa_bytestring(bytestring));130assert_size_equal(cbor_bytestring_length(bytestring), 0);131assert_true(cbor_bytestring_is_indefinite(bytestring));132assert_size_equal(cbor_bytestring_chunk_count(bytestring), 0);133134cbor_decref(&bytestring);135_cbor_stack_pop(&stack);136}137138static void test_builder_byte_string_callback_append_parent_alloc_failure(139void** _CBOR_UNUSED(_state)) {140struct _cbor_stack stack = _cbor_stack_init();141assert_non_null(142_cbor_stack_push(&stack, cbor_new_indefinite_bytestring(), 0));143struct _cbor_decoder_context context = {144.creation_failed = false,145.syntax_error = false,146.root = NULL,147.stack = &stack,148};149150// Allocate new item, but fail to push it into the parent on the stack151WITH_MOCK_MALLOC(152{ cbor_builder_byte_string_callback(&context, bytestring_data, 3); }, 3,153MALLOC, MALLOC, REALLOC_FAIL);154155assert_true(context.creation_failed);156assert_false(context.syntax_error);157assert_size_equal(context.stack->size, 1);158159// The stack remains unchanged160cbor_item_t* bytestring = stack.top->item;161assert_size_equal(cbor_refcount(bytestring), 1);162assert_true(cbor_typeof(bytestring) == CBOR_TYPE_BYTESTRING);163assert_true(cbor_isa_bytestring(bytestring));164assert_size_equal(cbor_bytestring_length(bytestring), 0);165assert_true(cbor_bytestring_is_indefinite(bytestring));166assert_size_equal(cbor_bytestring_chunk_count(bytestring), 0);167168cbor_decref(&bytestring);169_cbor_stack_pop(&stack);170}171172unsigned char string_data[] = {0x61, 0x62, 0x63};173static void test_builder_string_callback_append(void** _CBOR_UNUSED(_state)) {174struct _cbor_stack stack = _cbor_stack_init();175assert_non_null(_cbor_stack_push(&stack, cbor_new_indefinite_string(), 0));176struct _cbor_decoder_context context = {177.creation_failed = false,178.syntax_error = false,179.root = NULL,180.stack = &stack,181};182183cbor_builder_string_callback(&context, string_data, 3);184185assert_false(context.creation_failed);186assert_false(context.syntax_error);187assert_size_equal(context.stack->size, 1);188189cbor_item_t* string = stack.top->item;190assert_size_equal(cbor_refcount(string), 1);191assert_true(cbor_isa_string(string));192assert_size_equal(cbor_string_length(string), 0);193assert_true(cbor_string_is_indefinite(string));194assert_size_equal(cbor_string_chunk_count(string), 1);195196cbor_item_t* chunk = cbor_string_chunks_handle(string)[0];197assert_size_equal(cbor_refcount(chunk), 1);198assert_true(cbor_isa_string(chunk));199assert_true(cbor_string_is_definite(chunk));200assert_size_equal(cbor_string_length(chunk), 3);201assert_memory_equal(cbor_string_handle(chunk), "abc", 3);202// Data is copied203assert_ptr_not_equal(cbor_string_handle(chunk), string_data);204205cbor_decref(&string);206_cbor_stack_pop(&stack);207}208209static void test_builder_string_callback_append_alloc_failure(210void** _CBOR_UNUSED(_state)) {211struct _cbor_stack stack = _cbor_stack_init();212assert_non_null(_cbor_stack_push(&stack, cbor_new_indefinite_string(), 0));213struct _cbor_decoder_context context = {214.creation_failed = false,215.syntax_error = false,216.root = NULL,217.stack = &stack,218};219220WITH_FAILING_MALLOC(221{ cbor_builder_string_callback(&context, string_data, 3); });222223assert_true(context.creation_failed);224assert_false(context.syntax_error);225assert_size_equal(context.stack->size, 1);226227// The stack remains unchanged228cbor_item_t* string = stack.top->item;229assert_size_equal(cbor_refcount(string), 1);230assert_true(cbor_typeof(string) == CBOR_TYPE_STRING);231assert_true(cbor_isa_string(string));232assert_size_equal(cbor_string_length(string), 0);233assert_true(cbor_string_is_indefinite(string));234assert_size_equal(cbor_string_chunk_count(string), 0);235236cbor_decref(&string);237_cbor_stack_pop(&stack);238}239240static void test_builder_string_callback_append_item_alloc_failure(241void** _CBOR_UNUSED(_state)) {242struct _cbor_stack stack = _cbor_stack_init();243assert_non_null(_cbor_stack_push(&stack, cbor_new_indefinite_string(), 0));244struct _cbor_decoder_context context = {245.creation_failed = false,246.syntax_error = false,247.root = NULL,248.stack = &stack,249};250251// Allocate new data block, but fail to allocate a new item with it252WITH_MOCK_MALLOC({ cbor_builder_string_callback(&context, string_data, 3); },2532, MALLOC, MALLOC_FAIL);254255assert_true(context.creation_failed);256assert_false(context.syntax_error);257assert_size_equal(context.stack->size, 1);258259// The stack remains unchanged260cbor_item_t* string = stack.top->item;261assert_size_equal(cbor_refcount(string), 1);262assert_true(cbor_typeof(string) == CBOR_TYPE_STRING);263assert_true(cbor_isa_string(string));264assert_size_equal(cbor_string_length(string), 0);265assert_true(cbor_string_is_indefinite(string));266assert_size_equal(cbor_string_chunk_count(string), 0);267268cbor_decref(&string);269_cbor_stack_pop(&stack);270}271272static void test_builder_string_callback_append_parent_alloc_failure(273void** _CBOR_UNUSED(_state)) {274struct _cbor_stack stack = _cbor_stack_init();275assert_non_null(_cbor_stack_push(&stack, cbor_new_indefinite_string(), 0));276struct _cbor_decoder_context context = {277.creation_failed = false,278.syntax_error = false,279.root = NULL,280.stack = &stack,281};282283// Allocate new item, but fail to push it into the parent on the stack284WITH_MOCK_MALLOC({ cbor_builder_string_callback(&context, string_data, 3); },2853, MALLOC, MALLOC, REALLOC_FAIL);286287assert_true(context.creation_failed);288assert_false(context.syntax_error);289assert_size_equal(context.stack->size, 1);290291// The stack remains unchanged292cbor_item_t* string = stack.top->item;293assert_size_equal(cbor_refcount(string), 1);294assert_true(cbor_typeof(string) == CBOR_TYPE_STRING);295assert_true(cbor_isa_string(string));296assert_size_equal(cbor_string_length(string), 0);297assert_true(cbor_string_is_indefinite(string));298assert_size_equal(cbor_string_chunk_count(string), 0);299300cbor_decref(&string);301_cbor_stack_pop(&stack);302}303304static void test_append_array_failure(void** _CBOR_UNUSED(_state)) {305struct _cbor_stack stack = _cbor_stack_init();306assert_non_null(_cbor_stack_push(&stack, cbor_new_definite_array(0), 0));307stack.top->subitems = 1;308struct _cbor_decoder_context context = {309.creation_failed = false,310.syntax_error = false,311.root = NULL,312.stack = &stack,313};314cbor_item_t* item = cbor_build_uint8(42);315316_cbor_builder_append(item, &context);317318assert_true(context.creation_failed);319assert_false(context.syntax_error);320assert_size_equal(context.stack->size, 1);321322// The stack remains unchanged323cbor_item_t* array = stack.top->item;324assert_size_equal(cbor_refcount(array), 1);325assert_true(cbor_isa_array(array));326assert_size_equal(cbor_array_size(array), 0);327328// item free'd by _cbor_builder_append329cbor_decref(&array);330_cbor_stack_pop(&stack);331}332333static void test_append_map_failure(void** _CBOR_UNUSED(_state)) {334struct _cbor_stack stack = _cbor_stack_init();335assert_non_null(336_cbor_stack_push(&stack, cbor_new_indefinite_map(), /*subitems=*/0));337struct _cbor_decoder_context context = {338.creation_failed = false,339.syntax_error = false,340.root = NULL,341.stack = &stack,342};343cbor_item_t* item = cbor_build_uint8(42);344345WITH_MOCK_MALLOC({ _cbor_builder_append(item, &context); }, 1, REALLOC_FAIL);346347assert_true(context.creation_failed);348assert_false(context.syntax_error);349assert_size_equal(context.stack->size, 1);350351// The stack remains unchanged352cbor_item_t* map = stack.top->item;353assert_size_equal(cbor_refcount(map), 1);354assert_true(cbor_isa_map(map));355assert_size_equal(cbor_map_size(map), 0);356357// item free'd by _cbor_builder_append358cbor_decref(&map);359_cbor_stack_pop(&stack);360}361362// Size 1 array start, but we get an indef break363unsigned char invalid_indef_break_data[] = {0x81, 0xFF};364static void test_invalid_indef_break(void** _CBOR_UNUSED(_state)) {365struct cbor_load_result res;366cbor_item_t* item = cbor_load(invalid_indef_break_data, 2, &res);367368assert_null(item);369assert_size_equal(res.read, 2);370assert_true(res.error.code == CBOR_ERR_SYNTAXERROR);371}372373static void test_invalid_state_indef_break(void** _CBOR_UNUSED(_state)) {374struct _cbor_stack stack = _cbor_stack_init();375assert_non_null(_cbor_stack_push(&stack, cbor_new_int8(), /*subitems=*/0));376struct _cbor_decoder_context context = {377.creation_failed = false,378.syntax_error = false,379.root = NULL,380.stack = &stack,381};382383cbor_builder_indef_break_callback(&context);384385assert_false(context.creation_failed);386assert_true(context.syntax_error);387assert_size_equal(context.stack->size, 1);388// The stack remains unchanged389cbor_item_t* small_int = stack.top->item;390assert_size_equal(cbor_refcount(small_int), 1);391assert_true(cbor_isa_uint(small_int));392393cbor_decref(&small_int);394_cbor_stack_pop(&stack);395}396397int main(void) {398const struct CMUnitTest tests[] = {399cmocka_unit_test(test_default_callbacks),400cmocka_unit_test(test_builder_byte_string_callback_append),401cmocka_unit_test(test_builder_byte_string_callback_append_alloc_failure),402cmocka_unit_test(403test_builder_byte_string_callback_append_item_alloc_failure),404cmocka_unit_test(405test_builder_byte_string_callback_append_parent_alloc_failure),406cmocka_unit_test(test_builder_string_callback_append),407cmocka_unit_test(test_builder_string_callback_append_alloc_failure),408cmocka_unit_test(test_builder_string_callback_append_item_alloc_failure),409cmocka_unit_test(410test_builder_string_callback_append_parent_alloc_failure),411cmocka_unit_test(test_append_array_failure),412cmocka_unit_test(test_append_map_failure),413cmocka_unit_test(test_invalid_indef_break),414cmocka_unit_test(test_invalid_state_indef_break),415};416417cmocka_run_group_tests(tests, NULL, NULL);418}419420421