diff options
40 files changed, 3347 insertions, 3396 deletions
diff --git a/lib/libcbor/src/allocators.c b/lib/libcbor/src/allocators.c index ff22509a193..230306823f7 100644 --- a/lib/libcbor/src/allocators.c +++ b/lib/libcbor/src/allocators.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014-2017 Pavel Kalvoda <me@pavelkalvoda.com> + * Copyright (c) 2014-2019 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. @@ -11,9 +11,9 @@ _cbor_malloc_t _cbor_malloc = malloc; _cbor_realloc_t _cbor_realloc = realloc; _cbor_free_t _cbor_free = free; -void cbor_set_allocs(_cbor_malloc_t custom_malloc, _cbor_realloc_t custom_realloc, _cbor_free_t custom_free) -{ - _cbor_malloc = custom_malloc; - _cbor_realloc = custom_realloc; - _cbor_free = custom_free; +void cbor_set_allocs(_cbor_malloc_t custom_malloc, + _cbor_realloc_t custom_realloc, _cbor_free_t custom_free) { + _cbor_malloc = custom_malloc; + _cbor_realloc = custom_realloc; + _cbor_free = custom_free; } diff --git a/lib/libcbor/src/cbor.c b/lib/libcbor/src/cbor.c index 86a3012480c..b0b9dfd6cf5 100644 --- a/lib/libcbor/src/cbor.c +++ b/lib/libcbor/src/cbor.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014-2017 Pavel Kalvoda <me@pavelkalvoda.com> + * Copyright (c) 2014-2019 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. @@ -9,383 +9,339 @@ #include "cbor/internal/builder_callbacks.h" #include "cbor/internal/loaders.h" -cbor_item_t * cbor_load(cbor_data source, - size_t source_size, - struct cbor_load_result *result) -{ - /* Context stack */ - static struct cbor_callbacks callbacks = { - .uint8 = &cbor_builder_uint8_callback, - .uint16 = &cbor_builder_uint16_callback, - .uint32 = &cbor_builder_uint32_callback, - .uint64 = &cbor_builder_uint64_callback, - - .negint8 = &cbor_builder_negint8_callback, - .negint16 = &cbor_builder_negint16_callback, - .negint32 = &cbor_builder_negint32_callback, - .negint64 = &cbor_builder_negint64_callback, - - .byte_string = &cbor_builder_byte_string_callback, - .byte_string_start = &cbor_builder_byte_string_start_callback, - - .string = &cbor_builder_string_callback, - .string_start = &cbor_builder_string_start_callback, - - .array_start = &cbor_builder_array_start_callback, - .indef_array_start = &cbor_builder_indef_array_start_callback, - - .map_start = &cbor_builder_map_start_callback, - .indef_map_start = &cbor_builder_indef_map_start_callback, - - .tag = &cbor_builder_tag_callback, - - .null = &cbor_builder_null_callback, - .undefined = &cbor_builder_undefined_callback, - .boolean = &cbor_builder_boolean_callback, - .float2 = &cbor_builder_float2_callback, - .float4 = &cbor_builder_float4_callback, - .float8 = &cbor_builder_float8_callback, - .indef_break = &cbor_builder_indef_break_callback - }; - - if (source_size == 0) { - result->error.code = CBOR_ERR_NODATA; - return NULL; - } - struct _cbor_stack stack = _cbor_stack_init(); - - /* Target for callbacks */ - struct _cbor_decoder_context context = (struct _cbor_decoder_context) { - .stack = &stack, - .creation_failed = false, - .syntax_error = false - }; - struct cbor_decoder_result decode_result; - *result = (struct cbor_load_result) {.read = 0, .error = {.code = CBOR_ERR_NONE}}; - - do { - if (source_size > result->read) { /* Check for overflows */ - decode_result = cbor_stream_decode( - source + result->read, - source_size - result->read, - &callbacks, - &context); - } else { - result->error = (struct cbor_error) { - .code = CBOR_ERR_NOTENOUGHDATA, - .position = result->read - }; - goto error; - } - - switch (decode_result.status) { - case CBOR_DECODER_FINISHED: - /* Everything OK */ - { - result->read += decode_result.read; - break; - } - case CBOR_DECODER_NEDATA: - /* Data length doesn't match MTB expectation */ - { - result->error.code = CBOR_ERR_NOTENOUGHDATA; - goto error; - } - case CBOR_DECODER_EBUFFER: - /* Fallthrough */ - case CBOR_DECODER_ERROR: - /* Reserved/malformated item */ - { - result->error.code = CBOR_ERR_MALFORMATED; - goto error; - } - } - - if (context.creation_failed) { - /* Most likely unsuccessful allocation - our callback has failed */ - result->error.code = CBOR_ERR_MEMERROR; - goto error; - } else if (context.syntax_error) { - result->error.code = CBOR_ERR_SYNTAXERROR; - goto error; - } - } while (stack.size > 0); - - /* Move the result before free */ - cbor_item_t *result_item = context.root; - return result_item; - - error: - result->error.position = result->read; - //debug_print("Failed with decoder error %d at %d\n", result->error.code, result->error.position); - //cbor_describe(stack.top->item, stdout); - /* Free the stack */ - while (stack.size > 0) { - cbor_decref(&stack.top->item); - _cbor_stack_pop(&stack); - } - return NULL; +cbor_item_t *cbor_load(cbor_data source, size_t source_size, + struct cbor_load_result *result) { + /* Context stack */ + static struct cbor_callbacks callbacks = { + .uint8 = &cbor_builder_uint8_callback, + .uint16 = &cbor_builder_uint16_callback, + .uint32 = &cbor_builder_uint32_callback, + .uint64 = &cbor_builder_uint64_callback, + + .negint8 = &cbor_builder_negint8_callback, + .negint16 = &cbor_builder_negint16_callback, + .negint32 = &cbor_builder_negint32_callback, + .negint64 = &cbor_builder_negint64_callback, + + .byte_string = &cbor_builder_byte_string_callback, + .byte_string_start = &cbor_builder_byte_string_start_callback, + + .string = &cbor_builder_string_callback, + .string_start = &cbor_builder_string_start_callback, + + .array_start = &cbor_builder_array_start_callback, + .indef_array_start = &cbor_builder_indef_array_start_callback, + + .map_start = &cbor_builder_map_start_callback, + .indef_map_start = &cbor_builder_indef_map_start_callback, + + .tag = &cbor_builder_tag_callback, + + .null = &cbor_builder_null_callback, + .undefined = &cbor_builder_undefined_callback, + .boolean = &cbor_builder_boolean_callback, + .float2 = &cbor_builder_float2_callback, + .float4 = &cbor_builder_float4_callback, + .float8 = &cbor_builder_float8_callback, + .indef_break = &cbor_builder_indef_break_callback}; + + if (source_size == 0) { + result->error.code = CBOR_ERR_NODATA; + return NULL; + } + struct _cbor_stack stack = _cbor_stack_init(); + + /* Target for callbacks */ + struct _cbor_decoder_context context = (struct _cbor_decoder_context){ + .stack = &stack, .creation_failed = false, .syntax_error = false}; + struct cbor_decoder_result decode_result; + *result = + (struct cbor_load_result){.read = 0, .error = {.code = CBOR_ERR_NONE}}; + + do { + if (source_size > result->read) { /* Check for overflows */ + decode_result = + cbor_stream_decode(source + result->read, source_size - result->read, + &callbacks, &context); + } else { + result->error = (struct cbor_error){.code = CBOR_ERR_NOTENOUGHDATA, + .position = result->read}; + goto error; + } + + switch (decode_result.status) { + case CBOR_DECODER_FINISHED: + /* Everything OK */ + { + result->read += decode_result.read; + break; + } + case CBOR_DECODER_NEDATA: + /* Data length doesn't match MTB expectation */ + { + result->error.code = CBOR_ERR_NOTENOUGHDATA; + goto error; + } + case CBOR_DECODER_EBUFFER: + /* Fallthrough */ + case CBOR_DECODER_ERROR: + /* Reserved/malformated item */ + { + result->error.code = CBOR_ERR_MALFORMATED; + goto error; + } + } + + if (context.creation_failed) { + /* Most likely unsuccessful allocation - our callback has failed */ + result->error.code = CBOR_ERR_MEMERROR; + goto error; + } else if (context.syntax_error) { + result->error.code = CBOR_ERR_SYNTAXERROR; + goto error; + } + } while (stack.size > 0); + + /* Move the result before free */ + cbor_item_t *result_item = context.root; + return result_item; + +error: + result->error.position = result->read; + // debug_print("Failed with decoder error %d at %d\n", result->error.code, + // result->error.position); cbor_describe(stack.top->item, stdout); + /* Free the stack */ + while (stack.size > 0) { + cbor_decref(&stack.top->item); + _cbor_stack_pop(&stack); + } + return NULL; } - -static cbor_item_t * _cbor_copy_int(cbor_item_t * item, bool negative) -{ - cbor_item_t * res; - switch (cbor_int_get_width(item)) { - case CBOR_INT_8: res = cbor_build_uint8(cbor_get_uint8(item)); break; - case CBOR_INT_16: res = cbor_build_uint16(cbor_get_uint16(item)); break; - case CBOR_INT_32: res = cbor_build_uint32(cbor_get_uint32(item)); break; - case CBOR_INT_64: res = cbor_build_uint64(cbor_get_uint64(item)); break; - default: return NULL; - } - - if (negative) - cbor_mark_negint(res); - - return res; +static cbor_item_t *_cbor_copy_int(cbor_item_t *item, bool negative) { + cbor_item_t *res; + switch (cbor_int_get_width(item)) { + case CBOR_INT_8: + res = cbor_build_uint8(cbor_get_uint8(item)); + break; + case CBOR_INT_16: + res = cbor_build_uint16(cbor_get_uint16(item)); + break; + case CBOR_INT_32: + res = cbor_build_uint32(cbor_get_uint32(item)); + break; + case CBOR_INT_64: + res = cbor_build_uint64(cbor_get_uint64(item)); + break; + default: + return NULL; + } + + if (negative) cbor_mark_negint(res); + + return res; } -static cbor_item_t * _cbor_copy_float_ctrl(cbor_item_t * item) -{ - switch (cbor_float_get_width(item)) { - case CBOR_FLOAT_0: - return cbor_build_ctrl(cbor_ctrl_value(item)); - case CBOR_FLOAT_16: - return cbor_build_float2(cbor_float_get_float2(item)); - case CBOR_FLOAT_32: - return cbor_build_float4(cbor_float_get_float4(item)); - case CBOR_FLOAT_64: - return cbor_build_float8(cbor_float_get_float8(item)); - } - - return NULL; +static cbor_item_t *_cbor_copy_float_ctrl(cbor_item_t *item) { + switch (cbor_float_get_width(item)) { + case CBOR_FLOAT_0: + return cbor_build_ctrl(cbor_ctrl_value(item)); + case CBOR_FLOAT_16: + return cbor_build_float2(cbor_float_get_float2(item)); + case CBOR_FLOAT_32: + return cbor_build_float4(cbor_float_get_float4(item)); + case CBOR_FLOAT_64: + return cbor_build_float8(cbor_float_get_float8(item)); + } + + return NULL; } -cbor_item_t * cbor_copy(cbor_item_t * item) -{ - switch (cbor_typeof(item)) { - case CBOR_TYPE_UINT: - return _cbor_copy_int(item, false); - case CBOR_TYPE_NEGINT: - return _cbor_copy_int(item, true); - case CBOR_TYPE_BYTESTRING: - if (cbor_bytestring_is_definite(item)) { - return cbor_build_bytestring(cbor_bytestring_handle(item), cbor_bytestring_length(item)); - } else { - cbor_item_t * res = cbor_new_indefinite_bytestring(); - for (size_t i = 0; i < cbor_bytestring_chunk_count(item); i++) - cbor_bytestring_add_chunk( - res, - cbor_move( - cbor_copy(cbor_bytestring_chunks_handle(item)[i]) - ) - ); - return res; - } - case CBOR_TYPE_STRING: - if (cbor_string_is_definite(item)) { - return cbor_build_stringn((const char *) cbor_string_handle(item), cbor_string_length(item)); - } else { - cbor_item_t * res = cbor_new_indefinite_string(); - for (size_t i = 0; i < cbor_string_chunk_count(item); i++) - cbor_string_add_chunk( - res, - cbor_move( - cbor_copy(cbor_string_chunks_handle(item)[i]) - ) - ); - return res; - } - case CBOR_TYPE_ARRAY: { - cbor_item_t * res; - if (cbor_array_is_definite(item)) - res = cbor_new_definite_array(cbor_array_size(item)); - else - res = cbor_new_indefinite_array(); - - for (size_t i = 0; i < cbor_array_size(item); i++) - cbor_array_push( - res, - cbor_move(cbor_copy(cbor_move(cbor_array_get(item, i)))) - ); - return res; - } - case CBOR_TYPE_MAP: { - cbor_item_t * res; - if (cbor_map_is_definite(item)) - res = cbor_new_definite_map(cbor_map_size(item)); - else - res = cbor_new_indefinite_map(); - - struct cbor_pair * it = cbor_map_handle(item); - for (size_t i = 0; i < cbor_map_size(item); i++) - cbor_map_add(res, (struct cbor_pair) { - .key = cbor_move(cbor_copy(it[i].key)), - .value = cbor_move(cbor_copy(it[i].value)) - }); - return res; - } - case CBOR_TYPE_TAG: - return cbor_build_tag( - cbor_tag_value(item), - cbor_move(cbor_copy(cbor_tag_item(item))) - ); - case CBOR_TYPE_FLOAT_CTRL: - return _cbor_copy_float_ctrl(item); - } - - return NULL; +cbor_item_t *cbor_copy(cbor_item_t *item) { + switch (cbor_typeof(item)) { + case CBOR_TYPE_UINT: + return _cbor_copy_int(item, false); + case CBOR_TYPE_NEGINT: + return _cbor_copy_int(item, true); + case CBOR_TYPE_BYTESTRING: + if (cbor_bytestring_is_definite(item)) { + return cbor_build_bytestring(cbor_bytestring_handle(item), + cbor_bytestring_length(item)); + } else { + cbor_item_t *res = cbor_new_indefinite_bytestring(); + for (size_t i = 0; i < cbor_bytestring_chunk_count(item); i++) + cbor_bytestring_add_chunk( + res, + cbor_move(cbor_copy(cbor_bytestring_chunks_handle(item)[i]))); + return res; + } + case CBOR_TYPE_STRING: + if (cbor_string_is_definite(item)) { + return cbor_build_stringn((const char *)cbor_string_handle(item), + cbor_string_length(item)); + } else { + cbor_item_t *res = cbor_new_indefinite_string(); + for (size_t i = 0; i < cbor_string_chunk_count(item); i++) + cbor_string_add_chunk( + res, cbor_move(cbor_copy(cbor_string_chunks_handle(item)[i]))); + return res; + } + case CBOR_TYPE_ARRAY: { + cbor_item_t *res; + if (cbor_array_is_definite(item)) + res = cbor_new_definite_array(cbor_array_size(item)); + else + res = cbor_new_indefinite_array(); + + for (size_t i = 0; i < cbor_array_size(item); i++) + cbor_array_push( + res, cbor_move(cbor_copy(cbor_move(cbor_array_get(item, i))))); + return res; + } + case CBOR_TYPE_MAP: { + cbor_item_t *res; + if (cbor_map_is_definite(item)) + res = cbor_new_definite_map(cbor_map_size(item)); + else + res = cbor_new_indefinite_map(); + + struct cbor_pair *it = cbor_map_handle(item); + for (size_t i = 0; i < cbor_map_size(item); i++) + cbor_map_add(res, (struct cbor_pair){ + .key = cbor_move(cbor_copy(it[i].key)), + .value = cbor_move(cbor_copy(it[i].value))}); + return res; + } + case CBOR_TYPE_TAG: + return cbor_build_tag(cbor_tag_value(item), + cbor_move(cbor_copy(cbor_tag_item(item)))); + case CBOR_TYPE_FLOAT_CTRL: + return _cbor_copy_float_ctrl(item); + } + + return NULL; } #if CBOR_PRETTY_PRINTER #include <inttypes.h> -#include <wchar.h> #include <locale.h> #include <stdlib.h> +#include <wchar.h> #define __STDC_FORMAT_MACROS -static int _pow(int b, int ex) -{ - if (ex == 0) return 1; - int res = b; - while (--ex > 0) res *= b; - return res; +static int _pow(int b, int ex) { + if (ex == 0) return 1; + int res = b; + while (--ex > 0) res *= b; + return res; } -static void _cbor_nested_describe(cbor_item_t *item, FILE *out, int indent) -{ - setlocale(LC_ALL, ""); - switch (cbor_typeof(item)) { - case CBOR_TYPE_UINT: { - fprintf(out, "%*s[CBOR_TYPE_UINT] ", indent, " "); - fprintf(out, "Width: %dB, ", _pow(2, cbor_int_get_width(item))); - fprintf(out, "Value: %"PRIu64"\n", cbor_get_int(item)); - break; - }; - case CBOR_TYPE_NEGINT: { - fprintf(out, "%*s[CBOR_TYPE_NEGINT] ", indent, " "); - fprintf(out, "Width: %dB, ", _pow(2, cbor_int_get_width(item))); - fprintf(out, "Value: -%"PRIu64" -1\n", cbor_get_int(item)); - break; - }; - case CBOR_TYPE_BYTESTRING: { - fprintf(out, "%*s[CBOR_TYPE_BYTESTRING] ", indent, " "); - if (cbor_bytestring_is_indefinite(item)) { - fprintf(out, - "Indefinite, with %zu chunks:\n", - cbor_bytestring_chunk_count(item)); - for (size_t i = 0; i < cbor_bytestring_chunk_count(item); i++) - _cbor_nested_describe( - cbor_bytestring_chunks_handle(item)[i], - out, - indent + 4); - } else { - fprintf(out, - "Definite, length %zuB\n", - cbor_bytestring_length(item)); - } - break; - }; - case CBOR_TYPE_STRING: { - fprintf(out, "%*s[CBOR_TYPE_STRING] ", indent, " "); - if (cbor_string_is_indefinite(item)) { - fprintf(out, - "Indefinite, with %zu chunks:\n", - cbor_string_chunk_count(item)); - for (size_t i = 0; i < cbor_string_chunk_count(item); i++) - _cbor_nested_describe( - cbor_string_chunks_handle(item)[i], - out, - indent + 4); - } else { - fprintf(out, - "Definite, length %zuB, %zu codepoints\n", - cbor_string_length(item), - cbor_string_codepoint_count(item)); - /* Careful - this doesn't support multibyte characters! */ - /* Printing those is out of the scope of this demo :) */ - /* libICU is your friend */ - fprintf(out, "%*s", indent + 4, " "); - /* XXX: no null at the end -> confused vprintf */ - fwrite(cbor_string_handle(item), (int) cbor_string_length(item), 1, out); - fprintf(out, "\n"); - } - break; - }; - case CBOR_TYPE_ARRAY: { - fprintf(out, "%*s[CBOR_TYPE_ARRAY] ", indent, " "); - if (cbor_array_is_definite(item)) { - fprintf(out, - "Definite, size: %zu\n", - cbor_array_size(item)); - } else { - fprintf(out, - "Indefinite, size: %zu\n", - cbor_array_size(item)); - } - - for (size_t i = 0; i < cbor_array_size(item); i++) - _cbor_nested_describe( - cbor_array_handle(item)[i], - out, - indent + 4); - break; - }; - case CBOR_TYPE_MAP: { - fprintf(out, "%*s[CBOR_TYPE_MAP] ", indent, " "); - if (cbor_map_is_definite(item)) { - fprintf(out, - "Definite, size: %zu\n", - cbor_map_size(item)); - } else { - fprintf(out, - "Indefinite, size: %zu\n", - cbor_map_size(item)); - } - - for (size_t i = 0; i < cbor_map_size(item); i++) { - _cbor_nested_describe( - cbor_map_handle(item)[i].key, - out, - indent + 4); - _cbor_nested_describe( - cbor_map_handle(item)[i].value, - out, - indent + 4); - } - break; - }; - case CBOR_TYPE_TAG: { - fprintf(out, "%*s[CBOR_TYPE_TAG] ", indent, " "); - fprintf(out, "Value: %"PRIu64"\n", cbor_tag_value(item)); - _cbor_nested_describe(cbor_tag_item(item), out, indent + 4); - break; - }; - case CBOR_TYPE_FLOAT_CTRL: { - fprintf(out, "%*s[CBOR_TYPE_FLOAT_CTRL] ", indent, " "); - if (cbor_float_ctrl_is_ctrl(item)) { - if (cbor_is_bool(item)) - fprintf(out, "Bool: %s\n", cbor_ctrl_is_bool(item) ? "true" : "false"); - else if (cbor_is_undef(item)) - fprintf(out, "Undefined\n"); - else if (cbor_is_null(item)) - fprintf(out, "Null\n"); - else - fprintf(out, "Simple value %d\n", cbor_ctrl_value(item)); - } else { - fprintf(out, "Width: %dB, ", _pow(2, cbor_float_get_width(item))); - fprintf(out, "value: %lf\n", cbor_float_get_float(item)); - } - break; - }; - } +static void _cbor_nested_describe(cbor_item_t *item, FILE *out, int indent) { + setlocale(LC_ALL, ""); + switch (cbor_typeof(item)) { + case CBOR_TYPE_UINT: { + fprintf(out, "%*s[CBOR_TYPE_UINT] ", indent, " "); + fprintf(out, "Width: %dB, ", _pow(2, cbor_int_get_width(item))); + fprintf(out, "Value: %" PRIu64 "\n", cbor_get_int(item)); + break; + }; + case CBOR_TYPE_NEGINT: { + fprintf(out, "%*s[CBOR_TYPE_NEGINT] ", indent, " "); + fprintf(out, "Width: %dB, ", _pow(2, cbor_int_get_width(item))); + fprintf(out, "Value: -%" PRIu64 " -1\n", cbor_get_int(item)); + break; + }; + case CBOR_TYPE_BYTESTRING: { + fprintf(out, "%*s[CBOR_TYPE_BYTESTRING] ", indent, " "); + if (cbor_bytestring_is_indefinite(item)) { + fprintf(out, "Indefinite, with %zu chunks:\n", + cbor_bytestring_chunk_count(item)); + for (size_t i = 0; i < cbor_bytestring_chunk_count(item); i++) + _cbor_nested_describe(cbor_bytestring_chunks_handle(item)[i], out, + indent + 4); + } else { + fprintf(out, "Definite, length %zuB\n", cbor_bytestring_length(item)); + } + break; + }; + case CBOR_TYPE_STRING: { + fprintf(out, "%*s[CBOR_TYPE_STRING] ", indent, " "); + if (cbor_string_is_indefinite(item)) { + fprintf(out, "Indefinite, with %zu chunks:\n", + cbor_string_chunk_count(item)); + for (size_t i = 0; i < cbor_string_chunk_count(item); i++) + _cbor_nested_describe(cbor_string_chunks_handle(item)[i], out, + indent + 4); + } else { + fprintf(out, "Definite, length %zuB, %zu codepoints\n", + cbor_string_length(item), cbor_string_codepoint_count(item)); + /* Careful - this doesn't support multibyte characters! */ + /* Printing those is out of the scope of this demo :) */ + /* libICU is your friend */ + fprintf(out, "%*s", indent + 4, " "); + /* XXX: no null at the end -> confused vprintf */ + fwrite(cbor_string_handle(item), (int)cbor_string_length(item), 1, out); + fprintf(out, "\n"); + } + break; + }; + case CBOR_TYPE_ARRAY: { + fprintf(out, "%*s[CBOR_TYPE_ARRAY] ", indent, " "); + if (cbor_array_is_definite(item)) { + fprintf(out, "Definite, size: %zu\n", cbor_array_size(item)); + } else { + fprintf(out, "Indefinite, size: %zu\n", cbor_array_size(item)); + } + + for (size_t i = 0; i < cbor_array_size(item); i++) + _cbor_nested_describe(cbor_array_handle(item)[i], out, indent + 4); + break; + }; + case CBOR_TYPE_MAP: { + fprintf(out, "%*s[CBOR_TYPE_MAP] ", indent, " "); + if (cbor_map_is_definite(item)) { + fprintf(out, "Definite, size: %zu\n", cbor_map_size(item)); + } else { + fprintf(out, "Indefinite, size: %zu\n", cbor_map_size(item)); + } + + for (size_t i = 0; i < cbor_map_size(item); i++) { + _cbor_nested_describe(cbor_map_handle(item)[i].key, out, indent + 4); + _cbor_nested_describe(cbor_map_handle(item)[i].value, out, indent + 4); + } + break; + }; + case CBOR_TYPE_TAG: { + fprintf(out, "%*s[CBOR_TYPE_TAG] ", indent, " "); + fprintf(out, "Value: %" PRIu64 "\n", cbor_tag_value(item)); + _cbor_nested_describe(cbor_tag_item(item), out, indent + 4); + break; + }; + case CBOR_TYPE_FLOAT_CTRL: { + fprintf(out, "%*s[CBOR_TYPE_FLOAT_CTRL] ", indent, " "); + if (cbor_float_ctrl_is_ctrl(item)) { + if (cbor_is_bool(item)) + fprintf(out, "Bool: %s\n", + cbor_ctrl_is_bool(item) ? "true" : "false"); + else if (cbor_is_undef(item)) + fprintf(out, "Undefined\n"); + else if (cbor_is_null(item)) + fprintf(out, "Null\n"); + else + fprintf(out, "Simple value %d\n", cbor_ctrl_value(item)); + } else { + fprintf(out, "Width: %dB, ", _pow(2, cbor_float_get_width(item))); + fprintf(out, "value: %lf\n", cbor_float_get_float(item)); + } + break; + }; + } } -void cbor_describe(cbor_item_t *item, FILE *out) -{ - _cbor_nested_describe(item, out, 0); +void cbor_describe(cbor_item_t *item, FILE *out) { + _cbor_nested_describe(item, out, 0); } #endif diff --git a/lib/libcbor/src/cbor.h b/lib/libcbor/src/cbor.h index b8a857e2c67..5bf78e2e416 100644 --- a/lib/libcbor/src/cbor.h +++ b/lib/libcbor/src/cbor.h @@ -1,16 +1,15 @@ /* - * Copyright (c) 2014-2017 Pavel Kalvoda <me@pavelkalvoda.com> + * Copyright (c) 2014-2019 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. */ - #ifndef LIBCBOR_H_ #define LIBCBOR_H_ -#include "cbor/data.h" #include "cbor/common.h" +#include "cbor/data.h" #include "cbor/arrays.h" #include "cbor/bytestrings.h" @@ -20,9 +19,9 @@ #include "cbor/strings.h" #include "cbor/tags.h" +#include "cbor/callbacks.h" #include "cbor/encoding.h" #include "cbor/serialization.h" -#include "cbor/callbacks.h" #include "cbor/streaming.h" #ifdef __cplusplus @@ -30,21 +29,21 @@ extern "C" { #endif /* -* ============================================================================ -* High level decoding -* ============================================================================ -*/ + * ============================================================================ + * High level decoding + * ============================================================================ + */ /** Loads data item from a buffer * * @param source The buffer * @param source_size * @param result[out] Result indicator. #CBOR_ERR_NONE on success - * @return **new** CBOR item or `NULL` on failure. In that case, \p result contains location and description of the error. + * @return **new** CBOR item or `NULL` on failure. In that case, \p result + * contains location and description of the error. */ -cbor_item_t * cbor_load(cbor_data source, - size_t source_size, - struct cbor_load_result * result); +cbor_item_t* cbor_load(cbor_data source, size_t source_size, + struct cbor_load_result* result); /** Deep copy of an item * @@ -53,16 +52,16 @@ cbor_item_t * cbor_load(cbor_data source, * @param item[borrow] item to copy * @return **new** CBOR deep copy */ -cbor_item_t * cbor_copy(cbor_item_t * item); +cbor_item_t* cbor_copy(cbor_item_t* item); #if CBOR_PRETTY_PRINTER #include <stdio.h> -void cbor_describe(cbor_item_t * item, FILE * out); +void cbor_describe(cbor_item_t* item, FILE* out); #endif #ifdef __cplusplus } #endif -#endif //LIBCBOR_H_ +#endif // LIBCBOR_H_ diff --git a/lib/libcbor/src/cbor/arrays.c b/lib/libcbor/src/cbor/arrays.c index 4e3f0b67cf3..8a86cf102b7 100644 --- a/lib/libcbor/src/cbor/arrays.c +++ b/lib/libcbor/src/cbor/arrays.c @@ -1,157 +1,135 @@ /* - * Copyright (c) 2014-2017 Pavel Kalvoda <me@pavelkalvoda.com> + * Copyright (c) 2014-2019 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. */ -#include <string.h> #include "arrays.h" +#include <string.h> #include "internal/memory_utils.h" -size_t cbor_array_size(const cbor_item_t *item) -{ - assert(cbor_isa_array(item)); - return item->metadata.array_metadata.end_ptr; +size_t cbor_array_size(const cbor_item_t *item) { + assert(cbor_isa_array(item)); + return item->metadata.array_metadata.end_ptr; } -size_t cbor_array_allocated(const cbor_item_t * item) -{ - assert(cbor_isa_array(item)); - return item->metadata.array_metadata.allocated; +size_t cbor_array_allocated(const cbor_item_t *item) { + assert(cbor_isa_array(item)); + return item->metadata.array_metadata.allocated; } - -cbor_item_t * cbor_array_get(const cbor_item_t * item, size_t index) -{ - return cbor_incref(((cbor_item_t **) item->data)[index]); +cbor_item_t *cbor_array_get(const cbor_item_t *item, size_t index) { + return cbor_incref(((cbor_item_t **)item->data)[index]); } -bool cbor_array_set(cbor_item_t * item, size_t index, cbor_item_t * value) -{ - if (index == item->metadata.array_metadata.end_ptr) { - return cbor_array_push(item, value); - } else if (index < item->metadata.array_metadata.end_ptr) { - return cbor_array_replace(item, index, value); - } else { - return false; - } - return true; +bool cbor_array_set(cbor_item_t *item, size_t index, cbor_item_t *value) { + if (index == item->metadata.array_metadata.end_ptr) { + return cbor_array_push(item, value); + } else if (index < item->metadata.array_metadata.end_ptr) { + return cbor_array_replace(item, index, value); + } else { + return false; + } + // TODO: This is unreachable and the index checking logic above seems + // suspicious -- out of bounds index is a caller error. Figure out & fix. + return true; } -bool cbor_array_replace(cbor_item_t * item, size_t index, cbor_item_t * value) -{ - if (index >= item->metadata.array_metadata.end_ptr) - return false; - /* We cannot use cbor_array_get as that would increase the refcount */ - cbor_intermediate_decref(((cbor_item_t **) item->data)[index]); - ((cbor_item_t **) item->data)[index] = cbor_incref(value); - return true; +bool cbor_array_replace(cbor_item_t *item, size_t index, cbor_item_t *value) { + if (index >= item->metadata.array_metadata.end_ptr) return false; + /* We cannot use cbor_array_get as that would increase the refcount */ + cbor_intermediate_decref(((cbor_item_t **)item->data)[index]); + ((cbor_item_t **)item->data)[index] = cbor_incref(value); + return true; } -bool cbor_array_push(cbor_item_t *array, cbor_item_t *pushee) -{ - assert(cbor_isa_array(array)); - struct _cbor_array_metadata *metadata = (struct _cbor_array_metadata *) &array->metadata; - cbor_item_t **data = (cbor_item_t **) array->data; - if (cbor_array_is_definite(array)) { - /* Do not reallocate definite arrays */ - if (metadata->end_ptr >= metadata->allocated) { - return false; - } - data[metadata->end_ptr++] = pushee; - } else { - /* Exponential realloc */ - if (metadata->end_ptr >= metadata->allocated) { - // Check for overflows first - if (!_cbor_safe_to_multiply(CBOR_BUFFER_GROWTH, metadata->allocated)) { - return false; - } - - size_t new_allocation = metadata->allocated == 0 ? 1 : CBOR_BUFFER_GROWTH * metadata->allocated; - - unsigned char * new_data = _cbor_realloc_multiple(array->data, sizeof(cbor_item_t *), new_allocation); - if (new_data == NULL) { - return false; - } - - array->data = new_data; - metadata->allocated = new_allocation; - } - ((cbor_item_t **)array->data)[metadata->end_ptr++] = pushee; - } - cbor_incref(pushee); - return true; +bool cbor_array_push(cbor_item_t *array, cbor_item_t *pushee) { + assert(cbor_isa_array(array)); + struct _cbor_array_metadata *metadata = + (struct _cbor_array_metadata *)&array->metadata; + cbor_item_t **data = (cbor_item_t **)array->data; + if (cbor_array_is_definite(array)) { + /* Do not reallocate definite arrays */ + if (metadata->end_ptr >= metadata->allocated) { + return false; + } + data[metadata->end_ptr++] = pushee; + } else { + /* Exponential realloc */ + if (metadata->end_ptr >= metadata->allocated) { + // Check for overflows first + // TODO: Explicitly test this + if (!_cbor_safe_to_multiply(CBOR_BUFFER_GROWTH, metadata->allocated)) { + return false; + } + + size_t new_allocation = metadata->allocated == 0 + ? 1 + : CBOR_BUFFER_GROWTH * metadata->allocated; + + unsigned char *new_data = _cbor_realloc_multiple( + array->data, sizeof(cbor_item_t *), new_allocation); + if (new_data == NULL) { + return false; + } + + array->data = new_data; + metadata->allocated = new_allocation; + } + ((cbor_item_t **)array->data)[metadata->end_ptr++] = pushee; + } + cbor_incref(pushee); + return true; } - -bool cbor_array_is_definite(const cbor_item_t *item) -{ - assert(cbor_isa_array(item)); - return item->metadata.array_metadata.type == _CBOR_METADATA_DEFINITE; +bool cbor_array_is_definite(const cbor_item_t *item) { + assert(cbor_isa_array(item)); + return item->metadata.array_metadata.type == _CBOR_METADATA_DEFINITE; } -bool cbor_array_is_indefinite(const cbor_item_t *item) -{ - assert(cbor_isa_array(item)); - return item->metadata.array_metadata.type == _CBOR_METADATA_INDEFINITE; +bool cbor_array_is_indefinite(const cbor_item_t *item) { + assert(cbor_isa_array(item)); + return item->metadata.array_metadata.type == _CBOR_METADATA_INDEFINITE; } -cbor_item_t **cbor_array_handle(const cbor_item_t *item) -{ - assert(cbor_isa_array(item)); - return (cbor_item_t **) item->data; +cbor_item_t **cbor_array_handle(const cbor_item_t *item) { + assert(cbor_isa_array(item)); + return (cbor_item_t **)item->data; } -cbor_item_t *cbor_new_definite_array(size_t size) -{ - cbor_item_t *item = _CBOR_MALLOC(sizeof(cbor_item_t)); - if (item == NULL) { - return NULL; - } - - cbor_item_t ** data = _cbor_alloc_multiple(sizeof(cbor_item_t *), size); - if (data == NULL) { - _CBOR_FREE(item); - return NULL; - } - - for (size_t i = 0; i < size; i++) - data[i] = NULL; - - *item = (cbor_item_t) { - .refcount = 1, - .type = CBOR_TYPE_ARRAY, - .metadata = { - .array_metadata = { - .type = _CBOR_METADATA_DEFINITE, - .allocated = size, - .end_ptr = 0 - } - }, - .data = (unsigned char *)data - }; - - return item; +cbor_item_t *cbor_new_definite_array(size_t size) { + cbor_item_t *item = _CBOR_MALLOC(sizeof(cbor_item_t)); + _CBOR_NOTNULL(item); + cbor_item_t **data = _cbor_alloc_multiple(sizeof(cbor_item_t *), size); + _CBOR_DEPENDENT_NOTNULL(item, data); + + for (size_t i = 0; i < size; i++) { + data[i] = NULL; + } + + *item = (cbor_item_t){ + .refcount = 1, + .type = CBOR_TYPE_ARRAY, + .metadata = {.array_metadata = {.type = _CBOR_METADATA_DEFINITE, + .allocated = size, + .end_ptr = 0}}, + .data = (unsigned char *)data}; + + return item; } -cbor_item_t *cbor_new_indefinite_array() -{ - cbor_item_t *item = _CBOR_MALLOC(sizeof(cbor_item_t)); - if (item == NULL) - return NULL; - - *item = (cbor_item_t) { - .refcount = 1, - .type = CBOR_TYPE_ARRAY, - .metadata = { - .array_metadata = { - .type = _CBOR_METADATA_INDEFINITE, - .allocated = 0, - .end_ptr = 0 - } - }, - .data = NULL /* Can be safely realloc-ed */ - }; - return item; +cbor_item_t *cbor_new_indefinite_array() { + cbor_item_t *item = _CBOR_MALLOC(sizeof(cbor_item_t)); + _CBOR_NOTNULL(item); + + *item = (cbor_item_t){ + .refcount = 1, + .type = CBOR_TYPE_ARRAY, + .metadata = {.array_metadata = {.type = _CBOR_METADATA_INDEFINITE, + .allocated = 0, + .end_ptr = 0}}, + .data = NULL /* Can be safely realloc-ed */ + }; + return item; } diff --git a/lib/libcbor/src/cbor/arrays.h b/lib/libcbor/src/cbor/arrays.h index 62629f4e1c6..1e68689f462 100644 --- a/lib/libcbor/src/cbor/arrays.h +++ b/lib/libcbor/src/cbor/arrays.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014-2017 Pavel Kalvoda <me@pavelkalvoda.com> + * Copyright (c) 2014-2019 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. @@ -19,14 +19,14 @@ extern "C" { * @param item[borrow] An array * @return The number of members */ -size_t cbor_array_size(const cbor_item_t * item); +size_t cbor_array_size(const cbor_item_t* item); /** Get the size of the allocated storage * * @param item[borrow] An array * @return The size of the allocated storage (number of items) */ -size_t cbor_array_allocated(const cbor_item_t * item); +size_t cbor_array_allocated(const cbor_item_t* item); /** Get item by index * @@ -34,7 +34,7 @@ size_t cbor_array_allocated(const cbor_item_t * item); * @param index The index * @return **incref** The item, or `NULL` in case of boundary violation */ -cbor_item_t * cbor_array_get(const cbor_item_t * item, size_t index); +cbor_item_t* cbor_array_get(const cbor_item_t* item, size_t index); /** Set item by index * @@ -45,7 +45,7 @@ cbor_item_t * cbor_array_get(const cbor_item_t * item, size_t index); * @param index The index, first item is 0. * @return true on success, false on allocation failure. */ -bool cbor_array_set(cbor_item_t * item, size_t index, cbor_item_t * value); +bool cbor_array_set(cbor_item_t* item, size_t index, cbor_item_t* value); /** Replace item at an index * @@ -56,57 +56,58 @@ bool cbor_array_set(cbor_item_t * item, size_t index, cbor_item_t * value); * @param index The index, first item is 0. * @return true on success, false on allocation failure. */ -bool cbor_array_replace(cbor_item_t * item, size_t index, cbor_item_t * value); +bool cbor_array_replace(cbor_item_t* item, size_t index, cbor_item_t* value); /** Is the array definite? * * @param item[borrow] An array * @return Is the array definite? */ -bool cbor_array_is_definite(const cbor_item_t * item); +bool cbor_array_is_definite(const cbor_item_t* item); /** Is the array indefinite? * * @param item[borrow] An array * @return Is the array indefinite? */ -bool cbor_array_is_indefinite(const cbor_item_t * item); +bool cbor_array_is_indefinite(const cbor_item_t* item); /** Get the array contents * - * The items may be reordered and modified as long as references remain consistent. + * The items may be reordered and modified as long as references remain + * consistent. * * @param item[borrow] An array * @return #cbor_array_size items */ -cbor_item_t ** cbor_array_handle(const cbor_item_t * item); +cbor_item_t** cbor_array_handle(const cbor_item_t* item); /** Create new definite array * * @param size Number of slots to preallocate * @return **new** array or `NULL` upon malloc failure */ -cbor_item_t * cbor_new_definite_array(size_t size); +cbor_item_t* cbor_new_definite_array(size_t size); /** Create new indefinite array * * @return **new** array or `NULL` upon malloc failure */ -cbor_item_t * cbor_new_indefinite_array(); +cbor_item_t* cbor_new_indefinite_array(); /** Append to the end * - * For indefinite items, storage may be realloacted. For definite items, only the - * preallocated capacity is available. + * For indefinite items, storage may be realloacted. For definite items, only + * the preallocated capacity is available. * * @param array[borrow] An array * @param pushee[incref] The item to push * @return true on success, false on failure */ -bool cbor_array_push(cbor_item_t * array, cbor_item_t * pushee); +bool cbor_array_push(cbor_item_t* array, cbor_item_t* pushee); #ifdef __cplusplus } #endif -#endif //LIBCBOR_ARRAYS_H +#endif // LIBCBOR_ARRAYS_H diff --git a/lib/libcbor/src/cbor/bytestrings.c b/lib/libcbor/src/cbor/bytestrings.c index ada4832f0d9..3b96eeb34fa 100644 --- a/lib/libcbor/src/cbor/bytestrings.c +++ b/lib/libcbor/src/cbor/bytestrings.c @@ -1,118 +1,117 @@ /* - * Copyright (c) 2014-2017 Pavel Kalvoda <me@pavelkalvoda.com> + * Copyright (c) 2014-2019 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. */ -#include <string.h> #include "bytestrings.h" +#include <string.h> #include "internal/memory_utils.h" -size_t cbor_bytestring_length(const cbor_item_t *item) -{ - assert(cbor_isa_bytestring(item)); - return item->metadata.bytestring_metadata.length; +size_t cbor_bytestring_length(const cbor_item_t *item) { + assert(cbor_isa_bytestring(item)); + return item->metadata.bytestring_metadata.length; } -unsigned char *cbor_bytestring_handle(const cbor_item_t *item) -{ - assert(cbor_isa_bytestring(item)); - return item->data; +unsigned char *cbor_bytestring_handle(const cbor_item_t *item) { + assert(cbor_isa_bytestring(item)); + return item->data; } -bool cbor_bytestring_is_definite(const cbor_item_t *item) -{ - assert(cbor_isa_bytestring(item)); - return item->metadata.bytestring_metadata.type == _CBOR_METADATA_DEFINITE; +bool cbor_bytestring_is_definite(const cbor_item_t *item) { + assert(cbor_isa_bytestring(item)); + return item->metadata.bytestring_metadata.type == _CBOR_METADATA_DEFINITE; } -bool cbor_bytestring_is_indefinite(const cbor_item_t *item) -{ - return !cbor_bytestring_is_definite(item); +bool cbor_bytestring_is_indefinite(const cbor_item_t *item) { + return !cbor_bytestring_is_definite(item); } -cbor_item_t *cbor_new_definite_bytestring() -{ - cbor_item_t *item = _CBOR_MALLOC(sizeof(cbor_item_t)); - *item = (cbor_item_t) { - .refcount = 1, - .type = CBOR_TYPE_BYTESTRING, - .metadata = {.bytestring_metadata = {_CBOR_METADATA_DEFINITE, 0}} - }; - return item; +cbor_item_t *cbor_new_definite_bytestring() { + cbor_item_t *item = _CBOR_MALLOC(sizeof(cbor_item_t)); + _CBOR_NOTNULL(item); + *item = (cbor_item_t){ + .refcount = 1, + .type = CBOR_TYPE_BYTESTRING, + .metadata = {.bytestring_metadata = {_CBOR_METADATA_DEFINITE, 0}}}; + return item; } -cbor_item_t *cbor_new_indefinite_bytestring() -{ - cbor_item_t *item = _CBOR_MALLOC(sizeof(cbor_item_t)); - *item = (cbor_item_t) { - .refcount = 1, - .type = CBOR_TYPE_BYTESTRING, - .metadata = {.bytestring_metadata = {.type = _CBOR_METADATA_INDEFINITE, .length = 0}}, - .data = _CBOR_MALLOC(sizeof(struct cbor_indefinite_string_data)) - }; - *((struct cbor_indefinite_string_data *) item->data) = (struct cbor_indefinite_string_data) { - .chunk_count = 0, - .chunk_capacity = 0, - .chunks = NULL, - }; - return item; +cbor_item_t *cbor_new_indefinite_bytestring() { + cbor_item_t *item = _CBOR_MALLOC(sizeof(cbor_item_t)); + _CBOR_NOTNULL(item); + *item = (cbor_item_t){ + .refcount = 1, + .type = CBOR_TYPE_BYTESTRING, + .metadata = {.bytestring_metadata = {.type = _CBOR_METADATA_INDEFINITE, + .length = 0}}, + .data = _CBOR_MALLOC(sizeof(struct cbor_indefinite_string_data))}; + _CBOR_DEPENDENT_NOTNULL(item, item->data); + *((struct cbor_indefinite_string_data *)item->data) = + (struct cbor_indefinite_string_data){ + .chunk_count = 0, + .chunk_capacity = 0, + .chunks = NULL, + }; + return item; } -cbor_item_t *cbor_build_bytestring(cbor_data handle, size_t length) -{ - cbor_item_t *res = cbor_new_definite_bytestring(); - void * content = _CBOR_MALLOC(length); - memcpy(content, handle, length); - cbor_bytestring_set_handle(res, content, length); - return res; +cbor_item_t *cbor_build_bytestring(cbor_data handle, size_t length) { + cbor_item_t *item = cbor_new_definite_bytestring(); + _CBOR_NOTNULL(item); + void *content = _CBOR_MALLOC(length); + _CBOR_DEPENDENT_NOTNULL(item, content); + memcpy(content, handle, length); + cbor_bytestring_set_handle(item, content, length); + return item; } -void cbor_bytestring_set_handle(cbor_item_t *item, cbor_mutable_data CBOR_RESTRICT_POINTER data, size_t length) -{ - assert(cbor_isa_bytestring(item)); - assert(cbor_bytestring_is_definite(item)); - item->data = data; - item->metadata.bytestring_metadata.length = length; +void cbor_bytestring_set_handle(cbor_item_t *item, + cbor_mutable_data CBOR_RESTRICT_POINTER data, + size_t length) { + assert(cbor_isa_bytestring(item)); + assert(cbor_bytestring_is_definite(item)); + item->data = data; + item->metadata.bytestring_metadata.length = length; } -cbor_item_t **cbor_bytestring_chunks_handle(const cbor_item_t *item) -{ - assert(cbor_isa_bytestring(item)); - assert(cbor_bytestring_is_indefinite(item)); - return ((struct cbor_indefinite_string_data *) item->data)->chunks; +cbor_item_t **cbor_bytestring_chunks_handle(const cbor_item_t *item) { + assert(cbor_isa_bytestring(item)); + assert(cbor_bytestring_is_indefinite(item)); + return ((struct cbor_indefinite_string_data *)item->data)->chunks; } -size_t cbor_bytestring_chunk_count(const cbor_item_t *item) -{ - assert(cbor_isa_bytestring(item)); - assert(cbor_bytestring_is_indefinite(item)); - return ((struct cbor_indefinite_string_data *) item->data)->chunk_count; - +size_t cbor_bytestring_chunk_count(const cbor_item_t *item) { + assert(cbor_isa_bytestring(item)); + assert(cbor_bytestring_is_indefinite(item)); + return ((struct cbor_indefinite_string_data *)item->data)->chunk_count; } -bool cbor_bytestring_add_chunk(cbor_item_t *item, cbor_item_t *chunk) -{ - assert(cbor_isa_bytestring(item)); - assert(cbor_bytestring_is_indefinite(item)); - struct cbor_indefinite_string_data *data = (struct cbor_indefinite_string_data *) item->data; - if (data->chunk_count == data->chunk_capacity) { - /* We need more space */ - if (!_cbor_safe_to_multiply(CBOR_BUFFER_GROWTH, data->chunk_capacity)) { - return false; - } - - data->chunk_capacity = data->chunk_capacity == 0 ? 1 : CBOR_BUFFER_GROWTH * (data->chunk_capacity); - - cbor_item_t **new_chunks_data = _cbor_realloc_multiple(data->chunks, sizeof(cbor_item_t *), data->chunk_capacity); - - if (new_chunks_data == NULL) { - return false; - } - - data->chunks = new_chunks_data; - } - data->chunks[data->chunk_count++] = cbor_incref(chunk); - return true; +bool cbor_bytestring_add_chunk(cbor_item_t *item, cbor_item_t *chunk) { + assert(cbor_isa_bytestring(item)); + assert(cbor_bytestring_is_indefinite(item)); + struct cbor_indefinite_string_data *data = + (struct cbor_indefinite_string_data *)item->data; + if (data->chunk_count == data->chunk_capacity) { + // TODO: Add a test for this + if (!_cbor_safe_to_multiply(CBOR_BUFFER_GROWTH, data->chunk_capacity)) { + return false; + } + + size_t new_chunk_capacity = + data->chunk_capacity == 0 ? 1 + : CBOR_BUFFER_GROWTH * (data->chunk_capacity); + + cbor_item_t **new_chunks_data = _cbor_realloc_multiple( + data->chunks, sizeof(cbor_item_t *), new_chunk_capacity); + + if (new_chunks_data == NULL) { + return false; + } + data->chunk_capacity = new_chunk_capacity; + data->chunks = new_chunks_data; + } + data->chunks[data->chunk_count++] = cbor_incref(chunk); + return true; } diff --git a/lib/libcbor/src/cbor/bytestrings.h b/lib/libcbor/src/cbor/bytestrings.h index a5eb98b5e7e..a133f949edb 100644 --- a/lib/libcbor/src/cbor/bytestrings.h +++ b/lib/libcbor/src/cbor/bytestrings.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014-2017 Pavel Kalvoda <me@pavelkalvoda.com> + * Copyright (c) 2014-2019 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. @@ -15,10 +15,10 @@ extern "C" { #endif /* -* ============================================================================ -* Byte string manipulation -* ============================================================================ -*/ + * ============================================================================ + * Byte string manipulation + * ============================================================================ + */ /** Returns the length of the binary data * @@ -31,39 +31,44 @@ size_t cbor_bytestring_length(const cbor_item_t *item); /** Is the byte string definite? * - * @param item[borrow] a byte string + * @param item[borrow] a byte string * @return Is the byte string definite? */ bool cbor_bytestring_is_definite(const cbor_item_t *item); /** Is the byte string indefinite? * - * @param item[borrow] a byte string + * @param item[borrow] a byte string * @return Is the byte string indefinite? */ bool cbor_bytestring_is_indefinite(const cbor_item_t *item); /** Get the handle to the binary data * - * Definite items only. Modifying the data is allowed. In that case, the caller takes - * responsibility for the effect on items this item might be a part of + * Definite items only. Modifying the data is allowed. In that case, the caller + * takes responsibility for the effect on items this item might be a part of * * @param item[borrow] A definite byte string - * @return The address of the binary data. `NULL` if no data have been assigned yet. + * @return The address of the binary data. `NULL` if no data have been assigned + * yet. */ cbor_mutable_data cbor_bytestring_handle(const cbor_item_t *item); /** Set the handle to the binary data * * @param item[borrow] A definite byte string - * @param data The memory block. The caller gives up the ownership of the block. libcbor will deallocate it when appropriate using its free function + * @param data The memory block. The caller gives up the ownership of the block. + * libcbor will deallocate it when appropriate using its free function * @param length Length of the data block */ -void cbor_bytestring_set_handle(cbor_item_t *item, cbor_mutable_data CBOR_RESTRICT_POINTER data, size_t length); +void cbor_bytestring_set_handle(cbor_item_t *item, + cbor_mutable_data CBOR_RESTRICT_POINTER data, + size_t length); /** Get the handle to the array of chunks - * - * Manipulations with the memory block (e.g. sorting it) are allowed, but the validity and the number of chunks must be retained. + * + * Manipulations with the memory block (e.g. sorting it) are allowed, but the + * validity and the number of chunks must be retained. * * @param item[borrow] A indefinite byte string * @return array of #cbor_bytestring_chunk_count definite bytestrings @@ -85,7 +90,8 @@ size_t cbor_bytestring_chunk_count(const cbor_item_t *item); * * @param item[borrow] An indefinite byte string * @param item[incref] A definite byte string - * @return true on success, false on realloc failure. In that case, the refcount of `chunk` is not increased and the `item` is left intact. + * @return true on success, false on realloc failure. In that case, the refcount + * of `chunk` is not increased and the `item` is left intact. */ bool cbor_bytestring_add_chunk(cbor_item_t *item, cbor_item_t *chunk); @@ -111,7 +117,8 @@ cbor_item_t *cbor_new_indefinite_bytestring(); * * @param handle Block of binary data * @param length Length of `data` - * @return A **new** byte string with content `handle`. `NULL` on malloc failure. + * @return A **new** byte string with content `handle`. `NULL` on malloc + * failure. */ cbor_item_t *cbor_build_bytestring(cbor_data handle, size_t length); @@ -119,5 +126,4 @@ cbor_item_t *cbor_build_bytestring(cbor_data handle, size_t length); } #endif - -#endif //LIBCBOR_BYTESTRINGS_H +#endif // LIBCBOR_BYTESTRINGS_H diff --git a/lib/libcbor/src/cbor/callbacks.c b/lib/libcbor/src/cbor/callbacks.c index 81fe857319e..6f868f1b793 100644 --- a/lib/libcbor/src/cbor/callbacks.c +++ b/lib/libcbor/src/cbor/callbacks.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014-2017 Pavel Kalvoda <me@pavelkalvoda.com> + * Copyright (c) 2014-2019 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. @@ -7,98 +7,110 @@ #include "callbacks.h" -#define CBOR_DUMMY_CALLBACK { } +#define CBOR_DUMMY_CALLBACK \ + {} void cbor_null_uint8_callback(void *_ctx, uint8_t _val) CBOR_DUMMY_CALLBACK -void cbor_null_uint16_callback(void *_ctx, uint16_t _val) CBOR_DUMMY_CALLBACK + void cbor_null_uint16_callback(void *_ctx, + uint16_t _val) CBOR_DUMMY_CALLBACK -void cbor_null_uint32_callback(void *_ctx, uint32_t _val) CBOR_DUMMY_CALLBACK + void cbor_null_uint32_callback(void *_ctx, + uint32_t _val) CBOR_DUMMY_CALLBACK -void cbor_null_uint64_callback(void *_ctx, uint64_t _val) CBOR_DUMMY_CALLBACK + void cbor_null_uint64_callback(void *_ctx, + uint64_t _val) CBOR_DUMMY_CALLBACK -void cbor_null_negint8_callback(void *_ctx, uint8_t _val) CBOR_DUMMY_CALLBACK + void cbor_null_negint8_callback(void *_ctx, + uint8_t _val) CBOR_DUMMY_CALLBACK -void cbor_null_negint16_callback(void *_ctx, uint16_t _val) CBOR_DUMMY_CALLBACK + void cbor_null_negint16_callback(void *_ctx, + uint16_t _val) CBOR_DUMMY_CALLBACK -void cbor_null_negint32_callback(void *_ctx, uint32_t _val) CBOR_DUMMY_CALLBACK + void cbor_null_negint32_callback(void *_ctx, + uint32_t _val) CBOR_DUMMY_CALLBACK -void cbor_null_negint64_callback(void *_ctx, uint64_t _val) CBOR_DUMMY_CALLBACK + void cbor_null_negint64_callback(void *_ctx, + uint64_t _val) CBOR_DUMMY_CALLBACK -void cbor_null_string_callback(void *_ctx, cbor_data _val, size_t _val2) CBOR_DUMMY_CALLBACK + void cbor_null_string_callback(void *_ctx, cbor_data _val, + size_t _val2) CBOR_DUMMY_CALLBACK -void cbor_null_string_start_callback(void *_ctx) CBOR_DUMMY_CALLBACK + void cbor_null_string_start_callback(void *_ctx) CBOR_DUMMY_CALLBACK -void cbor_null_byte_string_callback(void *_ctx, cbor_data _val, size_t _val2) CBOR_DUMMY_CALLBACK + void cbor_null_byte_string_callback(void *_ctx, cbor_data _val, + size_t _val2) CBOR_DUMMY_CALLBACK -void cbor_null_byte_string_start_callback(void *_ctx) CBOR_DUMMY_CALLBACK + void cbor_null_byte_string_start_callback(void *_ctx) CBOR_DUMMY_CALLBACK -void cbor_null_array_start_callback(void *_ctx, size_t _val) CBOR_DUMMY_CALLBACK + void cbor_null_array_start_callback(void *_ctx, + size_t _val) CBOR_DUMMY_CALLBACK -void cbor_null_indef_array_start_callback(void *_ctx) CBOR_DUMMY_CALLBACK + void cbor_null_indef_array_start_callback(void *_ctx) CBOR_DUMMY_CALLBACK -void cbor_null_map_start_callback(void *_ctx, size_t _val) CBOR_DUMMY_CALLBACK + void cbor_null_map_start_callback(void *_ctx, + size_t _val) CBOR_DUMMY_CALLBACK -void cbor_null_indef_map_start_callback(void *_ctx) CBOR_DUMMY_CALLBACK + void cbor_null_indef_map_start_callback(void *_ctx) CBOR_DUMMY_CALLBACK -void cbor_null_tag_callback(void *_ctx, uint64_t _val) CBOR_DUMMY_CALLBACK + void cbor_null_tag_callback(void *_ctx, uint64_t _val) CBOR_DUMMY_CALLBACK -void cbor_null_float2_callback(void *_ctx, float _val) CBOR_DUMMY_CALLBACK + void cbor_null_float2_callback(void *_ctx, float _val) CBOR_DUMMY_CALLBACK -void cbor_null_float4_callback(void *_ctx, float _val) CBOR_DUMMY_CALLBACK + void cbor_null_float4_callback(void *_ctx, float _val) CBOR_DUMMY_CALLBACK -void cbor_null_float8_callback(void *_ctx, double _val) CBOR_DUMMY_CALLBACK + void cbor_null_float8_callback(void *_ctx, double _val) CBOR_DUMMY_CALLBACK -void cbor_null_null_callback(void *_ctx) CBOR_DUMMY_CALLBACK + void cbor_null_null_callback(void *_ctx) CBOR_DUMMY_CALLBACK -void cbor_null_undefined_callback(void *_ctx) CBOR_DUMMY_CALLBACK + void cbor_null_undefined_callback(void *_ctx) CBOR_DUMMY_CALLBACK -void cbor_null_boolean_callback(void *_ctx, bool _val) CBOR_DUMMY_CALLBACK + void cbor_null_boolean_callback(void *_ctx, bool _val) CBOR_DUMMY_CALLBACK -void cbor_null_indef_break_callback(void *_ctx) CBOR_DUMMY_CALLBACK + void cbor_null_indef_break_callback(void *_ctx) CBOR_DUMMY_CALLBACK -const struct cbor_callbacks cbor_empty_callbacks = { - /* Type 0 - Unsigned integers */ - .uint8 = cbor_null_uint8_callback, - .uint16 = cbor_null_uint16_callback, - .uint32 = cbor_null_uint32_callback, - .uint64 = cbor_null_uint64_callback, + const struct cbor_callbacks cbor_empty_callbacks = { + /* Type 0 - Unsigned integers */ + .uint8 = cbor_null_uint8_callback, + .uint16 = cbor_null_uint16_callback, + .uint32 = cbor_null_uint32_callback, + .uint64 = cbor_null_uint64_callback, - /* Type 1 - Negative integers */ - .negint8 = cbor_null_negint8_callback, - .negint16 = cbor_null_negint16_callback, - .negint32 = cbor_null_negint32_callback, - .negint64 = cbor_null_negint64_callback, + /* Type 1 - Negative integers */ + .negint8 = cbor_null_negint8_callback, + .negint16 = cbor_null_negint16_callback, + .negint32 = cbor_null_negint32_callback, + .negint64 = cbor_null_negint64_callback, - /* Type 2 - Byte strings */ - .byte_string_start = cbor_null_byte_string_start_callback, - .byte_string = cbor_null_byte_string_callback, + /* Type 2 - Byte strings */ + .byte_string_start = cbor_null_byte_string_start_callback, + .byte_string = cbor_null_byte_string_callback, - /* Type 3 - Strings */ - .string_start = cbor_null_string_start_callback, - .string = cbor_null_string_callback, + /* Type 3 - Strings */ + .string_start = cbor_null_string_start_callback, + .string = cbor_null_string_callback, - /* Type 4 - Arrays */ - .indef_array_start = cbor_null_indef_array_start_callback, - .array_start = cbor_null_array_start_callback, + /* Type 4 - Arrays */ + .indef_array_start = cbor_null_indef_array_start_callback, + .array_start = cbor_null_array_start_callback, - /* Type 5 - Maps */ - .indef_map_start = cbor_null_indef_map_start_callback, - .map_start = cbor_null_map_start_callback, + /* Type 5 - Maps */ + .indef_map_start = cbor_null_indef_map_start_callback, + .map_start = cbor_null_map_start_callback, - /* Type 6 - Tags */ - .tag = cbor_null_tag_callback, + /* Type 6 - Tags */ + .tag = cbor_null_tag_callback, - /* Type 7 - Floats & misc */ - /* Type names cannot be member names */ - .float2 = cbor_null_float2_callback, - /* 2B float is not supported in standard C */ - .float4 = cbor_null_float4_callback, - .float8 = cbor_null_float8_callback, - .undefined = cbor_null_undefined_callback, - .null = cbor_null_null_callback, - .boolean = cbor_null_boolean_callback, + /* Type 7 - Floats & misc */ + /* Type names cannot be member names */ + .float2 = cbor_null_float2_callback, + /* 2B float is not supported in standard C */ + .float4 = cbor_null_float4_callback, + .float8 = cbor_null_float8_callback, + .undefined = cbor_null_undefined_callback, + .null = cbor_null_null_callback, + .boolean = cbor_null_boolean_callback, - /* Shared indefinites */ - .indef_break = cbor_null_indef_break_callback, + /* Shared indefinites */ + .indef_break = cbor_null_indef_break_callback, }; diff --git a/lib/libcbor/src/cbor/callbacks.h b/lib/libcbor/src/cbor/callbacks.h index 7ca6cda9ea5..f789e5cef08 100644 --- a/lib/libcbor/src/cbor/callbacks.h +++ b/lib/libcbor/src/cbor/callbacks.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014-2017 Pavel Kalvoda <me@pavelkalvoda.com> + * Copyright (c) 2014-2019 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. @@ -15,93 +15,93 @@ extern "C" { #endif /** Callback prototype */ -typedef void(*cbor_int8_callback)(void *, uint8_t); +typedef void (*cbor_int8_callback)(void *, uint8_t); /** Callback prototype */ -typedef void(*cbor_int16_callback)(void *, uint16_t); +typedef void (*cbor_int16_callback)(void *, uint16_t); /** Callback prototype */ -typedef void(*cbor_int32_callback)(void *, uint32_t); +typedef void (*cbor_int32_callback)(void *, uint32_t); /** Callback prototype */ -typedef void(*cbor_int64_callback)(void *, uint64_t); +typedef void (*cbor_int64_callback)(void *, uint64_t); /** Callback prototype */ -typedef void(*cbor_simple_callback)(void *); +typedef void (*cbor_simple_callback)(void *); /** Callback prototype */ -typedef void(*cbor_string_callback)(void *, cbor_data, size_t); +typedef void (*cbor_string_callback)(void *, cbor_data, size_t); /** Callback prototype */ -typedef void(*cbor_collection_callback)(void *, size_t); +typedef void (*cbor_collection_callback)(void *, size_t); /** Callback prototype */ -typedef void(*cbor_float_callback)(void *, float); +typedef void (*cbor_float_callback)(void *, float); /** Callback prototype */ -typedef void(*cbor_double_callback)(void *, double); +typedef void (*cbor_double_callback)(void *, double); /** Callback prototype */ -typedef void(*cbor_bool_callback)(void *, bool); +typedef void (*cbor_bool_callback)(void *, bool); /** Callback bundle -- passed to the decoder */ struct cbor_callbacks { - /** Unsigned int */ - cbor_int8_callback uint8; - /** Unsigned int */ - cbor_int16_callback uint16; - /** Unsigned int */ - cbor_int32_callback uint32; - /** Unsigned int */ - cbor_int64_callback uint64; - - /** Negative int */ - cbor_int64_callback negint64; - /** Negative int */ - cbor_int32_callback negint32; - /** Negative int */ - cbor_int16_callback negint16; - /** Negative int */ - cbor_int8_callback negint8; - - /** Definite byte string */ - cbor_simple_callback byte_string_start; - /** Indefinite byte string start */ - cbor_string_callback byte_string; - - /** Definite string */ - cbor_string_callback string; - /** Indefinite string start */ - cbor_simple_callback string_start; - - /** Definite array */ - cbor_simple_callback indef_array_start; - /** Indefinite array */ - cbor_collection_callback array_start; - - /** Definite map */ - cbor_simple_callback indef_map_start; - /** Indefinite map */ - cbor_collection_callback map_start; - - /** Tags */ - cbor_int64_callback tag; - - /** Half float */ - cbor_float_callback float2; - /** Single float */ - cbor_float_callback float4; - /** Double float */ - cbor_double_callback float8; - /** Undef */ - cbor_simple_callback undefined; - /** Null */ - cbor_simple_callback null; - /** Bool */ - cbor_bool_callback boolean; - - /** Indefinite item break */ - cbor_simple_callback indef_break; + /** Unsigned int */ + cbor_int8_callback uint8; + /** Unsigned int */ + cbor_int16_callback uint16; + /** Unsigned int */ + cbor_int32_callback uint32; + /** Unsigned int */ + cbor_int64_callback uint64; + + /** Negative int */ + cbor_int64_callback negint64; + /** Negative int */ + cbor_int32_callback negint32; + /** Negative int */ + cbor_int16_callback negint16; + /** Negative int */ + cbor_int8_callback negint8; + + /** Definite byte string */ + cbor_simple_callback byte_string_start; + /** Indefinite byte string start */ + cbor_string_callback byte_string; + + /** Definite string */ + cbor_string_callback string; + /** Indefinite string start */ + cbor_simple_callback string_start; + + /** Definite array */ + cbor_simple_callback indef_array_start; + /** Indefinite array */ + cbor_collection_callback array_start; + + /** Definite map */ + cbor_simple_callback indef_map_start; + /** Indefinite map */ + cbor_collection_callback map_start; + + /** Tags */ + cbor_int64_callback tag; + + /** Half float */ + cbor_float_callback float2; + /** Single float */ + cbor_float_callback float4; + /** Double float */ + cbor_double_callback float8; + /** Undef */ + cbor_simple_callback undefined; + /** Null */ + cbor_simple_callback null; + /** Bool */ + cbor_bool_callback boolean; + + /** Indefinite item break */ + cbor_simple_callback indef_break; }; /** Dummy callback implementation - does nothing */ @@ -183,5 +183,4 @@ extern const struct cbor_callbacks cbor_empty_callbacks; } #endif - -#endif //LIBCBOR_CALLBACKS_H +#endif // LIBCBOR_CALLBACKS_H diff --git a/lib/libcbor/src/cbor/common.c b/lib/libcbor/src/cbor/common.c index 77544ae8107..9c1239d53ab 100644 --- a/lib/libcbor/src/cbor/common.c +++ b/lib/libcbor/src/cbor/common.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014-2017 Pavel Kalvoda <me@pavelkalvoda.com> + * Copyright (c) 2014-2019 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. @@ -15,174 +15,146 @@ #include "strings.h" #include "tags.h" -bool cbor_isa_uint(const cbor_item_t *item) -{ - return item->type == CBOR_TYPE_UINT; +bool cbor_isa_uint(const cbor_item_t *item) { + return item->type == CBOR_TYPE_UINT; } -bool cbor_isa_negint(const cbor_item_t *item) -{ - return item->type == CBOR_TYPE_NEGINT; +bool cbor_isa_negint(const cbor_item_t *item) { + return item->type == CBOR_TYPE_NEGINT; } -bool cbor_isa_bytestring(const cbor_item_t *item) -{ - return item->type == CBOR_TYPE_BYTESTRING; +bool cbor_isa_bytestring(const cbor_item_t *item) { + return item->type == CBOR_TYPE_BYTESTRING; } -bool cbor_isa_string(const cbor_item_t *item) -{ - return item->type == CBOR_TYPE_STRING; +bool cbor_isa_string(const cbor_item_t *item) { + return item->type == CBOR_TYPE_STRING; } -bool cbor_isa_array(const cbor_item_t *item) -{ - return item->type == CBOR_TYPE_ARRAY; +bool cbor_isa_array(const cbor_item_t *item) { + return item->type == CBOR_TYPE_ARRAY; } -bool cbor_isa_map(const cbor_item_t *item) -{ - return item->type == CBOR_TYPE_MAP; -} - -bool cbor_isa_tag(const cbor_item_t *item) -{ - return item->type == CBOR_TYPE_TAG; -} - -bool cbor_isa_float_ctrl(const cbor_item_t *item) -{ - return item->type == CBOR_TYPE_FLOAT_CTRL; -} - - -cbor_type cbor_typeof(const cbor_item_t *item) -{ - return item->type; -} - - -bool cbor_is_int(const cbor_item_t *item) -{ - return cbor_isa_uint(item) || cbor_isa_negint(item); -} - - -bool cbor_is_bool(const cbor_item_t *item) -{ - return cbor_isa_float_ctrl(item) && - (cbor_ctrl_value(item) == CBOR_CTRL_FALSE || cbor_ctrl_value(item) == CBOR_CTRL_TRUE); -} - -bool cbor_is_null(const cbor_item_t *item) -{ - return cbor_isa_float_ctrl(item) && cbor_ctrl_value(item) == CBOR_CTRL_NULL; -} - -bool cbor_is_undef(const cbor_item_t *item) -{ - return cbor_isa_float_ctrl(item) && cbor_ctrl_value(item) == CBOR_CTRL_UNDEF; -} - -bool cbor_is_float(const cbor_item_t *item) -{ - return cbor_isa_float_ctrl(item) && !cbor_float_ctrl_is_ctrl(item); -} - - -cbor_item_t * cbor_incref(cbor_item_t *item) -{ - item->refcount++; - return item; -} - -void cbor_decref(cbor_item_t **item_ref) -{ - cbor_item_t * item = *item_ref; - if (--item->refcount == 0) { - switch (item->type) { - case CBOR_TYPE_UINT: - /* Fallthrough */ - case CBOR_TYPE_NEGINT: - /* Combined allocation, freeing the item suffices */ - { - break; - } - case CBOR_TYPE_BYTESTRING: { - if (cbor_bytestring_is_definite(item)) { - _CBOR_FREE(item->data); - } else { - /* We need to decref all chunks */ - cbor_item_t **handle = cbor_bytestring_chunks_handle(item); - for (size_t i = 0; i < cbor_bytestring_chunk_count(item); i++) - cbor_decref(&handle[i]); - _CBOR_FREE(((struct cbor_indefinite_string_data *) item->data)->chunks); - _CBOR_FREE(item->data); - } - break; - } - case CBOR_TYPE_STRING: { - if (cbor_string_is_definite(item)) { - _CBOR_FREE(item->data); - } else { - /* We need to decref all chunks */ - cbor_item_t **handle = cbor_string_chunks_handle(item); - for (size_t i = 0; i < cbor_string_chunk_count(item); i++) - cbor_decref(&handle[i]); - _CBOR_FREE(((struct cbor_indefinite_string_data *) item->data)->chunks); - _CBOR_FREE(item->data); - } - break; - } - case CBOR_TYPE_ARRAY: { - /* Get all items and decref them */ - cbor_item_t **handle = cbor_array_handle(item); - size_t size = cbor_array_size(item); - for (size_t i = 0; i < size; i++) - if (handle[i] != NULL) - cbor_decref(&handle[i]); - _CBOR_FREE(item->data); - break; - } - case CBOR_TYPE_MAP: { - struct cbor_pair *handle = cbor_map_handle(item); - for (size_t i = 0; i < item->metadata.map_metadata.end_ptr; i++, handle++) { - cbor_decref(&handle->key); - if (handle->value != NULL) - cbor_decref(&handle->value); - } - _CBOR_FREE(item->data); - break; - }; - case CBOR_TYPE_TAG: { - if (item->metadata.tag_metadata.tagged_item != NULL) - cbor_decref(&item->metadata.tag_metadata.tagged_item); - _CBOR_FREE(item->data); - break; - } - case CBOR_TYPE_FLOAT_CTRL: { - /* Floats have combined allocation */ - break; - } - } - _CBOR_FREE(item); - //TODO - *item_ref = NULL; - } -} - -void cbor_intermediate_decref(cbor_item_t * item) -{ - cbor_decref(&item); -} - -size_t cbor_refcount(const cbor_item_t * item) -{ - return item->refcount; -} - -cbor_item_t * cbor_move(cbor_item_t * item) -{ - item->refcount--; - return item; +bool cbor_isa_map(const cbor_item_t *item) { + return item->type == CBOR_TYPE_MAP; +} + +bool cbor_isa_tag(const cbor_item_t *item) { + return item->type == CBOR_TYPE_TAG; +} + +bool cbor_isa_float_ctrl(const cbor_item_t *item) { + return item->type == CBOR_TYPE_FLOAT_CTRL; +} + +cbor_type cbor_typeof(const cbor_item_t *item) { return item->type; } + +bool cbor_is_int(const cbor_item_t *item) { + return cbor_isa_uint(item) || cbor_isa_negint(item); +} + +bool cbor_is_bool(const cbor_item_t *item) { + return cbor_isa_float_ctrl(item) && + (cbor_ctrl_value(item) == CBOR_CTRL_FALSE || + cbor_ctrl_value(item) == CBOR_CTRL_TRUE); +} + +bool cbor_is_null(const cbor_item_t *item) { + return cbor_isa_float_ctrl(item) && cbor_ctrl_value(item) == CBOR_CTRL_NULL; +} + +bool cbor_is_undef(const cbor_item_t *item) { + return cbor_isa_float_ctrl(item) && cbor_ctrl_value(item) == CBOR_CTRL_UNDEF; +} + +bool cbor_is_float(const cbor_item_t *item) { + return cbor_isa_float_ctrl(item) && !cbor_float_ctrl_is_ctrl(item); +} + +cbor_item_t *cbor_incref(cbor_item_t *item) { + item->refcount++; + return item; +} + +void cbor_decref(cbor_item_t **item_ref) { + cbor_item_t *item = *item_ref; + assert(item->refcount > 0); + if (--item->refcount == 0) { + switch (item->type) { + case CBOR_TYPE_UINT: + /* Fallthrough */ + case CBOR_TYPE_NEGINT: + /* Combined allocation, freeing the item suffices */ + { break; } + case CBOR_TYPE_BYTESTRING: { + if (cbor_bytestring_is_definite(item)) { + _CBOR_FREE(item->data); + } else { + /* We need to decref all chunks */ + cbor_item_t **handle = cbor_bytestring_chunks_handle(item); + for (size_t i = 0; i < cbor_bytestring_chunk_count(item); i++) + cbor_decref(&handle[i]); + _CBOR_FREE( + ((struct cbor_indefinite_string_data *)item->data)->chunks); + _CBOR_FREE(item->data); + } + break; + } + case CBOR_TYPE_STRING: { + if (cbor_string_is_definite(item)) { + _CBOR_FREE(item->data); + } else { + /* We need to decref all chunks */ + cbor_item_t **handle = cbor_string_chunks_handle(item); + for (size_t i = 0; i < cbor_string_chunk_count(item); i++) + cbor_decref(&handle[i]); + _CBOR_FREE( + ((struct cbor_indefinite_string_data *)item->data)->chunks); + _CBOR_FREE(item->data); + } + break; + } + case CBOR_TYPE_ARRAY: { + /* Get all items and decref them */ + cbor_item_t **handle = cbor_array_handle(item); + size_t size = cbor_array_size(item); + for (size_t i = 0; i < size; i++) + if (handle[i] != NULL) cbor_decref(&handle[i]); + _CBOR_FREE(item->data); + break; + } + case CBOR_TYPE_MAP: { + struct cbor_pair *handle = cbor_map_handle(item); + for (size_t i = 0; i < item->metadata.map_metadata.end_ptr; + i++, handle++) { + cbor_decref(&handle->key); + if (handle->value != NULL) cbor_decref(&handle->value); + } + _CBOR_FREE(item->data); + break; + }; + case CBOR_TYPE_TAG: { + if (item->metadata.tag_metadata.tagged_item != NULL) + cbor_decref(&item->metadata.tag_metadata.tagged_item); + _CBOR_FREE(item->data); + break; + } + case CBOR_TYPE_FLOAT_CTRL: { + /* Floats have combined allocation */ + break; + } + } + _CBOR_FREE(item); + // TODO + *item_ref = NULL; + } +} + +void cbor_intermediate_decref(cbor_item_t *item) { cbor_decref(&item); } + +size_t cbor_refcount(const cbor_item_t *item) { return item->refcount; } + +cbor_item_t *cbor_move(cbor_item_t *item) { + item->refcount--; + return item; } diff --git a/lib/libcbor/src/cbor/common.h b/lib/libcbor/src/cbor/common.h index 9e0b63c4a6f..fbe3e5719c3 100644 --- a/lib/libcbor/src/cbor/common.h +++ b/lib/libcbor/src/cbor/common.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014-2015 Pavel Kalvoda <me@pavelkalvoda.com> + * Copyright (c) 2014-2019 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. @@ -8,20 +8,21 @@ #ifndef LIBCBOR_COMMON_H #define LIBCBOR_COMMON_H -#include <stdlib.h> +#include <assert.h> +#include <stdbool.h> #include <stddef.h> #include <stdint.h> -#include <stdbool.h> -#include <assert.h> -#include "data.h" +#include <stdlib.h> #include "cbor/configuration.h" +#include "data.h" #ifdef __cplusplus extern "C" { -/** C++ is not a subset of C99 -- 'restrict' qualifier is not a part of the language. - * This is a workaround to keep it in C headers -- compilers allow linking non-restrict - * signatures with restrict implementations. +/** + * C++ is not a subset of C99 -- 'restrict' qualifier is not a part of the + * language. This is a workaround to keep it in C headers -- compilers allow + * linking non-restrict signatures with restrict implementations. * * If you know a nicer way, please do let me know. */ @@ -38,29 +39,53 @@ static const uint8_t cbor_major_version = CBOR_MAJOR_VERSION; static const uint8_t cbor_minor_version = CBOR_MINOR_VERSION; static const uint8_t cbor_patch_version = CBOR_PATCH_VERSION; -#define CBOR_VERSION TO_STR(CBOR_MAJOR_VERSION) "." TO_STR(CBOR_MINOR_VERSION) "." TO_STR(CBOR_PATCH_VERSION) -#define CBOR_HEX_VERSION ((CBOR_MAJOR_VERSION << 16) | (CBOR_MINOR_VERSION << 8) | CBOR_PATCH_VERSION) +#define CBOR_VERSION \ + TO_STR(CBOR_MAJOR_VERSION) \ + "." TO_STR(CBOR_MINOR_VERSION) "." TO_STR(CBOR_PATCH_VERSION) +#define CBOR_HEX_VERSION \ + ((CBOR_MAJOR_VERSION << 16) | (CBOR_MINOR_VERSION << 8) | CBOR_PATCH_VERSION) - -/* http://stackoverflow.com/questions/1644868/c-define-macro-for-debug-printing */ +/* http://stackoverflow.com/questions/1644868/c-define-macro-for-debug-printing + */ #ifdef DEBUG #include <stdio.h> -#define debug_print(fmt, ...) do { \ - if (DEBUG) \ - fprintf(stderr, "%s:%d:%s(): " fmt, __FILE__, __LINE__, __func__, __VA_ARGS__); \ - } while (0) +#define debug_print(fmt, ...) \ + do { \ + if (DEBUG) \ + fprintf(stderr, "%s:%d:%s(): " fmt, __FILE__, __LINE__, __func__, \ + __VA_ARGS__); \ + } while (0) #else -#define debug_print(fmt, ...) do {} while (0) +#define debug_print(fmt, ...) \ + do { \ + } while (0) #endif #define TO_STR_(x) #x #define TO_STR(x) TO_STR_(x) /* enables proper double expansion */ +// Macro to short-circuit builder functions when memory allocation fails +#define _CBOR_NOTNULL(cbor_item) \ + do { \ + if (cbor_item == NULL) { \ + return NULL; \ + } \ + } while (0) + +// Macro to short-circuit builders when memory allocation of nested data fails +#define _CBOR_DEPENDENT_NOTNULL(cbor_item, pointer) \ + do { \ + if (pointer == NULL) { \ + _CBOR_FREE(cbor_item); \ + return NULL; \ + } \ + } while (0) + #if CBOR_CUSTOM_ALLOC -typedef void * (* _cbor_malloc_t)(size_t); -typedef void * (* _cbor_realloc_t)(void *, size_t); -typedef void (* _cbor_free_t)(void *); +typedef void *(*_cbor_malloc_t)(size_t); +typedef void *(*_cbor_realloc_t)(void *, size_t); +typedef void (*_cbor_free_t)(void *); extern _cbor_malloc_t _cbor_malloc; extern _cbor_realloc_t _cbor_realloc; @@ -68,18 +93,23 @@ extern _cbor_free_t _cbor_free; /** Sets the memory management routines to use. * - * Only available when CBOR_CUSTOM_ALLOC is truthy + * Only available when `CBOR_CUSTOM_ALLOC` is truthy * * \rst - * .. warning:: This function modifies the global state and should therefore be used accordingly. Changing the memory handlers while allocated items exist will result in a ``free``/``malloc`` mismatch. This function is not thread safe with respect to both itself and all the other *libcbor* functions that work with the heap. + * .. warning:: This function modifies the global state and should therefore be + * used accordingly. Changing the memory handlers while allocated items exist + * will result in a ``free``/``malloc`` mismatch. This function is not thread + * safe with respect to both itself and all the other *libcbor* functions that + * work with the heap. * .. note:: `realloc` implementation must correctly support `NULL` reallocation - * \endrst + * (see e.g. http://en.cppreference.com/w/c/memory/realloc) \endrst * * @param custom_malloc malloc implementation * @param custom_realloc realloc implementation * @param custom_free free implementation */ -void cbor_set_allocs(_cbor_malloc_t custom_malloc, _cbor_realloc_t custom_realloc, _cbor_free_t custom_free); +void cbor_set_allocs(_cbor_malloc_t custom_malloc, + _cbor_realloc_t custom_realloc, _cbor_free_t custom_free); #define _CBOR_MALLOC _cbor_malloc #define _CBOR_REALLOC _cbor_realloc @@ -94,17 +124,18 @@ void cbor_set_allocs(_cbor_malloc_t custom_malloc, _cbor_realloc_t custom_reallo #endif /* -* ============================================================================ -* Type manipulation -* ============================================================================ -*/ + * ============================================================================ + * Type manipulation + * ============================================================================ + */ /** Get the type of the item * * @param item[borrow] * @return The type */ -cbor_type cbor_typeof(const cbor_item_t * item); /* Will be inlined iff link-time opt is enabled */ +cbor_type cbor_typeof( + const cbor_item_t *item); /* Will be inlined iff link-time opt is enabled */ /* Standard item types as described by the RFC */ @@ -112,49 +143,49 @@ cbor_type cbor_typeof(const cbor_item_t * item); /* Will be inlined iff link-tim * @param item[borrow] the item * @return Is the item an #CBOR_TYPE_UINT? */ -bool cbor_isa_uint(const cbor_item_t * item); +bool cbor_isa_uint(const cbor_item_t *item); /** Does the item have the appropriate major type? * @param item[borrow] the item * @return Is the item a #CBOR_TYPE_NEGINT? */ -bool cbor_isa_negint(const cbor_item_t * item); +bool cbor_isa_negint(const cbor_item_t *item); /** Does the item have the appropriate major type? * @param item[borrow] the item * @return Is the item a #CBOR_TYPE_BYTESTRING? */ -bool cbor_isa_bytestring(const cbor_item_t * item); +bool cbor_isa_bytestring(const cbor_item_t *item); /** Does the item have the appropriate major type? * @param item[borrow] the item * @return Is the item a #CBOR_TYPE_STRING? */ -bool cbor_isa_string(const cbor_item_t * item); +bool cbor_isa_string(const cbor_item_t *item); /** Does the item have the appropriate major type? * @param item[borrow] the item * @return Is the item an #CBOR_TYPE_ARRAY? */ -bool cbor_isa_array(const cbor_item_t * item); +bool cbor_isa_array(const cbor_item_t *item); /** Does the item have the appropriate major type? * @param item[borrow] the item * @return Is the item a #CBOR_TYPE_MAP? */ -bool cbor_isa_map(const cbor_item_t * item); +bool cbor_isa_map(const cbor_item_t *item); /** Does the item have the appropriate major type? * @param item[borrow] the item * @return Is the item a #CBOR_TYPE_TAG? */ -bool cbor_isa_tag(const cbor_item_t * item); +bool cbor_isa_tag(const cbor_item_t *item); /** Does the item have the appropriate major type? * @param item[borrow] the item * @return Is the item a #CBOR_TYPE_FLOAT_CTRL? */ -bool cbor_isa_float_ctrl(const cbor_item_t * item); +bool cbor_isa_float_ctrl(const cbor_item_t *item); /* Practical types with respect to their semantics (but not tag values) */ @@ -162,45 +193,43 @@ bool cbor_isa_float_ctrl(const cbor_item_t * item); * @param item[borrow] the item * @return Is the item an integer, either positive or negative? */ -bool cbor_is_int(const cbor_item_t * item); +bool cbor_is_int(const cbor_item_t *item); /** Is the item an a floating point number? * @param item[borrow] the item * @return Is the item a floating point number? */ -bool cbor_is_float(const cbor_item_t * item); +bool cbor_is_float(const cbor_item_t *item); /** Is the item an a boolean? * @param item[borrow] the item * @return Is the item a boolean? */ -bool cbor_is_bool(const cbor_item_t * item); +bool cbor_is_bool(const cbor_item_t *item); /** Does this item represent `null` * \rst - * .. warning:: This is in no way related to the value of the pointer. Passing a null pointer will most likely result in a crash. - * \endrst + * .. warning:: This is in no way related to the value of the pointer. Passing a + * null pointer will most likely result in a crash. \endrst * @param item[borrow] the item * @return Is the item (CBOR logical) null? */ -bool cbor_is_null(const cbor_item_t * item); - +bool cbor_is_null(const cbor_item_t *item); /** Does this item represent `undefined` * \rst - * .. warning:: Care must be taken to distinguish nulls and undefined values in C. - * \endrst + * .. warning:: Care must be taken to distinguish nulls and undefined values in + * C. \endrst * @param item[borrow] the item * @return Is the item (CBOR logical) undefined? */ -bool cbor_is_undef(const cbor_item_t * item); - +bool cbor_is_undef(const cbor_item_t *item); /* -* ============================================================================ -* Memory management -* ============================================================================ -*/ + * ============================================================================ + * Memory management + * ============================================================================ + */ /** Increases the reference count by one * @@ -209,7 +238,7 @@ bool cbor_is_undef(const cbor_item_t * item); * @param item[incref] item the item * @return the input reference */ -cbor_item_t * cbor_incref(cbor_item_t * item); +cbor_item_t *cbor_incref(cbor_item_t *item); /** Decreases the reference count by one, deallocating the item if needed * @@ -218,15 +247,16 @@ cbor_item_t * cbor_incref(cbor_item_t * item); * * @param item[take] the item. Set to `NULL` if deallocated */ -void cbor_decref(cbor_item_t ** item); +void cbor_decref(cbor_item_t **item); /** Decreases the reference count by one, deallocating the item if needed * - * Convenience wrapper for #cbor_decref when its set-to-null behavior is not needed + * Convenience wrapper for #cbor_decref when its set-to-null behavior is not + * needed * * @param item[take] the item */ -void cbor_intermediate_decref(cbor_item_t * item); +void cbor_intermediate_decref(cbor_item_t *item); /** Get the reference count * @@ -237,25 +267,26 @@ void cbor_intermediate_decref(cbor_item_t * item); * @param item[borrow] the item * @return the reference count */ -size_t cbor_refcount(const cbor_item_t * item); +size_t cbor_refcount(const cbor_item_t *item); /** Provides CPP-like move construct * - * Decreases the reference count by one, but does not deallocate the item even if its refcount - * reaches zero. This is useful for passing intermediate values to functions that increase - * reference count. Should only be used with functions that `incref` their arguments. + * Decreases the reference count by one, but does not deallocate the item even + * if its refcount reaches zero. This is useful for passing intermediate values + * to functions that increase reference count. Should only be used with + * functions that `incref` their arguments. * * \rst - * .. warning:: If the item is moved without correctly increasing the reference count afterwards, the memory will be leaked. - * \endrst + * .. warning:: If the item is moved without correctly increasing the reference + * count afterwards, the memory will be leaked. \endrst * * @param item[take] the item * @return the item with reference count decreased by one */ -cbor_item_t * cbor_move(cbor_item_t * item); +cbor_item_t *cbor_move(cbor_item_t *item); #ifdef __cplusplus } #endif -#endif //LIBCBOR_COMMON_H +#endif // LIBCBOR_COMMON_H diff --git a/lib/libcbor/src/cbor/data.h b/lib/libcbor/src/cbor/data.h index 91b59db756a..df0eb953083 100644 --- a/lib/libcbor/src/cbor/data.h +++ b/lib/libcbor/src/cbor/data.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014-2017 Pavel Kalvoda <me@pavelkalvoda.com> + * Copyright (c) 2014-2019 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. @@ -8,101 +8,115 @@ #ifndef LIBCBOR_DATA_H #define LIBCBOR_DATA_H -#include <stdlib.h> +#include <stdbool.h> #include <stddef.h> #include <stdint.h> -#include <stdbool.h> +#include <stdlib.h> #ifdef __cplusplus extern "C" { #endif -typedef const unsigned char * cbor_data; -typedef unsigned char * cbor_mutable_data; +typedef const unsigned char* cbor_data; +typedef unsigned char* cbor_mutable_data; /** Specifies the Major type of ::cbor_item_t */ typedef enum cbor_type { - CBOR_TYPE_UINT /** 0 - positive integers */ - ,CBOR_TYPE_NEGINT /** 1 - negative integers*/ - ,CBOR_TYPE_BYTESTRING /** 2 - byte strings */ - ,CBOR_TYPE_STRING /** 3 - strings */ - ,CBOR_TYPE_ARRAY /** 4 - arrays */ - ,CBOR_TYPE_MAP /** 5 - maps */ - ,CBOR_TYPE_TAG /** 6 - tags */ - ,CBOR_TYPE_FLOAT_CTRL /** 7 - decimals and special values (true, false, nil, ...) */ + CBOR_TYPE_UINT /** 0 - positive integers */ + , + CBOR_TYPE_NEGINT /** 1 - negative integers*/ + , + CBOR_TYPE_BYTESTRING /** 2 - byte strings */ + , + CBOR_TYPE_STRING /** 3 - strings */ + , + CBOR_TYPE_ARRAY /** 4 - arrays */ + , + CBOR_TYPE_MAP /** 5 - maps */ + , + CBOR_TYPE_TAG /** 6 - tags */ + , + CBOR_TYPE_FLOAT_CTRL /** 7 - decimals and special values (true, false, nil, + ...) */ } cbor_type; /** Possible decoding errors */ typedef enum { - CBOR_ERR_NONE - ,CBOR_ERR_NOTENOUGHDATA - ,CBOR_ERR_NODATA - ,CBOR_ERR_MALFORMATED - ,CBOR_ERR_MEMERROR /** Memory error - item allocation failed. Is it too big for your allocator? */ - ,CBOR_ERR_SYNTAXERROR /** Stack parsing algorithm failed */ + CBOR_ERR_NONE, + CBOR_ERR_NOTENOUGHDATA, + CBOR_ERR_NODATA, + CBOR_ERR_MALFORMATED, + CBOR_ERR_MEMERROR /** Memory error - item allocation failed. Is it too big for + your allocator? */ + , + CBOR_ERR_SYNTAXERROR /** Stack parsing algorithm failed */ } cbor_error_code; /** Possible widths of #CBOR_TYPE_UINT items */ typedef enum { - CBOR_INT_8 - ,CBOR_INT_16 - ,CBOR_INT_32 - ,CBOR_INT_64 + CBOR_INT_8, + CBOR_INT_16, + CBOR_INT_32, + CBOR_INT_64 } cbor_int_width; /** Possible widths of #CBOR_TYPE_FLOAT_CTRL items */ typedef enum { - CBOR_FLOAT_0 /** Internal use - ctrl and special values */ - ,CBOR_FLOAT_16 /** Half float */ - ,CBOR_FLOAT_32 /** Single float */ - ,CBOR_FLOAT_64 /** Double */ + CBOR_FLOAT_0 /** Internal use - ctrl and special values */ + , + CBOR_FLOAT_16 /** Half float */ + , + CBOR_FLOAT_32 /** Single float */ + , + CBOR_FLOAT_64 /** Double */ } cbor_float_width; /** Metadata for dynamically sized types */ typedef enum { - _CBOR_METADATA_DEFINITE - ,_CBOR_METADATA_INDEFINITE + _CBOR_METADATA_DEFINITE, + _CBOR_METADATA_INDEFINITE } _cbor_dst_metadata; /** Semantic mapping for CTRL simple values */ typedef enum { - CBOR_CTRL_NONE = 0, - CBOR_CTRL_FALSE = 20, - CBOR_CTRL_TRUE = 21, - CBOR_CTRL_NULL = 22, - CBOR_CTRL_UNDEF = 23 + CBOR_CTRL_NONE = 0, + CBOR_CTRL_FALSE = 20, + CBOR_CTRL_TRUE = 21, + CBOR_CTRL_NULL = 22, + CBOR_CTRL_UNDEF = 23 } _cbor_ctrl; /** Integers specific metadata */ struct _cbor_int_metadata { - cbor_int_width width; + cbor_int_width width; }; /** Bytestrings specific metadata */ struct _cbor_bytestring_metadata { - size_t length; - _cbor_dst_metadata type; + size_t length; + _cbor_dst_metadata type; }; /** Strings specific metadata */ struct _cbor_string_metadata { - size_t length; - size_t codepoint_count; /* Sum of chunks' codepoint_counts for indefinite strings */ - _cbor_dst_metadata type; + size_t length; + size_t codepoint_count; /* Sum of chunks' codepoint_counts for indefinite + strings */ + _cbor_dst_metadata type; }; /** Arrays specific metadata */ struct _cbor_array_metadata { - size_t allocated; - size_t end_ptr; - _cbor_dst_metadata type; + size_t allocated; + size_t end_ptr; + _cbor_dst_metadata type; }; /** Maps specific metadata */ struct _cbor_map_metadata { - size_t allocated; - size_t end_ptr; - _cbor_dst_metadata type; + size_t allocated; + size_t end_ptr; + _cbor_dst_metadata type; }; /** Arrays specific metadata @@ -112,49 +126,50 @@ struct _cbor_map_metadata { * lets use the space */ struct _cbor_tag_metadata { - struct cbor_item_t * tagged_item; - uint64_t value; + struct cbor_item_t* tagged_item; + uint64_t value; }; /** Floats specific metadata - includes CTRL values */ struct _cbor_float_ctrl_metadata { - cbor_float_width width; - uint8_t ctrl; + cbor_float_width width; + uint8_t ctrl; }; /** Raw memory casts helper */ union _cbor_float_helper { - float as_float; - uint32_t as_uint; + float as_float; + uint32_t as_uint; }; /** Raw memory casts helper */ union _cbor_double_helper { - double as_double; - uint64_t as_uint; + double as_double; + uint64_t as_uint; }; -/** Union of metadata across all possible types - discriminated in #cbor_item_t */ +/** Union of metadata across all possible types - discriminated in #cbor_item_t + */ union cbor_item_metadata { - struct _cbor_int_metadata int_metadata; - struct _cbor_bytestring_metadata bytestring_metadata; - struct _cbor_string_metadata string_metadata; - struct _cbor_array_metadata array_metadata; - struct _cbor_map_metadata map_metadata; - struct _cbor_tag_metadata tag_metadata; - struct _cbor_float_ctrl_metadata float_ctrl_metadata; + struct _cbor_int_metadata int_metadata; + struct _cbor_bytestring_metadata bytestring_metadata; + struct _cbor_string_metadata string_metadata; + struct _cbor_array_metadata array_metadata; + struct _cbor_map_metadata map_metadata; + struct _cbor_tag_metadata tag_metadata; + struct _cbor_float_ctrl_metadata float_ctrl_metadata; }; /** The item handle */ typedef struct cbor_item_t { - /** Discriminated by type */ - union cbor_item_metadata metadata; - /** Reference count - initialize to 0 */ - size_t refcount; - /** Major type discriminator */ - cbor_type type; - /** Raw data block - interpretation depends on metadata */ - unsigned char * data; + /** Discriminated by type */ + union cbor_item_metadata metadata; + /** Reference count - initialize to 0 */ + size_t refcount; + /** Major type discriminator */ + cbor_type type; + /** Raw data block - interpretation depends on metadata */ + unsigned char* data; } cbor_item_t; /** Defines cbor_item_t#data structure for indefinite strings and bytestrings @@ -162,51 +177,56 @@ typedef struct cbor_item_t { * Used to cast the raw representation for a sane manipulation */ struct cbor_indefinite_string_data { - size_t chunk_count; - size_t chunk_capacity; - cbor_item_t * * chunks; + size_t chunk_count; + size_t chunk_capacity; + cbor_item_t** chunks; }; /** High-level decoding error */ struct cbor_error { - /** Aproximate position */ - size_t position; - /** Description */ - cbor_error_code code; + /** Aproximate position */ + size_t position; + /** Description */ + cbor_error_code code; }; /** Simple pair of items for use in maps */ struct cbor_pair { - cbor_item_t * key, * value; + cbor_item_t *key, *value; }; /** High-level decoding result */ struct cbor_load_result { - /** Error indicator */ - struct cbor_error error; - /** Number of bytes read*/ - size_t read; + /** Error indicator */ + struct cbor_error error; + /** Number of bytes read*/ + size_t read; }; - /** Streaming decoder result - status */ enum cbor_decoder_status { - CBOR_DECODER_FINISHED /** OK, finished */ - ,CBOR_DECODER_NEDATA /** Not enough data - mismatch with MTB */ - ,CBOR_DECODER_EBUFFER /** Buffer manipulation problem */ - ,CBOR_DECODER_ERROR /** Malformed or reserved MTB/value */ + CBOR_DECODER_FINISHED /** OK, finished */ + , + CBOR_DECODER_NEDATA /** Not enough data - mismatch with MTB */ + , + CBOR_DECODER_EBUFFER /** Buffer manipulation problem */ + , + CBOR_DECODER_ERROR /** Malformed or reserved MTB/value */ }; /** Streaming decoder result */ struct cbor_decoder_result { - /** Bytes read */ - size_t read; - /** The result */ - enum cbor_decoder_status status; + /** Bytes read */ + size_t read; + /** The result */ + enum cbor_decoder_status status; + /** When status == CBOR_DECODER_NEDATA, + * the minimum number of bytes required to continue parsing */ + size_t required; }; #ifdef __cplusplus } #endif -#endif //LIBCBOR_DATA_H +#endif // LIBCBOR_DATA_H diff --git a/lib/libcbor/src/cbor/encoding.c b/lib/libcbor/src/cbor/encoding.c index bb636d82145..341d9290f34 100644 --- a/lib/libcbor/src/cbor/encoding.c +++ b/lib/libcbor/src/cbor/encoding.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014-2017 Pavel Kalvoda <me@pavelkalvoda.com> + * Copyright (c) 2014-2019 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. @@ -8,179 +8,185 @@ #include "encoding.h" #include "internal/encoders.h" -size_t cbor_encode_uint8(uint8_t value, unsigned char *buffer, size_t buffer_size) -{ - return _cbor_encode_uint8(value, buffer, buffer_size, 0x00); +size_t cbor_encode_uint8(uint8_t value, unsigned char *buffer, + size_t buffer_size) { + return _cbor_encode_uint8(value, buffer, buffer_size, 0x00); } -size_t cbor_encode_uint16(uint16_t value, unsigned char *buffer, size_t buffer_size) -{ - return _cbor_encode_uint16(value, buffer, buffer_size, 0x00); +size_t cbor_encode_uint16(uint16_t value, unsigned char *buffer, + size_t buffer_size) { + return _cbor_encode_uint16(value, buffer, buffer_size, 0x00); } -size_t cbor_encode_uint32(uint32_t value, unsigned char *buffer, size_t buffer_size) -{ - return _cbor_encode_uint32(value, buffer, buffer_size, 0x00); +size_t cbor_encode_uint32(uint32_t value, unsigned char *buffer, + size_t buffer_size) { + return _cbor_encode_uint32(value, buffer, buffer_size, 0x00); } -size_t cbor_encode_uint64(uint64_t value, unsigned char *buffer, size_t buffer_size) -{ - return _cbor_encode_uint64(value, buffer, buffer_size, 0x00); +size_t cbor_encode_uint64(uint64_t value, unsigned char *buffer, + size_t buffer_size) { + return _cbor_encode_uint64(value, buffer, buffer_size, 0x00); } -size_t cbor_encode_uint(uint64_t value, unsigned char *buffer, size_t buffer_size) -{ - return _cbor_encode_uint(value, buffer, buffer_size, 0x00); +size_t cbor_encode_uint(uint64_t value, unsigned char *buffer, + size_t buffer_size) { + return _cbor_encode_uint(value, buffer, buffer_size, 0x00); } - -size_t cbor_encode_negint8(uint8_t value, unsigned char *buffer, size_t buffer_size) -{ - return _cbor_encode_uint8(value, buffer, buffer_size, 0x20); +size_t cbor_encode_negint8(uint8_t value, unsigned char *buffer, + size_t buffer_size) { + return _cbor_encode_uint8(value, buffer, buffer_size, 0x20); } -size_t cbor_encode_negint16(uint16_t value, unsigned char *buffer, size_t buffer_size) -{ - return _cbor_encode_uint16(value, buffer, buffer_size, 0x20); +size_t cbor_encode_negint16(uint16_t value, unsigned char *buffer, + size_t buffer_size) { + return _cbor_encode_uint16(value, buffer, buffer_size, 0x20); } -size_t cbor_encode_negint32(uint32_t value, unsigned char *buffer, size_t buffer_size) -{ - return _cbor_encode_uint32(value, buffer, buffer_size, 0x20); +size_t cbor_encode_negint32(uint32_t value, unsigned char *buffer, + size_t buffer_size) { + return _cbor_encode_uint32(value, buffer, buffer_size, 0x20); } -size_t cbor_encode_negint64(uint64_t value, unsigned char *buffer, size_t buffer_size) -{ - return _cbor_encode_uint64(value, buffer, buffer_size, 0x20); +size_t cbor_encode_negint64(uint64_t value, unsigned char *buffer, + size_t buffer_size) { + return _cbor_encode_uint64(value, buffer, buffer_size, 0x20); } -size_t cbor_encode_negint(uint64_t value, unsigned char *buffer, size_t buffer_size) -{ - return _cbor_encode_uint(value, buffer, buffer_size, 0x20); +size_t cbor_encode_negint(uint64_t value, unsigned char *buffer, + size_t buffer_size) { + return _cbor_encode_uint(value, buffer, buffer_size, 0x20); } -size_t cbor_encode_bytestring_start(size_t length, unsigned char *buffer, size_t buffer_size) -{ - return _cbor_encode_uint((size_t) length, buffer, buffer_size, 0x40); +size_t cbor_encode_bytestring_start(size_t length, unsigned char *buffer, + size_t buffer_size) { + return _cbor_encode_uint((size_t)length, buffer, buffer_size, 0x40); } -size_t _cbor_encode_byte(uint8_t value, unsigned char *buffer, size_t buffer_size) -{ - if (buffer_size >= 1) { - buffer[0] = value; - return 1; - } else - return 0; +size_t _cbor_encode_byte(uint8_t value, unsigned char *buffer, + size_t buffer_size) { + if (buffer_size >= 1) { + buffer[0] = value; + return 1; + } else + return 0; } -size_t cbor_encode_indef_bytestring_start(unsigned char *buffer, size_t buffer_size) -{ - return _cbor_encode_byte(0x5F, buffer, buffer_size); +size_t cbor_encode_indef_bytestring_start(unsigned char *buffer, + size_t buffer_size) { + return _cbor_encode_byte(0x5F, buffer, buffer_size); } -size_t cbor_encode_string_start(size_t length, unsigned char *buffer, size_t buffer_size) -{ - return _cbor_encode_uint((size_t) length, buffer, buffer_size, 0x60); +size_t cbor_encode_string_start(size_t length, unsigned char *buffer, + size_t buffer_size) { + return _cbor_encode_uint((size_t)length, buffer, buffer_size, 0x60); } -size_t cbor_encode_indef_string_start(unsigned char *buffer, size_t buffer_size) -{ - return _cbor_encode_byte(0x7F, buffer, buffer_size); +size_t cbor_encode_indef_string_start(unsigned char *buffer, + size_t buffer_size) { + return _cbor_encode_byte(0x7F, buffer, buffer_size); } -size_t cbor_encode_array_start(size_t length, unsigned char *buffer, size_t buffer_size) -{ - return _cbor_encode_uint((size_t) length, buffer, buffer_size, 0x80); +size_t cbor_encode_array_start(size_t length, unsigned char *buffer, + size_t buffer_size) { + return _cbor_encode_uint((size_t)length, buffer, buffer_size, 0x80); } -size_t cbor_encode_indef_array_start(unsigned char *buffer, size_t buffer_size) -{ - return _cbor_encode_byte(0x9F, buffer, buffer_size); +size_t cbor_encode_indef_array_start(unsigned char *buffer, + size_t buffer_size) { + return _cbor_encode_byte(0x9F, buffer, buffer_size); } -size_t cbor_encode_map_start(size_t length, unsigned char *buffer, size_t buffer_size) -{ - return _cbor_encode_uint((size_t) length, buffer, buffer_size, 0xA0); +size_t cbor_encode_map_start(size_t length, unsigned char *buffer, + size_t buffer_size) { + return _cbor_encode_uint((size_t)length, buffer, buffer_size, 0xA0); } -size_t cbor_encode_indef_map_start(unsigned char *buffer, size_t buffer_size) -{ - return _cbor_encode_byte(0xBF, buffer, buffer_size); +size_t cbor_encode_indef_map_start(unsigned char *buffer, size_t buffer_size) { + return _cbor_encode_byte(0xBF, buffer, buffer_size); } -size_t cbor_encode_tag(uint64_t value, unsigned char *buffer, size_t buffer_size) -{ - return _cbor_encode_uint(value, buffer, buffer_size, 0xC0); +size_t cbor_encode_tag(uint64_t value, unsigned char *buffer, + size_t buffer_size) { + return _cbor_encode_uint(value, buffer, buffer_size, 0xC0); } -size_t cbor_encode_bool(bool value, unsigned char *buffer, size_t buffer_size) -{ - return value ? _cbor_encode_byte(0xF5, buffer, buffer_size) : _cbor_encode_byte(0xF4, buffer, buffer_size); +size_t cbor_encode_bool(bool value, unsigned char *buffer, size_t buffer_size) { + return value ? _cbor_encode_byte(0xF5, buffer, buffer_size) + : _cbor_encode_byte(0xF4, buffer, buffer_size); } -size_t cbor_encode_null(unsigned char *buffer, size_t buffer_size) -{ - return _cbor_encode_byte(0xF6, buffer, buffer_size); +size_t cbor_encode_null(unsigned char *buffer, size_t buffer_size) { + return _cbor_encode_byte(0xF6, buffer, buffer_size); } -size_t cbor_encode_undef(unsigned char *buffer, size_t buffer_size) -{ - return _cbor_encode_byte(0xF7, buffer, buffer_size); +size_t cbor_encode_undef(unsigned char *buffer, size_t buffer_size) { + return _cbor_encode_byte(0xF7, buffer, buffer_size); } -size_t cbor_encode_half(float value, unsigned char *buffer, size_t buffer_size) -{ - /* Assuming value is normalized */ - uint32_t val = ((union _cbor_float_helper) {.as_float = value}).as_uint; - uint16_t res; - uint8_t exp = (uint8_t) ((val & 0x7F800000) >> 23); /* 0b0111_1111_1000_0000_0000_0000_0000_0000 */ - uint32_t mant = val & 0x7FFFFF; /* 0b0000_0000_0111_1111_1111_1111_1111_1111 */ - if (exp == 0xFF) { /* Infinity or NaNs */ - if (value != value) { - res = (uint16_t) 0x00e700; /* Not IEEE semantics - required by CBOR [s. 3.9] */ - } else { - res = (uint16_t) ((val & 0x80000000) >> 16 | 0x7C00 | (mant ? 1 : 0) << 15); - } - } else if (exp == 0x00) { /* Zeroes or subnorms */ - res = (uint16_t) ((val & 0x80000000) >> 16 | mant >> 13); - } else { /* Normal numbers */ - int8_t logical_exp = (int8_t) (exp - 127); - assert(logical_exp == exp - 127); +size_t cbor_encode_half(float value, unsigned char *buffer, + size_t buffer_size) { + /* Assuming value is normalized */ + uint32_t val = ((union _cbor_float_helper){.as_float = value}).as_uint; + uint16_t res; + uint8_t exp = (uint8_t)((val & 0x7F800000) >> + 23); /* 0b0111_1111_1000_0000_0000_0000_0000_0000 */ + uint32_t mant = + val & 0x7FFFFF; /* 0b0000_0000_0111_1111_1111_1111_1111_1111 */ + if (exp == 0xFF) { /* Infinity or NaNs */ + if (value != value) { + res = (uint16_t)0x00e700; /* Not IEEE semantics - required by CBOR + [s. 3.9] */ + } else { + res = + (uint16_t)((val & 0x80000000) >> 16 | 0x7C00 | (mant ? 1 : 0) << 15); + } + } else if (exp == 0x00) { /* Zeroes or subnorms */ + res = (uint16_t)((val & 0x80000000) >> 16 | mant >> 13); + } else { /* Normal numbers */ + int8_t logical_exp = (int8_t)(exp - 127); + assert(logical_exp == exp - 127); - // Now we know that 2^exp <= 0 logically - if (logical_exp < -24) { - /* No unambiguous representation exists, this float is not a half float and is too small to - be represented using a half, round off to zero. Consistent with the reference implementation. */ - res = 0; - } else if (logical_exp < -14) { - /* Offset the remaining decimal places by shifting the significand, the value is lost. - This is an implementation decision that works around the absence of standard half-float - in the language. */ - res = (uint16_t) (val & 0x80000000) >> 16 | (uint16_t) (1 << (24 + logical_exp)); - } else { - res = (uint16_t) ((val & 0x80000000) >> 16 | ((((uint8_t) logical_exp) + 15) << 10) | (uint16_t) (mant >> 13)); - } - } - return _cbor_encode_uint16(res, buffer, buffer_size, 0xE0); + // Now we know that 2^exp <= 0 logically + if (logical_exp < -24) { + /* No unambiguous representation exists, this float is not a half float + and is too small to be represented using a half, round off to zero. + Consistent with the reference implementation. */ + res = 0; + } else if (logical_exp < -14) { + /* Offset the remaining decimal places by shifting the significand, the + value is lost. This is an implementation decision that works around the + absence of standard half-float in the language. */ + res = (uint16_t)(val & 0x80000000) >> 16 | + (uint16_t)(1 << (24 + logical_exp)); + } else { + res = (uint16_t)((val & 0x80000000) >> 16 | + ((((uint8_t)logical_exp) + 15) << 10) | + (uint16_t)(mant >> 13)); + } + } + return _cbor_encode_uint16(res, buffer, buffer_size, 0xE0); } -size_t cbor_encode_single(float value, unsigned char *buffer, size_t buffer_size) -{ - - return _cbor_encode_uint32(((union _cbor_float_helper) {.as_float = value}).as_uint, buffer, buffer_size, 0xE0); +size_t cbor_encode_single(float value, unsigned char *buffer, + size_t buffer_size) { + return _cbor_encode_uint32( + ((union _cbor_float_helper){.as_float = value}).as_uint, buffer, + buffer_size, 0xE0); } -size_t cbor_encode_double(double value, unsigned char *buffer, size_t buffer_size) -{ - return _cbor_encode_uint64(((union _cbor_double_helper) {.as_double = value}).as_uint, buffer, buffer_size, 0xE0); +size_t cbor_encode_double(double value, unsigned char *buffer, + size_t buffer_size) { + return _cbor_encode_uint64( + ((union _cbor_double_helper){.as_double = value}).as_uint, buffer, + buffer_size, 0xE0); } -size_t cbor_encode_break(unsigned char *buffer, size_t buffer_size) -{ - return _cbor_encode_byte(0xFF, buffer, buffer_size); +size_t cbor_encode_break(unsigned char *buffer, size_t buffer_size) { + return _cbor_encode_byte(0xFF, buffer, buffer_size); } -size_t cbor_encode_ctrl(uint8_t value, unsigned char * buffer, size_t buffer_size) -{ - return _cbor_encode_uint8(value, buffer, buffer_size, 0xE0); +size_t cbor_encode_ctrl(uint8_t value, unsigned char *buffer, + size_t buffer_size) { + return _cbor_encode_uint8(value, buffer, buffer_size, 0xE0); } diff --git a/lib/libcbor/src/cbor/encoding.h b/lib/libcbor/src/cbor/encoding.h index 8117582b6a1..8261467215e 100644 --- a/lib/libcbor/src/cbor/encoding.h +++ b/lib/libcbor/src/cbor/encoding.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014-2017 Pavel Kalvoda <me@pavelkalvoda.com> + * Copyright (c) 2014-2019 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. @@ -14,12 +14,11 @@ extern "C" { #endif - /* -* ============================================================================ -* Primitives encoding -* ============================================================================ -*/ + * ============================================================================ + * Primitives encoding + * ============================================================================ + */ size_t cbor_encode_uint8(uint8_t, unsigned char *, size_t); @@ -75,14 +74,16 @@ size_t cbor_encode_undef(unsigned char *, size_t); * unambiguously encoded. The behavior is as follows: * - Infinity, NaN are preserved * - Zero is preserved - * - Denormalized numbers keep their sign bit and 10 most significant bit of the significand + * - Denormalized numbers keep their sign bit and 10 most significant bit of + * the significand * - All other numbers * - If the logical value of the exponent is < -24, the output is zero * - If the logical value of the exponent is between -23 and -14, the output * is cut off to represent the 'magnitude' of the input, by which we - * mean (-1)^{signbit} x 1.0e{exponent}. The value in the significand is lost. - * - In all other cases, the sign bit, the exponent, and 10 most significant bits - * of the significand are kept + * mean (-1)^{signbit} x 1.0e{exponent}. The value in the significand is + * lost. + * - In all other cases, the sign bit, the exponent, and 10 most significant + * bits of the significand are kept * * @param value * @param buffer Target buffer @@ -103,5 +104,4 @@ size_t cbor_encode_ctrl(uint8_t, unsigned char *, size_t); } #endif - -#endif //LIBCBOR_ENCODING_H +#endif // LIBCBOR_ENCODING_H diff --git a/lib/libcbor/src/cbor/floats_ctrls.c b/lib/libcbor/src/cbor/floats_ctrls.c index 92bc1347ffc..1da8ed66771 100644 --- a/lib/libcbor/src/cbor/floats_ctrls.c +++ b/lib/libcbor/src/cbor/floats_ctrls.c @@ -1,191 +1,183 @@ /* - * Copyright (c) 2014-2017 Pavel Kalvoda <me@pavelkalvoda.com> + * Copyright (c) 2014-2019 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. */ #include "floats_ctrls.h" -#include "assert.h" #include <math.h> +#include "assert.h" + +cbor_float_width cbor_float_get_width(const cbor_item_t *item) { + assert(cbor_isa_float_ctrl(item)); + return item->metadata.float_ctrl_metadata.width; +} + +uint8_t cbor_ctrl_value(const cbor_item_t *item) { + assert(cbor_isa_float_ctrl(item)); + assert(cbor_float_get_width(item) == CBOR_FLOAT_0); + return item->metadata.float_ctrl_metadata.ctrl; +} + +bool cbor_float_ctrl_is_ctrl(const cbor_item_t *item) { + assert(cbor_isa_float_ctrl(item)); + return cbor_float_get_width(item) == CBOR_FLOAT_0; +} + +float cbor_float_get_float2(const cbor_item_t *item) { + assert(cbor_is_float(item)); + assert(cbor_float_get_width(item) == CBOR_FLOAT_16); + return *(float *)item->data; +} + +float cbor_float_get_float4(const cbor_item_t *item) { + assert(cbor_is_float(item)); + assert(cbor_float_get_width(item) == CBOR_FLOAT_32); + return *(float *)item->data; +} + +double cbor_float_get_float8(const cbor_item_t *item) { + assert(cbor_is_float(item)); + assert(cbor_float_get_width(item) == CBOR_FLOAT_64); + return *(double *)item->data; +} -cbor_float_width cbor_float_get_width(const cbor_item_t *item) -{ - assert(cbor_isa_float_ctrl(item)); - return item->metadata.float_ctrl_metadata.width; +double cbor_float_get_float(const cbor_item_t *item) { + assert(cbor_is_float(item)); + switch (cbor_float_get_width(item)) { + case CBOR_FLOAT_0: + return NAN; + case CBOR_FLOAT_16: + return cbor_float_get_float2(item); + case CBOR_FLOAT_32: + return cbor_float_get_float4(item); + case CBOR_FLOAT_64: + return cbor_float_get_float8(item); + } + return NAN; /* Compiler complaints */ } -uint8_t cbor_ctrl_value(const cbor_item_t *item) -{ - assert(cbor_isa_float_ctrl(item)); - assert(cbor_float_get_width(item) == CBOR_FLOAT_0); - return item->metadata.float_ctrl_metadata.ctrl; +void cbor_set_float2(cbor_item_t *item, float value) { + assert(cbor_is_float(item)); + assert(cbor_float_get_width(item) == CBOR_FLOAT_16); + *((float *)item->data) = value; } -bool cbor_float_ctrl_is_ctrl(const cbor_item_t *item) -{ - assert(cbor_isa_float_ctrl(item)); - return cbor_float_get_width(item) == CBOR_FLOAT_0; +void cbor_set_float4(cbor_item_t *item, float value) { + assert(cbor_is_float(item)); + assert(cbor_float_get_width(item) == CBOR_FLOAT_32); + *((float *)item->data) = value; } - -float cbor_float_get_float2(const cbor_item_t *item) -{ - assert(cbor_is_float(item)); - assert(cbor_float_get_width(item) == CBOR_FLOAT_16); - return *(float *) item->data; + +void cbor_set_float8(cbor_item_t *item, double value) { + assert(cbor_is_float(item)); + assert(cbor_float_get_width(item) == CBOR_FLOAT_64); + *((double *)item->data) = value; +} + +void cbor_set_ctrl(cbor_item_t *item, uint8_t value) { + assert(cbor_isa_float_ctrl(item)); + assert(cbor_float_get_width(item) == CBOR_FLOAT_0); + item->metadata.float_ctrl_metadata.ctrl = value; +} + +bool cbor_ctrl_is_bool(const cbor_item_t *item) { + assert(cbor_is_bool(item)); + return item->metadata.float_ctrl_metadata.ctrl == CBOR_CTRL_TRUE; +} + +cbor_item_t *cbor_new_ctrl() { + cbor_item_t *item = _CBOR_MALLOC(sizeof(cbor_item_t)); + _CBOR_NOTNULL(item); + + *item = (cbor_item_t){ + .type = CBOR_TYPE_FLOAT_CTRL, + .data = NULL, + .refcount = 1, + .metadata = {.float_ctrl_metadata = {.width = CBOR_FLOAT_0, + .ctrl = CBOR_CTRL_NONE}}}; + return item; +} + +cbor_item_t *cbor_new_float2() { + cbor_item_t *item = _CBOR_MALLOC(sizeof(cbor_item_t) + 4); + _CBOR_NOTNULL(item); + + *item = (cbor_item_t){ + .type = CBOR_TYPE_FLOAT_CTRL, + .data = (unsigned char *)item + sizeof(cbor_item_t), + .refcount = 1, + .metadata = {.float_ctrl_metadata = {.width = CBOR_FLOAT_16}}}; + return item; +} + +cbor_item_t *cbor_new_float4() { + cbor_item_t *item = _CBOR_MALLOC(sizeof(cbor_item_t) + 4); + _CBOR_NOTNULL(item); + + *item = (cbor_item_t){ + .type = CBOR_TYPE_FLOAT_CTRL, + .data = (unsigned char *)item + sizeof(cbor_item_t), + .refcount = 1, + .metadata = {.float_ctrl_metadata = {.width = CBOR_FLOAT_32}}}; + return item; } -float cbor_float_get_float4(const cbor_item_t *item) -{ - assert(cbor_is_float(item)); - assert(cbor_float_get_width(item) == CBOR_FLOAT_32); - return *(float *) item->data; -} - -double cbor_float_get_float8(const cbor_item_t *item) -{ - assert(cbor_is_float(item)); - assert(cbor_float_get_width(item) == CBOR_FLOAT_64); - return *(double *) item->data; -} - -double cbor_float_get_float(const cbor_item_t * item) -{ - assert(cbor_is_float(item)); - switch(cbor_float_get_width(item)) { - case CBOR_FLOAT_0: return NAN; - case CBOR_FLOAT_16: return cbor_float_get_float2(item); - case CBOR_FLOAT_32: return cbor_float_get_float4(item); - case CBOR_FLOAT_64: return cbor_float_get_float8(item); - } - return NAN; /* Compiler complaints */ -} +cbor_item_t *cbor_new_float8() { + cbor_item_t *item = _CBOR_MALLOC(sizeof(cbor_item_t) + 8); + _CBOR_NOTNULL(item); -void cbor_set_float2(cbor_item_t *item, float value) -{ - assert(cbor_is_float(item)); - assert(cbor_float_get_width(item) == CBOR_FLOAT_16); - *((float *) item->data) = value; + *item = (cbor_item_t){ + .type = CBOR_TYPE_FLOAT_CTRL, + .data = (unsigned char *)item + sizeof(cbor_item_t), + .refcount = 1, + .metadata = {.float_ctrl_metadata = {.width = CBOR_FLOAT_64}}}; + return item; } -void cbor_set_float4(cbor_item_t *item, float value) -{ - assert(cbor_is_float(item)); - assert(cbor_float_get_width(item) == CBOR_FLOAT_32); - *((float *) item->data) = value; +cbor_item_t *cbor_new_null() { + cbor_item_t *item = cbor_new_ctrl(); + _CBOR_NOTNULL(item); + cbor_set_ctrl(item, CBOR_CTRL_NULL); + return item; } -void cbor_set_float8(cbor_item_t *item, double value) -{ - assert(cbor_is_float(item)); - assert(cbor_float_get_width(item) == CBOR_FLOAT_64); - *((double *) item->data) = value; +cbor_item_t *cbor_new_undef() { + cbor_item_t *item = cbor_new_ctrl(); + _CBOR_NOTNULL(item); + cbor_set_ctrl(item, CBOR_CTRL_UNDEF); + return item; } -void cbor_set_ctrl(cbor_item_t *item, uint8_t value) -{ - assert(cbor_isa_float_ctrl(item)); - assert(cbor_float_get_width(item) == CBOR_FLOAT_0); - item->metadata.float_ctrl_metadata.ctrl = value; +cbor_item_t *cbor_build_bool(bool value) { + return cbor_build_ctrl(value ? CBOR_CTRL_TRUE : CBOR_CTRL_FALSE); } -bool cbor_ctrl_is_bool(const cbor_item_t *item) -{ - assert(cbor_is_bool(item)); - return item->metadata.float_ctrl_metadata.ctrl == CBOR_CTRL_TRUE; +cbor_item_t *cbor_build_float2(float value) { + cbor_item_t *item = cbor_new_float2(); + _CBOR_NOTNULL(item); + cbor_set_float2(item, value); + return item; } -cbor_item_t *cbor_new_ctrl() -{ - cbor_item_t *item = _CBOR_MALLOC(sizeof(cbor_item_t)); - *item = (cbor_item_t) { - .type = CBOR_TYPE_FLOAT_CTRL, - .data = NULL, - .refcount = 1, - .metadata = {.float_ctrl_metadata = {.width = CBOR_FLOAT_0, .ctrl = CBOR_CTRL_NONE}} - }; - return item; +cbor_item_t *cbor_build_float4(float value) { + cbor_item_t *item = cbor_new_float4(); + _CBOR_NOTNULL(item); + cbor_set_float4(item, value); + return item; } -cbor_item_t *cbor_new_float2() -{ - cbor_item_t *item = _CBOR_MALLOC(sizeof(cbor_item_t) + 4); - *item = (cbor_item_t) { - .type = CBOR_TYPE_FLOAT_CTRL, - .data = (unsigned char *) item + sizeof(cbor_item_t), - .refcount = 1, - .metadata = {.float_ctrl_metadata = {.width = CBOR_FLOAT_16}} - }; - return item; +cbor_item_t *cbor_build_float8(double value) { + cbor_item_t *item = cbor_new_float8(); + _CBOR_NOTNULL(item); + cbor_set_float8(item, value); + return item; } -cbor_item_t *cbor_new_float4() -{ - cbor_item_t *item = _CBOR_MALLOC(sizeof(cbor_item_t) + 4); - *item = (cbor_item_t) { - .type = CBOR_TYPE_FLOAT_CTRL, - .data = (unsigned char *) item + sizeof(cbor_item_t), - .refcount = 1, - .metadata = {.float_ctrl_metadata = {.width = CBOR_FLOAT_32}} - }; - return item; -} - -cbor_item_t *cbor_new_float8() -{ - cbor_item_t *item = _CBOR_MALLOC(sizeof(cbor_item_t) + 8); - *item = (cbor_item_t) { - .type = CBOR_TYPE_FLOAT_CTRL, - .data = (unsigned char *) item + sizeof(cbor_item_t), - .refcount = 1, - .metadata = {.float_ctrl_metadata = {.width = CBOR_FLOAT_64}} - }; - return item; -} - -cbor_item_t *cbor_new_null() -{ - cbor_item_t *item = cbor_new_ctrl(); - cbor_set_ctrl(item, CBOR_CTRL_NULL); - return item; -} - -cbor_item_t *cbor_new_undef() -{ - cbor_item_t *item = cbor_new_ctrl(); - cbor_set_ctrl(item, CBOR_CTRL_UNDEF); - return item; -} - -cbor_item_t *cbor_build_bool(bool value) -{ - return cbor_build_ctrl(value ? CBOR_CTRL_TRUE : CBOR_CTRL_FALSE); -} - -cbor_item_t *cbor_build_float2(float value) -{ - cbor_item_t *item = cbor_new_float2(); - cbor_set_float2(item, value); - return item; -} - -cbor_item_t *cbor_build_float4(float value) -{ - cbor_item_t *item = cbor_new_float4(); - cbor_set_float4(item, value); - return item; -} - -cbor_item_t *cbor_build_float8(double value) -{ - cbor_item_t *item = cbor_new_float8(); - cbor_set_float8(item, value); - return item; -} - -cbor_item_t *cbor_build_ctrl(uint8_t value) -{ - cbor_item_t *item = cbor_new_ctrl(); - cbor_set_ctrl(item, value); - return item; +cbor_item_t *cbor_build_ctrl(uint8_t value) { + cbor_item_t *item = cbor_new_ctrl(); + _CBOR_NOTNULL(item); + cbor_set_ctrl(item, value); + return item; } diff --git a/lib/libcbor/src/cbor/floats_ctrls.h b/lib/libcbor/src/cbor/floats_ctrls.h index a5cdc40e90b..83cb75acd6e 100644 --- a/lib/libcbor/src/cbor/floats_ctrls.h +++ b/lib/libcbor/src/cbor/floats_ctrls.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014-2017 Pavel Kalvoda <me@pavelkalvoda.com> + * Copyright (c) 2014-2019 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. @@ -15,24 +15,24 @@ extern "C" { #endif /* -* ============================================================================ -* Float manipulation -* ============================================================================ -*/ + * ============================================================================ + * Float manipulation + * ============================================================================ + */ /** Is this a ctrl value? * * @param item[borrow] A float or ctrl item * @return Is this a ctrl value? */ -bool cbor_float_ctrl_is_ctrl(const cbor_item_t * item); +bool cbor_float_ctrl_is_ctrl(const cbor_item_t *item); /** Get the float width * * @param item[borrow] A float or ctrl item * @return The width. */ -cbor_float_width cbor_float_get_width(const cbor_item_t * item); +cbor_float_width cbor_float_get_width(const cbor_item_t *item); /** Get a half precision float * @@ -41,7 +41,7 @@ cbor_float_width cbor_float_get_width(const cbor_item_t * item); * @param[borrow] A half precision float * @return half precision value */ -float cbor_float_get_float2(const cbor_item_t * item); +float cbor_float_get_float2(const cbor_item_t *item); /** Get a single precision float * @@ -50,7 +50,7 @@ float cbor_float_get_float2(const cbor_item_t * item); * @param[borrow] A signle precision float * @return single precision value */ -float cbor_float_get_float4(const cbor_item_t * item); +float cbor_float_get_float4(const cbor_item_t *item); /** Get a double precision float * @@ -59,7 +59,7 @@ float cbor_float_get_float4(const cbor_item_t * item); * @param[borrow] A double precision float * @return double precision value */ -double cbor_float_get_float8(const cbor_item_t * item); +double cbor_float_get_float8(const cbor_item_t *item); /** Get the float value represented as double * @@ -68,104 +68,106 @@ double cbor_float_get_float8(const cbor_item_t * item); * @param[borrow] Any float * @return double precision value */ -double cbor_float_get_float(const cbor_item_t * item); +double cbor_float_get_float(const cbor_item_t *item); /** Constructs a new ctrl item * * The width cannot be changed once the item is created * - * @return **new** 1B ctrl + * @return **new** 1B ctrl or `NULL` upon memory allocation failure */ -cbor_item_t * cbor_new_ctrl(); +cbor_item_t *cbor_new_ctrl(); /** Constructs a new float item * * The width cannot be changed once the item is created * - * @return **new** 2B float + * @return **new** 2B float or `NULL` upon memory allocation failure */ -cbor_item_t * cbor_new_float2(); +cbor_item_t *cbor_new_float2(); /** Constructs a new float item * * The width cannot be changed once the item is created * - * @return **new** 4B float + * @return **new** 4B float or `NULL` upon memory allocation failure */ -cbor_item_t * cbor_new_float4(); +cbor_item_t *cbor_new_float4(); /** Constructs a new float item * * The width cannot be changed once the item is created * - * @return **new** 8B float + * @return **new** 8B float or `NULL` upon memory allocation failure */ -cbor_item_t * cbor_new_float8(); +cbor_item_t *cbor_new_float8(); /** Constructs new null ctrl item * - * @return **new** null ctrl item + * @return **new** null ctrl item or `NULL` upon memory allocation failure */ -cbor_item_t * cbor_new_null(); +cbor_item_t *cbor_new_null(); -/** Constructs new under ctrl item +/** Constructs new undef ctrl item * - * @return **new** under ctrl item + * @return **new** undef ctrl item or `NULL` upon memory allocation failure */ -cbor_item_t * cbor_new_undef(); +cbor_item_t *cbor_new_undef(); /** Constructs new boolean ctrl item * * @param value The value to use - * @return **new** boolen ctrl item + * @return **new** boolen ctrl item or `NULL` upon memory allocation failure */ -cbor_item_t * cbor_build_bool(bool value); +cbor_item_t *cbor_build_bool(bool value); /** Assign a control value * * \rst - * .. warning:: It is possible to produce an invalid CBOR value by assigning a invalid value using this mechanism. Please consult the standard before use. + * .. warning:: It is possible to produce an invalid CBOR value by assigning a + * invalid value using this mechanism. Please consult the standard before use. * \endrst * * @param item[borrow] A ctrl item - * @param value The simple value to assign. Please consult the standard for allowed values + * @param value The simple value to assign. Please consult the standard for + * allowed values */ -void cbor_set_ctrl(cbor_item_t * item, uint8_t value); +void cbor_set_ctrl(cbor_item_t *item, uint8_t value); /** Assigns a float value * * @param item[borrow] A half precision float * @param value The value to assign */ -void cbor_set_float2(cbor_item_t * item, float value); +void cbor_set_float2(cbor_item_t *item, float value); /** Assigns a float value * * @param item[borrow] A single precision float * @param value The value to assign */ -void cbor_set_float4(cbor_item_t * item, float value); +void cbor_set_float4(cbor_item_t *item, float value); /** Assigns a float value * * @param item[borrow] A double precision float * @param value The value to assign */ -void cbor_set_float8(cbor_item_t * item, double value); +void cbor_set_float8(cbor_item_t *item, double value); /** Reads the control value * * @param item[borrow] A ctrl item * @return the simple value */ -uint8_t cbor_ctrl_value(const cbor_item_t * item); +uint8_t cbor_ctrl_value(const cbor_item_t *item); /** Is this ctrl item a boolean? * * @param item[borrow] A ctrl item * @return Is this ctrl item a boolean? */ -bool cbor_ctrl_is_bool(const cbor_item_t * item); +bool cbor_ctrl_is_bool(const cbor_item_t *item); /** Constructs a new float * @@ -177,27 +179,26 @@ cbor_item_t *cbor_build_float2(float value); /** Constructs a new float * * @param value the value to use - * @return **new** float + * @return **new** float or `NULL` upon memory allocation failure */ cbor_item_t *cbor_build_float4(float value); /** Constructs a new float * * @param value the value to use - * @return **new** float + * @return **new** float or `NULL` upon memory allocation failure */ cbor_item_t *cbor_build_float8(double value); /** Constructs a ctrl item * * @param value the value to use - * @return **new** ctrl item + * @return **new** ctrl item or `NULL` upon memory allocation failure */ -cbor_item_t *cbor_build_ctrl(uint8_t value); - +cbor_item_t *cbor_build_ctrl(uint8_t value); #ifdef __cplusplus } #endif -#endif //LIBCBOR_FLOATS_CTRLS_H +#endif // LIBCBOR_FLOATS_CTRLS_H diff --git a/lib/libcbor/src/cbor/internal/builder_callbacks.c b/lib/libcbor/src/cbor/internal/builder_callbacks.c index 7f28d28433f..bd445bd1ee8 100644 --- a/lib/libcbor/src/cbor/internal/builder_callbacks.c +++ b/lib/libcbor/src/cbor/internal/builder_callbacks.c @@ -1,12 +1,11 @@ /* - * Copyright (c) 2014-2017 Pavel Kalvoda <me@pavelkalvoda.com> + * Copyright (c) 2014-2019 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. */ #include "builder_callbacks.h" -#include "unicode.h" #include <string.h> #include "../arrays.h" #include "../bytestrings.h" @@ -15,345 +14,364 @@ #include "../maps.h" #include "../strings.h" #include "../tags.h" +#include "unicode.h" -void _cbor_builder_append(cbor_item_t *item, struct _cbor_decoder_context *ctx) -{ - if (ctx->stack->size == 0) { - /* Top level item */ - ctx->root = item; - } else { - /* Part of a bigger structure */ - switch (ctx->stack->top->item->type) { - case CBOR_TYPE_ARRAY: { - if (cbor_array_is_definite(ctx->stack->top->item)) { - assert(ctx->stack->top->subitems > 0); - cbor_array_push(ctx->stack->top->item, item); - ctx->stack->top->subitems--; - if (ctx->stack->top->subitems == 0) { - cbor_item_t *item = ctx->stack->top->item; - _cbor_stack_pop(ctx->stack); - _cbor_builder_append(item, ctx); - } - cbor_decref(&item); - } else { - /* Indefinite array, don't bother with subitems */ - cbor_array_push(ctx->stack->top->item, item); - cbor_decref(&item); - } - break; - } - case CBOR_TYPE_MAP: { - /* We use 0 and 1 subitems to distinguish between keys and values in indefinite items */ - if (ctx->stack->top->subitems % 2) { - /* Odd record, this is a value */ - _cbor_map_add_value(ctx->stack->top->item, cbor_move(item)); - } else { - /* Even record, this is a key */ - _cbor_map_add_key(ctx->stack->top->item, cbor_move(item)); - } - if (cbor_map_is_definite(ctx->stack->top->item)) { - ctx->stack->top->subitems--; - if (ctx->stack->top->subitems == 0) { - cbor_item_t *item = ctx->stack->top->item; - _cbor_stack_pop(ctx->stack); - _cbor_builder_append(item, ctx); - } - } else { - ctx->stack->top->subitems ^= 1; /* Flip the indicator for indefinite items */ - } - break; - } - case CBOR_TYPE_TAG: { - assert(ctx->stack->top->subitems == 1); - cbor_tag_set_item(ctx->stack->top->item, item); - cbor_decref(&item); /* Give up on our reference */ - cbor_item_t *item = ctx->stack->top->item; - _cbor_stack_pop(ctx->stack); - _cbor_builder_append(item, ctx); - break; - } - default: { - cbor_decref(&item); - ctx->syntax_error = true; - } - } - } +void _cbor_builder_append(cbor_item_t *item, + struct _cbor_decoder_context *ctx) { + if (ctx->stack->size == 0) { + /* Top level item */ + ctx->root = item; + } else { + /* Part of a bigger structure */ + switch (ctx->stack->top->item->type) { + case CBOR_TYPE_ARRAY: { + if (cbor_array_is_definite(ctx->stack->top->item)) { + /* + * We don't need an explicit check for whether the item still belongs + * into this array because if there are extra items, they will cause a + * syntax error when decoded. + */ + assert(ctx->stack->top->subitems > 0); + cbor_array_push(ctx->stack->top->item, item); + ctx->stack->top->subitems--; + if (ctx->stack->top->subitems == 0) { + cbor_item_t *item = ctx->stack->top->item; + _cbor_stack_pop(ctx->stack); + _cbor_builder_append(item, ctx); + } + cbor_decref(&item); + } else { + /* Indefinite array, don't bother with subitems */ + cbor_array_push(ctx->stack->top->item, item); + cbor_decref(&item); + } + break; + } + case CBOR_TYPE_MAP: { + /* We use 0 and 1 subitems to distinguish between keys and values in + * indefinite items */ + if (ctx->stack->top->subitems % 2) { + /* Odd record, this is a value */ + _cbor_map_add_value(ctx->stack->top->item, cbor_move(item)); + } else { + /* Even record, this is a key */ + _cbor_map_add_key(ctx->stack->top->item, cbor_move(item)); + } + if (cbor_map_is_definite(ctx->stack->top->item)) { + ctx->stack->top->subitems--; + if (ctx->stack->top->subitems == 0) { + cbor_item_t *item = ctx->stack->top->item; + _cbor_stack_pop(ctx->stack); + _cbor_builder_append(item, ctx); + } + } else { + ctx->stack->top->subitems ^= + 1; /* Flip the indicator for indefinite items */ + } + break; + } + case CBOR_TYPE_TAG: { + assert(ctx->stack->top->subitems == 1); + cbor_tag_set_item(ctx->stack->top->item, item); + cbor_decref(&item); /* Give up on our reference */ + cbor_item_t *item = ctx->stack->top->item; + _cbor_stack_pop(ctx->stack); + _cbor_builder_append(item, ctx); + break; + } + default: { + cbor_decref(&item); + ctx->syntax_error = true; + } + } + } } - -#define CHECK_RES do { if (res == NULL) { ctx->creation_failed = true; return; } } while (0) - -void cbor_builder_uint8_callback(void *context, uint8_t value) -{ - struct _cbor_decoder_context *ctx = context; - cbor_item_t *res = cbor_new_int8(); - CHECK_RES; - cbor_mark_uint(res); - cbor_set_uint8(res, value); - _cbor_builder_append(res, ctx); +// TODO: refactor this to take the parameter name, this is way too magical +#define CHECK_RES \ + do { \ + if (res == NULL) { \ + ctx->creation_failed = true; \ + return; \ + } \ + } while (0) + +void cbor_builder_uint8_callback(void *context, uint8_t value) { + struct _cbor_decoder_context *ctx = context; + cbor_item_t *res = cbor_new_int8(); + CHECK_RES; + cbor_mark_uint(res); + cbor_set_uint8(res, value); + _cbor_builder_append(res, ctx); } -void cbor_builder_uint16_callback(void *context, uint16_t value) -{ - struct _cbor_decoder_context *ctx = context; - cbor_item_t *res = cbor_new_int16(); - CHECK_RES; - cbor_mark_uint(res); - cbor_set_uint16(res, value); - _cbor_builder_append(res, ctx); +void cbor_builder_uint16_callback(void *context, uint16_t value) { + struct _cbor_decoder_context *ctx = context; + cbor_item_t *res = cbor_new_int16(); + CHECK_RES; + cbor_mark_uint(res); + cbor_set_uint16(res, value); + _cbor_builder_append(res, ctx); } -void cbor_builder_uint32_callback(void *context, uint32_t value) -{ - struct _cbor_decoder_context *ctx = context; - cbor_item_t *res = cbor_new_int32(); - CHECK_RES; - cbor_mark_uint(res); - cbor_set_uint32(res, value); - _cbor_builder_append(res, ctx); +void cbor_builder_uint32_callback(void *context, uint32_t value) { + struct _cbor_decoder_context *ctx = context; + cbor_item_t *res = cbor_new_int32(); + CHECK_RES; + cbor_mark_uint(res); + cbor_set_uint32(res, value); + _cbor_builder_append(res, ctx); } -void cbor_builder_uint64_callback(void *context, uint64_t value) -{ - struct _cbor_decoder_context *ctx = context; - cbor_item_t *res = cbor_new_int64(); - CHECK_RES; - cbor_mark_uint(res); - cbor_set_uint64(res, value); - _cbor_builder_append(res, ctx); +void cbor_builder_uint64_callback(void *context, uint64_t value) { + struct _cbor_decoder_context *ctx = context; + cbor_item_t *res = cbor_new_int64(); + CHECK_RES; + cbor_mark_uint(res); + cbor_set_uint64(res, value); + _cbor_builder_append(res, ctx); } -void cbor_builder_negint8_callback(void *context, uint8_t value) -{ - struct _cbor_decoder_context *ctx = context; - cbor_item_t *res = cbor_new_int8(); - CHECK_RES; - cbor_mark_negint(res); - cbor_set_uint8(res, value); - _cbor_builder_append(res, ctx); +void cbor_builder_negint8_callback(void *context, uint8_t value) { + struct _cbor_decoder_context *ctx = context; + cbor_item_t *res = cbor_new_int8(); + CHECK_RES; + cbor_mark_negint(res); + cbor_set_uint8(res, value); + _cbor_builder_append(res, ctx); } -void cbor_builder_negint16_callback(void *context, uint16_t value) -{ - struct _cbor_decoder_context *ctx = context; - cbor_item_t *res = cbor_new_int16(); - cbor_mark_negint(res); - cbor_set_uint16(res, value); - _cbor_builder_append(res, ctx); +void cbor_builder_negint16_callback(void *context, uint16_t value) { + struct _cbor_decoder_context *ctx = context; + cbor_item_t *res = cbor_new_int16(); + cbor_mark_negint(res); + cbor_set_uint16(res, value); + _cbor_builder_append(res, ctx); } -void cbor_builder_negint32_callback(void *context, uint32_t value) -{ - struct _cbor_decoder_context *ctx = context; - cbor_item_t *res = cbor_new_int32(); - CHECK_RES; - cbor_mark_negint(res); - cbor_set_uint32(res, value); - _cbor_builder_append(res, ctx); +void cbor_builder_negint32_callback(void *context, uint32_t value) { + struct _cbor_decoder_context *ctx = context; + cbor_item_t *res = cbor_new_int32(); + CHECK_RES; + cbor_mark_negint(res); + cbor_set_uint32(res, value); + _cbor_builder_append(res, ctx); } -void cbor_builder_negint64_callback(void *context, uint64_t value) -{ - struct _cbor_decoder_context *ctx = context; - cbor_item_t *res = cbor_new_int64(); - CHECK_RES; - cbor_mark_negint(res); - cbor_set_uint64(res, value); - _cbor_builder_append(res, ctx); +void cbor_builder_negint64_callback(void *context, uint64_t value) { + struct _cbor_decoder_context *ctx = context; + cbor_item_t *res = cbor_new_int64(); + CHECK_RES; + cbor_mark_negint(res); + cbor_set_uint64(res, value); + _cbor_builder_append(res, ctx); } -void cbor_builder_byte_string_callback(void *context, cbor_data data, size_t length) -{ - struct _cbor_decoder_context *ctx = context; - unsigned char *new_handle = _CBOR_MALLOC(length); - if (new_handle == NULL) { - ctx->creation_failed = true; - return; - } - - memcpy(new_handle, data, length); - cbor_item_t *res = cbor_new_definite_bytestring(); - - if (res == NULL) { - _CBOR_FREE(new_handle); - ctx->creation_failed = true; - return; - } - - cbor_bytestring_set_handle(res, new_handle, length); - - if (ctx->stack->size > 0 && cbor_isa_bytestring(ctx->stack->top->item)) { - if (cbor_bytestring_is_indefinite(ctx->stack->top->item)) { - cbor_bytestring_add_chunk(ctx->stack->top->item, cbor_move(res)); - } else { - cbor_decref(&res); - ctx->syntax_error = true; - } - } else { - _cbor_builder_append(res, ctx); - } +void cbor_builder_byte_string_callback(void *context, cbor_data data, + size_t length) { + struct _cbor_decoder_context *ctx = context; + unsigned char *new_handle = _CBOR_MALLOC(length); + if (new_handle == NULL) { + ctx->creation_failed = true; + return; + } + + memcpy(new_handle, data, length); + cbor_item_t *res = cbor_new_definite_bytestring(); + + if (res == NULL) { + _CBOR_FREE(new_handle); + ctx->creation_failed = true; + return; + } + + cbor_bytestring_set_handle(res, new_handle, length); + + if (ctx->stack->size > 0 && cbor_isa_bytestring(ctx->stack->top->item)) { + if (cbor_bytestring_is_indefinite(ctx->stack->top->item)) { + cbor_bytestring_add_chunk(ctx->stack->top->item, cbor_move(res)); + } else { + cbor_decref(&res); + ctx->syntax_error = true; + } + } else { + _cbor_builder_append(res, ctx); + } } -void cbor_builder_byte_string_start_callback(void *context) -{ - struct _cbor_decoder_context *ctx = context; - cbor_item_t *res = cbor_new_indefinite_bytestring(); - CHECK_RES; - _cbor_stack_push(ctx->stack, res, 0); +void cbor_builder_byte_string_start_callback(void *context) { + struct _cbor_decoder_context *ctx = context; + cbor_item_t *res = cbor_new_indefinite_bytestring(); + CHECK_RES; + _cbor_stack_push(ctx->stack, res, 0); } +void cbor_builder_string_callback(void *context, cbor_data data, + size_t length) { + struct _cbor_decoder_context *ctx = context; + struct _cbor_unicode_status unicode_status; + + size_t codepoint_count = + _cbor_unicode_codepoint_count(data, length, &unicode_status); + + if (unicode_status.status == _CBOR_UNICODE_BADCP) { + ctx->syntax_error = true; + return; + } + + unsigned char *new_handle = _CBOR_MALLOC(length); + + if (new_handle == NULL) { + ctx->creation_failed = true; + return; + } + + memcpy(new_handle, data, length); + cbor_item_t *res = cbor_new_definite_string(); + cbor_string_set_handle(res, new_handle, length); + res->metadata.string_metadata.codepoint_count = codepoint_count; + + /* Careful here: order matters */ + if (ctx->stack->size > 0 && cbor_isa_string(ctx->stack->top->item)) { + if (cbor_string_is_indefinite(ctx->stack->top->item)) { + cbor_string_add_chunk(ctx->stack->top->item, cbor_move(res)); + } else { + cbor_decref(&res); + ctx->syntax_error = true; + } + } else { + _cbor_builder_append(res, ctx); + } +} -void cbor_builder_string_callback(void *context, cbor_data data, size_t length) -{ - struct _cbor_decoder_context *ctx = context; - struct _cbor_unicode_status unicode_status; - - size_t codepoint_count = _cbor_unicode_codepoint_count(data, length, &unicode_status); - - if (unicode_status.status == _CBOR_UNICODE_BADCP) { - ctx->syntax_error = true; - return; - } - - unsigned char *new_handle = _CBOR_MALLOC(length); - - if (new_handle == NULL) { - ctx->creation_failed = true; - return; - } - - memcpy(new_handle, data, length); - cbor_item_t *res = cbor_new_definite_string(); - cbor_string_set_handle(res, new_handle, length); - res->metadata.string_metadata.codepoint_count = codepoint_count; - - /* Careful here: order matters */ - if (ctx->stack->size > 0 && cbor_isa_string(ctx->stack->top->item)) { - if (cbor_string_is_indefinite(ctx->stack->top->item)) { - cbor_string_add_chunk(ctx->stack->top->item, cbor_move(res)); - } else { - cbor_decref(&res); - ctx->syntax_error = true; - } - } else { - _cbor_builder_append(res, ctx); - } +void cbor_builder_string_start_callback(void *context) { + struct _cbor_decoder_context *ctx = context; + cbor_item_t *res = cbor_new_indefinite_string(); + CHECK_RES; + _cbor_stack_push(ctx->stack, res, 0); } -void cbor_builder_string_start_callback(void *context) -{ - struct _cbor_decoder_context *ctx = context; - cbor_item_t *res = cbor_new_indefinite_string(); - CHECK_RES; - _cbor_stack_push(ctx->stack, res, 0); +void cbor_builder_array_start_callback(void *context, size_t size) { + struct _cbor_decoder_context *ctx = context; + cbor_item_t *res = cbor_new_definite_array(size); + CHECK_RES; + if (size > 0) { + _cbor_stack_push(ctx->stack, res, size); + } else { + _cbor_builder_append(res, ctx); + } } -void cbor_builder_array_start_callback(void *context, size_t size) -{ - struct _cbor_decoder_context *ctx = context; - cbor_item_t *res = cbor_new_definite_array(size); - CHECK_RES; - if (size > 0) { - _cbor_stack_push(ctx->stack, res, size); - } else { - _cbor_builder_append(res, ctx); - } +void cbor_builder_indef_array_start_callback(void *context) { + struct _cbor_decoder_context *ctx = context; + cbor_item_t *res = cbor_new_indefinite_array(); + CHECK_RES; + _cbor_stack_push(ctx->stack, res, 0); } -void cbor_builder_indef_array_start_callback(void *context) -{ - struct _cbor_decoder_context *ctx = context; - cbor_item_t *res = cbor_new_indefinite_array(); - CHECK_RES; - _cbor_stack_push(ctx->stack, res, 0); +void cbor_builder_indef_map_start_callback(void *context) { + struct _cbor_decoder_context *ctx = context; + cbor_item_t *res = cbor_new_indefinite_map(); + CHECK_RES; + _cbor_stack_push(ctx->stack, res, 0); } -void cbor_builder_indef_map_start_callback(void *context) -{ - struct _cbor_decoder_context *ctx = context; - cbor_item_t *res = cbor_new_indefinite_map(); - CHECK_RES; - _cbor_stack_push(ctx->stack, res, 0); +void cbor_builder_map_start_callback(void *context, size_t size) { + struct _cbor_decoder_context *ctx = context; + cbor_item_t *res = cbor_new_definite_map(size); + CHECK_RES; + if (size > 0) { + _cbor_stack_push(ctx->stack, res, size * 2); + } else { + _cbor_builder_append(res, ctx); + } } -void cbor_builder_map_start_callback(void *context, size_t size) -{ - struct _cbor_decoder_context *ctx = context; - cbor_item_t *res = cbor_new_definite_map(size); - CHECK_RES; - if (size > 0) { - _cbor_stack_push(ctx->stack, res, size * 2); - } else { - _cbor_builder_append(res, ctx); - } +/** + * Is the (partially constructed) item indefinite? + */ +bool _cbor_is_indefinite(cbor_item_t *item) { + switch (item->type) { + case CBOR_TYPE_BYTESTRING: + return item->metadata.bytestring_metadata.type == + _CBOR_METADATA_INDEFINITE; + case CBOR_TYPE_STRING: + return item->metadata.string_metadata.type == _CBOR_METADATA_INDEFINITE; + case CBOR_TYPE_ARRAY: + return item->metadata.array_metadata.type == _CBOR_METADATA_INDEFINITE; + case CBOR_TYPE_MAP: + return item->metadata.map_metadata.type == _CBOR_METADATA_INDEFINITE; + default: + return false; + } } -void cbor_builder_indef_break_callback(void *context) -{ - struct _cbor_decoder_context *ctx = context; - if (ctx->stack->size == 0) { - // TODO complain - } else { - cbor_item_t *item = ctx->stack->top->item; - _cbor_stack_pop(ctx->stack); - _cbor_builder_append(item, ctx); - } +void cbor_builder_indef_break_callback(void *context) { + struct _cbor_decoder_context *ctx = context; + /* There must be an item to break out of*/ + if (ctx->stack->size > 0) { + cbor_item_t *item = ctx->stack->top->item; + if (_cbor_is_indefinite( + item) && /* Only indefinite items can be terminated by 0xFF */ + /* Special case: we cannot append up if an indefinite map is incomplete + (we are expecting a value). */ + (item->type != CBOR_TYPE_MAP || ctx->stack->top->subitems % 2 == 0)) { + _cbor_stack_pop(ctx->stack); + _cbor_builder_append(item, ctx); + return; + } + } + + ctx->syntax_error = true; } -void cbor_builder_float2_callback(void *context, float value) -{ - struct _cbor_decoder_context *ctx = context; - cbor_item_t *res = cbor_new_float2(); - cbor_set_float2(res, value); - _cbor_builder_append(res, ctx); +void cbor_builder_float2_callback(void *context, float value) { + struct _cbor_decoder_context *ctx = context; + cbor_item_t *res = cbor_new_float2(); + cbor_set_float2(res, value); + _cbor_builder_append(res, ctx); } -void cbor_builder_float4_callback(void *context, float value) -{ - struct _cbor_decoder_context *ctx = context; - cbor_item_t *res = cbor_new_float4(); - CHECK_RES; - cbor_set_float4(res, value); - _cbor_builder_append(res, ctx); +void cbor_builder_float4_callback(void *context, float value) { + struct _cbor_decoder_context *ctx = context; + cbor_item_t *res = cbor_new_float4(); + CHECK_RES; + cbor_set_float4(res, value); + _cbor_builder_append(res, ctx); } -void cbor_builder_float8_callback(void *context, double value) -{ - struct _cbor_decoder_context *ctx = context; - cbor_item_t *res = cbor_new_float8(); - CHECK_RES; - cbor_set_float8(res, value); - _cbor_builder_append(res, ctx); +void cbor_builder_float8_callback(void *context, double value) { + struct _cbor_decoder_context *ctx = context; + cbor_item_t *res = cbor_new_float8(); + CHECK_RES; + cbor_set_float8(res, value); + _cbor_builder_append(res, ctx); } -void cbor_builder_null_callback(void *context) -{ - struct _cbor_decoder_context *ctx = context; - cbor_item_t *res = cbor_new_null(); - CHECK_RES; - _cbor_builder_append(res, ctx); +void cbor_builder_null_callback(void *context) { + struct _cbor_decoder_context *ctx = context; + cbor_item_t *res = cbor_new_null(); + CHECK_RES; + _cbor_builder_append(res, ctx); } -void cbor_builder_undefined_callback(void *context) -{ - struct _cbor_decoder_context *ctx = context; - cbor_item_t *res = cbor_new_undef(); - CHECK_RES; - _cbor_builder_append(res, ctx); +void cbor_builder_undefined_callback(void *context) { + struct _cbor_decoder_context *ctx = context; + cbor_item_t *res = cbor_new_undef(); + CHECK_RES; + _cbor_builder_append(res, ctx); } -void cbor_builder_boolean_callback(void *context, bool value) -{ - struct _cbor_decoder_context *ctx = context; - cbor_item_t *res = cbor_build_bool(value); - CHECK_RES; - _cbor_builder_append(res, ctx); +void cbor_builder_boolean_callback(void *context, bool value) { + struct _cbor_decoder_context *ctx = context; + cbor_item_t *res = cbor_build_bool(value); + CHECK_RES; + _cbor_builder_append(res, ctx); } -void cbor_builder_tag_callback(void *context, uint64_t value) -{ - struct _cbor_decoder_context *ctx = context; - cbor_item_t *res = cbor_new_tag(value); - CHECK_RES; - _cbor_stack_push(ctx->stack, res, 1); +void cbor_builder_tag_callback(void *context, uint64_t value) { + struct _cbor_decoder_context *ctx = context; + cbor_item_t *res = cbor_new_tag(value); + CHECK_RES; + _cbor_stack_push(ctx->stack, res, 1); } diff --git a/lib/libcbor/src/cbor/internal/builder_callbacks.h b/lib/libcbor/src/cbor/internal/builder_callbacks.h index b16294f16af..66eea39b26b 100644 --- a/lib/libcbor/src/cbor/internal/builder_callbacks.h +++ b/lib/libcbor/src/cbor/internal/builder_callbacks.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014-2017 Pavel Kalvoda <me@pavelkalvoda.com> + * Copyright (c) 2014-2019 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. @@ -8,8 +8,8 @@ #ifndef LIBCBOR_BUILDER_CALLBACKS_H #define LIBCBOR_BUILDER_CALLBACKS_H -#include "cbor/common.h" #include "../callbacks.h" +#include "cbor/common.h" #include "stack.h" #ifdef __cplusplus @@ -18,12 +18,12 @@ extern "C" { /** High-level decoding context */ struct _cbor_decoder_context { - /** Callback creating the last item has failed */ - bool creation_failed; - /** Stack expectation mismatch */ - bool syntax_error; - cbor_item_t *root; - struct _cbor_stack *stack; + /** Callback creating the last item has failed */ + bool creation_failed; + /** Stack expectation mismatch */ + bool syntax_error; + cbor_item_t *root; + struct _cbor_stack *stack; }; void cbor_builder_uint8_callback(void *, uint8_t); @@ -78,4 +78,4 @@ void cbor_builder_indef_break_callback(void *); } #endif -#endif //LIBCBOR_BUILDER_CALLBACKS_H +#endif // LIBCBOR_BUILDER_CALLBACKS_H diff --git a/lib/libcbor/src/cbor/internal/encoders.c b/lib/libcbor/src/cbor/internal/encoders.c index 478b3885cb1..e562b49b5f6 100644 --- a/lib/libcbor/src/cbor/internal/encoders.c +++ b/lib/libcbor/src/cbor/internal/encoders.c @@ -1,112 +1,98 @@ /* - * Copyright (c) 2014-2017 Pavel Kalvoda <me@pavelkalvoda.com> + * Copyright (c) 2014-2019 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. */ #include "encoders.h" +#include <string.h> -#if HAVE_ENDIAN_H -#include <endian.h> -#endif - -size_t _cbor_encode_uint8(uint8_t value, unsigned char *buffer, size_t buffer_size, uint8_t offset) -{ - if (value <= 23) { - if (buffer_size >= 1) { - buffer[0] = value + offset; - return 1; - } - } else { - if (buffer_size >= 2) { - buffer[0] = 0x18 + offset; - buffer[1] = value; - return 2; - } - } - return 0; +size_t _cbor_encode_uint8(uint8_t value, unsigned char *buffer, + size_t buffer_size, uint8_t offset) { + if (value <= 23) { + if (buffer_size >= 1) { + buffer[0] = value + offset; + return 1; + } + } else { + if (buffer_size >= 2) { + buffer[0] = 0x18 + offset; + buffer[1] = value; + return 2; + } + } + return 0; } -size_t _cbor_encode_uint16(uint16_t value, unsigned char *buffer, size_t buffer_size, uint8_t offset) -{ - if (buffer_size >= 3) { - buffer[0] = 0x19 + offset; +size_t _cbor_encode_uint16(uint16_t value, unsigned char *buffer, + size_t buffer_size, uint8_t offset) { + if (buffer_size >= 3) { + buffer[0] = 0x19 + offset; -#ifdef HAVE_ENDIAN_H - *(uint16_t *) &buffer[1] = htobe16(value); +#ifdef IS_BIG_ENDIAN + memcpy(buffer + 1, &value, 2); #else - #ifdef IS_BIG_ENDIAN - *(uint16_t *) &buffer[1] = value; - #else - buffer[1] = value >> 8; - buffer[2] = value; - #endif + buffer[1] = value >> 8; + buffer[2] = value; #endif - return 3; - } else - return 0; + return 3; + } else + return 0; } -size_t _cbor_encode_uint32(uint32_t value, unsigned char *buffer, size_t buffer_size, uint8_t offset) -{ - if (buffer_size >= 5) { - buffer[0] = 0x1A + offset; +size_t _cbor_encode_uint32(uint32_t value, unsigned char *buffer, + size_t buffer_size, uint8_t offset) { + if (buffer_size >= 5) { + buffer[0] = 0x1A + offset; -#ifdef HAVE_ENDIAN_H - *(uint32_t *) &buffer[1] = htobe32(value); +#ifdef IS_BIG_ENDIAN + memcpy(buffer + 1, &value, 4); #else - #ifdef IS_BIG_ENDIAN - *(uint32_t *) &buffer[1] = value; - #else - buffer[1] = value >> 24; - buffer[2] = value >> 16; - buffer[3] = value >> 8; - buffer[4] = value; - #endif + buffer[1] = value >> 24; + buffer[2] = value >> 16; + buffer[3] = value >> 8; + buffer[4] = value; #endif - return 5; - } else - return 0; + return 5; + } else + return 0; } -size_t _cbor_encode_uint64(uint64_t value, unsigned char *buffer, size_t buffer_size, uint8_t offset) -{ - if (buffer_size >= 9) { - buffer[0] = 0x1B + offset; +size_t _cbor_encode_uint64(uint64_t value, unsigned char *buffer, + size_t buffer_size, uint8_t offset) { + if (buffer_size >= 9) { + buffer[0] = 0x1B + offset; -#ifdef HAVE_ENDIAN_H - *(uint64_t *) &buffer[1] = htobe64(value); +#ifdef IS_BIG_ENDIAN + memcpy(buffer + 1, &value, 8); #else - #ifdef IS_BIG_ENDIAN - *(uint64_t *) &buffer[1] = value; - #else - buffer[1] = value >> 56; - buffer[2] = value >> 48; - buffer[3] = value >> 40; - buffer[4] = value >> 32; - buffer[5] = value >> 24; - buffer[6] = value >> 16; - buffer[7] = value >> 8; - buffer[8] = value; - #endif + buffer[1] = value >> 56; + buffer[2] = value >> 48; + buffer[3] = value >> 40; + buffer[4] = value >> 32; + buffer[5] = value >> 24; + buffer[6] = value >> 16; + buffer[7] = value >> 8; + buffer[8] = value; #endif - return 9; - } else - return 0; + return 9; + } else + return 0; } -size_t _cbor_encode_uint(uint64_t value, unsigned char *buffer, size_t buffer_size, uint8_t offset) -{ - if (value <= UINT16_MAX) if (value <= UINT8_MAX) - return _cbor_encode_uint8((uint8_t) value, buffer, buffer_size, offset); - else - return _cbor_encode_uint16((uint16_t) value, buffer, buffer_size, offset); - else if (value <= UINT32_MAX) - return _cbor_encode_uint32((uint32_t) value, buffer, buffer_size, offset); - else - return _cbor_encode_uint64((uint64_t) value, buffer, buffer_size, offset); +size_t _cbor_encode_uint(uint64_t value, unsigned char *buffer, + size_t buffer_size, uint8_t offset) { + if (value <= UINT16_MAX) + if (value <= UINT8_MAX) + return _cbor_encode_uint8((uint8_t)value, buffer, buffer_size, offset); + else + return _cbor_encode_uint16((uint16_t)value, buffer, buffer_size, offset); + else if (value <= UINT32_MAX) + return _cbor_encode_uint32((uint32_t)value, buffer, buffer_size, offset); + else + return _cbor_encode_uint64((uint64_t)value, buffer, buffer_size, offset); } diff --git a/lib/libcbor/src/cbor/internal/encoders.h b/lib/libcbor/src/cbor/internal/encoders.h index 5629e60905a..e9b756070a1 100644 --- a/lib/libcbor/src/cbor/internal/encoders.h +++ b/lib/libcbor/src/cbor/internal/encoders.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014-2017 Pavel Kalvoda <me@pavelkalvoda.com> + * Copyright (c) 2014-2019 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. @@ -14,19 +14,23 @@ extern "C" { #endif +size_t _cbor_encode_uint8(uint8_t value, unsigned char *buffer, + size_t buffer_size, uint8_t offset); -size_t _cbor_encode_uint8(uint8_t value, unsigned char *buffer, size_t buffer_size, uint8_t offset); +size_t _cbor_encode_uint16(uint16_t value, unsigned char *buffer, + size_t buffer_size, uint8_t offset); -size_t _cbor_encode_uint16(uint16_t value, unsigned char *buffer, size_t buffer_size, uint8_t offset); +size_t _cbor_encode_uint32(uint32_t value, unsigned char *buffer, + size_t buffer_size, uint8_t offset); -size_t _cbor_encode_uint32(uint32_t value, unsigned char *buffer, size_t buffer_size, uint8_t offset); +size_t _cbor_encode_uint64(uint64_t value, unsigned char *buffer, + size_t buffer_size, uint8_t offset); -size_t _cbor_encode_uint64(uint64_t value, unsigned char *buffer, size_t buffer_size, uint8_t offset); - -size_t _cbor_encode_uint(uint64_t value, unsigned char *buffer, size_t buffer_size, uint8_t offset); +size_t _cbor_encode_uint(uint64_t value, unsigned char *buffer, + size_t buffer_size, uint8_t offset); #ifdef __cplusplus } #endif -#endif //LIBCBOR_ENCODERS_H +#endif // LIBCBOR_ENCODERS_H diff --git a/lib/libcbor/src/cbor/internal/loaders.c b/lib/libcbor/src/cbor/internal/loaders.c index 184691ca65a..fe000788923 100644 --- a/lib/libcbor/src/cbor/internal/loaders.c +++ b/lib/libcbor/src/cbor/internal/loaders.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014-2017 Pavel Kalvoda <me@pavelkalvoda.com> + * Copyright (c) 2014-2019 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. @@ -7,93 +7,74 @@ #include "loaders.h" #include <math.h> +#include <string.h> -#ifdef HAVE_ENDIAN_H -#include <endian.h> -#endif - -uint8_t _cbor_load_uint8(cbor_data source) -{ - return (uint8_t) *source; -} +uint8_t _cbor_load_uint8(cbor_data source) { return (uint8_t)*source; } -uint16_t _cbor_load_uint16(const unsigned char *source) -{ -#ifdef HAVE_ENDIAN_H - return be16toh(*(uint16_t *) source); +uint16_t _cbor_load_uint16(const unsigned char *source) { +#ifdef IS_BIG_ENDIAN + uint16_t result; + memcpy(&result, source, 2); + return result; #else - #ifdef IS_BIG_ENDIAN - return *(uint16_t *) source; - #else - return ((uint16_t) *(source + 0) << 8) + - (uint8_t) *(source + 1); - #endif + return ((uint16_t) * (source + 0) << 8) + (uint8_t) * (source + 1); #endif } -uint32_t _cbor_load_uint32(const unsigned char *source) -{ -#ifdef HAVE_ENDIAN_H - return be32toh(*(uint32_t *) source); +uint32_t _cbor_load_uint32(const unsigned char *source) { +#ifdef IS_BIG_ENDIAN + uint32_t result; + memcpy(&result, source, 4); + return result; #else - #ifdef IS_BIG_ENDIAN - return *(uint32_t *) source; - #else - return ((uint32_t) *(source + 0) << 0x18) + - ((uint32_t) *(source + 1) << 0x10) + - ((uint16_t) *(source + 2) << 0x08) + - (uint8_t) *(source + 3); - #endif + return ((uint32_t) * (source + 0) << 0x18) + + ((uint32_t) * (source + 1) << 0x10) + + ((uint16_t) * (source + 2) << 0x08) + (uint8_t) * (source + 3); #endif } -uint64_t _cbor_load_uint64(const unsigned char *source) -{ -#ifdef HAVE_ENDIAN_H - return be64toh(*(uint64_t *) source); +uint64_t _cbor_load_uint64(const unsigned char *source) { +#ifdef IS_BIG_ENDIAN + uint64_t result; + memcpy(&result, source, 8); + return result; #else - #ifdef IS_BIG_ENDIAN - return *(uint64_t *) source; - #else - return ((uint64_t) *(source + 0) << 0x38) + - ((uint64_t) *(source + 1) << 0x30) + - ((uint64_t) *(source + 2) << 0x28) + - ((uint64_t) *(source + 3) << 0x20) + - ((uint32_t) *(source + 4) << 0x18) + - ((uint32_t) *(source + 5) << 0x10) + - ((uint16_t) *(source + 6) << 0x08) + - (uint8_t) *(source + 7); - #endif + return ((uint64_t) * (source + 0) << 0x38) + + ((uint64_t) * (source + 1) << 0x30) + + ((uint64_t) * (source + 2) << 0x28) + + ((uint64_t) * (source + 3) << 0x20) + + ((uint32_t) * (source + 4) << 0x18) + + ((uint32_t) * (source + 5) << 0x10) + + ((uint16_t) * (source + 6) << 0x08) + (uint8_t) * (source + 7); #endif } /* As per http://tools.ietf.org/html/rfc7049#appendix-D */ -float _cbor_decode_half(unsigned char *halfp) -{ - int half = (halfp[0] << 8) + halfp[1]; - int exp = (half >> 10) & 0x1f; - int mant = half & 0x3ff; - double val; - if (exp == 0) val = ldexp(mant, -24); - else if (exp != 31) val = ldexp(mant + 1024, exp - 25); - else val = mant == 0 ? INFINITY : NAN; - return (float) (half & 0x8000 ? -val : val); +float _cbor_decode_half(unsigned char *halfp) { + int half = (halfp[0] << 8) + halfp[1]; + int exp = (half >> 10) & 0x1f; + int mant = half & 0x3ff; + double val; + if (exp == 0) + val = ldexp(mant, -24); + else if (exp != 31) + val = ldexp(mant + 1024, exp - 25); + else + val = mant == 0 ? INFINITY : NAN; + return (float)(half & 0x8000 ? -val : val); } -double _cbor_load_half(cbor_data source) -{ - /* Discard const */ - return _cbor_decode_half((unsigned char *) source); +double _cbor_load_half(cbor_data source) { + /* Discard const */ + return _cbor_decode_half((unsigned char *)source); } -float _cbor_load_float(cbor_data source) -{ - union _cbor_float_helper helper = {.as_uint = _cbor_load_uint32(source)}; - return helper.as_float; +float _cbor_load_float(cbor_data source) { + union _cbor_float_helper helper = {.as_uint = _cbor_load_uint32(source)}; + return helper.as_float; } -double _cbor_load_double(cbor_data source) -{ - union _cbor_double_helper helper = {.as_uint = _cbor_load_uint64(source)}; - return helper.as_double; +double _cbor_load_double(cbor_data source) { + union _cbor_double_helper helper = {.as_uint = _cbor_load_uint64(source)}; + return helper.as_double; } diff --git a/lib/libcbor/src/cbor/internal/loaders.h b/lib/libcbor/src/cbor/internal/loaders.h index cd5c1b5a45c..c39a1b81335 100644 --- a/lib/libcbor/src/cbor/internal/loaders.h +++ b/lib/libcbor/src/cbor/internal/loaders.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014-2017 Pavel Kalvoda <me@pavelkalvoda.com> + * Copyright (c) 2014-2019 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. @@ -33,4 +33,4 @@ double _cbor_load_double(cbor_data source); } #endif -#endif //LIBCBOR_LOADERS_H +#endif // LIBCBOR_LOADERS_H diff --git a/lib/libcbor/src/cbor/internal/memory_utils.c b/lib/libcbor/src/cbor/internal/memory_utils.c index 4d1024c4236..aa049a2f9e2 100644 --- a/lib/libcbor/src/cbor/internal/memory_utils.c +++ b/lib/libcbor/src/cbor/internal/memory_utils.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014-2017 Pavel Kalvoda <me@pavelkalvoda.com> + * Copyright (c) 2014-2019 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. @@ -8,39 +8,37 @@ #include "memory_utils.h" #include "cbor/common.h" -// TODO: Consider builtins (https://gcc.gnu.org/onlinedocs/gcc/Integer-Overflow-Builtins.html) +// TODO: Consider builtins +// (https://gcc.gnu.org/onlinedocs/gcc/Integer-Overflow-Builtins.html) /** Highest on bit position */ -size_t _cbor_highest_bit(size_t number) -{ - size_t bit = 0; - while (number != 0) { - bit++; - number >>= 1; - } +size_t _cbor_highest_bit(size_t number) { + size_t bit = 0; + while (number != 0) { + bit++; + number >>= 1; + } - return bit; + return bit; } -bool _cbor_safe_to_multiply(size_t a, size_t b) -{ - return _cbor_highest_bit(a) + _cbor_highest_bit(b) <= sizeof(size_t) * 8; +bool _cbor_safe_to_multiply(size_t a, size_t b) { + return _cbor_highest_bit(a) + _cbor_highest_bit(b) <= sizeof(size_t) * 8; } -void * _cbor_alloc_multiple(size_t item_size, size_t item_count) -{ - if (_cbor_safe_to_multiply(item_size, item_count)) { - return _CBOR_MALLOC(item_size * item_count); - } else { - return NULL; - } +void* _cbor_alloc_multiple(size_t item_size, size_t item_count) { + if (_cbor_safe_to_multiply(item_size, item_count)) { + return _CBOR_MALLOC(item_size * item_count); + } else { + return NULL; + } } -void * _cbor_realloc_multiple(void * pointer, size_t item_size, size_t item_count) -{ - if (_cbor_safe_to_multiply(item_size, item_count)) { - return _CBOR_REALLOC(pointer, item_size * item_count); - } else { - return NULL; - } +void* _cbor_realloc_multiple(void* pointer, size_t item_size, + size_t item_count) { + if (_cbor_safe_to_multiply(item_size, item_count)) { + return _CBOR_REALLOC(pointer, item_size * item_count); + } else { + return NULL; + } } diff --git a/lib/libcbor/src/cbor/internal/memory_utils.h b/lib/libcbor/src/cbor/internal/memory_utils.h index cec008d7578..132142383b6 100644 --- a/lib/libcbor/src/cbor/internal/memory_utils.h +++ b/lib/libcbor/src/cbor/internal/memory_utils.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014-2017 Pavel Kalvoda <me@pavelkalvoda.com> + * Copyright (c) 2014-2019 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. @@ -8,8 +8,8 @@ #ifndef LIBCBOR_MEMORY_UTILS_H #define LIBCBOR_MEMORY_UTILS_H -#include <string.h> #include <stdbool.h> +#include <string.h> /** Can a and b be multiplied without overflowing size_t? */ bool _cbor_safe_to_multiply(size_t a, size_t b); @@ -18,10 +18,10 @@ bool _cbor_safe_to_multiply(size_t a, size_t b); * * @param item_size * @param item_count - * @return Region of item_size * item_count bytes, or NULL if the total size overflows size_t or the underlying allocator failed + * @return Region of item_size * item_count bytes, or NULL if the total size + * overflows size_t or the underlying allocator failed */ -void * _cbor_alloc_multiple(size_t item_size, size_t item_count); - +void* _cbor_alloc_multiple(size_t item_size, size_t item_count); /** Overflow-proof contiguous array reallocation * @@ -30,8 +30,10 @@ void * _cbor_alloc_multiple(size_t item_size, size_t item_count); * @param pointer * @param item_size * @param item_count - * @return Realloc'd of item_size * item_count bytes, or NULL if the total size overflows size_t or the underlying allocator failed + * @return Realloc'd of item_size * item_count bytes, or NULL if the total size + * overflows size_t or the underlying allocator failed */ -void * _cbor_realloc_multiple(void * pointer, size_t item_size, size_t item_count); +void* _cbor_realloc_multiple(void* pointer, size_t item_size, + size_t item_count); -#endif //LIBCBOR_MEMORY_UTILS_H +#endif // LIBCBOR_MEMORY_UTILS_H diff --git a/lib/libcbor/src/cbor/internal/stack.c b/lib/libcbor/src/cbor/internal/stack.c index 65e15fe9379..fc433ef31f0 100644 --- a/lib/libcbor/src/cbor/internal/stack.c +++ b/lib/libcbor/src/cbor/internal/stack.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014-2017 Pavel Kalvoda <me@pavelkalvoda.com> + * Copyright (c) 2014-2019 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. @@ -7,27 +7,26 @@ #include "stack.h" -struct _cbor_stack _cbor_stack_init() -{ - return (struct _cbor_stack) {.top = NULL, .size = 0}; +struct _cbor_stack _cbor_stack_init() { + return (struct _cbor_stack){.top = NULL, .size = 0}; } -void _cbor_stack_pop(struct _cbor_stack *stack) -{ - struct _cbor_stack_record *top = stack->top; - stack->top = stack->top->lower; - _CBOR_FREE(top); - stack->size--; +void _cbor_stack_pop(struct _cbor_stack *stack) { + struct _cbor_stack_record *top = stack->top; + stack->top = stack->top->lower; + _CBOR_FREE(top); + stack->size--; } -struct _cbor_stack_record *_cbor_stack_push(struct _cbor_stack *stack, cbor_item_t *item, size_t subitems) -{ - struct _cbor_stack_record *new_top = _CBOR_MALLOC(sizeof(struct _cbor_stack_record)); - if (new_top == NULL) - return NULL; +struct _cbor_stack_record *_cbor_stack_push(struct _cbor_stack *stack, + cbor_item_t *item, + size_t subitems) { + struct _cbor_stack_record *new_top = + _CBOR_MALLOC(sizeof(struct _cbor_stack_record)); + if (new_top == NULL) return NULL; - *new_top = (struct _cbor_stack_record) {stack->top, item, subitems}; - stack->top = new_top; - stack->size++; - return new_top; + *new_top = (struct _cbor_stack_record){stack->top, item, subitems}; + stack->top = new_top; + stack->size++; + return new_top; } diff --git a/lib/libcbor/src/cbor/internal/stack.h b/lib/libcbor/src/cbor/internal/stack.h index 53b97090ade..0d92c96a0e8 100644 --- a/lib/libcbor/src/cbor/internal/stack.h +++ b/lib/libcbor/src/cbor/internal/stack.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014-2017 Pavel Kalvoda <me@pavelkalvoda.com> + * Copyright (c) 2014-2019 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. @@ -16,25 +16,26 @@ extern "C" { /** Simple stack record for the parser */ struct _cbor_stack_record { - struct _cbor_stack_record *lower; - cbor_item_t *item; - size_t subitems; + struct _cbor_stack_record *lower; + cbor_item_t *item; + size_t subitems; }; /** Stack handle - contents and size */ struct _cbor_stack { - struct _cbor_stack_record *top; - size_t size; + struct _cbor_stack_record *top; + size_t size; }; struct _cbor_stack _cbor_stack_init(); void _cbor_stack_pop(struct _cbor_stack *); -struct _cbor_stack_record *_cbor_stack_push(struct _cbor_stack *, cbor_item_t *, size_t); +struct _cbor_stack_record *_cbor_stack_push(struct _cbor_stack *, cbor_item_t *, + size_t); #ifdef __cplusplus } #endif -#endif //LIBCBOR_STACK_H +#endif // LIBCBOR_STACK_H diff --git a/lib/libcbor/src/cbor/internal/unicode.c b/lib/libcbor/src/cbor/internal/unicode.c index 23403095561..b92fefeb4d5 100644 --- a/lib/libcbor/src/cbor/internal/unicode.c +++ b/lib/libcbor/src/cbor/internal/unicode.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014-2017 Pavel Kalvoda <me@pavelkalvoda.com> + * Copyright (c) 2014-2019 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. @@ -11,59 +11,84 @@ #define UTF8_REJECT 1 static const uint8_t utf8d[] = { - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 00..1f */ - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 20..3f */ - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 40..5f */ - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 60..7f */ - 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9, /* 80..9f */ - 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, /* a0..bf */ - 8,8,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, /* c0..df */ - 0xa,0x3,0x3,0x3,0x3,0x3,0x3,0x3,0x3,0x3,0x3,0x3,0x3,0x4,0x3,0x3, /* e0..ef */ - 0xb,0x6,0x6,0x6,0x5,0x8,0x8,0x8,0x8,0x8,0x8,0x8,0x8,0x8,0x8,0x8, /* f0..ff */ - 0x0,0x1,0x2,0x3,0x5,0x8,0x7,0x1,0x1,0x1,0x4,0x6,0x1,0x1,0x1,0x1, /* s0..s0 */ - 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,1,1,1,1,1,0,1,0,1,1,1,1,1,1, /* s1..s2 */ - 1,2,1,1,1,1,1,2,1,2,1,1,1,1,1,1,1,1,1,1,1,1,1,2,1,1,1,1,1,1,1,1, /* s3..s4 */ - 1,2,1,1,1,1,1,1,1,2,1,1,1,1,1,1,1,1,1,1,1,1,1,3,1,3,1,1,1,1,1,1, /* s5..s6 */ - 1,3,1,1,1,1,1,3,1,3,1,1,1,1,1,1,1,3,1,1,1,1,1,1,1,1,1,1,1,1,1,1, /* s7..s8 */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 00..1f */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 20..3f */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 40..5f */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 60..7f */ + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, /* 80..9f */ + 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, + 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, + 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, /* a0..bf */ + 8, 8, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, /* c0..df */ + 0xa, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, + 0x3, 0x3, 0x4, 0x3, 0x3, /* e0..ef */ + 0xb, 0x6, 0x6, 0x6, 0x5, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, + 0x8, 0x8, 0x8, 0x8, 0x8, /* f0..ff */ + 0x0, 0x1, 0x2, 0x3, 0x5, 0x8, 0x7, 0x1, 0x1, 0x1, 0x4, + 0x6, 0x1, 0x1, 0x1, 0x1, /* s0..s0 */ + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, + 1, 0, 1, 0, 1, 1, 1, 1, 1, 1, /* s1..s2 */ + 1, 2, 1, 1, 1, 1, 1, 2, 1, 2, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 2, 1, 1, 1, 1, 1, 1, 1, 1, /* s3..s4 */ + 1, 2, 1, 1, 1, 1, 1, 1, 1, 2, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 3, 1, 3, 1, 1, 1, 1, 1, 1, /* s5..s6 */ + 1, 3, 1, 1, 1, 1, 1, 3, 1, 3, 1, + 1, 1, 1, 1, 1, 1, 3, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* s7..s8 */ }; -/* Copyright of this function: (c) 2008-2009 Bjoern Hoehrmann <bjoern@hoehrmann.de> */ +/* Copyright of this function: (c) 2008-2009 Bjoern Hoehrmann + * <bjoern@hoehrmann.de> */ /* See http://bjoern.hoehrmann.de/utf-8/decoder/dfa/ for details. */ uint32_t _cbor_unicode_decode(uint32_t* state, uint32_t* codep, uint32_t byte) { - uint32_t type = utf8d[byte]; + uint32_t type = utf8d[byte]; - *codep = (*state != UTF8_ACCEPT) ? - (byte & 0x3fu) | (*codep << 6) : - (0xff >> type) & (byte); + *codep = (*state != UTF8_ACCEPT) ? (byte & 0x3fu) | (*codep << 6) + : (0xff >> type) & (byte); - *state = utf8d[256 + *state * 16 + type]; - return *state; + *state = utf8d[256 + *state * 16 + type]; + return *state; } -size_t _cbor_unicode_codepoint_count(cbor_data source, size_t source_length, struct _cbor_unicode_status * status) -{ - *status = (struct _cbor_unicode_status) { .location = 0, .status = _CBOR_UNICODE_OK }; - uint32_t codepoint, state = UTF8_ACCEPT, res; - size_t pos = 0, count = 0; +size_t _cbor_unicode_codepoint_count(cbor_data source, size_t source_length, + struct _cbor_unicode_status* status) { + *status = + (struct _cbor_unicode_status){.location = 0, .status = _CBOR_UNICODE_OK}; + uint32_t codepoint, state = UTF8_ACCEPT, res; + size_t pos = 0, count = 0; - for (; pos < source_length; pos++) - { - res = _cbor_unicode_decode(&state, &codepoint, source[pos]); + for (; pos < source_length; pos++) { + res = _cbor_unicode_decode(&state, &codepoint, source[pos]); - if (res == UTF8_ACCEPT) { - count++; - } else if (res == UTF8_REJECT) { - goto error; - } - } + if (res == UTF8_ACCEPT) { + count++; + } else if (res == UTF8_REJECT) { + goto error; + } + } - /* Unfinished multibyte codepoint */ - if (state != UTF8_ACCEPT) - goto error; + /* Unfinished multibyte codepoint */ + if (state != UTF8_ACCEPT) goto error; - return count; + return count; - error: - *status = (struct _cbor_unicode_status) { .location = pos, .status = _CBOR_UNICODE_BADCP }; - return -1; +error: + *status = (struct _cbor_unicode_status){.location = pos, + .status = _CBOR_UNICODE_BADCP}; + return -1; } diff --git a/lib/libcbor/src/cbor/internal/unicode.h b/lib/libcbor/src/cbor/internal/unicode.h index 9d80bafcab2..fc3a5051223 100644 --- a/lib/libcbor/src/cbor/internal/unicode.h +++ b/lib/libcbor/src/cbor/internal/unicode.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014-2017 Pavel Kalvoda <me@pavelkalvoda.com> + * Copyright (c) 2014-2019 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. @@ -14,21 +14,19 @@ extern "C" { #endif -enum _cbor_unicode_status_error { - _CBOR_UNICODE_OK, - _CBOR_UNICODE_BADCP -}; +enum _cbor_unicode_status_error { _CBOR_UNICODE_OK, _CBOR_UNICODE_BADCP }; /** Signals unicode validation error and possibly its location */ struct _cbor_unicode_status { - enum _cbor_unicode_status_error status; - size_t location; + enum _cbor_unicode_status_error status; + size_t location; }; -size_t _cbor_unicode_codepoint_count(cbor_data source, size_t source_length, struct _cbor_unicode_status * status); +size_t _cbor_unicode_codepoint_count(cbor_data source, size_t source_length, + struct _cbor_unicode_status* status); #ifdef __cplusplus } #endif -#endif //LIBCBOR_UNICODE_H +#endif // LIBCBOR_UNICODE_H diff --git a/lib/libcbor/src/cbor/ints.c b/lib/libcbor/src/cbor/ints.c index 26f08cd3453..328d0bdf9f1 100644 --- a/lib/libcbor/src/cbor/ints.c +++ b/lib/libcbor/src/cbor/ints.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014-2017 Pavel Kalvoda <me@pavelkalvoda.com> + * Copyright (c) 2014-2019 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. @@ -7,201 +7,185 @@ #include "ints.h" -cbor_int_width cbor_int_get_width(const cbor_item_t *item) -{ - assert(cbor_is_int(item)); - return item->metadata.int_metadata.width; +cbor_int_width cbor_int_get_width(const cbor_item_t *item) { + assert(cbor_is_int(item)); + return item->metadata.int_metadata.width; } -uint8_t cbor_get_uint8(const cbor_item_t *item) -{ - assert(cbor_is_int(item)); - assert(cbor_int_get_width(item) == CBOR_INT_8); - return *item->data; +uint8_t cbor_get_uint8(const cbor_item_t *item) { + assert(cbor_is_int(item)); + assert(cbor_int_get_width(item) == CBOR_INT_8); + return *item->data; } -uint16_t cbor_get_uint16(const cbor_item_t *item) -{ - assert(cbor_is_int(item)); - assert(cbor_int_get_width(item) == CBOR_INT_16); - return *(uint16_t *) item->data; +uint16_t cbor_get_uint16(const cbor_item_t *item) { + assert(cbor_is_int(item)); + assert(cbor_int_get_width(item) == CBOR_INT_16); + return *(uint16_t *)item->data; } -uint32_t cbor_get_uint32(const cbor_item_t *item) -{ - assert(cbor_is_int(item)); - assert(cbor_int_get_width(item) == CBOR_INT_32); - return *(uint32_t *) item->data; +uint32_t cbor_get_uint32(const cbor_item_t *item) { + assert(cbor_is_int(item)); + assert(cbor_int_get_width(item) == CBOR_INT_32); + return *(uint32_t *)item->data; } -uint64_t cbor_get_uint64(const cbor_item_t *item) -{ - assert(cbor_is_int(item)); - assert(cbor_int_get_width(item) == CBOR_INT_64); - return *(uint64_t *) item->data; -} +uint64_t cbor_get_uint64(const cbor_item_t *item) { + assert(cbor_is_int(item)); + assert(cbor_int_get_width(item) == CBOR_INT_64); + return *(uint64_t *)item->data; +} + +uint64_t cbor_get_int(const cbor_item_t *item) { + assert(cbor_is_int(item)); + switch (cbor_int_get_width(item)) { + case CBOR_INT_8: + return cbor_get_uint8(item); + case CBOR_INT_16: + return cbor_get_uint16(item); + case CBOR_INT_32: + return cbor_get_uint32(item); + case CBOR_INT_64: + return cbor_get_uint64(item); + } + // TODO: This should be handled in a default branch + return 0xDEADBEEF; /* Compiler complaints */ +} + +void cbor_set_uint8(cbor_item_t *item, uint8_t value) { + assert(cbor_is_int(item)); + assert(cbor_int_get_width(item) == CBOR_INT_8); + *item->data = value; +} + +void cbor_set_uint16(cbor_item_t *item, uint16_t value) { + assert(cbor_is_int(item)); + assert(cbor_int_get_width(item) == CBOR_INT_16); + *(uint16_t *)item->data = value; +} + +void cbor_set_uint32(cbor_item_t *item, uint32_t value) { + assert(cbor_is_int(item)); + assert(cbor_int_get_width(item) == CBOR_INT_32); + *(uint32_t *)item->data = value; +} -uint64_t cbor_get_int(const cbor_item_t * item) -{ - assert(cbor_is_int(item)); - switch(cbor_int_get_width(item)) { - case CBOR_INT_8: return cbor_get_uint8(item); - case CBOR_INT_16: return cbor_get_uint16(item); - case CBOR_INT_32: return cbor_get_uint32(item); - case CBOR_INT_64: return cbor_get_uint64(item); - } - return 0xDEADBEEF; /* Compiler complaints */ +void cbor_set_uint64(cbor_item_t *item, uint64_t value) { + assert(cbor_is_int(item)); + assert(cbor_int_get_width(item) == CBOR_INT_64); + *(uint64_t *)item->data = value; } -void cbor_set_uint8(cbor_item_t *item, uint8_t value) -{ - assert(cbor_is_int(item)); - assert(cbor_int_get_width(item) == CBOR_INT_8); - *item->data = value; +void cbor_mark_uint(cbor_item_t *item) { + assert(cbor_is_int(item)); + item->type = CBOR_TYPE_UINT; } -void cbor_set_uint16(cbor_item_t *item, uint16_t value) -{ - assert(cbor_is_int(item)); - assert(cbor_int_get_width(item) == CBOR_INT_16); - *(uint16_t *) item->data = value; +void cbor_mark_negint(cbor_item_t *item) { + assert(cbor_is_int(item)); + item->type = CBOR_TYPE_NEGINT; } +cbor_item_t *cbor_new_int8() { + cbor_item_t *item = _CBOR_MALLOC(sizeof(cbor_item_t) + 1); + _CBOR_NOTNULL(item); + *item = (cbor_item_t){.data = (unsigned char *)item + sizeof(cbor_item_t), + .refcount = 1, + .metadata = {.int_metadata = {.width = CBOR_INT_8}}, + .type = CBOR_TYPE_UINT}; + return item; +} -void cbor_set_uint32(cbor_item_t *item, uint32_t value) -{ - assert(cbor_is_int(item)); - assert(cbor_int_get_width(item) == CBOR_INT_32); - *(uint32_t *) item->data = value; +cbor_item_t *cbor_new_int16() { + cbor_item_t *item = _CBOR_MALLOC(sizeof(cbor_item_t) + 2); + _CBOR_NOTNULL(item); + *item = (cbor_item_t){.data = (unsigned char *)item + sizeof(cbor_item_t), + .refcount = 1, + .metadata = {.int_metadata = {.width = CBOR_INT_16}}, + .type = CBOR_TYPE_UINT}; + return item; } -void cbor_set_uint64(cbor_item_t *item, uint64_t value) -{ - assert(cbor_is_int(item)); - assert(cbor_int_get_width(item) == CBOR_INT_64); - *(uint64_t *) item->data = value; +cbor_item_t *cbor_new_int32() { + cbor_item_t *item = _CBOR_MALLOC(sizeof(cbor_item_t) + 4); + _CBOR_NOTNULL(item); + *item = (cbor_item_t){.data = (unsigned char *)item + sizeof(cbor_item_t), + .refcount = 1, + .metadata = {.int_metadata = {.width = CBOR_INT_32}}, + .type = CBOR_TYPE_UINT}; + return item; +} + +cbor_item_t *cbor_new_int64() { + cbor_item_t *item = _CBOR_MALLOC(sizeof(cbor_item_t) + 8); + _CBOR_NOTNULL(item); + *item = (cbor_item_t){.data = (unsigned char *)item + sizeof(cbor_item_t), + .refcount = 1, + .metadata = {.int_metadata = {.width = CBOR_INT_64}}, + .type = CBOR_TYPE_UINT}; + return item; +} + +cbor_item_t *cbor_build_uint8(uint8_t value) { + cbor_item_t *item = cbor_new_int8(); + _CBOR_NOTNULL(item); + cbor_set_uint8(item, value); + cbor_mark_uint(item); + return item; } -void cbor_mark_uint(cbor_item_t *item) -{ - assert(cbor_is_int(item)); - item->type = CBOR_TYPE_UINT; -} - -void cbor_mark_negint(cbor_item_t *item) -{ - assert(cbor_is_int(item)); - item->type = CBOR_TYPE_NEGINT; +cbor_item_t *cbor_build_uint16(uint16_t value) { + cbor_item_t *item = cbor_new_int16(); + _CBOR_NOTNULL(item); + cbor_set_uint16(item, value); + cbor_mark_uint(item); + return item; +} + +cbor_item_t *cbor_build_uint32(uint32_t value) { + cbor_item_t *item = cbor_new_int32(); + _CBOR_NOTNULL(item); + cbor_set_uint32(item, value); + cbor_mark_uint(item); + return item; } - -cbor_item_t *cbor_new_int8() -{ - cbor_item_t *item = _CBOR_MALLOC(sizeof(cbor_item_t) + 1); - *item = (cbor_item_t) { - .data = (unsigned char *) item + sizeof(cbor_item_t), - .refcount = 1, - .metadata = {.int_metadata = {.width = CBOR_INT_8}}, - .type = CBOR_TYPE_UINT - }; - return item; -} - -cbor_item_t *cbor_new_int16() -{ - cbor_item_t *item = _CBOR_MALLOC(sizeof(cbor_item_t) + 2); - *item = (cbor_item_t) { - .data = (unsigned char *) item + sizeof(cbor_item_t), - .refcount = 1, - .metadata = {.int_metadata = {.width = CBOR_INT_16}}, - .type = CBOR_TYPE_UINT - }; - return item; -} - -cbor_item_t *cbor_new_int32() -{ - cbor_item_t *item = _CBOR_MALLOC(sizeof(cbor_item_t) + 4); - *item = (cbor_item_t) { - .data = (unsigned char *) item + sizeof(cbor_item_t), - .refcount = 1, - .metadata = {.int_metadata = {.width = CBOR_INT_32}}, - .type = CBOR_TYPE_UINT - }; - return item; -} - -cbor_item_t *cbor_new_int64() -{ - cbor_item_t *item = _CBOR_MALLOC(sizeof(cbor_item_t) + 8); - *item = (cbor_item_t) { - .data = (unsigned char *) item + sizeof(cbor_item_t), - .refcount = 1, - .metadata = {.int_metadata = {.width = CBOR_INT_64}}, - .type = CBOR_TYPE_UINT - }; - return item; -} - -cbor_item_t *cbor_build_uint8(uint8_t value) -{ - cbor_item_t *item = cbor_new_int8(); - cbor_set_uint8(item, value); - cbor_mark_uint(item); - return item; -} - -cbor_item_t *cbor_build_uint16(uint16_t value) -{ - cbor_item_t *item = cbor_new_int16(); - cbor_set_uint16(item, value); - cbor_mark_uint(item); - return item; -} - -cbor_item_t *cbor_build_uint32(uint32_t value) -{ - cbor_item_t *item = cbor_new_int32(); - cbor_set_uint32(item, value); - cbor_mark_uint(item); - return item; -} - -cbor_item_t *cbor_build_uint64(uint64_t value) -{ - cbor_item_t *item = cbor_new_int64(); - cbor_set_uint64(item, value); - cbor_mark_uint(item); - return item; -} - -cbor_item_t *cbor_build_negint8(uint8_t value) -{ - cbor_item_t *item = cbor_new_int8(); - cbor_set_uint8(item, value); - cbor_mark_negint(item); - return item; -} - -cbor_item_t *cbor_build_negint16(uint16_t value) -{ - cbor_item_t *item = cbor_new_int16(); - cbor_set_uint16(item, value); - cbor_mark_negint(item); - return item; -} - -cbor_item_t *cbor_build_negint32(uint32_t value) -{ - cbor_item_t *item = cbor_new_int32(); - cbor_set_uint32(item, value); - cbor_mark_negint(item); - return item; -} - -cbor_item_t *cbor_build_negint64(uint64_t value) -{ - cbor_item_t *item = cbor_new_int64(); - cbor_set_uint64(item, value); - cbor_mark_negint(item); - return item; + +cbor_item_t *cbor_build_uint64(uint64_t value) { + cbor_item_t *item = cbor_new_int64(); + _CBOR_NOTNULL(item); + cbor_set_uint64(item, value); + cbor_mark_uint(item); + return item; +} + +cbor_item_t *cbor_build_negint8(uint8_t value) { + cbor_item_t *item = cbor_new_int8(); + _CBOR_NOTNULL(item); + cbor_set_uint8(item, value); + cbor_mark_negint(item); + return item; +} + +cbor_item_t *cbor_build_negint16(uint16_t value) { + cbor_item_t *item = cbor_new_int16(); + _CBOR_NOTNULL(item); + cbor_set_uint16(item, value); + cbor_mark_negint(item); + return item; +} + +cbor_item_t *cbor_build_negint32(uint32_t value) { + cbor_item_t *item = cbor_new_int32(); + _CBOR_NOTNULL(item); + cbor_set_uint32(item, value); + cbor_mark_negint(item); + return item; +} + +cbor_item_t *cbor_build_negint64(uint64_t value) { + cbor_item_t *item = cbor_new_int64(); + _CBOR_NOTNULL(item); + cbor_set_uint64(item, value); + cbor_mark_negint(item); + return item; } diff --git a/lib/libcbor/src/cbor/ints.h b/lib/libcbor/src/cbor/ints.h index 31f9d056a4b..899caefd9bc 100644 --- a/lib/libcbor/src/cbor/ints.h +++ b/lib/libcbor/src/cbor/ints.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014-2017 Pavel Kalvoda <me@pavelkalvoda.com> + * Copyright (c) 2014-2019 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. @@ -15,10 +15,10 @@ extern "C" { #endif /* -* ============================================================================ -* Integer (uints and negints) manipulation -* ============================================================================ -*/ + * ============================================================================ + * Integer (uints and negints) manipulation + * ============================================================================ + */ /** Extracts the integer value * @@ -58,28 +58,32 @@ uint64_t cbor_get_int(const cbor_item_t *item); /** Assigns the integer value * * @param item[borrow] positive or negative integer item - * @param value the value to assign. For negative integer, the logical value is `-value - 1` + * @param value the value to assign. For negative integer, the logical value is + * `-value - 1` */ void cbor_set_uint8(cbor_item_t *item, uint8_t value); /** Assigns the integer value * * @param item[borrow] positive or negative integer item - * @param value the value to assign. For negative integer, the logical value is `-value - 1` + * @param value the value to assign. For negative integer, the logical value is + * `-value - 1` */ void cbor_set_uint16(cbor_item_t *item, uint16_t value); /** Assigns the integer value * * @param item[borrow] positive or negative integer item - * @param value the value to assign. For negative integer, the logical value is `-value - 1` + * @param value the value to assign. For negative integer, the logical value is + * `-value - 1` */ void cbor_set_uint32(cbor_item_t *item, uint32_t value); /** Assigns the integer value * * @param item[borrow] positive or negative integer item - * @param value the value to assign. For negative integer, the logical value is `-value - 1` + * @param value the value to assign. For negative integer, the logical value is + * `-value - 1` */ void cbor_set_uint64(cbor_item_t *item, uint64_t value); @@ -110,7 +114,8 @@ void cbor_mark_negint(cbor_item_t *item); * * The width cannot be changed once allocated * - * @return **new** positive integer. The value is not initialized. + * @return **new** positive integer or `NULL` on memory allocation failure. The + * value is not initialized */ cbor_item_t *cbor_new_int8(); @@ -118,7 +123,8 @@ cbor_item_t *cbor_new_int8(); * * The width cannot be changed once allocated * - * @return **new** positive integer. The value is not initialized. + * @return **new** positive integer or `NULL` on memory allocation failure. The + * value is not initialized */ cbor_item_t *cbor_new_int16(); @@ -126,7 +132,8 @@ cbor_item_t *cbor_new_int16(); * * The width cannot be changed once allocated * - * @return **new** positive integer. The value is not initialized. + * @return **new** positive integer or `NULL` on memory allocation failure. The + * value is not initialized */ cbor_item_t *cbor_new_int32(); @@ -134,70 +141,69 @@ cbor_item_t *cbor_new_int32(); * * The width cannot be changed once allocated * - * @return **new** positive integer. The value is not initialized. + * @return **new** positive integer or `NULL` on memory allocation failure. The + * value is not initialized */ cbor_item_t *cbor_new_int64(); /** Constructs a new positive integer * * @param value the value to use - * @return **new** positive integer + * @return **new** positive integer or `NULL` on memory allocation failure */ cbor_item_t *cbor_build_uint8(uint8_t value); /** Constructs a new positive integer * * @param value the value to use - * @return **new** positive integer + * @return **new** positive integer or `NULL` on memory allocation failure */ cbor_item_t *cbor_build_uint16(uint16_t value); /** Constructs a new positive integer * * @param value the value to use - * @return **new** positive integer + * @return **new** positive integer or `NULL` on memory allocation failure */ cbor_item_t *cbor_build_uint32(uint32_t value); /** Constructs a new positive integer * * @param value the value to use - * @return **new** positive integer + * @return **new** positive integer or `NULL` on memory allocation failure */ cbor_item_t *cbor_build_uint64(uint64_t value); /** Constructs a new negative integer * * @param value the value to use - * @return **new** negative integer + * @return **new** negative integer or `NULL` on memory allocation failure */ cbor_item_t *cbor_build_negint8(uint8_t value); /** Constructs a new negative integer * * @param value the value to use - * @return **new** negative integer + * @return **new** negative integer or `NULL` on memory allocation failure */ cbor_item_t *cbor_build_negint16(uint16_t value); /** Constructs a new negative integer * * @param value the value to use - * @return **new** negative integer + * @return **new** negative integer or `NULL` on memory allocation failure */ cbor_item_t *cbor_build_negint32(uint32_t value); /** Constructs a new negative integer * * @param value the value to use - * @return **new** negative integer + * @return **new** negative integer or `NULL` on memory allocation failure */ cbor_item_t *cbor_build_negint64(uint64_t value); - - #ifdef __cplusplus } #endif -#endif //LIBCBOR_INTS_H +#endif // LIBCBOR_INTS_H diff --git a/lib/libcbor/src/cbor/maps.c b/lib/libcbor/src/cbor/maps.c index 8a70d0cad64..6b04c5eef10 100644 --- a/lib/libcbor/src/cbor/maps.c +++ b/lib/libcbor/src/cbor/maps.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014-2017 Pavel Kalvoda <me@pavelkalvoda.com> + * Copyright (c) 2014-2019 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. @@ -8,134 +8,118 @@ #include "maps.h" #include "internal/memory_utils.h" -size_t cbor_map_size(const cbor_item_t *item) -{ - assert(cbor_isa_map(item)); - return item->metadata.map_metadata.end_ptr; +size_t cbor_map_size(const cbor_item_t *item) { + assert(cbor_isa_map(item)); + return item->metadata.map_metadata.end_ptr; } -size_t cbor_map_allocated(const cbor_item_t *item) -{ - assert(cbor_isa_map(item)); - return item->metadata.map_metadata.allocated; +size_t cbor_map_allocated(const cbor_item_t *item) { + assert(cbor_isa_map(item)); + return item->metadata.map_metadata.allocated; } -cbor_item_t *cbor_new_definite_map(size_t size) -{ - cbor_item_t *item = _CBOR_MALLOC(sizeof(cbor_item_t)); - if (item == NULL) { - return NULL; - } - *item = (cbor_item_t) { - .refcount = 1, - .type = CBOR_TYPE_MAP, - .metadata = {.map_metadata = { - .allocated = size, - .type = _CBOR_METADATA_DEFINITE, - .end_ptr = 0 - }}, - .data = _cbor_alloc_multiple(sizeof(struct cbor_pair), size) - }; - if (item->data == NULL) { - _CBOR_FREE(item); - return NULL; - } - return item; -} +cbor_item_t *cbor_new_definite_map(size_t size) { + cbor_item_t *item = _CBOR_MALLOC(sizeof(cbor_item_t)); + _CBOR_NOTNULL(item); + + *item = (cbor_item_t){ + .refcount = 1, + .type = CBOR_TYPE_MAP, + .metadata = {.map_metadata = {.allocated = size, + .type = _CBOR_METADATA_DEFINITE, + .end_ptr = 0}}, + .data = _cbor_alloc_multiple(sizeof(struct cbor_pair), size)}; + _CBOR_DEPENDENT_NOTNULL(item, item->data); -cbor_item_t *cbor_new_indefinite_map() -{ - cbor_item_t *item = _CBOR_MALLOC(sizeof(cbor_item_t)); - if (item == NULL) - return NULL; - *item = (cbor_item_t) { - .refcount = 1, - .type = CBOR_TYPE_MAP, - .metadata = {.map_metadata = { - .allocated = 0, - .type = _CBOR_METADATA_INDEFINITE, - .end_ptr = 0 - }}, - .data = NULL - }; - - return item; + return item; } +cbor_item_t *cbor_new_indefinite_map() { + cbor_item_t *item = _CBOR_MALLOC(sizeof(cbor_item_t)); + _CBOR_NOTNULL(item); + + *item = (cbor_item_t){ + .refcount = 1, + .type = CBOR_TYPE_MAP, + .metadata = {.map_metadata = {.allocated = 0, + .type = _CBOR_METADATA_INDEFINITE, + .end_ptr = 0}}, + .data = NULL}; + + return item; +} -bool _cbor_map_add_key(cbor_item_t *item, cbor_item_t *key) -{ - assert(cbor_isa_map(item)); - struct _cbor_map_metadata *metadata = (struct _cbor_map_metadata *) &item->metadata; - if (cbor_map_is_definite(item)) { - struct cbor_pair *data = cbor_map_handle(item); - if (metadata->end_ptr >= metadata->allocated) { - /* Don't realloc definite preallocated map */ - return false; - } - - data[metadata->end_ptr].key = key; - data[metadata->end_ptr++].value = NULL; - } else { - if (metadata->end_ptr >= metadata->allocated) { - /* Exponential realloc */ - // Check for overflows first - if (!_cbor_safe_to_multiply(CBOR_BUFFER_GROWTH, metadata->allocated)) { - return false; - } - - size_t new_allocation = metadata->allocated == 0 ? 1 : CBOR_BUFFER_GROWTH * metadata->allocated; - - unsigned char * new_data = _cbor_realloc_multiple(item->data, sizeof(struct cbor_pair), new_allocation); - - if (new_data == NULL) { - return false; - } - - item->data = new_data; - metadata->allocated = new_allocation; - } - struct cbor_pair *data = cbor_map_handle(item); - data[metadata->end_ptr].key = key; - data[metadata->end_ptr++].value = NULL; - } - cbor_incref(key); - return true; +bool _cbor_map_add_key(cbor_item_t *item, cbor_item_t *key) { + assert(cbor_isa_map(item)); + struct _cbor_map_metadata *metadata = + (struct _cbor_map_metadata *)&item->metadata; + if (cbor_map_is_definite(item)) { + struct cbor_pair *data = cbor_map_handle(item); + if (metadata->end_ptr >= metadata->allocated) { + /* Don't realloc definite preallocated map */ + return false; + } + + data[metadata->end_ptr].key = key; + data[metadata->end_ptr++].value = NULL; + } else { + if (metadata->end_ptr >= metadata->allocated) { + /* Exponential realloc */ + // Check for overflows first + // TODO: Explicitly test this + if (!_cbor_safe_to_multiply(CBOR_BUFFER_GROWTH, metadata->allocated)) { + return false; + } + + size_t new_allocation = metadata->allocated == 0 + ? 1 + : CBOR_BUFFER_GROWTH * metadata->allocated; + + unsigned char *new_data = _cbor_realloc_multiple( + item->data, sizeof(struct cbor_pair), new_allocation); + + if (new_data == NULL) { + return false; + } + + item->data = new_data; + metadata->allocated = new_allocation; + } + struct cbor_pair *data = cbor_map_handle(item); + data[metadata->end_ptr].key = key; + data[metadata->end_ptr++].value = NULL; + } + cbor_incref(key); + return true; } -bool _cbor_map_add_value(cbor_item_t *item, cbor_item_t *value) -{ - assert(cbor_isa_map(item)); - cbor_incref(value); - cbor_map_handle(item)[ - /* Move one back since we are assuming _add_key (which increased the ptr) - * was the previous operation on this object */ - item->metadata.map_metadata.end_ptr - 1 - ].value = value; - return true; +bool _cbor_map_add_value(cbor_item_t *item, cbor_item_t *value) { + assert(cbor_isa_map(item)); + cbor_incref(value); + cbor_map_handle(item)[ + /* Move one back since we are assuming _add_key (which increased the ptr) + * was the previous operation on this object */ + item->metadata.map_metadata.end_ptr - 1] + .value = value; + return true; } -bool cbor_map_add(cbor_item_t *item, struct cbor_pair pair) -{ - assert(cbor_isa_map(item)); - if (!_cbor_map_add_key(item, pair.key)) - return false; - return _cbor_map_add_value(item, pair.value); +bool cbor_map_add(cbor_item_t *item, struct cbor_pair pair) { + assert(cbor_isa_map(item)); + if (!_cbor_map_add_key(item, pair.key)) return false; + return _cbor_map_add_value(item, pair.value); } -bool cbor_map_is_definite(const cbor_item_t *item) -{ - assert(cbor_isa_map(item)); - return item->metadata.map_metadata.type == _CBOR_METADATA_DEFINITE; +bool cbor_map_is_definite(const cbor_item_t *item) { + assert(cbor_isa_map(item)); + return item->metadata.map_metadata.type == _CBOR_METADATA_DEFINITE; } -bool cbor_map_is_indefinite(const cbor_item_t *item) -{ - return !cbor_map_is_definite(item); +bool cbor_map_is_indefinite(const cbor_item_t *item) { + return !cbor_map_is_definite(item); } -struct cbor_pair *cbor_map_handle(const cbor_item_t *item) -{ - assert(cbor_isa_map(item)); - return (struct cbor_pair *) item->data; +struct cbor_pair *cbor_map_handle(const cbor_item_t *item) { + assert(cbor_isa_map(item)); + return (struct cbor_pair *)item->data; } diff --git a/lib/libcbor/src/cbor/maps.h b/lib/libcbor/src/cbor/maps.h index cd433b310f3..d737d6974ee 100644 --- a/lib/libcbor/src/cbor/maps.h +++ b/lib/libcbor/src/cbor/maps.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014-2017 Pavel Kalvoda <me@pavelkalvoda.com> + * Copyright (c) 2014-2019 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. @@ -15,10 +15,10 @@ extern "C" { #endif /* -* ============================================================================ -* Map manipulation -* ============================================================================ -*/ + * ============================================================================ + * Map manipulation + * ============================================================================ + */ /** Get the number of pairs * @@ -50,12 +50,13 @@ cbor_item_t *cbor_new_indefinite_map(); /** Add a pair to the map * - * For definite maps, items can only be added to the preallocated space. For indefinite - * maps, the storage will be expanded as needed + * For definite maps, items can only be added to the preallocated space. For + * indefinite maps, the storage will be expanded as needed * * @param item[borrow] A map * @param pair[incref] The key-value pair to add (incref is member-wise) - * @return `true` on success, `false` if either reallocation failed or the preallcoated storage is full + * @return `true` on success, `false` if either reallocation failed or the + * preallcoated storage is full */ bool cbor_map_add(cbor_item_t *item, struct cbor_pair pair); @@ -65,7 +66,8 @@ bool cbor_map_add(cbor_item_t *item, struct cbor_pair pair); * * @param item[borrow] A map * @param key[incref] The key - * @return `true` on success, `false` if either reallocation failed or the preallcoated storage is full + * @return `true` on success, `false` if either reallocation failed or the + * preallcoated storage is full */ bool _cbor_map_add_key(cbor_item_t *item, cbor_item_t *key); @@ -75,7 +77,8 @@ bool _cbor_map_add_key(cbor_item_t *item, cbor_item_t *key); * * @param item[borrow] A map * @param key[incref] The value - * @return `true` on success, `false` if either reallocation failed or the preallcoated storage is full + * @return `true` on success, `false` if either reallocation failed or the + * preallcoated storage is full */ bool _cbor_map_add_value(cbor_item_t *item, cbor_item_t *value); @@ -96,7 +99,8 @@ bool cbor_map_is_indefinite(const cbor_item_t *item); /** Get the pairs storage * * @param item[borrow] A map - * @return Array of #cbor_map_size pairs. Manipulation is possible as long as references remain valid. + * @return Array of #cbor_map_size pairs. Manipulation is possible as long as + * references remain valid. */ struct cbor_pair *cbor_map_handle(const cbor_item_t *item); @@ -104,4 +108,4 @@ struct cbor_pair *cbor_map_handle(const cbor_item_t *item); } #endif -#endif //LIBCBOR_MAPS_H +#endif // LIBCBOR_MAPS_H diff --git a/lib/libcbor/src/cbor/serialization.c b/lib/libcbor/src/cbor/serialization.c index 52f2bbe8b34..f2666e1b22f 100644 --- a/lib/libcbor/src/cbor/serialization.c +++ b/lib/libcbor/src/cbor/serialization.c @@ -1,12 +1,12 @@ /* - * Copyright (c) 2014-2017 Pavel Kalvoda <me@pavelkalvoda.com> + * Copyright (c) 2014-2019 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. */ #include "serialization.h" -#include "encoding.h" +#include <string.h> #include "cbor/arrays.h" #include "cbor/bytestrings.h" #include "cbor/floats_ctrls.h" @@ -14,274 +14,273 @@ #include "cbor/maps.h" #include "cbor/strings.h" #include "cbor/tags.h" +#include "encoding.h" #include "internal/memory_utils.h" -#include <string.h> -size_t cbor_serialize(const cbor_item_t *item, unsigned char *buffer, size_t buffer_size) -{ - switch (cbor_typeof(item)) { - case CBOR_TYPE_UINT: - return cbor_serialize_uint(item, buffer, buffer_size); - case CBOR_TYPE_NEGINT: - return cbor_serialize_negint(item, buffer, buffer_size); - case CBOR_TYPE_BYTESTRING: - return cbor_serialize_bytestring(item, buffer, buffer_size); - case CBOR_TYPE_STRING: - return cbor_serialize_string(item, buffer, buffer_size); - case CBOR_TYPE_ARRAY: - return cbor_serialize_array(item, buffer, buffer_size); - case CBOR_TYPE_MAP: - return cbor_serialize_map(item, buffer, buffer_size); - case CBOR_TYPE_TAG: - return cbor_serialize_tag(item, buffer, buffer_size); - case CBOR_TYPE_FLOAT_CTRL: - return cbor_serialize_float_ctrl(item, buffer, buffer_size); - default: - return 0; - } +size_t cbor_serialize(const cbor_item_t *item, unsigned char *buffer, + size_t buffer_size) { + switch (cbor_typeof(item)) { + case CBOR_TYPE_UINT: + return cbor_serialize_uint(item, buffer, buffer_size); + case CBOR_TYPE_NEGINT: + return cbor_serialize_negint(item, buffer, buffer_size); + case CBOR_TYPE_BYTESTRING: + return cbor_serialize_bytestring(item, buffer, buffer_size); + case CBOR_TYPE_STRING: + return cbor_serialize_string(item, buffer, buffer_size); + case CBOR_TYPE_ARRAY: + return cbor_serialize_array(item, buffer, buffer_size); + case CBOR_TYPE_MAP: + return cbor_serialize_map(item, buffer, buffer_size); + case CBOR_TYPE_TAG: + return cbor_serialize_tag(item, buffer, buffer_size); + case CBOR_TYPE_FLOAT_CTRL: + return cbor_serialize_float_ctrl(item, buffer, buffer_size); + default: + return 0; + } } -size_t cbor_serialize_alloc(const cbor_item_t * item, - unsigned char ** buffer, - size_t * buffer_size) -{ - size_t bfr_size = 32; - unsigned char * bfr = _CBOR_MALLOC(bfr_size), * tmp_bfr; - if (bfr == NULL) { - return 0; - } +size_t cbor_serialize_alloc(const cbor_item_t *item, unsigned char **buffer, + size_t *buffer_size) { + size_t bfr_size = 32; + unsigned char *bfr = _CBOR_MALLOC(bfr_size), *tmp_bfr; + if (bfr == NULL) { + return 0; + } - size_t written; + size_t written; - /* This is waaay too optimistic - figure out something smarter (eventually) */ - while ((written = cbor_serialize(item, bfr, bfr_size)) == 0) { - if (!_cbor_safe_to_multiply(CBOR_BUFFER_GROWTH, bfr_size)) { - _CBOR_FREE(bfr); - return 0; - } + /* This is waaay too optimistic - figure out something smarter (eventually) */ + while ((written = cbor_serialize(item, bfr, bfr_size)) == 0) { + if (!_cbor_safe_to_multiply(CBOR_BUFFER_GROWTH, bfr_size)) { + _CBOR_FREE(bfr); + return 0; + } - tmp_bfr = _CBOR_REALLOC(bfr, bfr_size *= 2); + tmp_bfr = _CBOR_REALLOC(bfr, bfr_size *= 2); - if (tmp_bfr == NULL) { - _CBOR_FREE(bfr); - return 0; - } - bfr = tmp_bfr; - } - *buffer = bfr; - *buffer_size = bfr_size; - return written; + if (tmp_bfr == NULL) { + _CBOR_FREE(bfr); + return 0; + } + bfr = tmp_bfr; + } + *buffer = bfr; + *buffer_size = bfr_size; + return written; } -size_t cbor_serialize_uint(const cbor_item_t *item, unsigned char *buffer, size_t buffer_size) -{ - assert(cbor_isa_uint(item)); - switch (cbor_int_get_width(item)) { - case CBOR_INT_8: - return cbor_encode_uint8(cbor_get_uint8(item), buffer, buffer_size); - case CBOR_INT_16: - return cbor_encode_uint16(cbor_get_uint16(item), buffer, buffer_size); - case CBOR_INT_32: - return cbor_encode_uint32(cbor_get_uint32(item), buffer, buffer_size); - case CBOR_INT_64: - return cbor_encode_uint64(cbor_get_uint64(item), buffer, buffer_size); - default: - return 0; - } +size_t cbor_serialize_uint(const cbor_item_t *item, unsigned char *buffer, + size_t buffer_size) { + assert(cbor_isa_uint(item)); + switch (cbor_int_get_width(item)) { + case CBOR_INT_8: + return cbor_encode_uint8(cbor_get_uint8(item), buffer, buffer_size); + case CBOR_INT_16: + return cbor_encode_uint16(cbor_get_uint16(item), buffer, buffer_size); + case CBOR_INT_32: + return cbor_encode_uint32(cbor_get_uint32(item), buffer, buffer_size); + case CBOR_INT_64: + return cbor_encode_uint64(cbor_get_uint64(item), buffer, buffer_size); + default: + return 0; + } } -size_t cbor_serialize_negint(const cbor_item_t *item, unsigned char *buffer, size_t buffer_size) -{ - assert(cbor_isa_negint(item)); - switch (cbor_int_get_width(item)) { - case CBOR_INT_8: - return cbor_encode_negint8(cbor_get_uint8(item), buffer, buffer_size); - case CBOR_INT_16: - return cbor_encode_negint16(cbor_get_uint16(item), buffer, buffer_size); - case CBOR_INT_32: - return cbor_encode_negint32(cbor_get_uint32(item), buffer, buffer_size); - case CBOR_INT_64: - return cbor_encode_negint64(cbor_get_uint64(item), buffer, buffer_size); - default: - return 0; - } +size_t cbor_serialize_negint(const cbor_item_t *item, unsigned char *buffer, + size_t buffer_size) { + assert(cbor_isa_negint(item)); + switch (cbor_int_get_width(item)) { + case CBOR_INT_8: + return cbor_encode_negint8(cbor_get_uint8(item), buffer, buffer_size); + case CBOR_INT_16: + return cbor_encode_negint16(cbor_get_uint16(item), buffer, buffer_size); + case CBOR_INT_32: + return cbor_encode_negint32(cbor_get_uint32(item), buffer, buffer_size); + case CBOR_INT_64: + return cbor_encode_negint64(cbor_get_uint64(item), buffer, buffer_size); + default: + return 0; + } } -size_t cbor_serialize_bytestring(const cbor_item_t *item, unsigned char *buffer, size_t buffer_size) -{ - assert(cbor_isa_bytestring(item)); - if (cbor_bytestring_is_definite(item)) { - size_t length = cbor_bytestring_length(item); - size_t written = cbor_encode_bytestring_start(length, buffer, buffer_size); - if (written && (buffer_size - written >= length)) { - memcpy(buffer + written, cbor_bytestring_handle(item), length); - return written + length; - } else - return 0; - } else { - assert(cbor_bytestring_is_indefinite(item)); - size_t chunk_count = cbor_bytestring_chunk_count(item); - size_t written = cbor_encode_indef_bytestring_start(buffer, buffer_size); +size_t cbor_serialize_bytestring(const cbor_item_t *item, unsigned char *buffer, + size_t buffer_size) { + assert(cbor_isa_bytestring(item)); + if (cbor_bytestring_is_definite(item)) { + size_t length = cbor_bytestring_length(item); + size_t written = cbor_encode_bytestring_start(length, buffer, buffer_size); + if (written && (buffer_size - written >= length)) { + memcpy(buffer + written, cbor_bytestring_handle(item), length); + return written + length; + } else + return 0; + } else { + assert(cbor_bytestring_is_indefinite(item)); + size_t chunk_count = cbor_bytestring_chunk_count(item); + size_t written = cbor_encode_indef_bytestring_start(buffer, buffer_size); - if (written == 0) - return 0; + if (written == 0) return 0; - cbor_item_t **chunks = cbor_bytestring_chunks_handle(item); - for (size_t i = 0; i < chunk_count; i++) { - size_t chunk_written = cbor_serialize_bytestring(chunks[i], buffer + written, buffer_size - written); - if (chunk_written == 0) - return 0; - else - written += chunk_written; - } - if (cbor_encode_break(buffer + written, buffer_size - written) > 0) - return written + 1; - else - return 0; - } + cbor_item_t **chunks = cbor_bytestring_chunks_handle(item); + for (size_t i = 0; i < chunk_count; i++) { + size_t chunk_written = cbor_serialize_bytestring( + chunks[i], buffer + written, buffer_size - written); + if (chunk_written == 0) + return 0; + else + written += chunk_written; + } + if (cbor_encode_break(buffer + written, buffer_size - written) > 0) + return written + 1; + else + return 0; + } } -size_t cbor_serialize_string(const cbor_item_t *item, unsigned char *buffer, size_t buffer_size) -{ - assert(cbor_isa_string(item)); - if (cbor_string_is_definite(item)) { - size_t length = cbor_string_length(item); - size_t written = cbor_encode_string_start(length, buffer, buffer_size); - if (written && (buffer_size - written >= length)) { - memcpy(buffer + written, cbor_string_handle(item), length); - return written + length; - } else - return 0; - } else { - assert(cbor_string_is_indefinite(item)); - size_t chunk_count = cbor_string_chunk_count(item); - size_t written = cbor_encode_indef_string_start(buffer, buffer_size); +size_t cbor_serialize_string(const cbor_item_t *item, unsigned char *buffer, + size_t buffer_size) { + assert(cbor_isa_string(item)); + if (cbor_string_is_definite(item)) { + size_t length = cbor_string_length(item); + size_t written = cbor_encode_string_start(length, buffer, buffer_size); + if (written && (buffer_size - written >= length)) { + memcpy(buffer + written, cbor_string_handle(item), length); + return written + length; + } else + return 0; + } else { + assert(cbor_string_is_indefinite(item)); + size_t chunk_count = cbor_string_chunk_count(item); + size_t written = cbor_encode_indef_string_start(buffer, buffer_size); - if (written == 0) - return 0; + if (written == 0) return 0; - cbor_item_t **chunks = cbor_string_chunks_handle(item); - for (size_t i = 0; i < chunk_count; i++) { - size_t chunk_written = cbor_serialize_string(chunks[i], buffer + written, buffer_size - written); - if (chunk_written == 0) - return 0; - else - written += chunk_written; - } - if (cbor_encode_break(buffer + written, buffer_size - written) > 0) - return written + 1; - else - return 0; - } + cbor_item_t **chunks = cbor_string_chunks_handle(item); + for (size_t i = 0; i < chunk_count; i++) { + size_t chunk_written = cbor_serialize_string(chunks[i], buffer + written, + buffer_size - written); + if (chunk_written == 0) + return 0; + else + written += chunk_written; + } + if (cbor_encode_break(buffer + written, buffer_size - written) > 0) + return written + 1; + else + return 0; + } } -size_t cbor_serialize_array(const cbor_item_t *item, unsigned char *buffer, size_t buffer_size) -{ - assert(cbor_isa_array(item)); - size_t size = cbor_array_size(item), - written = 0; - cbor_item_t **handle = cbor_array_handle(item); - if (cbor_array_is_definite(item)) { - written = cbor_encode_array_start(size, buffer, buffer_size); - } else { - assert(cbor_array_is_indefinite(item)); - written = cbor_encode_indef_array_start(buffer, buffer_size); - } - if (written == 0) - return 0; +size_t cbor_serialize_array(const cbor_item_t *item, unsigned char *buffer, + size_t buffer_size) { + assert(cbor_isa_array(item)); + size_t size = cbor_array_size(item), written = 0; + cbor_item_t **handle = cbor_array_handle(item); + if (cbor_array_is_definite(item)) { + written = cbor_encode_array_start(size, buffer, buffer_size); + } else { + assert(cbor_array_is_indefinite(item)); + written = cbor_encode_indef_array_start(buffer, buffer_size); + } + if (written == 0) return 0; - size_t item_written; - for (size_t i = 0; i < size; i++) { - item_written = cbor_serialize(*(handle++), buffer + written, buffer_size - written); - if (item_written == 0) - return 0; - else - written += item_written; - } + size_t item_written; + for (size_t i = 0; i < size; i++) { + item_written = + cbor_serialize(*(handle++), buffer + written, buffer_size - written); + if (item_written == 0) + return 0; + else + written += item_written; + } - if (cbor_array_is_definite(item)) { - return written; - } else { - assert(cbor_array_is_indefinite(item)); - item_written = cbor_encode_break(buffer + written, buffer_size - written); - if (item_written == 0) - return 0; - else - return written + 1; - } + if (cbor_array_is_definite(item)) { + return written; + } else { + assert(cbor_array_is_indefinite(item)); + item_written = cbor_encode_break(buffer + written, buffer_size - written); + if (item_written == 0) + return 0; + else + return written + 1; + } } -size_t cbor_serialize_map(const cbor_item_t *item, unsigned char *buffer, size_t buffer_size) -{ - assert(cbor_isa_map(item)); - size_t size = cbor_map_size(item), - written = 0; - struct cbor_pair * handle = cbor_map_handle(item); +size_t cbor_serialize_map(const cbor_item_t *item, unsigned char *buffer, + size_t buffer_size) { + assert(cbor_isa_map(item)); + size_t size = cbor_map_size(item), written = 0; + struct cbor_pair *handle = cbor_map_handle(item); - if (cbor_map_is_definite(item)) { - written = cbor_encode_map_start(size, buffer, buffer_size); - } else { - assert(cbor_map_is_indefinite(item)); - written = cbor_encode_indef_map_start(buffer, buffer_size); - } - if (written == 0) - return 0; + if (cbor_map_is_definite(item)) { + written = cbor_encode_map_start(size, buffer, buffer_size); + } else { + assert(cbor_map_is_indefinite(item)); + written = cbor_encode_indef_map_start(buffer, buffer_size); + } + if (written == 0) return 0; - size_t item_written; - for (size_t i = 0; i < size; i++) { - item_written = cbor_serialize(handle->key, buffer + written, buffer_size - written); - if (item_written == 0) - return 0; - else - written += item_written; - item_written = cbor_serialize((handle++)->value, buffer + written, buffer_size - written); - if (item_written == 0) - return 0; - else - written += item_written; - } + size_t item_written; + for (size_t i = 0; i < size; i++) { + item_written = + cbor_serialize(handle->key, buffer + written, buffer_size - written); + if (item_written == 0) + return 0; + else + written += item_written; + item_written = cbor_serialize((handle++)->value, buffer + written, + buffer_size - written); + if (item_written == 0) + return 0; + else + written += item_written; + } - if (cbor_map_is_definite(item)) { - return written; - } else { - assert(cbor_map_is_indefinite(item)); - item_written = cbor_encode_break(buffer + written, buffer_size - written); - if (item_written == 0) - return 0; - else - return written + 1; - } + if (cbor_map_is_definite(item)) { + return written; + } else { + assert(cbor_map_is_indefinite(item)); + item_written = cbor_encode_break(buffer + written, buffer_size - written); + if (item_written == 0) + return 0; + else + return written + 1; + } } -size_t cbor_serialize_tag(const cbor_item_t *item, unsigned char *buffer, size_t buffer_size) -{ - assert(cbor_isa_tag(item)); - size_t written = cbor_encode_tag(cbor_tag_value(item), buffer, buffer_size); - if (written == 0) - return 0; +size_t cbor_serialize_tag(const cbor_item_t *item, unsigned char *buffer, + size_t buffer_size) { + assert(cbor_isa_tag(item)); + size_t written = cbor_encode_tag(cbor_tag_value(item), buffer, buffer_size); + if (written == 0) return 0; - size_t item_written = cbor_serialize(cbor_tag_item(item), buffer + written, buffer_size - written); - if (item_written == 0) - return 0; - else - return written + item_written; + size_t item_written = cbor_serialize(cbor_tag_item(item), buffer + written, + buffer_size - written); + if (item_written == 0) + return 0; + else + return written + item_written; } -size_t cbor_serialize_float_ctrl(const cbor_item_t *item, unsigned char *buffer, size_t buffer_size) -{ - assert(cbor_isa_float_ctrl(item)); - switch (cbor_float_get_width(item)) { - case CBOR_FLOAT_0: - /* CTRL - special treatment */ - return cbor_encode_ctrl(cbor_ctrl_value(item), buffer, buffer_size); - case CBOR_FLOAT_16: - return cbor_encode_half(cbor_float_get_float2(item), buffer, buffer_size); - case CBOR_FLOAT_32: - return cbor_encode_single(cbor_float_get_float4(item), buffer, buffer_size); - case CBOR_FLOAT_64: - return cbor_encode_double(cbor_float_get_float8(item), buffer, buffer_size); - } +size_t cbor_serialize_float_ctrl(const cbor_item_t *item, unsigned char *buffer, + size_t buffer_size) { + assert(cbor_isa_float_ctrl(item)); + switch (cbor_float_get_width(item)) { + case CBOR_FLOAT_0: + /* CTRL - special treatment */ + return cbor_encode_ctrl(cbor_ctrl_value(item), buffer, buffer_size); + case CBOR_FLOAT_16: + return cbor_encode_half(cbor_float_get_float2(item), buffer, buffer_size); + case CBOR_FLOAT_32: + return cbor_encode_single(cbor_float_get_float4(item), buffer, + buffer_size); + case CBOR_FLOAT_64: + return cbor_encode_double(cbor_float_get_float8(item), buffer, + buffer_size); + } - /* Should never happen - make the compiler happy */ - return 0; + /* Should never happen - make the compiler happy */ + return 0; } diff --git a/lib/libcbor/src/cbor/serialization.h b/lib/libcbor/src/cbor/serialization.h index 75b0f02437e..44b47b74755 100644 --- a/lib/libcbor/src/cbor/serialization.h +++ b/lib/libcbor/src/cbor/serialization.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014-2017 Pavel Kalvoda <me@pavelkalvoda.com> + * Copyright (c) 2014-2019 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. @@ -14,12 +14,11 @@ extern "C" { #endif - /* -* ============================================================================ -* High level encoding -* ============================================================================ -*/ + * ============================================================================ + * High level encoding + * ============================================================================ + */ /** Serialize the given item * @@ -28,20 +27,23 @@ extern "C" { * @param buffer_size Size of the \p buffer * @return Length of the result. 0 on failure. */ -size_t cbor_serialize(const cbor_item_t * item, cbor_mutable_data buffer, size_t buffer_size); +size_t cbor_serialize(const cbor_item_t *item, cbor_mutable_data buffer, + size_t buffer_size); /** Serialize the given item, allocating buffers as needed * * \rst - * .. warning:: It is your responsibility to free the buffer using an appropriate ``free`` implementation. - * \endrst + * .. warning:: It is your responsibility to free the buffer using an + * appropriate ``free`` implementation. \endrst * * @param item[borrow] A data item * @param buffer[out] Buffer containing the result * @param buffer_size[out] Size of the \p buffer - * @return Length of the result. 0 on failure, in which case \p buffer is ``NULL``. + * @return Length of the result. 0 on failure, in which case \p buffer is + * ``NULL``. */ -size_t cbor_serialize_alloc(const cbor_item_t * item, cbor_mutable_data * buffer, size_t * buffer_size); +size_t cbor_serialize_alloc(const cbor_item_t *item, cbor_mutable_data *buffer, + size_t *buffer_size); /** Serialize an uint * @@ -68,7 +70,8 @@ size_t cbor_serialize_negint(const cbor_item_t *, cbor_mutable_data, size_t); * @param buffer_size Size of the \p buffer * @return Length of the result. 0 on failure. */ -size_t cbor_serialize_bytestring(const cbor_item_t *, cbor_mutable_data, size_t); +size_t cbor_serialize_bytestring(const cbor_item_t *, cbor_mutable_data, + size_t); /** Serialize a string * @@ -113,11 +116,11 @@ size_t cbor_serialize_tag(const cbor_item_t *, cbor_mutable_data, size_t); * @param buffer_size Size of the \p buffer * @return Length of the result. 0 on failure. */ -size_t cbor_serialize_float_ctrl(const cbor_item_t *, cbor_mutable_data, size_t); +size_t cbor_serialize_float_ctrl(const cbor_item_t *, cbor_mutable_data, + size_t); #ifdef __cplusplus } #endif - -#endif //LIBCBOR_SERIALIZATION_H +#endif // LIBCBOR_SERIALIZATION_H diff --git a/lib/libcbor/src/cbor/streaming.c b/lib/libcbor/src/cbor/streaming.c index b6398c5b541..9bc315687cc 100644 --- a/lib/libcbor/src/cbor/streaming.c +++ b/lib/libcbor/src/cbor/streaming.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014-2017 Pavel Kalvoda <me@pavelkalvoda.com> + * Copyright (c) 2014-2019 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. @@ -8,677 +8,660 @@ #include "streaming.h" #include "internal/loaders.h" -bool static _cbor_claim_bytes(size_t required, - size_t provided, struct cbor_decoder_result *result) -{ - if (required > (provided - result->read)) { - /* We need to keep all the metadata if parsing is to be resumed */ - result->read = 0; - result->status = CBOR_DECODER_NEDATA; - return false; - } else { - result->read += required; - return true; - } +bool static _cbor_claim_bytes(size_t required, size_t provided, + struct cbor_decoder_result *result) { + if (required > (provided - result->read)) { + /* We need to keep all the metadata if parsing is to be resumed */ + result->read = 0; + result->status = CBOR_DECODER_NEDATA; + result->required = required; + return false; + } else { + result->read += required; + result->required = 0; + return true; + } } +struct cbor_decoder_result cbor_stream_decode( + cbor_data source, size_t source_size, + const struct cbor_callbacks *callbacks, void *context) { + /* If we have no data, we cannot read even the MTB */ + if (source_size < 1) { + return (struct cbor_decoder_result){0, CBOR_DECODER_EBUFFER}; + } -struct cbor_decoder_result cbor_stream_decode(cbor_data source, size_t source_size, - const struct cbor_callbacks *callbacks, - void *context) -{ - /* If we have no data, we cannot read even the MTB */ - if (source_size < 1) { - return (struct cbor_decoder_result) {0, CBOR_DECODER_EBUFFER}; - } + /* If we have a byte, assume it's the MTB */ + struct cbor_decoder_result result = {1, CBOR_DECODER_FINISHED}; - /* If we have a byte, assume it's the MTB */ - struct cbor_decoder_result result = {1, CBOR_DECODER_FINISHED}; - - switch (*source) { - case 0x00: /* Fallthrough */ - case 0x01: /* Fallthrough */ - case 0x02: /* Fallthrough */ - case 0x03: /* Fallthrough */ - case 0x04: /* Fallthrough */ - case 0x05: /* Fallthrough */ - case 0x06: /* Fallthrough */ - case 0x07: /* Fallthrough */ - case 0x08: /* Fallthrough */ - case 0x09: /* Fallthrough */ - case 0x0A: /* Fallthrough */ - case 0x0B: /* Fallthrough */ - case 0x0C: /* Fallthrough */ - case 0x0D: /* Fallthrough */ - case 0x0E: /* Fallthrough */ - case 0x0F: /* Fallthrough */ - case 0x10: /* Fallthrough */ - case 0x11: /* Fallthrough */ - case 0x12: /* Fallthrough */ - case 0x13: /* Fallthrough */ - case 0x14: /* Fallthrough */ - case 0x15: /* Fallthrough */ - case 0x16: /* Fallthrough */ - case 0x17: - /* Embedded one byte unsigned integer */ - { - callbacks->uint8(context, _cbor_load_uint8(source)); - return result; - } - case 0x18: - /* One byte unsigned integer */ - { - if (_cbor_claim_bytes(1, source_size, &result)) { - callbacks->uint8(context, _cbor_load_uint8(source + 1)); - } - return result; - } - case 0x19: - /* Two bytes unsigned integer */ - { - if (_cbor_claim_bytes(2, source_size, &result)) { - callbacks->uint16(context, _cbor_load_uint16(source + 1)); - } - return result; - } - case 0x1A: - /* Four bytes unsigned integer */ - { - if (_cbor_claim_bytes(4, source_size, &result)) { - callbacks->uint32(context, _cbor_load_uint32(source + 1)); - } - return result; - } - case 0x1B: - /* Eight bytes unsigned integer */ - { - if (_cbor_claim_bytes(8, source_size, &result)) { - callbacks->uint64(context, _cbor_load_uint64(source + 1)); - } - return result; - } - case 0x1C: /* Fallthrough */ - case 0x1D: /* Fallthrough */ - case 0x1E: /* Fallthrough */ - case 0x1F: - /* Reserved */ - { - return (struct cbor_decoder_result) {0, CBOR_DECODER_ERROR}; - } - case 0x20: /* Fallthrough */ - case 0x21: /* Fallthrough */ - case 0x22: /* Fallthrough */ - case 0x23: /* Fallthrough */ - case 0x24: /* Fallthrough */ - case 0x25: /* Fallthrough */ - case 0x26: /* Fallthrough */ - case 0x27: /* Fallthrough */ - case 0x28: /* Fallthrough */ - case 0x29: /* Fallthrough */ - case 0x2A: /* Fallthrough */ - case 0x2B: /* Fallthrough */ - case 0x2C: /* Fallthrough */ - case 0x2D: /* Fallthrough */ - case 0x2E: /* Fallthrough */ - case 0x2F: /* Fallthrough */ - case 0x30: /* Fallthrough */ - case 0x31: /* Fallthrough */ - case 0x32: /* Fallthrough */ - case 0x33: /* Fallthrough */ - case 0x34: /* Fallthrough */ - case 0x35: /* Fallthrough */ - case 0x36: /* Fallthrough */ - case 0x37: - /* Embedded one byte negative integer */ - { - callbacks->negint8(context, _cbor_load_uint8(source) - 0x20); /* 0x20 offset */ - return result; - } - case 0x38: - /* One byte negative integer */ - { - if (_cbor_claim_bytes(1, source_size, &result)) { - callbacks->negint8(context, _cbor_load_uint8(source + 1)); - } - return result; - } - case 0x39: - /* Two bytes negative integer */ - { - if (_cbor_claim_bytes(2, source_size, &result)) { - callbacks->negint16(context, _cbor_load_uint16(source + 1)); - } - return result; - } - case 0x3A: - /* Four bytes negative integer */ - { - if (_cbor_claim_bytes(4, source_size, &result)) { - callbacks->negint32(context, _cbor_load_uint32(source + 1)); - } - return result; - } - case 0x3B: - /* Eight bytes negative integer */ - { - if (_cbor_claim_bytes(8, source_size, &result)) { - callbacks->negint64(context, _cbor_load_uint64(source + 1)); - } - return result; - } - case 0x3C: /* Fallthrough */ - case 0x3D: /* Fallthrough */ - case 0x3E: /* Fallthrough */ - case 0x3F: - /* Reserved */ - { - return (struct cbor_decoder_result) {0, CBOR_DECODER_ERROR}; - } - case 0x40: /* Fallthrough */ - case 0x41: /* Fallthrough */ - case 0x42: /* Fallthrough */ - case 0x43: /* Fallthrough */ - case 0x44: /* Fallthrough */ - case 0x45: /* Fallthrough */ - case 0x46: /* Fallthrough */ - case 0x47: /* Fallthrough */ - case 0x48: /* Fallthrough */ - case 0x49: /* Fallthrough */ - case 0x4A: /* Fallthrough */ - case 0x4B: /* Fallthrough */ - case 0x4C: /* Fallthrough */ - case 0x4D: /* Fallthrough */ - case 0x4E: /* Fallthrough */ - case 0x4F: /* Fallthrough */ - case 0x50: /* Fallthrough */ - case 0x51: /* Fallthrough */ - case 0x52: /* Fallthrough */ - case 0x53: /* Fallthrough */ - case 0x54: /* Fallthrough */ - case 0x55: /* Fallthrough */ - case 0x56: /* Fallthrough */ - case 0x57: - /* Embedded length byte string */ - { - size_t length = (size_t) _cbor_load_uint8(source) - 0x40; /* 0x40 offset */ - if (_cbor_claim_bytes(length, source_size, &result)) { - callbacks->byte_string(context, source + 1, length); - } - return result; - } - case 0x58: - /* One byte length byte string */ - // TODO template this? - { - if (_cbor_claim_bytes(1, source_size, &result)) { - size_t length = (size_t) _cbor_load_uint8(source + 1); - if (_cbor_claim_bytes(length, source_size, &result)) { - callbacks->byte_string(context, source + 1 + 1, length); - } - } - return result; - } - case 0x59: - /* Two bytes length byte string */ - { - if (_cbor_claim_bytes(2, source_size, &result)) { - size_t length = (size_t) _cbor_load_uint16(source + 1); - if (_cbor_claim_bytes(length, source_size, &result)) { - callbacks->byte_string(context, source + 1 + 2, length); - } - } - return result; - } - case 0x5A: - /* Four bytes length byte string */ - { - if (_cbor_claim_bytes(4, source_size, &result)) { - size_t length = (size_t) _cbor_load_uint32(source + 1); - if (_cbor_claim_bytes(length, source_size, &result)) { - callbacks->byte_string(context, source + 1 + 4, length); - } - } - return result; - } - case 0x5B: - /* Eight bytes length byte string */ - { - if (_cbor_claim_bytes(8, source_size, &result)) { - size_t length = (size_t) _cbor_load_uint64(source + 1); - if (_cbor_claim_bytes(length, source_size, &result)) { - callbacks->byte_string(context, source + 1 + 8, length); - } - } - return result; - } - case 0x5C: /* Fallthrough */ - case 0x5D: /* Fallthrough */ - case 0x5E: - /* Reserved */ - { - return (struct cbor_decoder_result) {0, CBOR_DECODER_ERROR}; - } - case 0x5F: - /* Indefinite byte string */ - { - callbacks->byte_string_start(context); - return result; - } - case 0x60: /* Fallthrough */ - case 0x61: /* Fallthrough */ - case 0x62: /* Fallthrough */ - case 0x63: /* Fallthrough */ - case 0x64: /* Fallthrough */ - case 0x65: /* Fallthrough */ - case 0x66: /* Fallthrough */ - case 0x67: /* Fallthrough */ - case 0x68: /* Fallthrough */ - case 0x69: /* Fallthrough */ - case 0x6A: /* Fallthrough */ - case 0x6B: /* Fallthrough */ - case 0x6C: /* Fallthrough */ - case 0x6D: /* Fallthrough */ - case 0x6E: /* Fallthrough */ - case 0x6F: /* Fallthrough */ - case 0x70: /* Fallthrough */ - case 0x71: /* Fallthrough */ - case 0x72: /* Fallthrough */ - case 0x73: /* Fallthrough */ - case 0x74: /* Fallthrough */ - case 0x75: /* Fallthrough */ - case 0x76: /* Fallthrough */ - case 0x77: - /* Embedded one byte length string */ - { - size_t length = (size_t) _cbor_load_uint8(source) - 0x60; /* 0x60 offset */ - if (_cbor_claim_bytes(length, source_size, &result)) { - callbacks->string(context, source + 1, length); - } - return result; - } - case 0x78: - /* One byte length string */ - { - if (_cbor_claim_bytes(1, source_size, &result)) { - size_t length = (size_t) _cbor_load_uint8(source + 1); - if (_cbor_claim_bytes(length, source_size, &result)) { - callbacks->string(context, source + 1 + 1, length); - } - } - return result; - } - case 0x79: - /* Two bytes length string */ - { - if (_cbor_claim_bytes(2, source_size, &result)) { - size_t length = (size_t) _cbor_load_uint16(source + 1); - if (_cbor_claim_bytes(length, source_size, &result)) { - callbacks->string(context, source + 1 + 2, length); - } - } - return result; - } - case 0x7A: - /* Four bytes length string */ - { - if (_cbor_claim_bytes(4, source_size, &result)) { - size_t length = (size_t) _cbor_load_uint32(source + 1); - if (_cbor_claim_bytes(length, source_size, &result)) { - callbacks->string(context, source + 1 + 4, length); - } - } - return result; - } - case 0x7B: - /* Eight bytes length string */ - { - if (_cbor_claim_bytes(8, source_size, &result)) { - size_t length = (size_t) _cbor_load_uint64(source + 1); - if (_cbor_claim_bytes(length, source_size, &result)) { - callbacks->string(context, source + 1 + 8, length); - } - } - return result; - } - case 0x7C: /* Fallthrough */ - case 0x7D: /* Fallthrough */ - case 0x7E: - /* Reserved */ - { - return (struct cbor_decoder_result) {0, CBOR_DECODER_ERROR}; - } - case 0x7F: - /* Indefinite length string */ - { - callbacks->string_start(context); - return result; - } - case 0x80: /* Fallthrough */ - case 0x81: /* Fallthrough */ - case 0x82: /* Fallthrough */ - case 0x83: /* Fallthrough */ - case 0x84: /* Fallthrough */ - case 0x85: /* Fallthrough */ - case 0x86: /* Fallthrough */ - case 0x87: /* Fallthrough */ - case 0x88: /* Fallthrough */ - case 0x89: /* Fallthrough */ - case 0x8A: /* Fallthrough */ - case 0x8B: /* Fallthrough */ - case 0x8C: /* Fallthrough */ - case 0x8D: /* Fallthrough */ - case 0x8E: /* Fallthrough */ - case 0x8F: /* Fallthrough */ - case 0x90: /* Fallthrough */ - case 0x91: /* Fallthrough */ - case 0x92: /* Fallthrough */ - case 0x93: /* Fallthrough */ - case 0x94: /* Fallthrough */ - case 0x95: /* Fallthrough */ - case 0x96: /* Fallthrough */ - case 0x97: - /* Embedded one byte length array */ - { - callbacks->array_start(context, (size_t) _cbor_load_uint8(source) - 0x80); /* 0x40 offset */ - return result; - } - case 0x98: - /* One byte length array */ - { - if (_cbor_claim_bytes(1, source_size, &result)) { - callbacks->array_start(context, (size_t) _cbor_load_uint8(source + 1)); - } - return result; - } - case 0x99: - /* Two bytes length string */ - { - if (_cbor_claim_bytes(2, source_size, &result)) { - callbacks->array_start(context, (size_t) _cbor_load_uint16(source + 1)); - } - return result; - } - case 0x9A: - /* Four bytes length string */ - { - if (_cbor_claim_bytes(4, source_size, &result)) { - callbacks->array_start(context, (size_t) _cbor_load_uint32(source + 1)); - } - return result; - } - case 0x9B: - /* Eight bytes length string */ - { - if (_cbor_claim_bytes(8, source_size, &result)) { - callbacks->array_start(context, (size_t) _cbor_load_uint64(source + 1)); - } - return result; - } - case 0x9C: /* Fallthrough */ - case 0x9D: /* Fallthrough */ - case 0x9E: - /* Reserved */ - { - return (struct cbor_decoder_result) {0, CBOR_DECODER_ERROR}; - } - case 0x9F: - /* Indefinite length array */ - { - callbacks->indef_array_start(context); - return result; - } - case 0xA0: /* Fallthrough */ - case 0xA1: /* Fallthrough */ - case 0xA2: /* Fallthrough */ - case 0xA3: /* Fallthrough */ - case 0xA4: /* Fallthrough */ - case 0xA5: /* Fallthrough */ - case 0xA6: /* Fallthrough */ - case 0xA7: /* Fallthrough */ - case 0xA8: /* Fallthrough */ - case 0xA9: /* Fallthrough */ - case 0xAA: /* Fallthrough */ - case 0xAB: /* Fallthrough */ - case 0xAC: /* Fallthrough */ - case 0xAD: /* Fallthrough */ - case 0xAE: /* Fallthrough */ - case 0xAF: /* Fallthrough */ - case 0xB0: /* Fallthrough */ - case 0xB1: /* Fallthrough */ - case 0xB2: /* Fallthrough */ - case 0xB3: /* Fallthrough */ - case 0xB4: /* Fallthrough */ - case 0xB5: /* Fallthrough */ - case 0xB6: /* Fallthrough */ - case 0xB7: - /* Embedded one byte length map */ - { - callbacks->map_start(context, (size_t) _cbor_load_uint8(source) - 0xA0); /* 0xA0 offset */ - return result; - } - case 0xB8: - /* One byte length map */ - { - if (_cbor_claim_bytes(1, source_size, &result)) { - callbacks->map_start(context, (size_t) _cbor_load_uint8(source + 1)); - } - return result; - } - case 0xB9: - /* Two bytes length map */ - { - if (_cbor_claim_bytes(2, source_size, &result)) { - callbacks->map_start(context, (size_t) _cbor_load_uint16(source + 1)); - } - return result; - } - case 0xBA: - /* Four bytes length map */ - { - if (_cbor_claim_bytes(4, source_size, &result)) { - callbacks->map_start(context, (size_t) _cbor_load_uint32(source + 1)); - } - return result; - } - case 0xBB: - /* Eight bytes length map */ - { - if (_cbor_claim_bytes(8, source_size, &result)) { - callbacks->map_start(context, (size_t) _cbor_load_uint64(source + 1)); - } - return result; - } - case 0xBC: /* Fallthrough */ - case 0xBD: /* Fallthrough */ - case 0xBE: - /* Reserved */ - { - return (struct cbor_decoder_result) {0, CBOR_DECODER_ERROR}; - } - case 0xBF: - /* Indefinite length map */ - { - callbacks->indef_map_start(context); - return result; - } - case 0xC0: - /* Text date/time - RFC 3339 tag, fallthrough */ - case 0xC1: - /* Epoch date tag, fallthrough */ - case 0xC2: - /* Positive bignum tag, fallthrough */ - case 0xC3: - /* Negative bignum tag, fallthrough */ - case 0xC4: - /* Fraction, fallthrough */ - case 0xC5: - /* Big float */ - { - callbacks->tag(context, _cbor_load_uint8(source) - 0xC0); /* 0xC0 offset */ - return result; - } - case 0xC6: /* Fallthrough */ - case 0xC7: /* Fallthrough */ - case 0xC8: /* Fallthrough */ - case 0xC9: /* Fallthrough */ - case 0xCA: /* Fallthrough */ - case 0xCB: /* Fallthrough */ - case 0xCC: /* Fallthrough */ - case 0xCD: /* Fallthrough */ - case 0xCE: /* Fallthrough */ - case 0xCF: /* Fallthrough */ - case 0xD0: /* Fallthrough */ - case 0xD1: /* Fallthrough */ - case 0xD2: /* Fallthrough */ - case 0xD3: /* Fallthrough */ - case 0xD4: /* Unassigned tag value */ - { - return (struct cbor_decoder_result) {0, CBOR_DECODER_ERROR}; - } - case 0xD5: /* Expected b64url conversion tag - fallthrough */ - case 0xD6: /* Expected b64 conversion tag - fallthrough */ - case 0xD7: /* Expected b16 conversion tag */ - { - callbacks->tag(context, _cbor_load_uint8(source) - 0xC0); /* 0xC0 offset */ - return result; - } - case 0xD8: /* 1B tag */ - { - if (_cbor_claim_bytes(1, source_size, &result)) { - callbacks->tag(context, _cbor_load_uint8(source + 1)); - } - return result; - } - case 0xD9: /* 2B tag */ - { - if (_cbor_claim_bytes(2, source_size, &result)) { - callbacks->tag(context, _cbor_load_uint16(source + 1)); - } - return result; - } - case 0xDA: /* 4B tag */ - { - if (_cbor_claim_bytes(4, source_size, &result)) { - callbacks->tag(context, _cbor_load_uint32(source + 1)); - } - return result; - } - case 0xDB: /* 8B tag */ - { - if (_cbor_claim_bytes(8, source_size, &result)) { - callbacks->tag(context, _cbor_load_uint64(source + 1)); - } - return result; - } - case 0xDC: /* Fallthrough */ - case 0xDD: /* Fallthrough */ - case 0xDE: /* Fallthrough */ - case 0xDF: /* Reserved */ - { - return (struct cbor_decoder_result) {0, CBOR_DECODER_ERROR}; - } - case 0xE0: /* Fallthrough */ - case 0xE1: /* Fallthrough */ - case 0xE2: /* Fallthrough */ - case 0xE3: /* Fallthrough */ - case 0xE4: /* Fallthrough */ - case 0xE5: /* Fallthrough */ - case 0xE6: /* Fallthrough */ - case 0xE7: /* Fallthrough */ - case 0xE8: /* Fallthrough */ - case 0xE9: /* Fallthrough */ - case 0xEA: /* Fallthrough */ - case 0xEB: /* Fallthrough */ - case 0xEC: /* Fallthrough */ - case 0xED: /* Fallthrough */ - case 0xEE: /* Fallthrough */ - case 0xEF: /* Fallthrough */ - case 0xF0: /* Fallthrough */ - case 0xF1: /* Fallthrough */ - case 0xF2: /* Fallthrough */ - case 0xF3: /* Simple value - unassigned */ - { - return (struct cbor_decoder_result) {0, CBOR_DECODER_ERROR}; - } - case 0xF4: - /* False */ - { - callbacks->boolean(context, false); - return result; - } - case 0xF5: - /* True */ - { - callbacks->boolean(context, true); - return result; - } - case 0xF6: - /* Null */ - { - callbacks->null(context); - return result; - } - case 0xF7: - /* Undefined */ - { - callbacks->undefined(context); - return result; - } - case 0xF8: - /* 1B simple value, unassigned */ - { - return (struct cbor_decoder_result) {0, CBOR_DECODER_ERROR}; - } - case 0xF9: - /* 2B float */ - { - if (_cbor_claim_bytes(2, source_size, &result)) { - callbacks->float2(context, _cbor_load_half(source + 1)); - } - return result; - } - case 0xFA: - /* 4B float */ - { - if (_cbor_claim_bytes(4, source_size, &result)) { - callbacks->float4(context, _cbor_load_float(source + 1)); - } - return result; - } - case 0xFB: - /* 8B float */ - { - if (_cbor_claim_bytes(8, source_size, &result)) { - callbacks->float8(context, _cbor_load_double(source + 1)); - } - return result; - } - case 0xFC: /* Fallthrough */ - case 0xFD: /* Fallthrough */ - case 0xFE: - /* Reserved */ - { - return (struct cbor_decoder_result) {0, CBOR_DECODER_ERROR}; - } - case 0xFF: - /* Break */ - { - callbacks->indef_break(context); - return result; - } - default: /* Never happens - this shuts up the compiler */ - { - return result; - } - } + switch (*source) { + case 0x00: /* Fallthrough */ + case 0x01: /* Fallthrough */ + case 0x02: /* Fallthrough */ + case 0x03: /* Fallthrough */ + case 0x04: /* Fallthrough */ + case 0x05: /* Fallthrough */ + case 0x06: /* Fallthrough */ + case 0x07: /* Fallthrough */ + case 0x08: /* Fallthrough */ + case 0x09: /* Fallthrough */ + case 0x0A: /* Fallthrough */ + case 0x0B: /* Fallthrough */ + case 0x0C: /* Fallthrough */ + case 0x0D: /* Fallthrough */ + case 0x0E: /* Fallthrough */ + case 0x0F: /* Fallthrough */ + case 0x10: /* Fallthrough */ + case 0x11: /* Fallthrough */ + case 0x12: /* Fallthrough */ + case 0x13: /* Fallthrough */ + case 0x14: /* Fallthrough */ + case 0x15: /* Fallthrough */ + case 0x16: /* Fallthrough */ + case 0x17: + /* Embedded one byte unsigned integer */ + { + callbacks->uint8(context, _cbor_load_uint8(source)); + return result; + } + case 0x18: + /* One byte unsigned integer */ + { + if (_cbor_claim_bytes(1, source_size, &result)) { + callbacks->uint8(context, _cbor_load_uint8(source + 1)); + } + return result; + } + case 0x19: + /* Two bytes unsigned integer */ + { + if (_cbor_claim_bytes(2, source_size, &result)) { + callbacks->uint16(context, _cbor_load_uint16(source + 1)); + } + return result; + } + case 0x1A: + /* Four bytes unsigned integer */ + { + if (_cbor_claim_bytes(4, source_size, &result)) { + callbacks->uint32(context, _cbor_load_uint32(source + 1)); + } + return result; + } + case 0x1B: + /* Eight bytes unsigned integer */ + { + if (_cbor_claim_bytes(8, source_size, &result)) { + callbacks->uint64(context, _cbor_load_uint64(source + 1)); + } + return result; + } + case 0x1C: /* Fallthrough */ + case 0x1D: /* Fallthrough */ + case 0x1E: /* Fallthrough */ + case 0x1F: + /* Reserved */ + { return (struct cbor_decoder_result){0, CBOR_DECODER_ERROR}; } + case 0x20: /* Fallthrough */ + case 0x21: /* Fallthrough */ + case 0x22: /* Fallthrough */ + case 0x23: /* Fallthrough */ + case 0x24: /* Fallthrough */ + case 0x25: /* Fallthrough */ + case 0x26: /* Fallthrough */ + case 0x27: /* Fallthrough */ + case 0x28: /* Fallthrough */ + case 0x29: /* Fallthrough */ + case 0x2A: /* Fallthrough */ + case 0x2B: /* Fallthrough */ + case 0x2C: /* Fallthrough */ + case 0x2D: /* Fallthrough */ + case 0x2E: /* Fallthrough */ + case 0x2F: /* Fallthrough */ + case 0x30: /* Fallthrough */ + case 0x31: /* Fallthrough */ + case 0x32: /* Fallthrough */ + case 0x33: /* Fallthrough */ + case 0x34: /* Fallthrough */ + case 0x35: /* Fallthrough */ + case 0x36: /* Fallthrough */ + case 0x37: + /* Embedded one byte negative integer */ + { + callbacks->negint8(context, + _cbor_load_uint8(source) - 0x20); /* 0x20 offset */ + return result; + } + case 0x38: + /* One byte negative integer */ + { + if (_cbor_claim_bytes(1, source_size, &result)) { + callbacks->negint8(context, _cbor_load_uint8(source + 1)); + } + return result; + } + case 0x39: + /* Two bytes negative integer */ + { + if (_cbor_claim_bytes(2, source_size, &result)) { + callbacks->negint16(context, _cbor_load_uint16(source + 1)); + } + return result; + } + case 0x3A: + /* Four bytes negative integer */ + { + if (_cbor_claim_bytes(4, source_size, &result)) { + callbacks->negint32(context, _cbor_load_uint32(source + 1)); + } + return result; + } + case 0x3B: + /* Eight bytes negative integer */ + { + if (_cbor_claim_bytes(8, source_size, &result)) { + callbacks->negint64(context, _cbor_load_uint64(source + 1)); + } + return result; + } + case 0x3C: /* Fallthrough */ + case 0x3D: /* Fallthrough */ + case 0x3E: /* Fallthrough */ + case 0x3F: + /* Reserved */ + { return (struct cbor_decoder_result){0, CBOR_DECODER_ERROR}; } + case 0x40: /* Fallthrough */ + case 0x41: /* Fallthrough */ + case 0x42: /* Fallthrough */ + case 0x43: /* Fallthrough */ + case 0x44: /* Fallthrough */ + case 0x45: /* Fallthrough */ + case 0x46: /* Fallthrough */ + case 0x47: /* Fallthrough */ + case 0x48: /* Fallthrough */ + case 0x49: /* Fallthrough */ + case 0x4A: /* Fallthrough */ + case 0x4B: /* Fallthrough */ + case 0x4C: /* Fallthrough */ + case 0x4D: /* Fallthrough */ + case 0x4E: /* Fallthrough */ + case 0x4F: /* Fallthrough */ + case 0x50: /* Fallthrough */ + case 0x51: /* Fallthrough */ + case 0x52: /* Fallthrough */ + case 0x53: /* Fallthrough */ + case 0x54: /* Fallthrough */ + case 0x55: /* Fallthrough */ + case 0x56: /* Fallthrough */ + case 0x57: + /* Embedded length byte string */ + { + size_t length = + (size_t)_cbor_load_uint8(source) - 0x40; /* 0x40 offset */ + if (_cbor_claim_bytes(length, source_size, &result)) { + callbacks->byte_string(context, source + 1, length); + } + return result; + } + case 0x58: + /* One byte length byte string */ + // TODO template this? + { + if (_cbor_claim_bytes(1, source_size, &result)) { + size_t length = (size_t)_cbor_load_uint8(source + 1); + if (_cbor_claim_bytes(length, source_size, &result)) { + callbacks->byte_string(context, source + 1 + 1, length); + } + } + return result; + } + case 0x59: + /* Two bytes length byte string */ + { + if (_cbor_claim_bytes(2, source_size, &result)) { + size_t length = (size_t)_cbor_load_uint16(source + 1); + if (_cbor_claim_bytes(length, source_size, &result)) { + callbacks->byte_string(context, source + 1 + 2, length); + } + } + return result; + } + case 0x5A: + /* Four bytes length byte string */ + { + if (_cbor_claim_bytes(4, source_size, &result)) { + size_t length = (size_t)_cbor_load_uint32(source + 1); + if (_cbor_claim_bytes(length, source_size, &result)) { + callbacks->byte_string(context, source + 1 + 4, length); + } + } + return result; + } + case 0x5B: + /* Eight bytes length byte string */ + { + if (_cbor_claim_bytes(8, source_size, &result)) { + size_t length = (size_t)_cbor_load_uint64(source + 1); + if (_cbor_claim_bytes(length, source_size, &result)) { + callbacks->byte_string(context, source + 1 + 8, length); + } + } + return result; + } + case 0x5C: /* Fallthrough */ + case 0x5D: /* Fallthrough */ + case 0x5E: + /* Reserved */ + { return (struct cbor_decoder_result){0, CBOR_DECODER_ERROR}; } + case 0x5F: + /* Indefinite byte string */ + { + callbacks->byte_string_start(context); + return result; + } + case 0x60: /* Fallthrough */ + case 0x61: /* Fallthrough */ + case 0x62: /* Fallthrough */ + case 0x63: /* Fallthrough */ + case 0x64: /* Fallthrough */ + case 0x65: /* Fallthrough */ + case 0x66: /* Fallthrough */ + case 0x67: /* Fallthrough */ + case 0x68: /* Fallthrough */ + case 0x69: /* Fallthrough */ + case 0x6A: /* Fallthrough */ + case 0x6B: /* Fallthrough */ + case 0x6C: /* Fallthrough */ + case 0x6D: /* Fallthrough */ + case 0x6E: /* Fallthrough */ + case 0x6F: /* Fallthrough */ + case 0x70: /* Fallthrough */ + case 0x71: /* Fallthrough */ + case 0x72: /* Fallthrough */ + case 0x73: /* Fallthrough */ + case 0x74: /* Fallthrough */ + case 0x75: /* Fallthrough */ + case 0x76: /* Fallthrough */ + case 0x77: + /* Embedded one byte length string */ + { + size_t length = + (size_t)_cbor_load_uint8(source) - 0x60; /* 0x60 offset */ + if (_cbor_claim_bytes(length, source_size, &result)) { + callbacks->string(context, source + 1, length); + } + return result; + } + case 0x78: + /* One byte length string */ + { + if (_cbor_claim_bytes(1, source_size, &result)) { + size_t length = (size_t)_cbor_load_uint8(source + 1); + if (_cbor_claim_bytes(length, source_size, &result)) { + callbacks->string(context, source + 1 + 1, length); + } + } + return result; + } + case 0x79: + /* Two bytes length string */ + { + if (_cbor_claim_bytes(2, source_size, &result)) { + size_t length = (size_t)_cbor_load_uint16(source + 1); + if (_cbor_claim_bytes(length, source_size, &result)) { + callbacks->string(context, source + 1 + 2, length); + } + } + return result; + } + case 0x7A: + /* Four bytes length string */ + { + if (_cbor_claim_bytes(4, source_size, &result)) { + size_t length = (size_t)_cbor_load_uint32(source + 1); + if (_cbor_claim_bytes(length, source_size, &result)) { + callbacks->string(context, source + 1 + 4, length); + } + } + return result; + } + case 0x7B: + /* Eight bytes length string */ + { + if (_cbor_claim_bytes(8, source_size, &result)) { + size_t length = (size_t)_cbor_load_uint64(source + 1); + if (_cbor_claim_bytes(length, source_size, &result)) { + callbacks->string(context, source + 1 + 8, length); + } + } + return result; + } + case 0x7C: /* Fallthrough */ + case 0x7D: /* Fallthrough */ + case 0x7E: + /* Reserved */ + { return (struct cbor_decoder_result){0, CBOR_DECODER_ERROR}; } + case 0x7F: + /* Indefinite length string */ + { + callbacks->string_start(context); + return result; + } + case 0x80: /* Fallthrough */ + case 0x81: /* Fallthrough */ + case 0x82: /* Fallthrough */ + case 0x83: /* Fallthrough */ + case 0x84: /* Fallthrough */ + case 0x85: /* Fallthrough */ + case 0x86: /* Fallthrough */ + case 0x87: /* Fallthrough */ + case 0x88: /* Fallthrough */ + case 0x89: /* Fallthrough */ + case 0x8A: /* Fallthrough */ + case 0x8B: /* Fallthrough */ + case 0x8C: /* Fallthrough */ + case 0x8D: /* Fallthrough */ + case 0x8E: /* Fallthrough */ + case 0x8F: /* Fallthrough */ + case 0x90: /* Fallthrough */ + case 0x91: /* Fallthrough */ + case 0x92: /* Fallthrough */ + case 0x93: /* Fallthrough */ + case 0x94: /* Fallthrough */ + case 0x95: /* Fallthrough */ + case 0x96: /* Fallthrough */ + case 0x97: + /* Embedded one byte length array */ + { + callbacks->array_start( + context, (size_t)_cbor_load_uint8(source) - 0x80); /* 0x40 offset */ + return result; + } + case 0x98: + /* One byte length array */ + { + if (_cbor_claim_bytes(1, source_size, &result)) { + callbacks->array_start(context, (size_t)_cbor_load_uint8(source + 1)); + } + return result; + } + case 0x99: + /* Two bytes length array */ + { + if (_cbor_claim_bytes(2, source_size, &result)) { + callbacks->array_start(context, + (size_t)_cbor_load_uint16(source + 1)); + } + return result; + } + case 0x9A: + /* Four bytes length array */ + { + if (_cbor_claim_bytes(4, source_size, &result)) { + callbacks->array_start(context, + (size_t)_cbor_load_uint32(source + 1)); + } + return result; + } + case 0x9B: + /* Eight bytes length array */ + { + if (_cbor_claim_bytes(8, source_size, &result)) { + callbacks->array_start(context, + (size_t)_cbor_load_uint64(source + 1)); + } + return result; + } + case 0x9C: /* Fallthrough */ + case 0x9D: /* Fallthrough */ + case 0x9E: + /* Reserved */ + { return (struct cbor_decoder_result){0, CBOR_DECODER_ERROR}; } + case 0x9F: + /* Indefinite length array */ + { + callbacks->indef_array_start(context); + return result; + } + case 0xA0: /* Fallthrough */ + case 0xA1: /* Fallthrough */ + case 0xA2: /* Fallthrough */ + case 0xA3: /* Fallthrough */ + case 0xA4: /* Fallthrough */ + case 0xA5: /* Fallthrough */ + case 0xA6: /* Fallthrough */ + case 0xA7: /* Fallthrough */ + case 0xA8: /* Fallthrough */ + case 0xA9: /* Fallthrough */ + case 0xAA: /* Fallthrough */ + case 0xAB: /* Fallthrough */ + case 0xAC: /* Fallthrough */ + case 0xAD: /* Fallthrough */ + case 0xAE: /* Fallthrough */ + case 0xAF: /* Fallthrough */ + case 0xB0: /* Fallthrough */ + case 0xB1: /* Fallthrough */ + case 0xB2: /* Fallthrough */ + case 0xB3: /* Fallthrough */ + case 0xB4: /* Fallthrough */ + case 0xB5: /* Fallthrough */ + case 0xB6: /* Fallthrough */ + case 0xB7: + /* Embedded one byte length map */ + { + callbacks->map_start( + context, (size_t)_cbor_load_uint8(source) - 0xA0); /* 0xA0 offset */ + return result; + } + case 0xB8: + /* One byte length map */ + { + if (_cbor_claim_bytes(1, source_size, &result)) { + callbacks->map_start(context, (size_t)_cbor_load_uint8(source + 1)); + } + return result; + } + case 0xB9: + /* Two bytes length map */ + { + if (_cbor_claim_bytes(2, source_size, &result)) { + callbacks->map_start(context, (size_t)_cbor_load_uint16(source + 1)); + } + return result; + } + case 0xBA: + /* Four bytes length map */ + { + if (_cbor_claim_bytes(4, source_size, &result)) { + callbacks->map_start(context, (size_t)_cbor_load_uint32(source + 1)); + } + return result; + } + case 0xBB: + /* Eight bytes length map */ + { + if (_cbor_claim_bytes(8, source_size, &result)) { + callbacks->map_start(context, (size_t)_cbor_load_uint64(source + 1)); + } + return result; + } + case 0xBC: /* Fallthrough */ + case 0xBD: /* Fallthrough */ + case 0xBE: + /* Reserved */ + { return (struct cbor_decoder_result){0, CBOR_DECODER_ERROR}; } + case 0xBF: + /* Indefinite length map */ + { + callbacks->indef_map_start(context); + return result; + } + case 0xC0: + /* Text date/time - RFC 3339 tag, fallthrough */ + case 0xC1: + /* Epoch date tag, fallthrough */ + case 0xC2: + /* Positive bignum tag, fallthrough */ + case 0xC3: + /* Negative bignum tag, fallthrough */ + case 0xC4: + /* Fraction, fallthrough */ + case 0xC5: + /* Big float */ + { + callbacks->tag(context, + _cbor_load_uint8(source) - 0xC0); /* 0xC0 offset */ + return result; + } + case 0xC6: /* Fallthrough */ + case 0xC7: /* Fallthrough */ + case 0xC8: /* Fallthrough */ + case 0xC9: /* Fallthrough */ + case 0xCA: /* Fallthrough */ + case 0xCB: /* Fallthrough */ + case 0xCC: /* Fallthrough */ + case 0xCD: /* Fallthrough */ + case 0xCE: /* Fallthrough */ + case 0xCF: /* Fallthrough */ + case 0xD0: /* Fallthrough */ + case 0xD1: /* Fallthrough */ + case 0xD2: /* Fallthrough */ + case 0xD3: /* Fallthrough */ + case 0xD4: /* Unassigned tag value */ + { + return (struct cbor_decoder_result){0, CBOR_DECODER_ERROR}; + } + case 0xD5: /* Expected b64url conversion tag - fallthrough */ + case 0xD6: /* Expected b64 conversion tag - fallthrough */ + case 0xD7: /* Expected b16 conversion tag */ + { + callbacks->tag(context, + _cbor_load_uint8(source) - 0xC0); /* 0xC0 offset */ + return result; + } + case 0xD8: /* 1B tag */ + { + if (_cbor_claim_bytes(1, source_size, &result)) { + callbacks->tag(context, _cbor_load_uint8(source + 1)); + } + return result; + } + case 0xD9: /* 2B tag */ + { + if (_cbor_claim_bytes(2, source_size, &result)) { + callbacks->tag(context, _cbor_load_uint16(source + 1)); + } + return result; + } + case 0xDA: /* 4B tag */ + { + if (_cbor_claim_bytes(4, source_size, &result)) { + callbacks->tag(context, _cbor_load_uint32(source + 1)); + } + return result; + } + case 0xDB: /* 8B tag */ + { + if (_cbor_claim_bytes(8, source_size, &result)) { + callbacks->tag(context, _cbor_load_uint64(source + 1)); + } + return result; + } + case 0xDC: /* Fallthrough */ + case 0xDD: /* Fallthrough */ + case 0xDE: /* Fallthrough */ + case 0xDF: /* Reserved */ + { + return (struct cbor_decoder_result){0, CBOR_DECODER_ERROR}; + } + case 0xE0: /* Fallthrough */ + case 0xE1: /* Fallthrough */ + case 0xE2: /* Fallthrough */ + case 0xE3: /* Fallthrough */ + case 0xE4: /* Fallthrough */ + case 0xE5: /* Fallthrough */ + case 0xE6: /* Fallthrough */ + case 0xE7: /* Fallthrough */ + case 0xE8: /* Fallthrough */ + case 0xE9: /* Fallthrough */ + case 0xEA: /* Fallthrough */ + case 0xEB: /* Fallthrough */ + case 0xEC: /* Fallthrough */ + case 0xED: /* Fallthrough */ + case 0xEE: /* Fallthrough */ + case 0xEF: /* Fallthrough */ + case 0xF0: /* Fallthrough */ + case 0xF1: /* Fallthrough */ + case 0xF2: /* Fallthrough */ + case 0xF3: /* Simple value - unassigned */ + { + return (struct cbor_decoder_result){0, CBOR_DECODER_ERROR}; + } + case 0xF4: + /* False */ + { + callbacks->boolean(context, false); + return result; + } + case 0xF5: + /* True */ + { + callbacks->boolean(context, true); + return result; + } + case 0xF6: + /* Null */ + { + callbacks->null(context); + return result; + } + case 0xF7: + /* Undefined */ + { + callbacks->undefined(context); + return result; + } + case 0xF8: + /* 1B simple value, unassigned */ + { return (struct cbor_decoder_result){0, CBOR_DECODER_ERROR}; } + case 0xF9: + /* 2B float */ + { + if (_cbor_claim_bytes(2, source_size, &result)) { + callbacks->float2(context, _cbor_load_half(source + 1)); + } + return result; + } + case 0xFA: + /* 4B float */ + { + if (_cbor_claim_bytes(4, source_size, &result)) { + callbacks->float4(context, _cbor_load_float(source + 1)); + } + return result; + } + case 0xFB: + /* 8B float */ + { + if (_cbor_claim_bytes(8, source_size, &result)) { + callbacks->float8(context, _cbor_load_double(source + 1)); + } + return result; + } + case 0xFC: /* Fallthrough */ + case 0xFD: /* Fallthrough */ + case 0xFE: + /* Reserved */ + { return (struct cbor_decoder_result){0, CBOR_DECODER_ERROR}; } + case 0xFF: + /* Break */ + { + callbacks->indef_break(context); + return result; + } + default: /* Never happens - this shuts up the compiler */ + { + return result; + } + } } - - - - - - - - - - diff --git a/lib/libcbor/src/cbor/streaming.h b/lib/libcbor/src/cbor/streaming.h index b3e3c685b91..8c153bb0019 100644 --- a/lib/libcbor/src/cbor/streaming.h +++ b/lib/libcbor/src/cbor/streaming.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014-2017 Pavel Kalvoda <me@pavelkalvoda.com> + * Copyright (c) 2014-2019 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. @@ -8,8 +8,8 @@ #ifndef LIBCBOR_STREAMING_H #define LIBCBOR_STREAMING_H -#include "cbor/common.h" #include "callbacks.h" +#include "cbor/common.h" #ifdef __cplusplus extern "C" { @@ -17,22 +17,20 @@ extern "C" { /** Stateless decoder * - * Will try parsing the \p buffer and will invoke the appropriate callback on success. - * Decodes one item at a time. No memory allocations occur. + * Will try parsing the \p buffer and will invoke the appropriate callback on + * success. Decodes one item at a time. No memory allocations occur. * * @param buffer Input buffer * @param buffer_size Length of the buffer * @param callbacks The callback bundle * @param context An arbitrary pointer to allow for maintaining context. */ -struct cbor_decoder_result cbor_stream_decode(cbor_data buffer, - size_t buffer_size, - const struct cbor_callbacks * callbacks, - void * context); - +struct cbor_decoder_result cbor_stream_decode( + cbor_data buffer, size_t buffer_size, + const struct cbor_callbacks* callbacks, void* context); #ifdef __cplusplus } #endif -#endif //LIBCBOR_STREAMING_H +#endif // LIBCBOR_STREAMING_H diff --git a/lib/libcbor/src/cbor/strings.c b/lib/libcbor/src/cbor/strings.c index 35589ac9cf7..4e201cccb12 100644 --- a/lib/libcbor/src/cbor/strings.c +++ b/lib/libcbor/src/cbor/strings.c @@ -1,133 +1,133 @@ /* - * Copyright (c) 2014-2017 Pavel Kalvoda <me@pavelkalvoda.com> + * Copyright (c) 2014-2019 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. */ -#include <string.h> #include "strings.h" +#include <string.h> #include "internal/memory_utils.h" -cbor_item_t *cbor_new_definite_string() -{ - cbor_item_t *item = _CBOR_MALLOC(sizeof(cbor_item_t)); - *item = (cbor_item_t) { - .refcount = 1, - .type = CBOR_TYPE_STRING, - .metadata = {.string_metadata = {_CBOR_METADATA_DEFINITE, 0}} - }; - return item; +cbor_item_t *cbor_new_definite_string() { + cbor_item_t *item = _CBOR_MALLOC(sizeof(cbor_item_t)); + _CBOR_NOTNULL(item); + *item = (cbor_item_t){ + .refcount = 1, + .type = CBOR_TYPE_STRING, + .metadata = {.string_metadata = {_CBOR_METADATA_DEFINITE, 0}}}; + return item; } -cbor_item_t *cbor_new_indefinite_string() -{ - cbor_item_t *item = _CBOR_MALLOC(sizeof(cbor_item_t)); - *item = (cbor_item_t) { - .refcount = 1, - .type = CBOR_TYPE_STRING, - .metadata = {.string_metadata = {.type = _CBOR_METADATA_INDEFINITE, .length = 0}}, - .data = _CBOR_MALLOC(sizeof(struct cbor_indefinite_string_data)) - }; - *((struct cbor_indefinite_string_data *) item->data) = (struct cbor_indefinite_string_data) { - .chunk_count = 0, - .chunk_capacity = 0, - .chunks = NULL, - }; - return item; +cbor_item_t *cbor_new_indefinite_string() { + cbor_item_t *item = _CBOR_MALLOC(sizeof(cbor_item_t)); + _CBOR_NOTNULL(item); + *item = (cbor_item_t){ + .refcount = 1, + .type = CBOR_TYPE_STRING, + .metadata = {.string_metadata = {.type = _CBOR_METADATA_INDEFINITE, + .length = 0}}, + .data = _CBOR_MALLOC(sizeof(struct cbor_indefinite_string_data))}; + _CBOR_DEPENDENT_NOTNULL(item, item->data); + *((struct cbor_indefinite_string_data *)item->data) = + (struct cbor_indefinite_string_data){ + .chunk_count = 0, + .chunk_capacity = 0, + .chunks = NULL, + }; + return item; } -cbor_item_t *cbor_build_string(const char *val) -{ - cbor_item_t *item = cbor_new_definite_string(); - size_t len = strlen(val); - unsigned char * handle = _CBOR_MALLOC(len); - memcpy(handle, val, len); - cbor_string_set_handle(item, handle, len); - return item; +cbor_item_t *cbor_build_string(const char *val) { + cbor_item_t *item = cbor_new_definite_string(); + _CBOR_NOTNULL(item); + size_t len = strlen(val); + unsigned char *handle = _CBOR_MALLOC(len); + _CBOR_DEPENDENT_NOTNULL(item, handle); + memcpy(handle, val, len); + cbor_string_set_handle(item, handle, len); + return item; } -cbor_item_t *cbor_build_stringn(const char *val, size_t length) -{ - cbor_item_t *item = cbor_new_definite_string(); - unsigned char * handle = _CBOR_MALLOC(length); - memcpy(handle, val, length); - cbor_string_set_handle(item, handle, length); - return item; +cbor_item_t *cbor_build_stringn(const char *val, size_t length) { + cbor_item_t *item = cbor_new_definite_string(); + _CBOR_NOTNULL(item); + unsigned char *handle = _CBOR_MALLOC(length); + _CBOR_DEPENDENT_NOTNULL(item, handle); + memcpy(handle, val, length); + cbor_string_set_handle(item, handle, length); + return item; } -void cbor_string_set_handle(cbor_item_t *item, cbor_mutable_data CBOR_RESTRICT_POINTER data, size_t length) -{ - assert(cbor_isa_string(item)); - assert(cbor_string_is_definite(item)); - item->data = data; - item->metadata.string_metadata.length = length; +void cbor_string_set_handle(cbor_item_t *item, + cbor_mutable_data CBOR_RESTRICT_POINTER data, + size_t length) { + assert(cbor_isa_string(item)); + assert(cbor_string_is_definite(item)); + item->data = data; + item->metadata.string_metadata.length = length; } -cbor_item_t **cbor_string_chunks_handle(const cbor_item_t *item) -{ - assert(cbor_isa_string(item)); - assert(cbor_string_is_indefinite(item)); - return ((struct cbor_indefinite_string_data *) item->data)->chunks; +cbor_item_t **cbor_string_chunks_handle(const cbor_item_t *item) { + assert(cbor_isa_string(item)); + assert(cbor_string_is_indefinite(item)); + return ((struct cbor_indefinite_string_data *)item->data)->chunks; } -size_t cbor_string_chunk_count(const cbor_item_t *item) -{ - assert(cbor_isa_string(item)); - assert(cbor_string_is_indefinite(item)); - return ((struct cbor_indefinite_string_data *) item->data)->chunk_count; - +size_t cbor_string_chunk_count(const cbor_item_t *item) { + assert(cbor_isa_string(item)); + assert(cbor_string_is_indefinite(item)); + return ((struct cbor_indefinite_string_data *)item->data)->chunk_count; } -bool cbor_string_add_chunk(cbor_item_t *item, cbor_item_t *chunk) -{ - assert(cbor_isa_string(item)); - assert(cbor_string_is_indefinite(item)); - struct cbor_indefinite_string_data *data = (struct cbor_indefinite_string_data *) item->data; - if (data->chunk_count == data->chunk_capacity) { - /* We need more space */ - if (!_cbor_safe_to_multiply(CBOR_BUFFER_GROWTH, data->chunk_capacity)) { - return false; - } - - data->chunk_capacity = data->chunk_capacity == 0 ? 1 : CBOR_BUFFER_GROWTH * (data->chunk_capacity); - cbor_item_t **new_chunks_data = _cbor_realloc_multiple(data->chunks, sizeof(cbor_item_t *), data->chunk_capacity); - - if (new_chunks_data == NULL) { - return false; - } - - data->chunks = new_chunks_data; - } - data->chunks[data->chunk_count++] = cbor_incref(chunk); - return true; +bool cbor_string_add_chunk(cbor_item_t *item, cbor_item_t *chunk) { + assert(cbor_isa_string(item)); + assert(cbor_string_is_indefinite(item)); + struct cbor_indefinite_string_data *data = + (struct cbor_indefinite_string_data *)item->data; + if (data->chunk_count == data->chunk_capacity) { + // TODO: Add a test for this + if (!_cbor_safe_to_multiply(CBOR_BUFFER_GROWTH, data->chunk_capacity)) { + return false; + } + + size_t new_chunk_capacity = data->chunk_capacity == 0 + ? 1 + : CBOR_BUFFER_GROWTH * (data->chunk_capacity); + cbor_item_t **new_chunks_data = _cbor_realloc_multiple( + data->chunks, sizeof(cbor_item_t *), new_chunk_capacity); + + if (new_chunks_data == NULL) { + return false; + } + + data->chunk_capacity = new_chunk_capacity; + data->chunks = new_chunks_data; + } + data->chunks[data->chunk_count++] = cbor_incref(chunk); + return true; } -size_t cbor_string_length(const cbor_item_t *item) -{ - assert(cbor_isa_string(item)); - return item->metadata.string_metadata.length; +size_t cbor_string_length(const cbor_item_t *item) { + assert(cbor_isa_string(item)); + return item->metadata.string_metadata.length; } -unsigned char *cbor_string_handle(const cbor_item_t *item) -{ - assert(cbor_isa_string(item)); - return item->data; +unsigned char *cbor_string_handle(const cbor_item_t *item) { + assert(cbor_isa_string(item)); + return item->data; } -size_t cbor_string_codepoint_count(const cbor_item_t *item) -{ - assert(cbor_isa_string(item)); - return item->metadata.string_metadata.codepoint_count; +size_t cbor_string_codepoint_count(const cbor_item_t *item) { + assert(cbor_isa_string(item)); + return item->metadata.string_metadata.codepoint_count; } -bool cbor_string_is_definite(const cbor_item_t *item) -{ - assert(cbor_isa_string(item)); - return item->metadata.string_metadata.type == _CBOR_METADATA_DEFINITE; +bool cbor_string_is_definite(const cbor_item_t *item) { + assert(cbor_isa_string(item)); + return item->metadata.string_metadata.type == _CBOR_METADATA_DEFINITE; } -bool cbor_string_is_indefinite(const cbor_item_t *item) -{ - return !cbor_string_is_definite(item); +bool cbor_string_is_indefinite(const cbor_item_t *item) { + return !cbor_string_is_definite(item); } diff --git a/lib/libcbor/src/cbor/strings.h b/lib/libcbor/src/cbor/strings.h index 2ec3de9cb20..b867afa9d88 100644 --- a/lib/libcbor/src/cbor/strings.h +++ b/lib/libcbor/src/cbor/strings.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014-2017 Pavel Kalvoda <me@pavelkalvoda.com> + * Copyright (c) 2014-2019 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. @@ -15,10 +15,10 @@ extern "C" { #endif /* -* ============================================================================ -* String manipulation -* ============================================================================ -*/ + * ============================================================================ + * String manipulation + * ============================================================================ + */ /** Returns the length of the underlying string * @@ -40,25 +40,26 @@ size_t cbor_string_codepoint_count(const cbor_item_t *item); /** Is the string definite? * - * @param item[borrow] a string + * @param item[borrow] a string * @return Is the string definite? */ bool cbor_string_is_definite(const cbor_item_t *item); /** Is the string indefinite? * - * @param item[borrow] a string + * @param item[borrow] a string * @return Is the string indefinite? */ bool cbor_string_is_indefinite(const cbor_item_t *item); /** Get the handle to the underlying string * - * Definite items only. Modifying the data is allowed. In that case, the caller takes - * responsibility for the effect on items this item might be a part of + * Definite items only. Modifying the data is allowed. In that case, the caller + * takes responsibility for the effect on items this item might be a part of * * @param item[borrow] A definite string - * @return The address of the underlying string. `NULL` if no data have been assigned yet. + * @return The address of the underlying string. `NULL` if no data have been + * assigned yet. */ cbor_mutable_data cbor_string_handle(const cbor_item_t *item); @@ -66,18 +67,23 @@ cbor_mutable_data cbor_string_handle(const cbor_item_t *item); * * * \rst - * .. warning:: Using a pointer to a stack allocated constant is a common mistake. Lifetime of the string will expire when it goes out of scope and the CBOR item will be left inconsistent. - * \endrst + * .. warning:: Using a pointer to a stack allocated constant is a common + * mistake. Lifetime of the string will expire when it goes out of scope and the + * CBOR item will be left inconsistent. \endrst * * @param item[borrow] A definite string - * @param data The memory block. The caller gives up the ownership of the block. libcbor will deallocate it when appropriate using its free function + * @param data The memory block. The caller gives up the ownership of the block. + * libcbor will deallocate it when appropriate using its free function * @param length Length of the data block */ -void cbor_string_set_handle(cbor_item_t *item, cbor_mutable_data CBOR_RESTRICT_POINTER data, size_t length); +void cbor_string_set_handle(cbor_item_t *item, + cbor_mutable_data CBOR_RESTRICT_POINTER data, + size_t length); /** Get the handle to the array of chunks - * - * Manipulations with the memory block (e.g. sorting it) are allowed, but the validity and the number of chunks must be retained. + * + * Manipulations with the memory block (e.g. sorting it) are allowed, but the + * validity and the number of chunks must be retained. * * @param item[borrow] A indefinite string * @return array of #cbor_string_chunk_count definite strings @@ -99,7 +105,8 @@ size_t cbor_string_chunk_count(const cbor_item_t *item); * * @param item[borrow] An indefinite string * @param item[incref] A definite string - * @return true on success. false on realloc failure. In that case, the refcount of `chunk` is not increased and the `item` is left intact. + * @return true on success. false on realloc failure. In that case, the refcount + * of `chunk` is not increased and the `item` is left intact. */ bool cbor_string_add_chunk(cbor_item_t *item, cbor_item_t *chunk); @@ -141,4 +148,4 @@ cbor_item_t *cbor_build_stringn(const char *val, size_t length); } #endif -#endif //LIBCBOR_STRINGS_H +#endif // LIBCBOR_STRINGS_H diff --git a/lib/libcbor/src/cbor/tags.c b/lib/libcbor/src/cbor/tags.c index 09ec05610b0..0a29e46476f 100644 --- a/lib/libcbor/src/cbor/tags.c +++ b/lib/libcbor/src/cbor/tags.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014-2017 Pavel Kalvoda <me@pavelkalvoda.com> + * Copyright (c) 2014-2019 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. @@ -7,39 +7,37 @@ #include "tags.h" -cbor_item_t *cbor_new_tag(uint64_t value) -{ - cbor_item_t *item = _CBOR_MALLOC(sizeof(cbor_item_t)); - *item = (cbor_item_t) { - .refcount = 1, - .type = CBOR_TYPE_TAG, - .metadata = {.tag_metadata = {.value = value, .tagged_item = NULL}}, - .data = NULL /* Never used */ - }; - return item; +cbor_item_t *cbor_new_tag(uint64_t value) { + cbor_item_t *item = _CBOR_MALLOC(sizeof(cbor_item_t)); + _CBOR_NOTNULL(item); + + *item = (cbor_item_t){ + .refcount = 1, + .type = CBOR_TYPE_TAG, + .metadata = {.tag_metadata = {.value = value, .tagged_item = NULL}}, + .data = NULL /* Never used */ + }; + return item; } -cbor_item_t *cbor_tag_item(const cbor_item_t *item) -{ - assert(cbor_isa_tag(item)); - return item->metadata.tag_metadata.tagged_item; +cbor_item_t *cbor_tag_item(const cbor_item_t *item) { + assert(cbor_isa_tag(item)); + return item->metadata.tag_metadata.tagged_item; } -uint64_t cbor_tag_value(const cbor_item_t *item) -{ - assert(cbor_isa_tag(item)); - return item->metadata.tag_metadata.value; +uint64_t cbor_tag_value(const cbor_item_t *item) { + assert(cbor_isa_tag(item)); + return item->metadata.tag_metadata.value; } -void cbor_tag_set_item(cbor_item_t *item, cbor_item_t *tagged_item) -{ - assert(cbor_isa_tag(item)); - cbor_incref(tagged_item); - item->metadata.tag_metadata.tagged_item = tagged_item; +void cbor_tag_set_item(cbor_item_t *item, cbor_item_t *tagged_item) { + assert(cbor_isa_tag(item)); + cbor_incref(tagged_item); + item->metadata.tag_metadata.tagged_item = tagged_item; } -cbor_item_t * cbor_build_tag(uint64_t value, cbor_item_t * item) { - cbor_item_t *res = cbor_new_tag(value); - cbor_tag_set_item(res, item); - return res; +cbor_item_t *cbor_build_tag(uint64_t value, cbor_item_t *item) { + cbor_item_t *res = cbor_new_tag(value); + cbor_tag_set_item(res, item); + return res; } diff --git a/lib/libcbor/src/cbor/tags.h b/lib/libcbor/src/cbor/tags.h index f74cb636e3f..3a805fb096c 100644 --- a/lib/libcbor/src/cbor/tags.h +++ b/lib/libcbor/src/cbor/tags.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014-2017 Pavel Kalvoda <me@pavelkalvoda.com> + * Copyright (c) 2014-2019 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. @@ -15,15 +15,16 @@ extern "C" { #endif /* -* ============================================================================ -* Tag manipulation -* ============================================================================ -*/ + * ============================================================================ + * Tag manipulation + * ============================================================================ + */ /** Create a new tag * * @param value The tag value. Please consult the tag repository - * @return **new** tag. Item reference is `NULL`. + * @return **new** tag. Item reference is `NULL`. Returns `NULL` upon + * memory allocation failure */ cbor_item_t *cbor_new_tag(uint64_t value); @@ -54,10 +55,10 @@ void cbor_tag_set_item(cbor_item_t *item, cbor_item_t *tagged_item); * @param value Tag value * @return **new** tag item */ -cbor_item_t * cbor_build_tag(uint64_t value, cbor_item_t * item); +cbor_item_t *cbor_build_tag(uint64_t value, cbor_item_t *item); #ifdef __cplusplus } #endif -#endif //LIBCBOR_TAGS_H +#endif // LIBCBOR_TAGS_H |