/
githubmirror
/
libcbor
Обзор
Документация
Войти
/
githubmirror
/
libcbor
Код
Запросы
0
Пакеты
0
Релизы
0
Аналитика
Безопасность
master
test/cbor_serialize_test.c
770 строк
27 KB
Pavel Kalvoda
Fix NULL dereference when serializing/measuring a tag with no item set (#420)
06 апр 2026, 22:35
Не верифицирован
06 апр 2026, 22:35
90d5771
Код
Авторство
О чём код?
/* * Copyright (c) 2014-2020 Pavel Kalvoda <me@pavelkalvoda.com> * * libcbor is free software; you can redistribute it and/or modify * it under the terms of the MIT license. See LICENSE for details. */ // cbor_serialize_alloc #pragma GCC diagnostic ignored "-Wdeprecated-declarations" #include <math.h> #include <setjmp.h> #include <stdarg.h> #include <stddef.h> #include <stdint.h> #include <string.h> #include <cmocka.h> #include "assertions.h" #include "cbor.h" #include "test_allocator.h" unsigned char buffer[512]; static void test_serialize_uint8_embed(void** _state _CBOR_UNUSED) { cbor_item_t* item = cbor_new_int8(); cbor_set_uint8(item, 0); assert_size_equal(1, cbor_serialize(item, buffer, 512)); assert_memory_equal(buffer, (unsigned char[]){0x00}, 1); assert_size_equal(cbor_serialized_size(item), 1); cbor_decref(&item); } static void test_serialize_uint8(void** _state _CBOR_UNUSED) { cbor_item_t* item = cbor_new_int8(); cbor_set_uint8(item, 42); assert_size_equal(2, cbor_serialize(item, buffer, 512)); assert_memory_equal(buffer, ((unsigned char[]){0x18, 0x2a}), 2); assert_size_equal(cbor_serialized_size(item), 2); cbor_decref(&item); } static void test_serialize_uint16(void** _state _CBOR_UNUSED) { cbor_item_t* item = cbor_new_int16(); cbor_set_uint16(item, 1000); assert_size_equal(3, cbor_serialize(item, buffer, 512)); assert_memory_equal(buffer, ((unsigned char[]){0x19, 0x03, 0xE8}), 3); assert_size_equal(cbor_serialized_size(item), 3); cbor_decref(&item); } static void test_serialize_uint32(void** _state _CBOR_UNUSED) { cbor_item_t* item = cbor_new_int32(); cbor_set_uint32(item, 1000000); assert_size_equal(5, cbor_serialize(item, buffer, 512)); assert_memory_equal(buffer, ((unsigned char[]){0x1A, 0x00, 0x0F, 0x42, 0x40}), 5); assert_size_equal(cbor_serialized_size(item), 5); cbor_decref(&item); } static void test_serialize_uint64(void** _state _CBOR_UNUSED) { cbor_item_t* item = cbor_new_int64(); cbor_set_uint64(item, 1000000000000); assert_size_equal(9, cbor_serialize(item, buffer, 512)); assert_memory_equal( buffer, ((unsigned char[]){0x1B, 0x00, 0x00, 0x00, 0xE8, 0xD4, 0xA5, 0x10, 0x00}), 9); assert_size_equal(cbor_serialized_size(item), 9); cbor_decref(&item); } static void test_serialize_negint8_embed(void** _state _CBOR_UNUSED) { cbor_item_t* item = cbor_new_int8(); cbor_set_uint8(item, 0); cbor_mark_negint(item); assert_size_equal(1, cbor_serialize(item, buffer, 512)); assert_memory_equal(buffer, (unsigned char[]){0x20}, 1); assert_size_equal(cbor_serialized_size(item), 1); cbor_decref(&item); } static void test_serialize_negint8(void** _state _CBOR_UNUSED) { cbor_item_t* item = cbor_new_int8(); cbor_set_uint8(item, 42); cbor_mark_negint(item); assert_size_equal(2, cbor_serialize(item, buffer, 512)); assert_memory_equal(buffer, ((unsigned char[]){0x38, 0x2a}), 2); assert_size_equal(cbor_serialized_size(item), 2); cbor_decref(&item); } static void test_serialize_negint16(void** _state _CBOR_UNUSED) { cbor_item_t* item = cbor_new_int16(); cbor_set_uint16(item, 1000); cbor_mark_negint(item); assert_size_equal(3, cbor_serialize(item, buffer, 512)); assert_memory_equal(buffer, ((unsigned char[]){0x39, 0x03, 0xE8}), 3); assert_size_equal(cbor_serialized_size(item), 3); cbor_decref(&item); } static void test_serialize_negint32(void** _state _CBOR_UNUSED) { cbor_item_t* item = cbor_new_int32(); cbor_set_uint32(item, 1000000); cbor_mark_negint(item); assert_size_equal(5, cbor_serialize(item, buffer, 512)); assert_memory_equal(buffer, ((unsigned char[]){0x3A, 0x00, 0x0F, 0x42, 0x40}), 5); assert_size_equal(cbor_serialized_size(item), 5); cbor_decref(&item); } static void test_serialize_negint64(void** _state _CBOR_UNUSED) { cbor_item_t* item = cbor_new_int64(); cbor_set_uint64(item, 1000000000000); cbor_mark_negint(item); assert_size_equal(9, cbor_serialize(item, buffer, 512)); assert_memory_equal( buffer, ((unsigned char[]){0x3B, 0x00, 0x00, 0x00, 0xE8, 0xD4, 0xA5, 0x10, 0x00}), 9); assert_size_equal(cbor_serialized_size(item), 9); cbor_decref(&item); } static void test_serialize_definite_bytestring(void** _state _CBOR_UNUSED) { cbor_item_t* item = cbor_new_definite_bytestring(); unsigned char* data = malloc(256); cbor_bytestring_set_handle(item, data, 256); memset(data, 0, 256); /* Prevent undefined behavior in comparison */ assert_size_equal(256 + 3, cbor_serialize(item, buffer, 512)); assert_memory_equal(buffer, ((unsigned char[]){0x59, 0x01, 0x00}), 3); assert_memory_equal(buffer + 3, data, 256); assert_size_equal(cbor_serialized_size(item), 259); cbor_decref(&item); } static void test_serialize_indefinite_bytestring(void** _state _CBOR_UNUSED) { cbor_item_t* item = cbor_new_indefinite_bytestring(); cbor_item_t* chunk = cbor_new_definite_bytestring(); unsigned char* data = malloc(256); memset(data, 0, 256); /* Prevent undefined behavior in comparison */ cbor_bytestring_set_handle(chunk, data, 256); assert_true(cbor_bytestring_add_chunk(item, cbor_move(chunk))); assert_size_equal(cbor_bytestring_chunk_count(item), 1); assert_size_equal(1 + 3 + 256 + 1, cbor_serialize(item, buffer, 512)); assert_memory_equal(buffer, ((unsigned char[]){0x5F, 0x59, 0x01, 0x00}), 4); assert_memory_equal(buffer + 4, data, 256); assert_memory_equal(buffer + 4 + 256, ((unsigned char[]){0xFF}), 1); assert_size_equal(cbor_serialized_size(item), 261); cbor_decref(&item); } static void test_serialize_bytestring_size_overflow( void** _state _CBOR_UNUSED) { cbor_item_t* item = cbor_new_definite_bytestring(); // Fake having a huge chunk of data unsigned char* data = malloc(1); cbor_bytestring_set_handle(item, data, SIZE_MAX); // Would require 1 + 8 + SIZE_MAX bytes, which overflows size_t assert_size_equal(cbor_serialize(item, buffer, 512), 0); assert_size_equal(cbor_serialized_size(item), 0); cbor_decref(&item); } static void test_serialize_string_size_overflow(void** _state _CBOR_UNUSED) { cbor_item_t* item = cbor_new_definite_string(); // Fake having a huge chunk of data. Set fields directly to avoid // cbor_string_set_handle's UTF-8 validation reading out of bounds. unsigned char* data = malloc(1); item->data = data; item->metadata.string_metadata.length = SIZE_MAX; // Would require 1 + 8 + SIZE_MAX bytes, which overflows size_t assert_size_equal(cbor_serialize(item, buffer, 512), 0); assert_size_equal(cbor_serialized_size(item), 0); cbor_decref(&item); } static void test_serialize_indef_bytestring_size_overflow( void** _state _CBOR_UNUSED) { cbor_item_t* item = cbor_new_indefinite_bytestring(); cbor_item_t* chunk = cbor_new_definite_bytestring(); // Fake a chunk with SIZE_MAX length so the total overflows unsigned char* data = malloc(1); cbor_bytestring_set_handle(chunk, data, SIZE_MAX); cbor_bytestring_add_chunk(item, cbor_move(chunk)); assert_size_equal(cbor_serialized_size(item), 0); cbor_decref(&item); } static void test_serialize_indef_string_size_overflow( void** _state _CBOR_UNUSED) { cbor_item_t* item = cbor_new_indefinite_string(); cbor_item_t* chunk = cbor_new_definite_string(); // Fake a chunk with SIZE_MAX length so the total overflows. Set fields // directly to avoid cbor_string_set_handle's UTF-8 validation. unsigned char* data = malloc(1); chunk->data = data; chunk->metadata.string_metadata.length = SIZE_MAX; cbor_string_add_chunk(item, cbor_move(chunk)); assert_size_equal(cbor_serialized_size(item), 0); cbor_decref(&item); } static void test_serialize_bytestring_no_space(void** _state _CBOR_UNUSED) { cbor_item_t* item = cbor_new_definite_bytestring(); unsigned char* data = malloc(12); cbor_bytestring_set_handle(item, data, 12); assert_size_equal(cbor_serialize(item, buffer, 1), 0); cbor_decref(&item); } static void test_serialize_indefinite_bytestring_no_space( void** _state _CBOR_UNUSED) { cbor_item_t* item = cbor_new_indefinite_bytestring(); cbor_item_t* chunk = cbor_new_definite_bytestring(); unsigned char* data = malloc(256); cbor_bytestring_set_handle(chunk, data, 256); assert_true(cbor_bytestring_add_chunk(item, cbor_move(chunk))); // Not enough space for the leading byte assert_size_equal(cbor_serialize(item, buffer, 0), 0); // Not enough space for the chunk assert_size_equal(cbor_serialize(item, buffer, 30), 0); // Not enough space for the indef break assert_size_equal( cbor_serialize(item, buffer, 1 + cbor_serialized_size(chunk)), 0); cbor_decref(&item); } static void test_serialize_definite_string(void** _state _CBOR_UNUSED) { cbor_item_t* item = cbor_new_definite_string(); unsigned char* data = malloc(12); strncpy((char*)data, "Hello world!", 12); cbor_string_set_handle(item, data, 12); assert_size_equal(1 + 12, cbor_serialize(item, buffer, 512)); assert_memory_equal( buffer, ((unsigned char[]){0x6C, 0x48, 0x65, 0x6C, 0x6C, 0x6F, 0x20, 0x77, 0x6F, 0x72, 0x6C, 0x64, 0x21}), 13); assert_size_equal(cbor_serialized_size(item), 13); cbor_decref(&item); } static void test_serialize_definite_string_4b_header( void** _state _CBOR_UNUSED) { #if SIZE_MAX > UINT16_MAX cbor_item_t* item = cbor_new_definite_string(); const size_t size = (size_t)UINT16_MAX + 1; unsigned char* data = malloc(size); memset(data, 0, size); cbor_string_set_handle(item, data, size); assert_size_equal(cbor_serialized_size(item), 1 + 4 + size); cbor_decref(&item); #endif } static void test_serialize_definite_string_8b_header( void** _state _CBOR_UNUSED) { #if SIZE_MAX > UINT32_MAX cbor_item_t* item = cbor_new_definite_string(); const size_t size = (size_t)UINT32_MAX + 1; unsigned char* data = malloc(1); data[0] = '\0'; cbor_string_set_handle(item, data, 1); // Pretend that we have a big item to avoid the huge malloc item->metadata.string_metadata.length = size; assert_size_equal(cbor_serialized_size(item), 1 + 8 + size); cbor_decref(&item); #endif } static void test_serialize_indefinite_string(void** _state _CBOR_UNUSED) { cbor_item_t* item = cbor_new_indefinite_string(); cbor_item_t* chunk = cbor_new_definite_string(); unsigned char* data = malloc(12); strncpy((char*)data, "Hello world!", 12); cbor_string_set_handle(chunk, data, 12); assert_true(cbor_string_add_chunk(item, cbor_move(chunk))); assert_size_equal(cbor_string_chunk_count(item), 1); assert_size_equal(15, cbor_serialize(item, buffer, 512)); assert_memory_equal( buffer, ((unsigned char[]){0x7F, 0x6C, 0x48, 0x65, 0x6C, 0x6C, 0x6F, 0x20, 0x77, 0x6F, 0x72, 0x6C, 0x64, 0x21, 0xFF}), 15); assert_size_equal(cbor_serialized_size(item), 15); cbor_decref(&item); } static void test_serialize_string_no_space(void** _state _CBOR_UNUSED) { cbor_item_t* item = cbor_new_definite_string(); unsigned char* data = malloc(12); memset(data, 0, 12); cbor_string_set_handle(item, data, 12); assert_size_equal(cbor_serialize(item, buffer, 1), 0); cbor_decref(&item); } static void test_serialize_indefinite_string_no_space( void** _state _CBOR_UNUSED) { cbor_item_t* item = cbor_new_indefinite_string(); cbor_item_t* chunk = cbor_new_definite_string(); unsigned char* data = malloc(256); memset(data, 0, 256); cbor_string_set_handle(chunk, data, 256); assert_true(cbor_string_add_chunk(item, cbor_move(chunk))); // Not enough space for the leading byte assert_size_equal(cbor_serialize(item, buffer, 0), 0); // Not enough space for the chunk assert_size_equal(cbor_serialize(item, buffer, 30), 0); // Not enough space for the indef break assert_size_equal( cbor_serialize(item, buffer, 1 + cbor_serialized_size(chunk)), 0); cbor_decref(&item); } static void test_serialize_definite_array(void** _state _CBOR_UNUSED) { cbor_item_t* item = cbor_new_definite_array(2); cbor_item_t* one = cbor_build_uint8(1); cbor_item_t* two = cbor_build_uint8(2); assert_true(cbor_array_push(item, one)); assert_true(cbor_array_set(item, 1, two)); assert_true(cbor_array_replace(item, 0, one)); assert_size_equal(3, cbor_serialize(item, buffer, 512)); assert_memory_equal(buffer, ((unsigned char[]){0x82, 0x01, 0x02}), 3); assert_size_equal(cbor_serialized_size(item), 3); cbor_decref(&item); cbor_decref(&one); cbor_decref(&two); } static void test_serialize_array_no_space(void** _state _CBOR_UNUSED) { cbor_item_t* item = cbor_new_indefinite_array(); cbor_item_t* one = cbor_build_uint8(1); assert_true(cbor_array_push(item, one)); assert_size_equal(cbor_serialized_size(item), 3); // Not enough space for the leading byte assert_size_equal(0, cbor_serialize(item, buffer, 0)); // Not enough space for the item assert_size_equal(0, cbor_serialize(item, buffer, 1)); // Not enough space for the indef break assert_size_equal(0, cbor_serialize(item, buffer, 2)); cbor_decref(&item); cbor_decref(&one); } static void test_serialize_indefinite_array(void** _state _CBOR_UNUSED) { cbor_item_t* item = cbor_new_indefinite_array(); cbor_item_t* one = cbor_build_uint8(1); cbor_item_t* two = cbor_build_uint8(2); assert_true(cbor_array_push(item, one)); assert_true(cbor_array_push(item, two)); assert_size_equal(4, cbor_serialize(item, buffer, 512)); assert_memory_equal(buffer, ((unsigned char[]){0x9F, 0x01, 0x02, 0xFF}), 4); assert_size_equal(cbor_serialized_size(item), 4); cbor_decref(&item); cbor_decref(&one); cbor_decref(&two); } static void test_serialize_definite_map(void** _state _CBOR_UNUSED) { cbor_item_t* item = cbor_new_definite_map(2); cbor_item_t* one = cbor_build_uint8(1); cbor_item_t* two = cbor_build_uint8(2); assert_true(cbor_map_add(item, (struct cbor_pair){.key = one, .value = two})); assert_true(cbor_map_add(item, (struct cbor_pair){.key = two, .value = one})); assert_size_equal(5, cbor_serialize(item, buffer, 512)); assert_memory_equal(buffer, ((unsigned char[]){0xA2, 0x01, 0x02, 0x02, 0x01}), 5); assert_size_equal(cbor_serialized_size(item), 5); cbor_decref(&item); cbor_decref(&one); cbor_decref(&two); } static void test_serialize_indefinite_map(void** _state _CBOR_UNUSED) { cbor_item_t* item = cbor_new_indefinite_map(); cbor_item_t* one = cbor_build_uint8(1); cbor_item_t* two = cbor_build_uint8(2); assert_true(cbor_map_add(item, (struct cbor_pair){.key = one, .value = two})); assert_true(cbor_map_add(item, (struct cbor_pair){.key = two, .value = one})); assert_size_equal(6, cbor_serialize(item, buffer, 512)); assert_memory_equal( buffer, ((unsigned char[]){0xBF, 0x01, 0x02, 0x02, 0x01, 0xFF}), 6); assert_size_equal(cbor_serialized_size(item), 6); cbor_decref(&item); cbor_decref(&one); cbor_decref(&two); } static void test_serialize_map_no_space(void** _state _CBOR_UNUSED) { cbor_item_t* item = cbor_new_indefinite_map(); cbor_item_t* one = cbor_build_uint8(1); cbor_item_t* two = cbor_build_uint8(2); assert_true(cbor_map_add(item, (struct cbor_pair){.key = one, .value = two})); assert_size_equal(cbor_serialized_size(item), 4); // Not enough space for the leading byte assert_size_equal(cbor_serialize(item, buffer, 0), 0); // Not enough space for the key assert_size_equal(cbor_serialize(item, buffer, 1), 0); // Not enough space for the value assert_size_equal(cbor_serialize(item, buffer, 2), 0); // Not enough space for the indef break assert_size_equal(cbor_serialize(item, buffer, 3), 0); cbor_decref(&item); cbor_decref(&one); cbor_decref(&two); } static void test_serialize_tags(void** _state _CBOR_UNUSED) { cbor_item_t* item = cbor_new_tag(21); cbor_item_t* one = cbor_build_uint8(1); cbor_tag_set_item(item, one); assert_size_equal(2, cbor_serialize(item, buffer, 512)); assert_memory_equal(buffer, ((unsigned char[]){0xD5, 0x01}), 2); assert_size_equal(cbor_serialized_size(item), 2); cbor_decref(&item); cbor_decref(&one); } static void test_serialized_size_tag_no_item(void** _state _CBOR_UNUSED) { cbor_item_t* item = cbor_new_tag(21); // cbor_tag_item returns NULL, cbor_move(NULL) crashes without the fix assert_size_equal(cbor_serialized_size(item), 0); cbor_decref(&item); } static void test_serialize_tag_no_item(void** _state _CBOR_UNUSED) { cbor_item_t* item = cbor_new_tag(21); // cbor_tag_item returns NULL, cbor_move(NULL) crashes without the fix assert_size_equal(cbor_serialize(item, buffer, 512), 0); cbor_decref(&item); } static void test_serialize_tags_no_space(void** _state _CBOR_UNUSED) { cbor_item_t* item = cbor_new_tag(21); cbor_item_t* one = cbor_build_uint8(1); cbor_tag_set_item(item, one); assert_size_equal(cbor_serialized_size(item), 2); // Not enough space for the leading byte assert_size_equal(cbor_serialize(item, buffer, 0), 0); // Not enough space for the item assert_size_equal(cbor_serialize(item, buffer, 1), 0); cbor_decref(&item); cbor_decref(&one); } static void test_serialize_half(void** _state _CBOR_UNUSED) { cbor_item_t* item = cbor_new_float2(); cbor_set_float2(item, NAN); assert_size_equal(3, cbor_serialize(item, buffer, 512)); /* The C NAN constant has platform-specific bits (e.g. MIPS legacy NaN). * Check structural validity: CBOR half marker, all exponent bits set, * non-zero mantissa (distinguishes NaN from Infinity). */ assert_int_equal(buffer[0], 0xF9); assert_true((buffer[1] & 0x7C) == 0x7C); assert_true((buffer[1] & 0x03) || buffer[2]); assert_size_equal(cbor_serialized_size(item), 3); cbor_decref(&item); } static void test_serialize_single(void** _state _CBOR_UNUSED) { cbor_item_t* item = cbor_new_float4(); cbor_set_float4(item, 100000.0f); assert_size_equal(5, cbor_serialize(item, buffer, 512)); assert_memory_equal(buffer, ((unsigned char[]){0xFA, 0x47, 0xC3, 0x50, 0x00}), 5); assert_size_equal(cbor_serialized_size(item), 5); cbor_decref(&item); } static void test_serialize_double(void** _state _CBOR_UNUSED) { cbor_item_t* item = cbor_new_float8(); cbor_set_float8(item, -4.1); assert_size_equal(9, cbor_serialize(item, buffer, 512)); assert_memory_equal( buffer, ((unsigned char[]){0xFB, 0xC0, 0x10, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66}), 9); assert_size_equal(cbor_serialized_size(item), 9); cbor_decref(&item); } static void test_serialize_ctrl(void** _state _CBOR_UNUSED) { cbor_item_t* item = cbor_new_undef(); assert_size_equal(1, cbor_serialize(item, buffer, 512)); assert_memory_equal(buffer, ((unsigned char[]){0xF7}), 1); assert_size_equal(cbor_serialized_size(item), 1); cbor_decref(&item); } static void test_serialize_long_ctrl(void** _state _CBOR_UNUSED) { cbor_item_t* item = cbor_new_ctrl(); cbor_set_ctrl(item, 254); assert_size_equal(2, cbor_serialize(item, buffer, 512)); assert_memory_equal(buffer, ((unsigned char[]){0xF8, 0xFE}), 2); assert_size_equal(cbor_serialized_size(item), 2); cbor_decref(&item); } static void test_auto_serialize(void** _state _CBOR_UNUSED) { cbor_item_t* item = cbor_new_definite_array(4); for (size_t i = 0; i < 4; i++) { assert_true(cbor_array_push(item, cbor_move(cbor_build_uint64(0)))); } unsigned char* output; size_t output_size; assert_size_equal(cbor_serialize_alloc(item, &output, &output_size), 37); assert_size_equal(output_size, 37); assert_size_equal(cbor_serialized_size(item), 37); assert_memory_equal(output, ((unsigned char[]){0x84, 0x1B}), 2); cbor_decref(&item); _cbor_free(output); } static void test_auto_serialize_no_size(void** _state _CBOR_UNUSED) { cbor_item_t* item = cbor_build_uint8(1); unsigned char* output; assert_size_equal(cbor_serialize_alloc(item, &output, NULL), 1); assert_memory_equal(output, ((unsigned char[]){0x01}), 1); assert_size_equal(cbor_serialized_size(item), 1); cbor_decref(&item); _cbor_free(output); } static void test_auto_serialize_too_large(void** _state _CBOR_UNUSED) { cbor_item_t* item = cbor_new_indefinite_string(); cbor_item_t* chunk = cbor_new_definite_string(); assert_true(cbor_string_add_chunk(item, chunk)); // Pretend the chunk is huge chunk->metadata.string_metadata.length = SIZE_MAX; assert_true(SIZE_MAX + 2 == 1); assert_size_equal(cbor_serialized_size(item), 0); unsigned char* output; size_t output_size; assert_size_equal(cbor_serialize_alloc(item, &output, &output_size), 0); assert_size_equal(output_size, 0); assert_null(output); chunk->metadata.string_metadata.length = 0; cbor_decref(&chunk); cbor_decref(&item); } static void test_auto_serialize_alloc_fail(void** _state _CBOR_UNUSED) { cbor_item_t* item = cbor_build_uint8(42); WITH_FAILING_MALLOC({ unsigned char* output; size_t output_size; assert_size_equal(cbor_serialize_alloc(item, &output, &output_size), 0); assert_size_equal(output_size, 0); assert_null(output); }); cbor_decref(&item); } static void test_auto_serialize_zero_len_bytestring( void** _state _CBOR_UNUSED) { cbor_item_t* item = cbor_build_bytestring((cbor_data) "", 0); unsigned char* output; assert_size_equal(cbor_serialize_alloc(item, &output, NULL), 1); assert_memory_equal(output, ((unsigned char[]){0x40}), 1); assert_size_equal(cbor_serialized_size(item), 1); cbor_decref(&item); _cbor_free(output); } static void test_auto_serialize_zero_len_string(void** _state _CBOR_UNUSED) { cbor_item_t* item = cbor_build_string(""); unsigned char* output; assert_size_equal(cbor_serialize_alloc(item, &output, NULL), 1); assert_memory_equal(output, ((unsigned char[]){0x60}), 1); assert_size_equal(cbor_serialized_size(item), 1); cbor_decref(&item); _cbor_free(output); } static void test_auto_serialize_zero_len_bytestring_chunk( void** _state _CBOR_UNUSED) { cbor_item_t* item = cbor_new_indefinite_bytestring(); assert_true(cbor_bytestring_add_chunk( item, cbor_move(cbor_build_bytestring((cbor_data) "", 0)))); unsigned char* output; assert_size_equal(cbor_serialize_alloc(item, &output, NULL), 3); assert_memory_equal(output, ((unsigned char[]){0x5f, 0x40, 0xff}), 3); assert_size_equal(cbor_serialized_size(item), 3); cbor_decref(&item); _cbor_free(output); } static void test_auto_serialize_zero_len_string_chunk( void** _state _CBOR_UNUSED) { cbor_item_t* item = cbor_new_indefinite_string(); assert_true(cbor_string_add_chunk(item, cbor_move(cbor_build_string("")))); unsigned char* output; assert_size_equal(cbor_serialize_alloc(item, &output, NULL), 3); assert_memory_equal(output, ((unsigned char[]){0x7f, 0x60, 0xff}), 3); assert_size_equal(cbor_serialized_size(item), 3); cbor_decref(&item); _cbor_free(output); } static void test_auto_serialize_zero_len_array(void** _state _CBOR_UNUSED) { cbor_item_t* item = cbor_new_definite_array(0); unsigned char* output; assert_size_equal(cbor_serialize_alloc(item, &output, NULL), 1); assert_memory_equal(output, ((unsigned char[]){0x80}), 1); assert_size_equal(cbor_serialized_size(item), 1); cbor_decref(&item); _cbor_free(output); } static void test_auto_serialize_zero_len_indef_array( void** _state _CBOR_UNUSED) { cbor_item_t* item = cbor_new_indefinite_array(); unsigned char* output; assert_size_equal(cbor_serialize_alloc(item, &output, NULL), 2); assert_memory_equal(output, ((unsigned char[]){0x9f, 0xff}), 2); assert_size_equal(cbor_serialized_size(item), 2); cbor_decref(&item); _cbor_free(output); } static void test_auto_serialize_zero_len_map(void** _state _CBOR_UNUSED) { cbor_item_t* item = cbor_new_definite_map(0); unsigned char* output; assert_size_equal(cbor_serialize_alloc(item, &output, NULL), 1); assert_memory_equal(output, ((unsigned char[]){0xa0}), 1); assert_size_equal(cbor_serialized_size(item), 1); cbor_decref(&item); _cbor_free(output); } static void test_auto_serialize_zero_len_indef_map(void** _state _CBOR_UNUSED) { cbor_item_t* item = cbor_new_indefinite_map(); unsigned char* output; assert_size_equal(cbor_serialize_alloc(item, &output, NULL), 2); assert_memory_equal(output, ((unsigned char[]){0xbf, 0xff}), 2); assert_size_equal(cbor_serialized_size(item), 2); cbor_decref(&item); _cbor_free(output); } int main(void) { const struct CMUnitTest tests[] = { cmocka_unit_test(test_serialize_uint8_embed), cmocka_unit_test(test_serialize_uint8), cmocka_unit_test(test_serialize_uint16), cmocka_unit_test(test_serialize_uint32), cmocka_unit_test(test_serialize_uint64), cmocka_unit_test(test_serialize_negint8_embed), cmocka_unit_test(test_serialize_negint8), cmocka_unit_test(test_serialize_negint16), cmocka_unit_test(test_serialize_negint32), cmocka_unit_test(test_serialize_negint64), cmocka_unit_test(test_serialize_definite_bytestring), cmocka_unit_test(test_serialize_indefinite_bytestring), cmocka_unit_test(test_serialize_bytestring_size_overflow), cmocka_unit_test(test_serialize_string_size_overflow), cmocka_unit_test(test_serialize_indef_bytestring_size_overflow), cmocka_unit_test(test_serialize_indef_string_size_overflow), cmocka_unit_test(test_serialize_bytestring_no_space), cmocka_unit_test(test_serialize_indefinite_bytestring_no_space), cmocka_unit_test(test_serialize_definite_string), cmocka_unit_test(test_serialize_definite_string_4b_header), cmocka_unit_test(test_serialize_definite_string_8b_header), cmocka_unit_test(test_serialize_indefinite_string), cmocka_unit_test(test_serialize_string_no_space), cmocka_unit_test(test_serialize_indefinite_string_no_space), cmocka_unit_test(test_serialize_definite_array), cmocka_unit_test(test_serialize_indefinite_array), cmocka_unit_test(test_serialize_array_no_space), cmocka_unit_test(test_serialize_definite_map), cmocka_unit_test(test_serialize_indefinite_map), cmocka_unit_test(test_serialize_map_no_space), cmocka_unit_test(test_serialize_tags), cmocka_unit_test(test_serialized_size_tag_no_item), cmocka_unit_test(test_serialize_tag_no_item), cmocka_unit_test(test_serialize_tags_no_space), cmocka_unit_test(test_serialize_half), cmocka_unit_test(test_serialize_single), cmocka_unit_test(test_serialize_double), cmocka_unit_test(test_serialize_ctrl), cmocka_unit_test(test_serialize_long_ctrl), cmocka_unit_test(test_auto_serialize), cmocka_unit_test(test_auto_serialize_no_size), cmocka_unit_test(test_auto_serialize_too_large), cmocka_unit_test(test_auto_serialize_alloc_fail), cmocka_unit_test(test_auto_serialize_zero_len_bytestring), cmocka_unit_test(test_auto_serialize_zero_len_string), cmocka_unit_test(test_auto_serialize_zero_len_bytestring_chunk), cmocka_unit_test(test_auto_serialize_zero_len_string_chunk), cmocka_unit_test(test_auto_serialize_zero_len_array), cmocka_unit_test(test_auto_serialize_zero_len_indef_array), cmocka_unit_test(test_auto_serialize_zero_len_map), cmocka_unit_test(test_auto_serialize_zero_len_indef_map), }; return cmocka_run_group_tests(tests, NULL, NULL); }