110ff414cSEd Maste /* 210ff414cSEd Maste * Copyright (c) 2014-2020 Pavel Kalvoda <me@pavelkalvoda.com> 310ff414cSEd Maste * 410ff414cSEd Maste * libcbor is free software; you can redistribute it and/or modify 510ff414cSEd Maste * it under the terms of the MIT license. See LICENSE for details. 610ff414cSEd Maste */ 75d3e7166SEd Maste #include "assertions.h" 810ff414cSEd Maste #include "cbor.h" 95d3e7166SEd Maste #include "cbor/internal/builder_callbacks.h" 105d3e7166SEd Maste #include "cbor/internal/stack.h" 115d3e7166SEd Maste #include "test_allocator.h" 1210ff414cSEd Maste 1310ff414cSEd Maste unsigned char data[] = { 1410ff414cSEd Maste 0x93, 0x01, 0x19, 0x01, 0x01, 0x1A, 0x00, 0x01, 0x05, 0xB8, 0x1B, 0x00, 1510ff414cSEd Maste 0x00, 0x00, 0x01, 0x8F, 0x5A, 0xE8, 0xB8, 0x20, 0x39, 0x01, 0x00, 0x3A, 1610ff414cSEd Maste 0x00, 0x01, 0x05, 0xB7, 0x3B, 0x00, 0x00, 0x00, 0x01, 0x8F, 0x5A, 0xE8, 1710ff414cSEd Maste 0xB7, 0x5F, 0x41, 0x01, 0x41, 0x02, 0xFF, 0x7F, 0x61, 0x61, 0x61, 0x62, 1810ff414cSEd Maste 0xFF, 0x9F, 0xFF, 0xA1, 0x61, 0x61, 0x61, 0x62, 0xC0, 0xBF, 0xFF, 0xF9, 1910ff414cSEd Maste 0x3C, 0x00, 0xFA, 0x47, 0xC3, 0x50, 0x00, 0xFB, 0x7E, 0x37, 0xE4, 0x3C, 2010ff414cSEd Maste 0x88, 0x00, 0x75, 0x9C, 0xF6, 0xF7, 0xF5}; 2110ff414cSEd Maste 2210ff414cSEd Maste /* Exercise the default callbacks */ 235d3e7166SEd Maste static void test_default_callbacks(void** _CBOR_UNUSED(_state)) { 2410ff414cSEd Maste size_t read = 0; 2510ff414cSEd Maste while (read < 79) { 2610ff414cSEd Maste struct cbor_decoder_result result = 2710ff414cSEd Maste cbor_stream_decode(data + read, 79 - read, &cbor_empty_callbacks, NULL); 2810ff414cSEd Maste read += result.read; 2910ff414cSEd Maste } 3010ff414cSEd Maste } 3110ff414cSEd Maste 325d3e7166SEd Maste unsigned char bytestring_data[] = {0x01, 0x02, 0x03}; 335d3e7166SEd Maste static void test_builder_byte_string_callback_append( 345d3e7166SEd Maste void** _CBOR_UNUSED(_state)) { 355d3e7166SEd Maste struct _cbor_stack stack = _cbor_stack_init(); 365d3e7166SEd Maste assert_non_null( 375d3e7166SEd Maste _cbor_stack_push(&stack, cbor_new_indefinite_bytestring(), 0)); 385d3e7166SEd Maste struct _cbor_decoder_context context = { 395d3e7166SEd Maste .creation_failed = false, 405d3e7166SEd Maste .syntax_error = false, 415d3e7166SEd Maste .root = NULL, 425d3e7166SEd Maste .stack = &stack, 435d3e7166SEd Maste }; 445d3e7166SEd Maste 455d3e7166SEd Maste cbor_builder_byte_string_callback(&context, bytestring_data, 3); 465d3e7166SEd Maste 475d3e7166SEd Maste assert_false(context.creation_failed); 485d3e7166SEd Maste assert_false(context.syntax_error); 495d3e7166SEd Maste assert_size_equal(context.stack->size, 1); 505d3e7166SEd Maste 515d3e7166SEd Maste cbor_item_t* bytestring = stack.top->item; 525d3e7166SEd Maste assert_size_equal(cbor_refcount(bytestring), 1); 535d3e7166SEd Maste assert_true(cbor_typeof(bytestring) == CBOR_TYPE_BYTESTRING); 545d3e7166SEd Maste assert_true(cbor_isa_bytestring(bytestring)); 555d3e7166SEd Maste assert_size_equal(cbor_bytestring_length(bytestring), 0); 565d3e7166SEd Maste assert_true(cbor_bytestring_is_indefinite(bytestring)); 575d3e7166SEd Maste assert_size_equal(cbor_bytestring_chunk_count(bytestring), 1); 585d3e7166SEd Maste 595d3e7166SEd Maste cbor_item_t* chunk = cbor_bytestring_chunks_handle(bytestring)[0]; 605d3e7166SEd Maste assert_size_equal(cbor_refcount(chunk), 1); 615d3e7166SEd Maste assert_true(cbor_typeof(bytestring) == CBOR_TYPE_BYTESTRING); 625d3e7166SEd Maste assert_true(cbor_isa_bytestring(chunk)); 635d3e7166SEd Maste assert_true(cbor_bytestring_is_definite(chunk)); 645d3e7166SEd Maste assert_size_equal(cbor_bytestring_length(chunk), 3); 655d3e7166SEd Maste assert_memory_equal(cbor_bytestring_handle(chunk), bytestring_data, 3); 665d3e7166SEd Maste // Data is copied 675d3e7166SEd Maste assert_ptr_not_equal(cbor_bytestring_handle(chunk), bytestring_data); 685d3e7166SEd Maste 695d3e7166SEd Maste cbor_decref(&bytestring); 705d3e7166SEd Maste _cbor_stack_pop(&stack); 715d3e7166SEd Maste } 725d3e7166SEd Maste 735d3e7166SEd Maste static void test_builder_byte_string_callback_append_alloc_failure( 745d3e7166SEd Maste void** _CBOR_UNUSED(_state)) { 755d3e7166SEd Maste struct _cbor_stack stack = _cbor_stack_init(); 765d3e7166SEd Maste assert_non_null( 775d3e7166SEd Maste _cbor_stack_push(&stack, cbor_new_indefinite_bytestring(), 0)); 785d3e7166SEd Maste struct _cbor_decoder_context context = { 795d3e7166SEd Maste .creation_failed = false, 805d3e7166SEd Maste .syntax_error = false, 815d3e7166SEd Maste .root = NULL, 825d3e7166SEd Maste .stack = &stack, 835d3e7166SEd Maste }; 845d3e7166SEd Maste 855d3e7166SEd Maste WITH_FAILING_MALLOC( 865d3e7166SEd Maste { cbor_builder_byte_string_callback(&context, bytestring_data, 3); }); 875d3e7166SEd Maste 885d3e7166SEd Maste assert_true(context.creation_failed); 895d3e7166SEd Maste assert_false(context.syntax_error); 905d3e7166SEd Maste assert_size_equal(context.stack->size, 1); 915d3e7166SEd Maste 925d3e7166SEd Maste // The stack remains unchanged 935d3e7166SEd Maste cbor_item_t* bytestring = stack.top->item; 945d3e7166SEd Maste assert_size_equal(cbor_refcount(bytestring), 1); 955d3e7166SEd Maste assert_true(cbor_typeof(bytestring) == CBOR_TYPE_BYTESTRING); 965d3e7166SEd Maste assert_true(cbor_isa_bytestring(bytestring)); 975d3e7166SEd Maste assert_size_equal(cbor_bytestring_length(bytestring), 0); 985d3e7166SEd Maste assert_true(cbor_bytestring_is_indefinite(bytestring)); 995d3e7166SEd Maste assert_size_equal(cbor_bytestring_chunk_count(bytestring), 0); 1005d3e7166SEd Maste 1015d3e7166SEd Maste cbor_decref(&bytestring); 1025d3e7166SEd Maste _cbor_stack_pop(&stack); 1035d3e7166SEd Maste } 1045d3e7166SEd Maste 1055d3e7166SEd Maste static void test_builder_byte_string_callback_append_item_alloc_failure( 1065d3e7166SEd Maste void** _CBOR_UNUSED(_state)) { 1075d3e7166SEd Maste struct _cbor_stack stack = _cbor_stack_init(); 1085d3e7166SEd Maste assert_non_null( 1095d3e7166SEd Maste _cbor_stack_push(&stack, cbor_new_indefinite_bytestring(), 0)); 1105d3e7166SEd Maste struct _cbor_decoder_context context = { 1115d3e7166SEd Maste .creation_failed = false, 1125d3e7166SEd Maste .syntax_error = false, 1135d3e7166SEd Maste .root = NULL, 1145d3e7166SEd Maste .stack = &stack, 1155d3e7166SEd Maste }; 1165d3e7166SEd Maste 1175d3e7166SEd Maste // Allocate new data block, but fail to allocate a new item with it 1185d3e7166SEd Maste WITH_MOCK_MALLOC( 1195d3e7166SEd Maste { cbor_builder_byte_string_callback(&context, bytestring_data, 3); }, 2, 1205d3e7166SEd Maste MALLOC, MALLOC_FAIL); 1215d3e7166SEd Maste 1225d3e7166SEd Maste assert_true(context.creation_failed); 1235d3e7166SEd Maste assert_false(context.syntax_error); 1245d3e7166SEd Maste assert_size_equal(context.stack->size, 1); 1255d3e7166SEd Maste 1265d3e7166SEd Maste // The stack remains unchanged 1275d3e7166SEd Maste cbor_item_t* bytestring = stack.top->item; 1285d3e7166SEd Maste assert_size_equal(cbor_refcount(bytestring), 1); 1295d3e7166SEd Maste assert_true(cbor_typeof(bytestring) == CBOR_TYPE_BYTESTRING); 1305d3e7166SEd Maste assert_true(cbor_isa_bytestring(bytestring)); 1315d3e7166SEd Maste assert_size_equal(cbor_bytestring_length(bytestring), 0); 1325d3e7166SEd Maste assert_true(cbor_bytestring_is_indefinite(bytestring)); 1335d3e7166SEd Maste assert_size_equal(cbor_bytestring_chunk_count(bytestring), 0); 1345d3e7166SEd Maste 1355d3e7166SEd Maste cbor_decref(&bytestring); 1365d3e7166SEd Maste _cbor_stack_pop(&stack); 1375d3e7166SEd Maste } 1385d3e7166SEd Maste 1395d3e7166SEd Maste static void test_builder_byte_string_callback_append_parent_alloc_failure( 1405d3e7166SEd Maste void** _CBOR_UNUSED(_state)) { 1415d3e7166SEd Maste struct _cbor_stack stack = _cbor_stack_init(); 1425d3e7166SEd Maste assert_non_null( 1435d3e7166SEd Maste _cbor_stack_push(&stack, cbor_new_indefinite_bytestring(), 0)); 1445d3e7166SEd Maste struct _cbor_decoder_context context = { 1455d3e7166SEd Maste .creation_failed = false, 1465d3e7166SEd Maste .syntax_error = false, 1475d3e7166SEd Maste .root = NULL, 1485d3e7166SEd Maste .stack = &stack, 1495d3e7166SEd Maste }; 1505d3e7166SEd Maste 1515d3e7166SEd Maste // Allocate new item, but fail to push it into the parent on the stack 1525d3e7166SEd Maste WITH_MOCK_MALLOC( 1535d3e7166SEd Maste { cbor_builder_byte_string_callback(&context, bytestring_data, 3); }, 3, 1545d3e7166SEd Maste MALLOC, MALLOC, REALLOC_FAIL); 1555d3e7166SEd Maste 1565d3e7166SEd Maste assert_true(context.creation_failed); 1575d3e7166SEd Maste assert_false(context.syntax_error); 1585d3e7166SEd Maste assert_size_equal(context.stack->size, 1); 1595d3e7166SEd Maste 1605d3e7166SEd Maste // The stack remains unchanged 1615d3e7166SEd Maste cbor_item_t* bytestring = stack.top->item; 1625d3e7166SEd Maste assert_size_equal(cbor_refcount(bytestring), 1); 1635d3e7166SEd Maste assert_true(cbor_typeof(bytestring) == CBOR_TYPE_BYTESTRING); 1645d3e7166SEd Maste assert_true(cbor_isa_bytestring(bytestring)); 1655d3e7166SEd Maste assert_size_equal(cbor_bytestring_length(bytestring), 0); 1665d3e7166SEd Maste assert_true(cbor_bytestring_is_indefinite(bytestring)); 1675d3e7166SEd Maste assert_size_equal(cbor_bytestring_chunk_count(bytestring), 0); 1685d3e7166SEd Maste 1695d3e7166SEd Maste cbor_decref(&bytestring); 1705d3e7166SEd Maste _cbor_stack_pop(&stack); 1715d3e7166SEd Maste } 1725d3e7166SEd Maste 1735d3e7166SEd Maste unsigned char string_data[] = {0x61, 0x62, 0x63}; 1745d3e7166SEd Maste static void test_builder_string_callback_append(void** _CBOR_UNUSED(_state)) { 1755d3e7166SEd Maste struct _cbor_stack stack = _cbor_stack_init(); 1765d3e7166SEd Maste assert_non_null(_cbor_stack_push(&stack, cbor_new_indefinite_string(), 0)); 1775d3e7166SEd Maste struct _cbor_decoder_context context = { 1785d3e7166SEd Maste .creation_failed = false, 1795d3e7166SEd Maste .syntax_error = false, 1805d3e7166SEd Maste .root = NULL, 1815d3e7166SEd Maste .stack = &stack, 1825d3e7166SEd Maste }; 1835d3e7166SEd Maste 1845d3e7166SEd Maste cbor_builder_string_callback(&context, string_data, 3); 1855d3e7166SEd Maste 1865d3e7166SEd Maste assert_false(context.creation_failed); 1875d3e7166SEd Maste assert_false(context.syntax_error); 1885d3e7166SEd Maste assert_size_equal(context.stack->size, 1); 1895d3e7166SEd Maste 1905d3e7166SEd Maste cbor_item_t* string = stack.top->item; 1915d3e7166SEd Maste assert_size_equal(cbor_refcount(string), 1); 1925d3e7166SEd Maste assert_true(cbor_isa_string(string)); 1935d3e7166SEd Maste assert_size_equal(cbor_string_length(string), 0); 1945d3e7166SEd Maste assert_true(cbor_string_is_indefinite(string)); 1955d3e7166SEd Maste assert_size_equal(cbor_string_chunk_count(string), 1); 1965d3e7166SEd Maste 1975d3e7166SEd Maste cbor_item_t* chunk = cbor_string_chunks_handle(string)[0]; 1985d3e7166SEd Maste assert_size_equal(cbor_refcount(chunk), 1); 1995d3e7166SEd Maste assert_true(cbor_isa_string(chunk)); 2005d3e7166SEd Maste assert_true(cbor_string_is_definite(chunk)); 2015d3e7166SEd Maste assert_size_equal(cbor_string_length(chunk), 3); 2025d3e7166SEd Maste assert_memory_equal(cbor_string_handle(chunk), "abc", 3); 2035d3e7166SEd Maste // Data is copied 2045d3e7166SEd Maste assert_ptr_not_equal(cbor_string_handle(chunk), string_data); 2055d3e7166SEd Maste 2065d3e7166SEd Maste cbor_decref(&string); 2075d3e7166SEd Maste _cbor_stack_pop(&stack); 2085d3e7166SEd Maste } 2095d3e7166SEd Maste 2105d3e7166SEd Maste static void test_builder_string_callback_append_alloc_failure( 2115d3e7166SEd Maste void** _CBOR_UNUSED(_state)) { 2125d3e7166SEd Maste struct _cbor_stack stack = _cbor_stack_init(); 2135d3e7166SEd Maste assert_non_null(_cbor_stack_push(&stack, cbor_new_indefinite_string(), 0)); 2145d3e7166SEd Maste struct _cbor_decoder_context context = { 2155d3e7166SEd Maste .creation_failed = false, 2165d3e7166SEd Maste .syntax_error = false, 2175d3e7166SEd Maste .root = NULL, 2185d3e7166SEd Maste .stack = &stack, 2195d3e7166SEd Maste }; 2205d3e7166SEd Maste 2215d3e7166SEd Maste WITH_FAILING_MALLOC( 2225d3e7166SEd Maste { cbor_builder_string_callback(&context, string_data, 3); }); 2235d3e7166SEd Maste 2245d3e7166SEd Maste assert_true(context.creation_failed); 2255d3e7166SEd Maste assert_false(context.syntax_error); 2265d3e7166SEd Maste assert_size_equal(context.stack->size, 1); 2275d3e7166SEd Maste 2285d3e7166SEd Maste // The stack remains unchanged 2295d3e7166SEd Maste cbor_item_t* string = stack.top->item; 2305d3e7166SEd Maste assert_size_equal(cbor_refcount(string), 1); 2315d3e7166SEd Maste assert_true(cbor_typeof(string) == CBOR_TYPE_STRING); 2325d3e7166SEd Maste assert_true(cbor_isa_string(string)); 2335d3e7166SEd Maste assert_size_equal(cbor_string_length(string), 0); 2345d3e7166SEd Maste assert_true(cbor_string_is_indefinite(string)); 2355d3e7166SEd Maste assert_size_equal(cbor_string_chunk_count(string), 0); 2365d3e7166SEd Maste 2375d3e7166SEd Maste cbor_decref(&string); 2385d3e7166SEd Maste _cbor_stack_pop(&stack); 2395d3e7166SEd Maste } 2405d3e7166SEd Maste 2415d3e7166SEd Maste static void test_builder_string_callback_append_item_alloc_failure( 2425d3e7166SEd Maste void** _CBOR_UNUSED(_state)) { 2435d3e7166SEd Maste struct _cbor_stack stack = _cbor_stack_init(); 2445d3e7166SEd Maste assert_non_null(_cbor_stack_push(&stack, cbor_new_indefinite_string(), 0)); 2455d3e7166SEd Maste struct _cbor_decoder_context context = { 2465d3e7166SEd Maste .creation_failed = false, 2475d3e7166SEd Maste .syntax_error = false, 2485d3e7166SEd Maste .root = NULL, 2495d3e7166SEd Maste .stack = &stack, 2505d3e7166SEd Maste }; 2515d3e7166SEd Maste 2525d3e7166SEd Maste // Allocate new data block, but fail to allocate a new item with it 2535d3e7166SEd Maste WITH_MOCK_MALLOC({ cbor_builder_string_callback(&context, string_data, 3); }, 2545d3e7166SEd Maste 2, MALLOC, MALLOC_FAIL); 2555d3e7166SEd Maste 2565d3e7166SEd Maste assert_true(context.creation_failed); 2575d3e7166SEd Maste assert_false(context.syntax_error); 2585d3e7166SEd Maste assert_size_equal(context.stack->size, 1); 2595d3e7166SEd Maste 2605d3e7166SEd Maste // The stack remains unchanged 2615d3e7166SEd Maste cbor_item_t* string = stack.top->item; 2625d3e7166SEd Maste assert_size_equal(cbor_refcount(string), 1); 2635d3e7166SEd Maste assert_true(cbor_typeof(string) == CBOR_TYPE_STRING); 2645d3e7166SEd Maste assert_true(cbor_isa_string(string)); 2655d3e7166SEd Maste assert_size_equal(cbor_string_length(string), 0); 2665d3e7166SEd Maste assert_true(cbor_string_is_indefinite(string)); 2675d3e7166SEd Maste assert_size_equal(cbor_string_chunk_count(string), 0); 2685d3e7166SEd Maste 2695d3e7166SEd Maste cbor_decref(&string); 2705d3e7166SEd Maste _cbor_stack_pop(&stack); 2715d3e7166SEd Maste } 2725d3e7166SEd Maste 2735d3e7166SEd Maste static void test_builder_string_callback_append_parent_alloc_failure( 2745d3e7166SEd Maste void** _CBOR_UNUSED(_state)) { 2755d3e7166SEd Maste struct _cbor_stack stack = _cbor_stack_init(); 2765d3e7166SEd Maste assert_non_null(_cbor_stack_push(&stack, cbor_new_indefinite_string(), 0)); 2775d3e7166SEd Maste struct _cbor_decoder_context context = { 2785d3e7166SEd Maste .creation_failed = false, 2795d3e7166SEd Maste .syntax_error = false, 2805d3e7166SEd Maste .root = NULL, 2815d3e7166SEd Maste .stack = &stack, 2825d3e7166SEd Maste }; 2835d3e7166SEd Maste 2845d3e7166SEd Maste // Allocate new item, but fail to push it into the parent on the stack 2855d3e7166SEd Maste WITH_MOCK_MALLOC({ cbor_builder_string_callback(&context, string_data, 3); }, 2865d3e7166SEd Maste 3, MALLOC, MALLOC, REALLOC_FAIL); 2875d3e7166SEd Maste 2885d3e7166SEd Maste assert_true(context.creation_failed); 2895d3e7166SEd Maste assert_false(context.syntax_error); 2905d3e7166SEd Maste assert_size_equal(context.stack->size, 1); 2915d3e7166SEd Maste 2925d3e7166SEd Maste // The stack remains unchanged 2935d3e7166SEd Maste cbor_item_t* string = stack.top->item; 2945d3e7166SEd Maste assert_size_equal(cbor_refcount(string), 1); 2955d3e7166SEd Maste assert_true(cbor_typeof(string) == CBOR_TYPE_STRING); 2965d3e7166SEd Maste assert_true(cbor_isa_string(string)); 2975d3e7166SEd Maste assert_size_equal(cbor_string_length(string), 0); 2985d3e7166SEd Maste assert_true(cbor_string_is_indefinite(string)); 2995d3e7166SEd Maste assert_size_equal(cbor_string_chunk_count(string), 0); 3005d3e7166SEd Maste 3015d3e7166SEd Maste cbor_decref(&string); 3025d3e7166SEd Maste _cbor_stack_pop(&stack); 3035d3e7166SEd Maste } 3045d3e7166SEd Maste 3055d3e7166SEd Maste static void test_append_array_failure(void** _CBOR_UNUSED(_state)) { 3065d3e7166SEd Maste struct _cbor_stack stack = _cbor_stack_init(); 3075d3e7166SEd Maste assert_non_null(_cbor_stack_push(&stack, cbor_new_definite_array(0), 0)); 3085d3e7166SEd Maste stack.top->subitems = 1; 3095d3e7166SEd Maste struct _cbor_decoder_context context = { 3105d3e7166SEd Maste .creation_failed = false, 3115d3e7166SEd Maste .syntax_error = false, 3125d3e7166SEd Maste .root = NULL, 3135d3e7166SEd Maste .stack = &stack, 3145d3e7166SEd Maste }; 3155d3e7166SEd Maste cbor_item_t* item = cbor_build_uint8(42); 3165d3e7166SEd Maste 3175d3e7166SEd Maste _cbor_builder_append(item, &context); 3185d3e7166SEd Maste 3195d3e7166SEd Maste assert_true(context.creation_failed); 3205d3e7166SEd Maste assert_false(context.syntax_error); 3215d3e7166SEd Maste assert_size_equal(context.stack->size, 1); 3225d3e7166SEd Maste 3235d3e7166SEd Maste // The stack remains unchanged 3245d3e7166SEd Maste cbor_item_t* array = stack.top->item; 3255d3e7166SEd Maste assert_size_equal(cbor_refcount(array), 1); 3265d3e7166SEd Maste assert_true(cbor_isa_array(array)); 3275d3e7166SEd Maste assert_size_equal(cbor_array_size(array), 0); 3285d3e7166SEd Maste 3295d3e7166SEd Maste // item free'd by _cbor_builder_append 3305d3e7166SEd Maste cbor_decref(&array); 3315d3e7166SEd Maste _cbor_stack_pop(&stack); 3325d3e7166SEd Maste } 3335d3e7166SEd Maste 3345d3e7166SEd Maste static void test_append_map_failure(void** _CBOR_UNUSED(_state)) { 3355d3e7166SEd Maste struct _cbor_stack stack = _cbor_stack_init(); 3365d3e7166SEd Maste assert_non_null( 3375d3e7166SEd Maste _cbor_stack_push(&stack, cbor_new_indefinite_map(), /*subitems=*/0)); 3385d3e7166SEd Maste struct _cbor_decoder_context context = { 3395d3e7166SEd Maste .creation_failed = false, 3405d3e7166SEd Maste .syntax_error = false, 3415d3e7166SEd Maste .root = NULL, 3425d3e7166SEd Maste .stack = &stack, 3435d3e7166SEd Maste }; 3445d3e7166SEd Maste cbor_item_t* item = cbor_build_uint8(42); 3455d3e7166SEd Maste 3465d3e7166SEd Maste WITH_MOCK_MALLOC({ _cbor_builder_append(item, &context); }, 1, REALLOC_FAIL); 3475d3e7166SEd Maste 3485d3e7166SEd Maste assert_true(context.creation_failed); 3495d3e7166SEd Maste assert_false(context.syntax_error); 3505d3e7166SEd Maste assert_size_equal(context.stack->size, 1); 3515d3e7166SEd Maste 3525d3e7166SEd Maste // The stack remains unchanged 3535d3e7166SEd Maste cbor_item_t* map = stack.top->item; 3545d3e7166SEd Maste assert_size_equal(cbor_refcount(map), 1); 3555d3e7166SEd Maste assert_true(cbor_isa_map(map)); 3565d3e7166SEd Maste assert_size_equal(cbor_map_size(map), 0); 3575d3e7166SEd Maste 3585d3e7166SEd Maste // item free'd by _cbor_builder_append 3595d3e7166SEd Maste cbor_decref(&map); 3605d3e7166SEd Maste _cbor_stack_pop(&stack); 3615d3e7166SEd Maste } 3625d3e7166SEd Maste 3635d3e7166SEd Maste // Size 1 array start, but we get an indef break 3645d3e7166SEd Maste unsigned char invalid_indef_break_data[] = {0x81, 0xFF}; 3655d3e7166SEd Maste static void test_invalid_indef_break(void** _CBOR_UNUSED(_state)) { 3665d3e7166SEd Maste struct cbor_load_result res; 3675d3e7166SEd Maste cbor_item_t* item = cbor_load(invalid_indef_break_data, 2, &res); 3685d3e7166SEd Maste 3695d3e7166SEd Maste assert_null(item); 3705d3e7166SEd Maste assert_size_equal(res.read, 2); 3715d3e7166SEd Maste assert_true(res.error.code == CBOR_ERR_SYNTAXERROR); 3725d3e7166SEd Maste } 3735d3e7166SEd Maste 374*abd87254SEd Maste static void test_invalid_state_indef_break(void** _CBOR_UNUSED(_state)) { 375*abd87254SEd Maste struct _cbor_stack stack = _cbor_stack_init(); 376*abd87254SEd Maste assert_non_null(_cbor_stack_push(&stack, cbor_new_int8(), /*subitems=*/0)); 377*abd87254SEd Maste struct _cbor_decoder_context context = { 378*abd87254SEd Maste .creation_failed = false, 379*abd87254SEd Maste .syntax_error = false, 380*abd87254SEd Maste .root = NULL, 381*abd87254SEd Maste .stack = &stack, 382*abd87254SEd Maste }; 383*abd87254SEd Maste 384*abd87254SEd Maste cbor_builder_indef_break_callback(&context); 385*abd87254SEd Maste 386*abd87254SEd Maste assert_false(context.creation_failed); 387*abd87254SEd Maste assert_true(context.syntax_error); 388*abd87254SEd Maste assert_size_equal(context.stack->size, 1); 389*abd87254SEd Maste // The stack remains unchanged 390*abd87254SEd Maste cbor_item_t* small_int = stack.top->item; 391*abd87254SEd Maste assert_size_equal(cbor_refcount(small_int), 1); 392*abd87254SEd Maste assert_true(cbor_isa_uint(small_int)); 393*abd87254SEd Maste 394*abd87254SEd Maste cbor_decref(&small_int); 395*abd87254SEd Maste _cbor_stack_pop(&stack); 396*abd87254SEd Maste } 397*abd87254SEd Maste 39810ff414cSEd Maste int main(void) { 39910ff414cSEd Maste const struct CMUnitTest tests[] = { 4005d3e7166SEd Maste cmocka_unit_test(test_default_callbacks), 4015d3e7166SEd Maste cmocka_unit_test(test_builder_byte_string_callback_append), 4025d3e7166SEd Maste cmocka_unit_test(test_builder_byte_string_callback_append_alloc_failure), 4035d3e7166SEd Maste cmocka_unit_test( 4045d3e7166SEd Maste test_builder_byte_string_callback_append_item_alloc_failure), 4055d3e7166SEd Maste cmocka_unit_test( 4065d3e7166SEd Maste test_builder_byte_string_callback_append_parent_alloc_failure), 4075d3e7166SEd Maste cmocka_unit_test(test_builder_string_callback_append), 4085d3e7166SEd Maste cmocka_unit_test(test_builder_string_callback_append_alloc_failure), 4095d3e7166SEd Maste cmocka_unit_test(test_builder_string_callback_append_item_alloc_failure), 4105d3e7166SEd Maste cmocka_unit_test( 4115d3e7166SEd Maste test_builder_string_callback_append_parent_alloc_failure), 4125d3e7166SEd Maste cmocka_unit_test(test_append_array_failure), 4135d3e7166SEd Maste cmocka_unit_test(test_append_map_failure), 4145d3e7166SEd Maste cmocka_unit_test(test_invalid_indef_break), 415*abd87254SEd Maste cmocka_unit_test(test_invalid_state_indef_break), 4165d3e7166SEd Maste }; 41710ff414cSEd Maste 4185d3e7166SEd Maste cmocka_run_group_tests(tests, NULL, NULL); 41910ff414cSEd Maste } 420