diff options
Diffstat (limited to 'contrib/libcbor/src/cbor')
38 files changed, 1265 insertions, 915 deletions
diff --git a/contrib/libcbor/src/cbor/arrays.c b/contrib/libcbor/src/cbor/arrays.c index c1d01afafee1..a23bbe3cd152 100644 --- a/contrib/libcbor/src/cbor/arrays.c +++ b/contrib/libcbor/src/cbor/arrays.c @@ -10,12 +10,12 @@ #include "internal/memory_utils.h" size_t cbor_array_size(const cbor_item_t *item) { - assert(cbor_isa_array(item)); + CBOR_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)); + CBOR_ASSERT(cbor_isa_array(item)); return item->metadata.array_metadata.allocated; } @@ -31,9 +31,6 @@ bool cbor_array_set(cbor_item_t *item, size_t index, cbor_item_t *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) { @@ -45,7 +42,7 @@ bool cbor_array_replace(cbor_item_t *item, size_t index, cbor_item_t *value) { } bool cbor_array_push(cbor_item_t *array, cbor_item_t *pushee) { - assert(cbor_isa_array(array)); + CBOR_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; @@ -59,7 +56,6 @@ bool cbor_array_push(cbor_item_t *array, cbor_item_t *pushee) { /* 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; } @@ -84,22 +80,22 @@ bool cbor_array_push(cbor_item_t *array, cbor_item_t *pushee) { } bool cbor_array_is_definite(const cbor_item_t *item) { - assert(cbor_isa_array(item)); + CBOR_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)); + CBOR_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)); + CBOR_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)); + 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); @@ -119,8 +115,8 @@ cbor_item_t *cbor_new_definite_array(size_t size) { return item; } -cbor_item_t *cbor_new_indefinite_array() { - cbor_item_t *item = _CBOR_MALLOC(sizeof(cbor_item_t)); +cbor_item_t *cbor_new_indefinite_array(void) { + cbor_item_t *item = _cbor_malloc(sizeof(cbor_item_t)); _CBOR_NOTNULL(item); *item = (cbor_item_t){ diff --git a/contrib/libcbor/src/cbor/arrays.h b/contrib/libcbor/src/cbor/arrays.h index 85fe51dcd8dc..db19e59d0624 100644 --- a/contrib/libcbor/src/cbor/arrays.h +++ b/contrib/libcbor/src/cbor/arrays.h @@ -17,62 +17,74 @@ extern "C" { /** Get the number of members * - * @param item[borrow] An array + * @param item An array * @return The number of members */ +_CBOR_NODISCARD CBOR_EXPORT size_t cbor_array_size(const cbor_item_t* item); /** Get the size of the allocated storage * - * @param item[borrow] An array + * @param item An array * @return The size of the allocated storage (number of items) */ +_CBOR_NODISCARD CBOR_EXPORT size_t cbor_array_allocated(const cbor_item_t* item); /** Get item by index * - * @param item[borrow] An array - * @param index The index - * @return **incref** The item, or `NULL` in case of boundary violation + * @param item An array + * @param index The index (zero-based) + * @return Reference to the item, or `NULL` in case of boundary violation. + * + * Increases the reference count of the underlying item. The returned reference + * must be released using #cbor_decref. */ +_CBOR_NODISCARD CBOR_EXPORT cbor_item_t* cbor_array_get(const cbor_item_t* item, size_t index); /** Set item by index * - * Creating arrays with holes is not possible + * If the index is out of bounds, the array is not modified and false is + * returned. Creating arrays with holes is not possible. * - * @param item[borrow] An array - * @param value[incref] The item to assign - * @param index The index, first item is 0. - * @return true on success, false on allocation failure. + * @param item An array + * @param value The item to assign + * @param index The index (zero-based) + * @return `true` on success, `false` on allocation failure. */ +_CBOR_NODISCARD CBOR_EXPORT bool cbor_array_set(cbor_item_t* item, size_t index, cbor_item_t* value); /** Replace item at an index * - * The item being replace will be #cbor_decref 'ed. + * The reference to the item being replaced will be released using #cbor_decref. * - * @param item[borrow] An array - * @param value[incref] The item to assign - * @param index The index, first item is 0. + * @param item An array + * @param value The item to assign. Its reference count will be increased by + * one. + * @param index The index (zero-based) * @return true on success, false on allocation failure. */ +_CBOR_NODISCARD CBOR_EXPORT bool cbor_array_replace(cbor_item_t* item, size_t index, cbor_item_t* value); /** Is the array definite? * - * @param item[borrow] An array + * @param item An array * @return Is the array definite? */ +_CBOR_NODISCARD CBOR_EXPORT bool cbor_array_is_definite(const cbor_item_t* item); /** Is the array indefinite? * - * @param item[borrow] An array + * @param item An array * @return Is the array indefinite? */ +_CBOR_NODISCARD CBOR_EXPORT bool cbor_array_is_indefinite(const cbor_item_t* item); /** Get the array contents @@ -80,33 +92,42 @@ CBOR_EXPORT bool cbor_array_is_indefinite(const cbor_item_t* item); * The items may be reordered and modified as long as references remain * consistent. * - * @param item[borrow] An array - * @return #cbor_array_size items + * @param item An array item + * @return An array of #cbor_item_t pointers of size #cbor_array_size. */ +_CBOR_NODISCARD CBOR_EXPORT 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 + * @return Reference to the new array item. The item's reference count is + * initialized to one. + * @return `NULL` if memory allocation fails */ +_CBOR_NODISCARD CBOR_EXPORT cbor_item_t* cbor_new_definite_array(size_t size); /** Create new indefinite array * - * @return **new** array or `NULL` upon malloc failure + * @return Reference to the new array item. The item's reference count is + * initialized to one. + * @return `NULL` if memory allocation fails */ -CBOR_EXPORT cbor_item_t* cbor_new_indefinite_array(); +_CBOR_NODISCARD +CBOR_EXPORT cbor_item_t* cbor_new_indefinite_array(void); /** Append to the end * - * For indefinite items, storage may be realloacted. For definite items, only + * For indefinite items, storage may be reallocated. 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 + * @param array An array + * @param pushee The item to push. Its reference count will be increased by + * one. + * @return `true` on success, `false` on failure */ +_CBOR_NODISCARD CBOR_EXPORT bool cbor_array_push(cbor_item_t* array, cbor_item_t* pushee); #ifdef __cplusplus diff --git a/contrib/libcbor/src/cbor/bytestrings.c b/contrib/libcbor/src/cbor/bytestrings.c index 75a737bd92ae..528937179aee 100644 --- a/contrib/libcbor/src/cbor/bytestrings.c +++ b/contrib/libcbor/src/cbor/bytestrings.c @@ -10,17 +10,17 @@ #include "internal/memory_utils.h" size_t cbor_bytestring_length(const cbor_item_t *item) { - assert(cbor_isa_bytestring(item)); + CBOR_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)); + CBOR_ASSERT(cbor_isa_bytestring(item)); return item->data; } bool cbor_bytestring_is_definite(const cbor_item_t *item) { - assert(cbor_isa_bytestring(item)); + CBOR_ASSERT(cbor_isa_bytestring(item)); return item->metadata.bytestring_metadata.type == _CBOR_METADATA_DEFINITE; } @@ -28,25 +28,26 @@ 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)); +cbor_item_t *cbor_new_definite_bytestring(void) { + 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}}}; + .metadata = {.bytestring_metadata = {.type = _CBOR_METADATA_DEFINITE, + .length = 0}}}; return item; } -cbor_item_t *cbor_new_indefinite_bytestring() { - cbor_item_t *item = _CBOR_MALLOC(sizeof(cbor_item_t)); +cbor_item_t *cbor_new_indefinite_bytestring(void) { + 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))}; + .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){ @@ -60,7 +61,7 @@ cbor_item_t *cbor_new_indefinite_bytestring() { 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); + void *content = _cbor_malloc(length); _CBOR_DEPENDENT_NOTNULL(item, content); memcpy(content, handle, length); cbor_bytestring_set_handle(item, content, length); @@ -70,31 +71,32 @@ cbor_item_t *cbor_build_bytestring(cbor_data handle, size_t 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)); + CBOR_ASSERT(cbor_isa_bytestring(item)); + CBOR_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)); + CBOR_ASSERT(cbor_isa_bytestring(item)); + CBOR_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)); + CBOR_ASSERT(cbor_isa_bytestring(item)); + CBOR_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)); + CBOR_ASSERT(cbor_isa_bytestring(item)); + CBOR_ASSERT(cbor_bytestring_is_indefinite(item)); + CBOR_ASSERT(cbor_isa_bytestring(chunk)); + CBOR_ASSERT(cbor_bytestring_is_definite(chunk)); 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; } diff --git a/contrib/libcbor/src/cbor/bytestrings.h b/contrib/libcbor/src/cbor/bytestrings.h index 71483f708e26..cacd1adf95f3 100644 --- a/contrib/libcbor/src/cbor/bytestrings.h +++ b/contrib/libcbor/src/cbor/bytestrings.h @@ -25,23 +25,26 @@ extern "C" { * * For definite byte strings only * - * @param item[borrow] a definite bytestring + * @param item a definite bytestring * @return length of the binary data. Zero if no chunk has been attached yet */ +_CBOR_NODISCARD CBOR_EXPORT size_t cbor_bytestring_length(const cbor_item_t *item); /** Is the byte string definite? * - * @param item[borrow] a byte string + * @param item a byte string * @return Is the byte string definite? */ +_CBOR_NODISCARD CBOR_EXPORT bool cbor_bytestring_is_definite(const cbor_item_t *item); /** Is the byte string indefinite? * - * @param item[borrow] a byte string + * @param item a byte string * @return Is the byte string indefinite? */ +_CBOR_NODISCARD CBOR_EXPORT bool cbor_bytestring_is_indefinite(const cbor_item_t *item); /** Get the handle to the binary data @@ -49,17 +52,20 @@ CBOR_EXPORT bool cbor_bytestring_is_indefinite(const cbor_item_t *item); * 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 + * @param item A definite byte string + * @return The address of the underlying binary data + * @return `NULL` if no data have been assigned * yet. */ +_CBOR_NODISCARD CBOR_EXPORT 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 item 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 + * libcbor will deallocate it when appropriate using the `free` implementation + * configured using #cbor_set_allocs * @param length Length of the data block */ CBOR_EXPORT void cbor_bytestring_set_handle( @@ -71,17 +77,19 @@ CBOR_EXPORT void cbor_bytestring_set_handle( * 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 + * @param item A indefinite byte string * @return array of #cbor_bytestring_chunk_count definite bytestrings */ +_CBOR_NODISCARD CBOR_EXPORT cbor_item_t **cbor_bytestring_chunks_handle( const cbor_item_t *item); /** Get the number of chunks this string consist of * - * @param item[borrow] A indefinite bytestring + * @param item A indefinite bytestring * @return The chunk count. 0 for freshly created items. */ +_CBOR_NODISCARD CBOR_EXPORT size_t cbor_bytestring_chunk_count(const cbor_item_t *item); /** Appends a chunk to the bytestring @@ -90,11 +98,13 @@ CBOR_EXPORT size_t cbor_bytestring_chunk_count(const cbor_item_t *item); * * May realloc the chunk storage. * - * @param item[borrow] An indefinite byte string - * @param item[incref] A definite byte string + * @param item An indefinite byte string + * @param chunk A definite byte string. Its reference count will be be increased + * by one. * @return true on success, false on realloc failure. In that case, the refcount * of `chunk` is not increased and the `item` is left intact. */ +_CBOR_NODISCARD CBOR_EXPORT bool cbor_bytestring_add_chunk(cbor_item_t *item, cbor_item_t *chunk); @@ -102,17 +112,23 @@ CBOR_EXPORT bool cbor_bytestring_add_chunk(cbor_item_t *item, * * The handle is initialized to `NULL` and length to 0 * - * @return **new** definite bytestring. `NULL` on malloc failure. + * @return Reference to the new bytestring item. The item's reference count is + * initialized to one. + * @return `NULL` if memory allocation fails */ -CBOR_EXPORT cbor_item_t *cbor_new_definite_bytestring(); +_CBOR_NODISCARD +CBOR_EXPORT cbor_item_t *cbor_new_definite_bytestring(void); /** Creates a new indefinite byte string * - * The chunks array is initialized to `NULL` and chunkcount to 0 + * The chunks array is initialized to `NULL` and chunk count to 0 * - * @return **new** indefinite bytestring. `NULL` on malloc failure. + * @return Reference to the new bytestring item. The item's reference count is + * initialized to one. + * @return `NULL` if memory allocation fails */ -CBOR_EXPORT cbor_item_t *cbor_new_indefinite_bytestring(); +_CBOR_NODISCARD +CBOR_EXPORT cbor_item_t *cbor_new_indefinite_bytestring(void); /** Creates a new byte string and initializes it * @@ -120,9 +136,11 @@ CBOR_EXPORT 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 Reference to the new bytestring item. The item's reference count is + * initialized to one. + * @return `NULL` if memory allocation fails */ +_CBOR_NODISCARD CBOR_EXPORT cbor_item_t *cbor_build_bytestring(cbor_data handle, size_t length); #ifdef __cplusplus diff --git a/contrib/libcbor/src/cbor/callbacks.c b/contrib/libcbor/src/cbor/callbacks.c index 3f1f547a09ef..bdf3f79eee69 100644 --- a/contrib/libcbor/src/cbor/callbacks.c +++ b/contrib/libcbor/src/cbor/callbacks.c @@ -7,110 +7,115 @@ #include "callbacks.h" -#define CBOR_DUMMY_CALLBACK \ - {} +void cbor_null_uint8_callback(void *_CBOR_UNUSED(_ctx), + uint8_t _CBOR_UNUSED(_val)) {} -void cbor_null_uint8_callback(void *_ctx, uint8_t _val) CBOR_DUMMY_CALLBACK +void cbor_null_uint16_callback(void *_CBOR_UNUSED(_ctx), + uint16_t _CBOR_UNUSED(_val)) {} - void cbor_null_uint16_callback(void *_ctx, - uint16_t _val) CBOR_DUMMY_CALLBACK +void cbor_null_uint32_callback(void *_CBOR_UNUSED(_ctx), + uint32_t _CBOR_UNUSED(_val)) {} - void cbor_null_uint32_callback(void *_ctx, - uint32_t _val) CBOR_DUMMY_CALLBACK +void cbor_null_uint64_callback(void *_CBOR_UNUSED(_ctx), + uint64_t _CBOR_UNUSED(_val)) {} - void cbor_null_uint64_callback(void *_ctx, - uint64_t _val) CBOR_DUMMY_CALLBACK +void cbor_null_negint8_callback(void *_CBOR_UNUSED(_ctx), + uint8_t _CBOR_UNUSED(_val)) {} - void cbor_null_negint8_callback(void *_ctx, - uint8_t _val) CBOR_DUMMY_CALLBACK +void cbor_null_negint16_callback(void *_CBOR_UNUSED(_ctx), + uint16_t _CBOR_UNUSED(_val)) {} - void cbor_null_negint16_callback(void *_ctx, - uint16_t _val) CBOR_DUMMY_CALLBACK +void cbor_null_negint32_callback(void *_CBOR_UNUSED(_ctx), + uint32_t _CBOR_UNUSED(_val)) {} - void cbor_null_negint32_callback(void *_ctx, - uint32_t _val) CBOR_DUMMY_CALLBACK +void cbor_null_negint64_callback(void *_CBOR_UNUSED(_ctx), + uint64_t _CBOR_UNUSED(_val)) {} - void cbor_null_negint64_callback(void *_ctx, - uint64_t _val) CBOR_DUMMY_CALLBACK +void cbor_null_string_callback(void *_CBOR_UNUSED(_ctx), + cbor_data _CBOR_UNUSED(_val), + uint64_t _CBOR_UNUSED(_val2)) {} - void cbor_null_string_callback(void *_ctx, cbor_data _val, - size_t _val2) CBOR_DUMMY_CALLBACK +void cbor_null_string_start_callback(void *_CBOR_UNUSED(_ctx)) {} - void cbor_null_string_start_callback(void *_ctx) CBOR_DUMMY_CALLBACK +void cbor_null_byte_string_callback(void *_CBOR_UNUSED(_ctx), + cbor_data _CBOR_UNUSED(_val), + uint64_t _CBOR_UNUSED(_val2)) {} - 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 *_CBOR_UNUSED(_ctx)) {} - void cbor_null_byte_string_start_callback(void *_ctx) CBOR_DUMMY_CALLBACK +void cbor_null_array_start_callback(void *_CBOR_UNUSED(_ctx), + uint64_t _CBOR_UNUSED(_val)) {} - void cbor_null_array_start_callback(void *_ctx, - size_t _val) CBOR_DUMMY_CALLBACK +void cbor_null_indef_array_start_callback(void *_CBOR_UNUSED(_ctx)) {} - void cbor_null_indef_array_start_callback(void *_ctx) CBOR_DUMMY_CALLBACK +void cbor_null_map_start_callback(void *_CBOR_UNUSED(_ctx), + uint64_t _CBOR_UNUSED(_val)) {} - void cbor_null_map_start_callback(void *_ctx, - size_t _val) CBOR_DUMMY_CALLBACK +void cbor_null_indef_map_start_callback(void *_CBOR_UNUSED(_ctx)) {} - void cbor_null_indef_map_start_callback(void *_ctx) CBOR_DUMMY_CALLBACK +void cbor_null_tag_callback(void *_CBOR_UNUSED(_ctx), + uint64_t _CBOR_UNUSED(_val)) {} - void cbor_null_tag_callback(void *_ctx, uint64_t _val) CBOR_DUMMY_CALLBACK +void cbor_null_float2_callback(void *_CBOR_UNUSED(_ctx), + float _CBOR_UNUSED(_val)) {} - void cbor_null_float2_callback(void *_ctx, float _val) CBOR_DUMMY_CALLBACK +void cbor_null_float4_callback(void *_CBOR_UNUSED(_ctx), + float _CBOR_UNUSED(_val)) {} - void cbor_null_float4_callback(void *_ctx, float _val) CBOR_DUMMY_CALLBACK +void cbor_null_float8_callback(void *_CBOR_UNUSED(_ctx), + double _CBOR_UNUSED(_val)) {} - void cbor_null_float8_callback(void *_ctx, double _val) CBOR_DUMMY_CALLBACK +void cbor_null_null_callback(void *_CBOR_UNUSED(_ctx)) {} - void cbor_null_null_callback(void *_ctx) CBOR_DUMMY_CALLBACK +void cbor_null_undefined_callback(void *_CBOR_UNUSED(_ctx)) {} - void cbor_null_undefined_callback(void *_ctx) CBOR_DUMMY_CALLBACK +void cbor_null_boolean_callback(void *_CBOR_UNUSED(_ctx), + bool _CBOR_UNUSED(_val)) {} - void cbor_null_boolean_callback(void *_ctx, bool _val) CBOR_DUMMY_CALLBACK +void cbor_null_indef_break_callback(void *_CBOR_UNUSED(_ctx)) {} - void cbor_null_indef_break_callback(void *_ctx) CBOR_DUMMY_CALLBACK +CBOR_EXPORT 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, - CBOR_EXPORT 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/contrib/libcbor/src/cbor/callbacks.h b/contrib/libcbor/src/cbor/callbacks.h index 9e5965f2d921..c7ae20568dc8 100644 --- a/contrib/libcbor/src/cbor/callbacks.h +++ b/contrib/libcbor/src/cbor/callbacks.h @@ -8,6 +8,8 @@ #ifndef LIBCBOR_CALLBACKS_H #define LIBCBOR_CALLBACKS_H +#include <stdint.h> + #include "cbor/cbor_export.h" #include "cbor/common.h" @@ -31,10 +33,10 @@ typedef void (*cbor_int64_callback)(void *, uint64_t); 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, uint64_t); /** Callback prototype */ -typedef void (*cbor_collection_callback)(void *, size_t); +typedef void (*cbor_collection_callback)(void *, uint64_t); /** Callback prototype */ typedef void (*cbor_float_callback)(void *, float); @@ -130,25 +132,25 @@ CBOR_EXPORT void cbor_null_negint32_callback(void *, uint32_t); CBOR_EXPORT void cbor_null_negint64_callback(void *, uint64_t); /** Dummy callback implementation - does nothing */ -CBOR_EXPORT void cbor_null_string_callback(void *, cbor_data, size_t); +CBOR_EXPORT void cbor_null_string_callback(void *, cbor_data, uint64_t); /** Dummy callback implementation - does nothing */ CBOR_EXPORT void cbor_null_string_start_callback(void *); /** Dummy callback implementation - does nothing */ -CBOR_EXPORT void cbor_null_byte_string_callback(void *, cbor_data, size_t); +CBOR_EXPORT void cbor_null_byte_string_callback(void *, cbor_data, uint64_t); /** Dummy callback implementation - does nothing */ CBOR_EXPORT void cbor_null_byte_string_start_callback(void *); /** Dummy callback implementation - does nothing */ -CBOR_EXPORT void cbor_null_array_start_callback(void *, size_t); +CBOR_EXPORT void cbor_null_array_start_callback(void *, uint64_t); /** Dummy callback implementation - does nothing */ CBOR_EXPORT void cbor_null_indef_array_start_callback(void *); /** Dummy callback implementation - does nothing */ -CBOR_EXPORT void cbor_null_map_start_callback(void *, size_t); +CBOR_EXPORT void cbor_null_map_start_callback(void *, uint64_t); /** Dummy callback implementation - does nothing */ CBOR_EXPORT void cbor_null_indef_map_start_callback(void *); diff --git a/contrib/libcbor/src/cbor/common.c b/contrib/libcbor/src/cbor/common.c index 7ccce38ac25b..efbd37ed79d3 100644 --- a/contrib/libcbor/src/cbor/common.c +++ b/contrib/libcbor/src/cbor/common.c @@ -15,6 +15,10 @@ #include "strings.h" #include "tags.h" +#ifdef DEBUG +bool _cbor_enable_assert = true; +#endif + bool cbor_isa_uint(const cbor_item_t *item) { return item->type == CBOR_TYPE_UINT; } @@ -78,7 +82,7 @@ cbor_item_t *cbor_incref(cbor_item_t *item) { void cbor_decref(cbor_item_t **item_ref) { cbor_item_t *item = *item_ref; - assert(item->refcount > 0); + CBOR_ASSERT(item->refcount > 0); if (--item->refcount == 0) { switch (item->type) { case CBOR_TYPE_UINT: @@ -88,29 +92,29 @@ void cbor_decref(cbor_item_t **item_ref) { { break; } case CBOR_TYPE_BYTESTRING: { if (cbor_bytestring_is_definite(item)) { - _CBOR_FREE(item->data); + _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( + _cbor_free( ((struct cbor_indefinite_string_data *)item->data)->chunks); - _CBOR_FREE(item->data); + _cbor_free(item->data); } break; } case CBOR_TYPE_STRING: { if (cbor_string_is_definite(item)) { - _CBOR_FREE(item->data); + _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( + _cbor_free( ((struct cbor_indefinite_string_data *)item->data)->chunks); - _CBOR_FREE(item->data); + _cbor_free(item->data); } break; } @@ -120,7 +124,7 @@ void cbor_decref(cbor_item_t **item_ref) { 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); + _cbor_free(item->data); break; } case CBOR_TYPE_MAP: { @@ -130,13 +134,13 @@ void cbor_decref(cbor_item_t **item_ref) { cbor_decref(&handle->key); if (handle->value != NULL) cbor_decref(&handle->value); } - _CBOR_FREE(item->data); + _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); + _cbor_free(item->data); break; } case CBOR_TYPE_FLOAT_CTRL: { @@ -144,8 +148,7 @@ void cbor_decref(cbor_item_t **item_ref) { break; } } - _CBOR_FREE(item); - // TODO + _cbor_free(item); *item_ref = NULL; } } diff --git a/contrib/libcbor/src/cbor/common.h b/contrib/libcbor/src/cbor/common.h index 1f9b79e16d9d..fddaabf3b9cf 100644 --- a/contrib/libcbor/src/cbor/common.h +++ b/contrib/libcbor/src/cbor/common.h @@ -13,6 +13,7 @@ #include <stddef.h> #include <stdint.h> #include <stdlib.h> + #include "cbor/cbor_export.h" #include "cbor/configuration.h" #include "data.h" @@ -21,7 +22,7 @@ extern "C" { /** - * C++ is not a subset of C99 -- 'restrict' qualifier is not a part of the + * C99 is not a subset of C++ -- '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. * @@ -40,9 +41,9 @@ 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_VERSION \ + _CBOR_TO_STR(CBOR_MAJOR_VERSION) \ + "." _CBOR_TO_STR(CBOR_MINOR_VERSION) "." _CBOR_TO_STR(CBOR_PATCH_VERSION) #define CBOR_HEX_VERSION \ ((CBOR_MAJOR_VERSION << 16) | (CBOR_MINOR_VERSION << 8) | CBOR_PATCH_VERSION) @@ -50,20 +51,55 @@ static const uint8_t cbor_patch_version = CBOR_PATCH_VERSION; */ #ifdef DEBUG #include <stdio.h> -#define debug_print(fmt, ...) \ +#define _cbor_debug_print(fmt, ...) \ do { \ if (DEBUG) \ fprintf(stderr, "%s:%d:%s(): " fmt, __FILE__, __LINE__, __func__, \ __VA_ARGS__); \ } while (0) +extern bool _cbor_enable_assert; +// Like `assert`, but can be dynamically disabled in tests to allow testing +// invalid behaviors. +#define CBOR_ASSERT(e) assert(!_cbor_enable_assert || (e)) +#define _CBOR_TEST_DISABLE_ASSERT(block) \ + do { \ + _cbor_enable_assert = false; \ + block _cbor_enable_assert = true; \ + } while (0) #else #define debug_print(fmt, ...) \ do { \ } while (0) +#define CBOR_ASSERT(e) +#define _CBOR_TEST_DISABLE_ASSERT(block) \ + do { \ + block \ + } while (0) #endif -#define TO_STR_(x) #x -#define TO_STR(x) TO_STR_(x) /* enables proper double expansion */ +#define _CBOR_TO_STR_(x) #x +#define _CBOR_TO_STR(x) _CBOR_TO_STR_(x) /* enables proper double expansion */ + +#ifdef __GNUC__ +#define _CBOR_UNUSED(x) __attribute__((__unused__)) x +// TODO(https://github.com/PJK/libcbor/issues/247): Prefer [[nodiscard]] if +// available +#define _CBOR_NODISCARD __attribute__((warn_unused_result)) +#elif defined(_MSC_VER) +#define _CBOR_UNUSED(x) __pragma(warning(suppress : 4100 4101)) x +#define _CBOR_NODISCARD +#else +#define _CBOR_UNUSED(x) x +#define _CBOR_NODISCARD +#endif + +typedef void *(*_cbor_malloc_t)(size_t); +typedef void *(*_cbor_realloc_t)(void *, size_t); +typedef void (*_cbor_free_t)(void *); + +CBOR_EXPORT extern _cbor_malloc_t _cbor_malloc; +CBOR_EXPORT extern _cbor_realloc_t _cbor_realloc; +CBOR_EXPORT extern _cbor_free_t _cbor_free; // Macro to short-circuit builder functions when memory allocation fails #define _CBOR_NOTNULL(cbor_item) \ @@ -77,24 +113,15 @@ static const uint8_t cbor_patch_version = CBOR_PATCH_VERSION; #define _CBOR_DEPENDENT_NOTNULL(cbor_item, pointer) \ do { \ if (pointer == NULL) { \ - _CBOR_FREE(cbor_item); \ + _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 *); - -CBOR_EXPORT extern _cbor_malloc_t _cbor_malloc; -CBOR_EXPORT extern _cbor_realloc_t _cbor_realloc; -CBOR_EXPORT extern _cbor_free_t _cbor_free; - /** Sets the memory management routines to use. * - * Only available when `CBOR_CUSTOM_ALLOC` is truthy + * By default, libcbor will use the standard library `malloc`, `realloc`, and + * `free`. * * \rst * .. warning:: This function modifies the global state and should therefore be @@ -115,18 +142,6 @@ CBOR_EXPORT 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 -#define _CBOR_FREE _cbor_free - -#else - -#define _CBOR_MALLOC malloc -#define _CBOR_REALLOC realloc -#define _CBOR_FREE free - -#endif - /* * ============================================================================ * Type manipulation @@ -135,80 +150,92 @@ CBOR_EXPORT void cbor_set_allocs(_cbor_malloc_t custom_malloc, /** Get the type of the item * - * @param item[borrow] + * @param item * @return The type */ +_CBOR_NODISCARD CBOR_EXPORT 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 */ /** Does the item have the appropriate major type? - * @param item[borrow] the item + * @param item the item * @return Is the item an #CBOR_TYPE_UINT? */ +_CBOR_NODISCARD CBOR_EXPORT bool cbor_isa_uint(const cbor_item_t *item); /** Does the item have the appropriate major type? - * @param item[borrow] the item + * @param item the item * @return Is the item a #CBOR_TYPE_NEGINT? */ +_CBOR_NODISCARD CBOR_EXPORT bool cbor_isa_negint(const cbor_item_t *item); /** Does the item have the appropriate major type? - * @param item[borrow] the item + * @param item the item * @return Is the item a #CBOR_TYPE_BYTESTRING? */ +_CBOR_NODISCARD CBOR_EXPORT bool cbor_isa_bytestring(const cbor_item_t *item); /** Does the item have the appropriate major type? - * @param item[borrow] the item + * @param item the item * @return Is the item a #CBOR_TYPE_STRING? */ +_CBOR_NODISCARD CBOR_EXPORT bool cbor_isa_string(const cbor_item_t *item); /** Does the item have the appropriate major type? - * @param item[borrow] the item + * @param item the item * @return Is the item an #CBOR_TYPE_ARRAY? */ +_CBOR_NODISCARD CBOR_EXPORT bool cbor_isa_array(const cbor_item_t *item); /** Does the item have the appropriate major type? - * @param item[borrow] the item + * @param item the item * @return Is the item a #CBOR_TYPE_MAP? */ +_CBOR_NODISCARD CBOR_EXPORT bool cbor_isa_map(const cbor_item_t *item); /** Does the item have the appropriate major type? - * @param item[borrow] the item + * @param item the item * @return Is the item a #CBOR_TYPE_TAG? */ +_CBOR_NODISCARD CBOR_EXPORT bool cbor_isa_tag(const cbor_item_t *item); /** Does the item have the appropriate major type? - * @param item[borrow] the item + * @param item the item * @return Is the item a #CBOR_TYPE_FLOAT_CTRL? */ +_CBOR_NODISCARD CBOR_EXPORT bool cbor_isa_float_ctrl(const cbor_item_t *item); /* Practical types with respect to their semantics (but not tag values) */ /** Is the item an integer, either positive or negative? - * @param item[borrow] the item + * @param item the item * @return Is the item an integer, either positive or negative? */ +_CBOR_NODISCARD CBOR_EXPORT bool cbor_is_int(const cbor_item_t *item); /** Is the item an a floating point number? - * @param item[borrow] the item + * @param item the item * @return Is the item a floating point number? */ +_CBOR_NODISCARD CBOR_EXPORT bool cbor_is_float(const cbor_item_t *item); /** Is the item an a boolean? - * @param item[borrow] the item + * @param item the item * @return Is the item a boolean? */ +_CBOR_NODISCARD CBOR_EXPORT bool cbor_is_bool(const cbor_item_t *item); /** Does this item represent `null` @@ -218,9 +245,10 @@ CBOR_EXPORT bool cbor_is_bool(const cbor_item_t *item); * null pointer will most likely result in a crash. * \endrst * - * @param item[borrow] the item + * @param item the item * @return Is the item (CBOR logical) null? */ +_CBOR_NODISCARD CBOR_EXPORT bool cbor_is_null(const cbor_item_t *item); /** Does this item represent `undefined` @@ -230,9 +258,10 @@ CBOR_EXPORT bool cbor_is_null(const cbor_item_t *item); * C. * \endrst * - * @param item[borrow] the item + * @param item the item * @return Is the item (CBOR logical) undefined? */ +_CBOR_NODISCARD CBOR_EXPORT bool cbor_is_undef(const cbor_item_t *item); /* @@ -241,42 +270,48 @@ CBOR_EXPORT bool cbor_is_undef(const cbor_item_t *item); * ============================================================================ */ -/** Increases the reference count by one +/** Increases the item's reference count by one + * + * Constant complexity; items referring to this one or items being referred to + * are not updated. * - * No dependent items are affected. + * This function can be used to extend reference counting to client code. * - * @param item[incref] item the item - * @return the input reference + * @param item Reference to an item + * @return The input \p item */ CBOR_EXPORT cbor_item_t *cbor_incref(cbor_item_t *item); -/** Decreases the reference count by one, deallocating the item if needed +/** Decreases the item's reference count by one, deallocating the item if needed * - * In case the item is deallocated, the reference count of any dependent items - * is adjusted accordingly in a recursive manner. + * In case the item is deallocated, the reference count of all items this item + * references will also be #cbor_decref 'ed recursively. * - * @param item[take] the item. Set to `NULL` if deallocated + * @param item Reference to an item. Will be set to `NULL` if deallocated */ CBOR_EXPORT void cbor_decref(cbor_item_t **item); -/** Decreases the reference count by one, deallocating the item if needed +/** Decreases the item's reference count by one, deallocating the item if needed * * Convenience wrapper for #cbor_decref when its set-to-null behavior is not * needed * - * @param item[take] the item + * @param item Reference to an item */ CBOR_EXPORT void cbor_intermediate_decref(cbor_item_t *item); -/** Get the reference count +/** Get the item's reference count * * \rst * .. warning:: This does *not* account for transitive references. * \endrst * - * @param item[borrow] the item + * @todo Add some inline examples for reference counting + * + * @param item the item * @return the reference count */ +_CBOR_NODISCARD CBOR_EXPORT size_t cbor_refcount(const cbor_item_t *item); /** Provides CPP-like move construct @@ -291,9 +326,10 @@ CBOR_EXPORT size_t cbor_refcount(const cbor_item_t *item); * count afterwards, the memory will be leaked. * \endrst * - * @param item[take] the item + * @param item Reference to an item * @return the item with reference count decreased by one */ +_CBOR_NODISCARD CBOR_EXPORT cbor_item_t *cbor_move(cbor_item_t *item); #ifdef __cplusplus diff --git a/contrib/libcbor/src/cbor/configuration.h.in b/contrib/libcbor/src/cbor/configuration.h.in index 6f65980aa8a2..0052a150489f 100644 --- a/contrib/libcbor/src/cbor/configuration.h.in +++ b/contrib/libcbor/src/cbor/configuration.h.in @@ -5,7 +5,6 @@ #define CBOR_MINOR_VERSION ${CBOR_VERSION_MINOR} #define CBOR_PATCH_VERSION ${CBOR_VERSION_PATCH} -#cmakedefine01 CBOR_CUSTOM_ALLOC #define CBOR_BUFFER_GROWTH ${CBOR_BUFFER_GROWTH} #define CBOR_MAX_STACK_SIZE ${CBOR_MAX_STACK_SIZE} #cmakedefine01 CBOR_PRETTY_PRINTER diff --git a/contrib/libcbor/src/cbor/data.h b/contrib/libcbor/src/cbor/data.h index 982e6a2c9987..a12e92f20c36 100644 --- a/contrib/libcbor/src/cbor/data.h +++ b/contrib/libcbor/src/cbor/data.h @@ -45,6 +45,8 @@ typedef enum { CBOR_ERR_NONE, CBOR_ERR_NOTENOUGHDATA, CBOR_ERR_NODATA, + // TODO: Should be "malformed" or at least "malformatted". Retained for + // backwards compatibility. CBOR_ERR_MALFORMATED, CBOR_ERR_MEMERROR /** Memory error - item allocation failed. Is it too big for your allocator? */ @@ -86,6 +88,11 @@ typedef enum { CBOR_CTRL_UNDEF = 23 } _cbor_ctrl; +// Metadata items use size_t (instead of uint64_t) because items in memory take +// up at least 1B per entry or string byte, so if size_t is narrower than +// uint64_t, we wouldn't be able to create them in the first place and can save +// some space. + /** Integers specific metadata */ struct _cbor_int_metadata { cbor_int_width width; @@ -184,7 +191,7 @@ struct cbor_indefinite_string_data { /** High-level decoding error */ struct cbor_error { - /** Aproximate position */ + /** Approximate position */ size_t position; /** Description */ cbor_error_code code; @@ -212,6 +219,8 @@ enum cbor_decoder_status { */ CBOR_DECODER_FINISHED, /** Not enough data to invoke a callback */ + // TODO: The name is inconsistent with CBOR_ERR_NOTENOUGHDATA. Retained for + // backwards compatibility. CBOR_DECODER_NEDATA, /** Bad data (reserved MTB, malformed value, etc.) */ CBOR_DECODER_ERROR diff --git a/contrib/libcbor/src/cbor/encoding.c b/contrib/libcbor/src/cbor/encoding.c index 19281520edd9..9d931d17570f 100644 --- a/contrib/libcbor/src/cbor/encoding.c +++ b/contrib/libcbor/src/cbor/encoding.c @@ -135,17 +135,23 @@ size_t cbor_encode_half(float value, unsigned char *buffer, val & 0x7FFFFFu; /* 0b0000_0000_0111_1111_1111_1111_1111_1111 */ if (exp == 0xFF) { /* Infinity or NaNs */ if (value != value) { - res = (uint16_t)0x007e00; /* Not IEEE semantics - required by CBOR - [s. 3.9] */ + // We discard information bits in half-float NaNs. This is + // not required for the core CBOR protocol (it is only a suggestion in + // Section 3.9). + // See https://github.com/PJK/libcbor/issues/215 + res = (uint16_t)0x007e00; } else { - res = (uint16_t)((val & 0x80000000u) >> 16u | 0x7C00u | - (mant ? 1u : 0u) << 15u); + // If the mantissa is non-zero, we have a NaN, but those are handled + // above. See + // https://en.wikipedia.org/wiki/Half-precision_floating-point_format + CBOR_ASSERT(mant == 0u); + res = (uint16_t)((val & 0x80000000u) >> 16u | 0x7C00u); } } else if (exp == 0x00) { /* Zeroes or subnorms */ res = (uint16_t)((val & 0x80000000u) >> 16u | mant >> 13u); } else { /* Normal numbers */ int8_t logical_exp = (int8_t)(exp - 127); - assert(logical_exp == exp - 127); + CBOR_ASSERT(logical_exp == exp - 127); // Now we know that 2^exp <= 0 logically if (logical_exp < -24) { @@ -158,7 +164,9 @@ size_t cbor_encode_half(float value, unsigned char *buffer, value is lost. This is an implementation decision that works around the absence of standard half-float in the language. */ res = (uint16_t)((val & 0x80000000u) >> 16u) | // Extract sign bit - (uint16_t)(1u << (24u + logical_exp)); + ((uint16_t)(1u << (24u + logical_exp)) + + (uint16_t)(((mant >> (-logical_exp - 2)) + 1) >> + 1)); // Round half away from zero for simplicity } else { res = (uint16_t)((val & 0x80000000u) >> 16u | ((((uint8_t)logical_exp) + 15u) << 10u) | diff --git a/contrib/libcbor/src/cbor/encoding.h b/contrib/libcbor/src/cbor/encoding.h index e4f2102b636a..bcc04f8a98e5 100644 --- a/contrib/libcbor/src/cbor/encoding.h +++ b/contrib/libcbor/src/cbor/encoding.h @@ -16,55 +16,87 @@ extern "C" { #endif /* - * ============================================================================ - * Primitives encoding - * ============================================================================ + * All cbor_encode_* methods take 2 or 3 arguments: + * - a logical `value` to encode (except for trivial items such as NULLs) + * - an output `buffer` pointer + * - a `buffer_size` specification + * + * They serialize the `value` into one or more bytes and write the bytes to the + * output `buffer` and return either the number of bytes written, or 0 if the + * `buffer_size` was too small to small to fit the serialized value (in which + * case it is not modified). */ -CBOR_EXPORT size_t cbor_encode_uint8(uint8_t, unsigned char *, size_t); +_CBOR_NODISCARD CBOR_EXPORT size_t cbor_encode_uint8(uint8_t, unsigned char *, + size_t); -CBOR_EXPORT size_t cbor_encode_uint16(uint16_t, unsigned char *, size_t); +_CBOR_NODISCARD CBOR_EXPORT size_t cbor_encode_uint16(uint16_t, unsigned char *, + size_t); -CBOR_EXPORT size_t cbor_encode_uint32(uint32_t, unsigned char *, size_t); +_CBOR_NODISCARD CBOR_EXPORT size_t cbor_encode_uint32(uint32_t, unsigned char *, + size_t); -CBOR_EXPORT size_t cbor_encode_uint64(uint64_t, unsigned char *, size_t); +_CBOR_NODISCARD CBOR_EXPORT size_t cbor_encode_uint64(uint64_t, unsigned char *, + size_t); -CBOR_EXPORT size_t cbor_encode_uint(uint64_t, unsigned char *, size_t); +_CBOR_NODISCARD CBOR_EXPORT size_t cbor_encode_uint(uint64_t, unsigned char *, + size_t); -CBOR_EXPORT size_t cbor_encode_negint8(uint8_t, unsigned char *, size_t); +_CBOR_NODISCARD CBOR_EXPORT size_t cbor_encode_negint8(uint8_t, unsigned char *, + size_t); -CBOR_EXPORT size_t cbor_encode_negint16(uint16_t, unsigned char *, size_t); +_CBOR_NODISCARD CBOR_EXPORT size_t cbor_encode_negint16(uint16_t, + unsigned char *, + size_t); -CBOR_EXPORT size_t cbor_encode_negint32(uint32_t, unsigned char *, size_t); +_CBOR_NODISCARD CBOR_EXPORT size_t cbor_encode_negint32(uint32_t, + unsigned char *, + size_t); -CBOR_EXPORT size_t cbor_encode_negint64(uint64_t, unsigned char *, size_t); +_CBOR_NODISCARD CBOR_EXPORT size_t cbor_encode_negint64(uint64_t, + unsigned char *, + size_t); -CBOR_EXPORT size_t cbor_encode_negint(uint64_t, unsigned char *, size_t); +_CBOR_NODISCARD CBOR_EXPORT size_t cbor_encode_negint(uint64_t, unsigned char *, + size_t); -CBOR_EXPORT size_t cbor_encode_bytestring_start(size_t, unsigned char *, - size_t); +_CBOR_NODISCARD CBOR_EXPORT size_t cbor_encode_bytestring_start(size_t, + unsigned char *, + size_t); -CBOR_EXPORT size_t cbor_encode_indef_bytestring_start(unsigned char *, size_t); +_CBOR_NODISCARD CBOR_EXPORT size_t +cbor_encode_indef_bytestring_start(unsigned char *, size_t); -CBOR_EXPORT size_t cbor_encode_string_start(size_t, unsigned char *, size_t); +_CBOR_NODISCARD CBOR_EXPORT size_t cbor_encode_string_start(size_t, + unsigned char *, + size_t); -CBOR_EXPORT size_t cbor_encode_indef_string_start(unsigned char *, size_t); +_CBOR_NODISCARD CBOR_EXPORT size_t +cbor_encode_indef_string_start(unsigned char *, size_t); -CBOR_EXPORT size_t cbor_encode_array_start(size_t, unsigned char *, size_t); +_CBOR_NODISCARD CBOR_EXPORT size_t cbor_encode_array_start(size_t, + unsigned char *, + size_t); -CBOR_EXPORT size_t cbor_encode_indef_array_start(unsigned char *, size_t); +_CBOR_NODISCARD CBOR_EXPORT size_t +cbor_encode_indef_array_start(unsigned char *, size_t); -CBOR_EXPORT size_t cbor_encode_map_start(size_t, unsigned char *, size_t); +_CBOR_NODISCARD CBOR_EXPORT size_t cbor_encode_map_start(size_t, + unsigned char *, + size_t); -CBOR_EXPORT size_t cbor_encode_indef_map_start(unsigned char *, size_t); +_CBOR_NODISCARD CBOR_EXPORT size_t cbor_encode_indef_map_start(unsigned char *, + size_t); -CBOR_EXPORT size_t cbor_encode_tag(uint64_t, unsigned char *, size_t); +_CBOR_NODISCARD CBOR_EXPORT size_t cbor_encode_tag(uint64_t, unsigned char *, + size_t); -CBOR_EXPORT size_t cbor_encode_bool(bool, unsigned char *, size_t); +_CBOR_NODISCARD CBOR_EXPORT size_t cbor_encode_bool(bool, unsigned char *, + size_t); -CBOR_EXPORT size_t cbor_encode_null(unsigned char *, size_t); +_CBOR_NODISCARD CBOR_EXPORT size_t cbor_encode_null(unsigned char *, size_t); -CBOR_EXPORT size_t cbor_encode_undef(unsigned char *, size_t); +_CBOR_NODISCARD CBOR_EXPORT size_t cbor_encode_undef(unsigned char *, size_t); /** Encodes a half-precision float * @@ -86,21 +118,20 @@ CBOR_EXPORT size_t cbor_encode_undef(unsigned char *, size_t); * 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 - * @param buffer_size Available space in the buffer - * @return number of bytes written */ -CBOR_EXPORT size_t cbor_encode_half(float, unsigned char *, size_t); +_CBOR_NODISCARD CBOR_EXPORT size_t cbor_encode_half(float, unsigned char *, + size_t); -CBOR_EXPORT size_t cbor_encode_single(float, unsigned char *, size_t); +_CBOR_NODISCARD CBOR_EXPORT size_t cbor_encode_single(float, unsigned char *, + size_t); -CBOR_EXPORT size_t cbor_encode_double(double, unsigned char *, size_t); +_CBOR_NODISCARD CBOR_EXPORT size_t cbor_encode_double(double, unsigned char *, + size_t); -CBOR_EXPORT size_t cbor_encode_break(unsigned char *, size_t); +_CBOR_NODISCARD CBOR_EXPORT size_t cbor_encode_break(unsigned char *, size_t); -CBOR_EXPORT size_t cbor_encode_ctrl(uint8_t, unsigned char *, size_t); +_CBOR_NODISCARD CBOR_EXPORT size_t cbor_encode_ctrl(uint8_t, unsigned char *, + size_t); #ifdef __cplusplus } diff --git a/contrib/libcbor/src/cbor/floats_ctrls.c b/contrib/libcbor/src/cbor/floats_ctrls.c index b7e5fcef8530..57bf477d4d3d 100644 --- a/contrib/libcbor/src/cbor/floats_ctrls.c +++ b/contrib/libcbor/src/cbor/floats_ctrls.c @@ -10,41 +10,42 @@ #include "assert.h" cbor_float_width cbor_float_get_width(const cbor_item_t *item) { - assert(cbor_isa_float_ctrl(item)); + CBOR_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); + CBOR_ASSERT(cbor_isa_float_ctrl(item)); + CBOR_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)); + CBOR_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); + CBOR_ASSERT(cbor_is_float(item)); + CBOR_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); + CBOR_ASSERT(cbor_is_float(item)); + CBOR_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); + CBOR_ASSERT(cbor_is_float(item)); + CBOR_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)); + CBOR_ASSERT(cbor_is_float(item)); + // cppcheck-suppress missingReturn switch (cbor_float_get_width(item)) { case CBOR_FLOAT_0: return NAN; @@ -55,46 +56,45 @@ double cbor_float_get_float(const cbor_item_t *item) { case CBOR_FLOAT_64: return cbor_float_get_float8(item); } - return NAN; /* Compiler complaints */ } bool cbor_get_bool(const cbor_item_t *item) { - assert(cbor_is_bool(item)); + CBOR_ASSERT(cbor_is_bool(item)); return item->metadata.float_ctrl_metadata.ctrl == CBOR_CTRL_TRUE; } void cbor_set_float2(cbor_item_t *item, float value) { - assert(cbor_is_float(item)); - assert(cbor_float_get_width(item) == CBOR_FLOAT_16); + CBOR_ASSERT(cbor_is_float(item)); + CBOR_ASSERT(cbor_float_get_width(item) == CBOR_FLOAT_16); *((float *)item->data) = value; } void cbor_set_float4(cbor_item_t *item, float value) { - assert(cbor_is_float(item)); - assert(cbor_float_get_width(item) == CBOR_FLOAT_32); + CBOR_ASSERT(cbor_is_float(item)); + CBOR_ASSERT(cbor_float_get_width(item) == CBOR_FLOAT_32); *((float *)item->data) = value; } void cbor_set_float8(cbor_item_t *item, double value) { - assert(cbor_is_float(item)); - assert(cbor_float_get_width(item) == CBOR_FLOAT_64); + CBOR_ASSERT(cbor_is_float(item)); + CBOR_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); + CBOR_ASSERT(cbor_isa_float_ctrl(item)); + CBOR_ASSERT(cbor_float_get_width(item) == CBOR_FLOAT_0); item->metadata.float_ctrl_metadata.ctrl = value; } void cbor_set_bool(cbor_item_t *item, bool value) { - assert(cbor_is_bool(item)); + CBOR_ASSERT(cbor_is_bool(item)); item->metadata.float_ctrl_metadata.ctrl = value ? CBOR_CTRL_TRUE : CBOR_CTRL_FALSE; } -cbor_item_t *cbor_new_ctrl() { - cbor_item_t *item = _CBOR_MALLOC(sizeof(cbor_item_t)); +cbor_item_t *cbor_new_ctrl(void) { + cbor_item_t *item = _cbor_malloc(sizeof(cbor_item_t)); _CBOR_NOTNULL(item); *item = (cbor_item_t){ @@ -106,8 +106,8 @@ cbor_item_t *cbor_new_ctrl() { return item; } -cbor_item_t *cbor_new_float2() { - cbor_item_t *item = _CBOR_MALLOC(sizeof(cbor_item_t) + 4); +cbor_item_t *cbor_new_float2(void) { + cbor_item_t *item = _cbor_malloc(sizeof(cbor_item_t) + 4); _CBOR_NOTNULL(item); *item = (cbor_item_t){ @@ -118,8 +118,8 @@ cbor_item_t *cbor_new_float2() { return item; } -cbor_item_t *cbor_new_float4() { - cbor_item_t *item = _CBOR_MALLOC(sizeof(cbor_item_t) + 4); +cbor_item_t *cbor_new_float4(void) { + cbor_item_t *item = _cbor_malloc(sizeof(cbor_item_t) + 4); _CBOR_NOTNULL(item); *item = (cbor_item_t){ @@ -130,8 +130,8 @@ cbor_item_t *cbor_new_float4() { return item; } -cbor_item_t *cbor_new_float8() { - cbor_item_t *item = _CBOR_MALLOC(sizeof(cbor_item_t) + 8); +cbor_item_t *cbor_new_float8(void) { + cbor_item_t *item = _cbor_malloc(sizeof(cbor_item_t) + 8); _CBOR_NOTNULL(item); *item = (cbor_item_t){ @@ -142,14 +142,14 @@ cbor_item_t *cbor_new_float8() { return item; } -cbor_item_t *cbor_new_null() { +cbor_item_t *cbor_new_null(void) { cbor_item_t *item = cbor_new_ctrl(); _CBOR_NOTNULL(item); cbor_set_ctrl(item, CBOR_CTRL_NULL); return item; } -cbor_item_t *cbor_new_undef() { +cbor_item_t *cbor_new_undef(void) { cbor_item_t *item = cbor_new_ctrl(); _CBOR_NOTNULL(item); cbor_set_ctrl(item, CBOR_CTRL_UNDEF); diff --git a/contrib/libcbor/src/cbor/floats_ctrls.h b/contrib/libcbor/src/cbor/floats_ctrls.h index 92eb8bc3eaa3..335eab8328be 100644 --- a/contrib/libcbor/src/cbor/floats_ctrls.h +++ b/contrib/libcbor/src/cbor/floats_ctrls.h @@ -23,111 +23,131 @@ extern "C" { /** Is this a ctrl value? * - * @param item[borrow] A float or ctrl item + * @param item A float or ctrl item * @return Is this a ctrl value? */ -CBOR_EXPORT bool cbor_float_ctrl_is_ctrl(const cbor_item_t *item); +_CBOR_NODISCARD CBOR_EXPORT bool cbor_float_ctrl_is_ctrl( + const cbor_item_t *item); /** Get the float width * - * @param item[borrow] A float or ctrl item + * @param item A float or ctrl item * @return The width. */ -CBOR_EXPORT cbor_float_width cbor_float_get_width(const cbor_item_t *item); +_CBOR_NODISCARD CBOR_EXPORT cbor_float_width +cbor_float_get_width(const cbor_item_t *item); /** Get a half precision float * * The item must have the corresponding width * - * @param[borrow] A half precision float + * @param item A half precision float * @return half precision value */ -CBOR_EXPORT float cbor_float_get_float2(const cbor_item_t *item); +_CBOR_NODISCARD CBOR_EXPORT float cbor_float_get_float2( + const cbor_item_t *item); /** Get a single precision float * * The item must have the corresponding width * - * @param[borrow] A signle precision float + * @param item A single precision float * @return single precision value */ -CBOR_EXPORT float cbor_float_get_float4(const cbor_item_t *item); +_CBOR_NODISCARD CBOR_EXPORT float cbor_float_get_float4( + const cbor_item_t *item); /** Get a double precision float * * The item must have the corresponding width * - * @param[borrow] A double precision float + * @param item A double precision float * @return double precision value */ -CBOR_EXPORT double cbor_float_get_float8(const cbor_item_t *item); +_CBOR_NODISCARD CBOR_EXPORT double cbor_float_get_float8( + const cbor_item_t *item); /** Get the float value represented as double * * Can be used regardless of the width. * - * @param[borrow] Any float + * @param item Any float * @return double precision value */ -CBOR_EXPORT double cbor_float_get_float(const cbor_item_t *item); +_CBOR_NODISCARD CBOR_EXPORT double cbor_float_get_float( + const cbor_item_t *item); /** Get value from a boolean ctrl item * - * @param item[borrow] A ctrl item + * @param item A ctrl item * @return boolean value */ -CBOR_EXPORT bool cbor_get_bool(const cbor_item_t *item); +_CBOR_NODISCARD CBOR_EXPORT bool cbor_get_bool(const cbor_item_t *item); /** Constructs a new ctrl item * * The width cannot be changed once the item is created * - * @return **new** 1B ctrl or `NULL` upon memory allocation failure + * @return Reference to the new ctrl item. The item's reference count is + * initialized to one. + * @return `NULL` if memory allocation fails */ -CBOR_EXPORT cbor_item_t *cbor_new_ctrl(); +_CBOR_NODISCARD CBOR_EXPORT cbor_item_t *cbor_new_ctrl(void); /** Constructs a new float item * * The width cannot be changed once the item is created * - * @return **new** 2B float or `NULL` upon memory allocation failure + * @return Reference to the new float item. The item's reference count is + * initialized to one. + * @return `NULL` if memory allocation fails */ -CBOR_EXPORT cbor_item_t *cbor_new_float2(); +_CBOR_NODISCARD CBOR_EXPORT cbor_item_t *cbor_new_float2(void); /** Constructs a new float item * * The width cannot be changed once the item is created * - * @return **new** 4B float or `NULL` upon memory allocation failure + * @return Reference to the new float item. The item's reference count is + * initialized to one. + * @return `NULL` if memory allocation fails */ -CBOR_EXPORT cbor_item_t *cbor_new_float4(); +_CBOR_NODISCARD CBOR_EXPORT cbor_item_t *cbor_new_float4(void); /** Constructs a new float item * * The width cannot be changed once the item is created * - * @return **new** 8B float or `NULL` upon memory allocation failure + * @return Reference to the new float item. The item's reference count is + * initialized to one. + * @return `NULL` if memory allocation fails */ -CBOR_EXPORT cbor_item_t *cbor_new_float8(); +_CBOR_NODISCARD CBOR_EXPORT cbor_item_t *cbor_new_float8(void); /** Constructs new null ctrl item * - * @return **new** null ctrl item or `NULL` upon memory allocation failure + * @return Reference to the new null item. The item's reference count is + * initialized to one. + * @return `NULL` if memory allocation fails */ -CBOR_EXPORT cbor_item_t *cbor_new_null(); +_CBOR_NODISCARD CBOR_EXPORT cbor_item_t *cbor_new_null(void); /** Constructs new undef ctrl item * - * @return **new** undef ctrl item or `NULL` upon memory allocation failure + * @return Reference to the new undef item. The item's reference count is + * initialized to one. + * @return `NULL` if memory allocation fails */ -CBOR_EXPORT cbor_item_t *cbor_new_undef(); +_CBOR_NODISCARD CBOR_EXPORT cbor_item_t *cbor_new_undef(void); /** Constructs new boolean ctrl item * * @param value The value to use - * @return **new** boolen ctrl item or `NULL` upon memory allocation failure + * @return Reference to the new boolean item. The item's reference count is + * initialized to one. + * @return `NULL` if memory allocation fails */ -CBOR_EXPORT cbor_item_t *cbor_build_bool(bool value); +_CBOR_NODISCARD CBOR_EXPORT cbor_item_t *cbor_build_bool(bool value); /** Assign a control value * @@ -136,7 +156,7 @@ CBOR_EXPORT cbor_item_t *cbor_build_bool(bool value); * invalid value using this mechanism. Please consult the standard before use. * \endrst * - * @param item[borrow] A ctrl item + * @param item A ctrl item * @param value The simple value to assign. Please consult the standard for * allowed values */ @@ -144,66 +164,74 @@ CBOR_EXPORT void cbor_set_ctrl(cbor_item_t *item, uint8_t value); /** Assign a boolean value to a boolean ctrl item * - * @param item[borrow] A ctrl item + * @param item A ctrl item * @param value The simple value to assign. */ CBOR_EXPORT void cbor_set_bool(cbor_item_t *item, bool value); /** Assigns a float value * - * @param item[borrow] A half precision float + * @param item A half precision float * @param value The value to assign */ CBOR_EXPORT void cbor_set_float2(cbor_item_t *item, float value); /** Assigns a float value * - * @param item[borrow] A single precision float + * @param item A single precision float * @param value The value to assign */ CBOR_EXPORT void cbor_set_float4(cbor_item_t *item, float value); /** Assigns a float value * - * @param item[borrow] A double precision float + * @param item A double precision float * @param value The value to assign */ CBOR_EXPORT void cbor_set_float8(cbor_item_t *item, double value); /** Reads the control value * - * @param item[borrow] A ctrl item + * @param item A ctrl item * @return the simple value */ -CBOR_EXPORT uint8_t cbor_ctrl_value(const cbor_item_t *item); +_CBOR_NODISCARD CBOR_EXPORT uint8_t cbor_ctrl_value(const cbor_item_t *item); /** Constructs a new float * * @param value the value to use - * @return **new** float + * @return Reference to the new float item. The item's reference count is + * initialized to one. + * @return `NULL` if memory allocation fails */ -CBOR_EXPORT cbor_item_t *cbor_build_float2(float value); +_CBOR_NODISCARD CBOR_EXPORT cbor_item_t *cbor_build_float2(float value); /** Constructs a new float * * @param value the value to use - * @return **new** float or `NULL` upon memory allocation failure + * @return Reference to the new float item. The item's reference count is + * initialized to one. + * @return `NULL` if memory allocation fails */ -CBOR_EXPORT cbor_item_t *cbor_build_float4(float value); +_CBOR_NODISCARD CBOR_EXPORT cbor_item_t *cbor_build_float4(float value); /** Constructs a new float * * @param value the value to use - * @return **new** float or `NULL` upon memory allocation failure + * @return Reference to the new float item. The item's reference count is + * initialized to one. + * @return `NULL` if memory allocation fails */ -CBOR_EXPORT cbor_item_t *cbor_build_float8(double value); +_CBOR_NODISCARD CBOR_EXPORT cbor_item_t *cbor_build_float8(double value); /** Constructs a ctrl item * * @param value the value to use - * @return **new** ctrl item or `NULL` upon memory allocation failure + * @return Reference to the new ctrl item. The item's reference count is + * initialized to one. + * @return `NULL` if memory allocation fails */ -CBOR_EXPORT cbor_item_t *cbor_build_ctrl(uint8_t value); +_CBOR_NODISCARD CBOR_EXPORT cbor_item_t *cbor_build_ctrl(uint8_t value); #ifdef __cplusplus } diff --git a/contrib/libcbor/src/cbor/internal/builder_callbacks.c b/contrib/libcbor/src/cbor/internal/builder_callbacks.c index f6c571136162..78277f050c2b 100644 --- a/contrib/libcbor/src/cbor/internal/builder_callbacks.c +++ b/contrib/libcbor/src/cbor/internal/builder_callbacks.c @@ -6,9 +6,12 @@ */ #include "builder_callbacks.h" + #include <string.h> + #include "../arrays.h" #include "../bytestrings.h" +#include "../common.h" #include "../floats_ctrls.h" #include "../ints.h" #include "../maps.h" @@ -16,73 +19,96 @@ #include "../tags.h" #include "unicode.h" +// `_cbor_builder_append` takes ownership of `item`. If adding the item to +// parent container fails, `item` will be deallocated to prevent memory. 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); + return; + } + /* Part of a bigger structure */ + switch (ctx->stack->top->item->type) { + // Handle Arrays and Maps since they can contain subitems of any type. + // Byte/string construction from chunks is handled in the respective chunk + // handlers. + 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. + CBOR_ASSERT(ctx->stack->top->subitems > 0); + // This should never happen since the definite array should be + // preallocated for the expected number of items. + if (!cbor_array_push(ctx->stack->top->item, item)) { + ctx->creation_failed = true; cbor_decref(&item); + break; } - 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)); + cbor_decref(&item); + ctx->stack->top->subitems--; + if (ctx->stack->top->subitems == 0) { + cbor_item_t *stack_item = ctx->stack->top->item; + _cbor_stack_pop(ctx->stack); + _cbor_builder_append(stack_item, ctx); } - 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 */ + } else { + /* Indefinite array, don't bother with subitems */ + if (!cbor_array_push(ctx->stack->top->item, item)) { + ctx->creation_failed = true; } - break; + cbor_decref(&item); } - 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; + break; + } + case CBOR_TYPE_MAP: { + // Handle both definite and indefinite maps the same initially. + // Note: 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 */ + if (!_cbor_map_add_value(ctx->stack->top->item, item)) { + ctx->creation_failed = true; + cbor_decref(&item); + break; + } + } else { + /* Even record, this is a key */ + if (!_cbor_map_add_key(ctx->stack->top->item, item)) { + ctx->creation_failed = true; + cbor_decref(&item); + break; + } } - default: { - cbor_decref(&item); - ctx->syntax_error = true; + cbor_decref(&item); + if (cbor_map_is_definite(ctx->stack->top->item)) { + CBOR_ASSERT(ctx->stack->top->subitems > 0); + ctx->stack->top->subitems--; + if (ctx->stack->top->subitems == 0) { + cbor_item_t *map_entry = ctx->stack->top->item; + _cbor_stack_pop(ctx->stack); + _cbor_builder_append(map_entry, ctx); + } + } else { + ctx->stack->top->subitems ^= + 1; /* Flip the indicator for indefinite items */ } + break; + } + case CBOR_TYPE_TAG: { + CBOR_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 *tagged_item = ctx->stack->top->item; + _cbor_stack_pop(ctx->stack); + _cbor_builder_append(tagged_item, ctx); + break; + } + // We have an item to append but nothing to append it to. + default: { + cbor_decref(&item); + ctx->syntax_error = true; } } } @@ -95,6 +121,16 @@ void _cbor_builder_append(cbor_item_t *item, } \ } while (0) +// Check that the length fits into size_t. If not, we cannot possibly allocate +// the required memory and should fail fast. +#define CHECK_LENGTH(ctx, length) \ + do { \ + if (length > SIZE_MAX) { \ + ctx->creation_failed = true; \ + return; \ + } \ + } while (0) + #define PUSH_CTX_STACK(ctx, res, subitems) \ do { \ if (_cbor_stack_push(ctx->stack, res, subitems) == NULL) { \ @@ -151,6 +187,7 @@ void cbor_builder_negint8_callback(void *context, uint8_t value) { void cbor_builder_negint16_callback(void *context, uint16_t value) { struct _cbor_decoder_context *ctx = context; cbor_item_t *res = cbor_new_int16(); + CHECK_RES(ctx, res); cbor_mark_negint(res); cbor_set_uint16(res, value); _cbor_builder_append(res, ctx); @@ -175,34 +212,36 @@ void cbor_builder_negint64_callback(void *context, uint64_t value) { } void cbor_builder_byte_string_callback(void *context, cbor_data data, - size_t length) { + uint64_t length) { struct _cbor_decoder_context *ctx = context; - unsigned char *new_handle = _CBOR_MALLOC(length); + CHECK_LENGTH(ctx, length); + 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(); + cbor_item_t *new_chunk = cbor_new_definite_bytestring(); - if (res == NULL) { - _CBOR_FREE(new_handle); + if (new_chunk == NULL) { + _cbor_free(new_handle); ctx->creation_failed = true; return; } - cbor_bytestring_set_handle(res, new_handle, length); + cbor_bytestring_set_handle(new_chunk, 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; + // If an indef bytestring is on the stack, extend it (if it were closed, it + // would have been popped). Handle any syntax errors upstream. + if (ctx->stack->size > 0 && cbor_isa_bytestring(ctx->stack->top->item) && + cbor_bytestring_is_indefinite(ctx->stack->top->item)) { + if (!cbor_bytestring_add_chunk(ctx->stack->top->item, new_chunk)) { + ctx->creation_failed = true; } + cbor_decref(&new_chunk); } else { - _cbor_builder_append(res, ctx); + _cbor_builder_append(new_chunk, ctx); } } @@ -214,19 +253,20 @@ void cbor_builder_byte_string_start_callback(void *context) { } void cbor_builder_string_callback(void *context, cbor_data data, - size_t length) { + uint64_t length) { struct _cbor_decoder_context *ctx = context; + CHECK_LENGTH(ctx, length); struct _cbor_unicode_status unicode_status; - - size_t codepoint_count = + uint64_t codepoint_count = _cbor_unicode_codepoint_count(data, length, &unicode_status); - if (unicode_status.status == _CBOR_UNICODE_BADCP) { + if (unicode_status.status != _CBOR_UNICODE_OK) { ctx->syntax_error = true; return; } + CBOR_ASSERT(codepoint_count <= length); - unsigned char *new_handle = _CBOR_MALLOC(length); + unsigned char *new_handle = _cbor_malloc(length); if (new_handle == NULL) { ctx->creation_failed = true; @@ -234,25 +274,25 @@ void cbor_builder_string_callback(void *context, cbor_data data, } memcpy(new_handle, data, length); - cbor_item_t *res = cbor_new_definite_string(); - if (res == NULL) { - _CBOR_FREE(new_handle); + cbor_item_t *new_chunk = cbor_new_definite_string(); + if (new_chunk == NULL) { + _cbor_free(new_handle); ctx->creation_failed = true; return; } - 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; + cbor_string_set_handle(new_chunk, new_handle, length); + new_chunk->metadata.string_metadata.codepoint_count = codepoint_count; + + // If an indef string is on the stack, extend it (if it were closed, it would + // have been popped). Handle any syntax errors upstream. + if (ctx->stack->size > 0 && cbor_isa_string(ctx->stack->top->item) && + cbor_string_is_indefinite(ctx->stack->top->item)) { + if (!cbor_string_add_chunk(ctx->stack->top->item, new_chunk)) { + ctx->creation_failed = true; } + cbor_decref(&new_chunk); } else { - _cbor_builder_append(res, ctx); + _cbor_builder_append(new_chunk, ctx); } } @@ -263,8 +303,9 @@ void cbor_builder_string_start_callback(void *context) { PUSH_CTX_STACK(ctx, res, 0); } -void cbor_builder_array_start_callback(void *context, size_t size) { +void cbor_builder_array_start_callback(void *context, uint64_t size) { struct _cbor_decoder_context *ctx = context; + CHECK_LENGTH(ctx, size); cbor_item_t *res = cbor_new_definite_array(size); CHECK_RES(ctx, res); if (size > 0) { @@ -288,8 +329,9 @@ void cbor_builder_indef_map_start_callback(void *context) { PUSH_CTX_STACK(ctx, res, 0); } -void cbor_builder_map_start_callback(void *context, size_t size) { +void cbor_builder_map_start_callback(void *context, uint64_t size) { struct _cbor_decoder_context *ctx = context; + CHECK_LENGTH(ctx, size); cbor_item_t *res = cbor_new_definite_map(size); CHECK_RES(ctx, res); if (size > 0) { @@ -305,14 +347,13 @@ void cbor_builder_map_start_callback(void *context, size_t size) { bool _cbor_is_indefinite(cbor_item_t *item) { switch (item->type) { case CBOR_TYPE_BYTESTRING: - return item->metadata.bytestring_metadata.type == - _CBOR_METADATA_INDEFINITE; + return cbor_bytestring_is_indefinite(item); case CBOR_TYPE_STRING: - return item->metadata.string_metadata.type == _CBOR_METADATA_INDEFINITE; + return cbor_string_is_indefinite(item); case CBOR_TYPE_ARRAY: - return item->metadata.array_metadata.type == _CBOR_METADATA_INDEFINITE; + return cbor_array_is_indefinite(item); case CBOR_TYPE_MAP: - return item->metadata.map_metadata.type == _CBOR_METADATA_INDEFINITE; + return cbor_map_is_indefinite(item); default: return false; } @@ -340,6 +381,7 @@ void cbor_builder_indef_break_callback(void *context) { void cbor_builder_float2_callback(void *context, float value) { struct _cbor_decoder_context *ctx = context; cbor_item_t *res = cbor_new_float2(); + CHECK_RES(ctx, res); cbor_set_float2(res, value); _cbor_builder_append(res, ctx); } diff --git a/contrib/libcbor/src/cbor/internal/builder_callbacks.h b/contrib/libcbor/src/cbor/internal/builder_callbacks.h index a93afb1ca8f8..7893960e4131 100644 --- a/contrib/libcbor/src/cbor/internal/builder_callbacks.h +++ b/contrib/libcbor/src/cbor/internal/builder_callbacks.h @@ -26,6 +26,10 @@ struct _cbor_decoder_context { struct _cbor_stack *stack; }; +/** Internal helper: Append item to the top of the stack while handling errors. + */ +void _cbor_builder_append(cbor_item_t *item, struct _cbor_decoder_context *ctx); + void cbor_builder_uint8_callback(void *, uint8_t); void cbor_builder_uint16_callback(void *, uint16_t); @@ -42,19 +46,19 @@ void cbor_builder_negint32_callback(void *, uint32_t); void cbor_builder_negint64_callback(void *, uint64_t); -void cbor_builder_string_callback(void *, cbor_data, size_t); +void cbor_builder_string_callback(void *, cbor_data, uint64_t); void cbor_builder_string_start_callback(void *); -void cbor_builder_byte_string_callback(void *, cbor_data, size_t); +void cbor_builder_byte_string_callback(void *, cbor_data, uint64_t); void cbor_builder_byte_string_start_callback(void *); -void cbor_builder_array_start_callback(void *, size_t); +void cbor_builder_array_start_callback(void *, uint64_t); void cbor_builder_indef_array_start_callback(void *); -void cbor_builder_map_start_callback(void *, size_t); +void cbor_builder_map_start_callback(void *, uint64_t); void cbor_builder_indef_map_start_callback(void *); diff --git a/contrib/libcbor/src/cbor/internal/encoders.c b/contrib/libcbor/src/cbor/internal/encoders.c index 657e25c3987a..49d4d7f33d2b 100644 --- a/contrib/libcbor/src/cbor/internal/encoders.c +++ b/contrib/libcbor/src/cbor/internal/encoders.c @@ -33,8 +33,8 @@ size_t _cbor_encode_uint16(uint16_t value, unsigned char *buffer, #ifdef IS_BIG_ENDIAN memcpy(buffer + 1, &value, 2); #else - buffer[1] = value >> 8; - buffer[2] = value; + buffer[1] = (unsigned char)(value >> 8); + buffer[2] = (unsigned char)value; #endif return 3; @@ -50,10 +50,10 @@ size_t _cbor_encode_uint32(uint32_t value, unsigned char *buffer, #ifdef IS_BIG_ENDIAN memcpy(buffer + 1, &value, 4); #else - buffer[1] = value >> 24; - buffer[2] = value >> 16; - buffer[3] = value >> 8; - buffer[4] = value; + buffer[1] = (unsigned char)(value >> 24); + buffer[2] = (unsigned char)(value >> 16); + buffer[3] = (unsigned char)(value >> 8); + buffer[4] = (unsigned char)value; #endif return 5; @@ -69,14 +69,14 @@ size_t _cbor_encode_uint64(uint64_t value, unsigned char *buffer, #ifdef IS_BIG_ENDIAN memcpy(buffer + 1, &value, 8); #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; + buffer[1] = (unsigned char)(value >> 56); + buffer[2] = (unsigned char)(value >> 48); + buffer[3] = (unsigned char)(value >> 40); + buffer[4] = (unsigned char)(value >> 32); + buffer[5] = (unsigned char)(value >> 24); + buffer[6] = (unsigned char)(value >> 16); + buffer[7] = (unsigned char)(value >> 8); + buffer[8] = (unsigned char)value; #endif return 9; diff --git a/contrib/libcbor/src/cbor/internal/encoders.h b/contrib/libcbor/src/cbor/internal/encoders.h index 14ad5015cb5a..7eadb7121646 100644 --- a/contrib/libcbor/src/cbor/internal/encoders.h +++ b/contrib/libcbor/src/cbor/internal/encoders.h @@ -14,18 +14,23 @@ extern "C" { #endif +_CBOR_NODISCARD size_t _cbor_encode_uint8(uint8_t value, unsigned char *buffer, size_t buffer_size, uint8_t offset); +_CBOR_NODISCARD size_t _cbor_encode_uint16(uint16_t value, unsigned char *buffer, size_t buffer_size, uint8_t offset); +_CBOR_NODISCARD size_t _cbor_encode_uint32(uint32_t value, unsigned char *buffer, size_t buffer_size, uint8_t offset); +_CBOR_NODISCARD size_t _cbor_encode_uint64(uint64_t value, unsigned char *buffer, size_t buffer_size, uint8_t offset); +_CBOR_NODISCARD size_t _cbor_encode_uint(uint64_t value, unsigned char *buffer, size_t buffer_size, uint8_t offset); diff --git a/contrib/libcbor/src/cbor/internal/loaders.c b/contrib/libcbor/src/cbor/internal/loaders.c index af00f135527f..c25c63358318 100644 --- a/contrib/libcbor/src/cbor/internal/loaders.c +++ b/contrib/libcbor/src/cbor/internal/loaders.c @@ -64,7 +64,7 @@ float _cbor_decode_half(unsigned char *halfp) { return (float)(half & 0x8000 ? -val : val); } -double _cbor_load_half(cbor_data source) { +float _cbor_load_half(cbor_data source) { /* Discard const */ return _cbor_decode_half((unsigned char *)source); } diff --git a/contrib/libcbor/src/cbor/internal/loaders.h b/contrib/libcbor/src/cbor/internal/loaders.h index a4c82b209f55..ce37563a3d80 100644 --- a/contrib/libcbor/src/cbor/internal/loaders.h +++ b/contrib/libcbor/src/cbor/internal/loaders.h @@ -15,18 +15,25 @@ extern "C" { #endif /* Read the given uint from the given location, no questions asked */ +_CBOR_NODISCARD uint8_t _cbor_load_uint8(const unsigned char *source); +_CBOR_NODISCARD uint16_t _cbor_load_uint16(const unsigned char *source); +_CBOR_NODISCARD uint32_t _cbor_load_uint32(const unsigned char *source); +_CBOR_NODISCARD uint64_t _cbor_load_uint64(const unsigned char *source); -double _cbor_load_half(cbor_data source); +_CBOR_NODISCARD +float _cbor_load_half(cbor_data source); +_CBOR_NODISCARD float _cbor_load_float(cbor_data source); +_CBOR_NODISCARD double _cbor_load_double(cbor_data source); #ifdef __cplusplus diff --git a/contrib/libcbor/src/cbor/internal/memory_utils.c b/contrib/libcbor/src/cbor/internal/memory_utils.c index 918b708e3313..bbea63cb9f06 100644 --- a/contrib/libcbor/src/cbor/internal/memory_utils.c +++ b/contrib/libcbor/src/cbor/internal/memory_utils.c @@ -23,12 +23,25 @@ size_t _cbor_highest_bit(size_t number) { } bool _cbor_safe_to_multiply(size_t a, size_t b) { + if (a <= 1 || b <= 1) return true; return _cbor_highest_bit(a) + _cbor_highest_bit(b) <= sizeof(size_t) * 8; } +bool _cbor_safe_to_add(size_t a, size_t b) { + // Unsigned integer overflow doesn't constitute UB + size_t sum = a + b; + return sum >= a && sum >= b; +} + +size_t _cbor_safe_signaling_add(size_t a, size_t b) { + if (a == 0 || b == 0) return 0; + if (_cbor_safe_to_add(a, b)) return a + b; + return 0; +} + 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); + return _cbor_malloc(item_size * item_count); } else { return NULL; } @@ -37,7 +50,7 @@ void* _cbor_alloc_multiple(size_t item_size, size_t item_count) { 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); + return _cbor_realloc(pointer, item_size * item_count); } else { return NULL; } diff --git a/contrib/libcbor/src/cbor/internal/memory_utils.h b/contrib/libcbor/src/cbor/internal/memory_utils.h index c41ace67948f..14843c8c56f6 100644 --- a/contrib/libcbor/src/cbor/internal/memory_utils.h +++ b/contrib/libcbor/src/cbor/internal/memory_utils.h @@ -11,9 +11,20 @@ #include <stdbool.h> #include <string.h> -/** Can a and b be multiplied without overflowing size_t? */ +#include "cbor/common.h" + +/** Can `a` and `b` be multiplied without overflowing size_t? */ +_CBOR_NODISCARD bool _cbor_safe_to_multiply(size_t a, size_t b); +/** Can `a` and `b` be added without overflowing size_t? */ +_CBOR_NODISCARD +bool _cbor_safe_to_add(size_t a, size_t b); + +/** Adds `a` and `b`, propagating zeros and returing 0 on overflow. */ +_CBOR_NODISCARD +size_t _cbor_safe_signaling_add(size_t a, size_t b); + /** Overflow-proof contiguous array allocation * * @param item_size diff --git a/contrib/libcbor/src/cbor/internal/stack.c b/contrib/libcbor/src/cbor/internal/stack.c index 79c9e5e5297e..2db03cbbf081 100644 --- a/contrib/libcbor/src/cbor/internal/stack.c +++ b/contrib/libcbor/src/cbor/internal/stack.c @@ -7,14 +7,14 @@ #include "stack.h" -struct _cbor_stack _cbor_stack_init() { +struct _cbor_stack _cbor_stack_init(void) { 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); + _cbor_free(top); stack->size--; } @@ -23,7 +23,7 @@ struct _cbor_stack_record *_cbor_stack_push(struct _cbor_stack *stack, size_t subitems) { if (stack->size == CBOR_MAX_STACK_SIZE) return NULL; struct _cbor_stack_record *new_top = - _CBOR_MALLOC(sizeof(struct _cbor_stack_record)); + _cbor_malloc(sizeof(struct _cbor_stack_record)); if (new_top == NULL) return NULL; *new_top = (struct _cbor_stack_record){stack->top, item, subitems}; diff --git a/contrib/libcbor/src/cbor/internal/stack.h b/contrib/libcbor/src/cbor/internal/stack.h index 42ed04429c7e..cf2206b40e58 100644 --- a/contrib/libcbor/src/cbor/internal/stack.h +++ b/contrib/libcbor/src/cbor/internal/stack.h @@ -16,8 +16,18 @@ extern "C" { /** Simple stack record for the parser */ struct _cbor_stack_record { + /** Pointer to the parent stack frame */ struct _cbor_stack_record *lower; + /** Item under construction */ cbor_item_t *item; + /** + * How many outstanding subitems are expected. + * + * For example, when we see a new definite array, `subitems` is initialized to + * the array length. With every item added, the counter is decreased. When it + * reaches zero, the stack is popped and the complete item is propagated + * upwards. + */ size_t subitems; }; @@ -27,10 +37,12 @@ struct _cbor_stack { size_t size; }; -struct _cbor_stack _cbor_stack_init(); +_CBOR_NODISCARD +struct _cbor_stack _cbor_stack_init(void); void _cbor_stack_pop(struct _cbor_stack *); +_CBOR_NODISCARD struct _cbor_stack_record *_cbor_stack_push(struct _cbor_stack *, cbor_item_t *, size_t); diff --git a/contrib/libcbor/src/cbor/internal/unicode.c b/contrib/libcbor/src/cbor/internal/unicode.c index 98b49728989e..1831c8e62057 100644 --- a/contrib/libcbor/src/cbor/internal/unicode.c +++ b/contrib/libcbor/src/cbor/internal/unicode.c @@ -6,6 +6,7 @@ */ #include "unicode.h" +#include <stdint.h> #define UTF8_ACCEPT 0 #define UTF8_REJECT 1 @@ -65,12 +66,12 @@ uint32_t _cbor_unicode_decode(uint32_t* state, uint32_t* codep, uint32_t byte) { return *state; } -size_t _cbor_unicode_codepoint_count(cbor_data source, size_t source_length, - struct _cbor_unicode_status* status) { +uint64_t _cbor_unicode_codepoint_count(cbor_data source, uint64_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; + uint64_t pos = 0, count = 0; for (; pos < source_length; pos++) { res = _cbor_unicode_decode(&state, &codepoint, source[pos]); @@ -90,5 +91,5 @@ size_t _cbor_unicode_codepoint_count(cbor_data source, size_t source_length, error: *status = (struct _cbor_unicode_status){.location = pos, .status = _CBOR_UNICODE_BADCP}; - return -1; + return 0; } diff --git a/contrib/libcbor/src/cbor/internal/unicode.h b/contrib/libcbor/src/cbor/internal/unicode.h index 5f6456029306..af32cc7ff027 100644 --- a/contrib/libcbor/src/cbor/internal/unicode.h +++ b/contrib/libcbor/src/cbor/internal/unicode.h @@ -19,11 +19,12 @@ 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; + uint64_t location; }; -size_t _cbor_unicode_codepoint_count(cbor_data source, size_t source_length, - struct _cbor_unicode_status* status); +_CBOR_NODISCARD +uint64_t _cbor_unicode_codepoint_count(cbor_data source, uint64_t source_length, + struct _cbor_unicode_status* status); #ifdef __cplusplus } diff --git a/contrib/libcbor/src/cbor/ints.c b/contrib/libcbor/src/cbor/ints.c index 880982e5a3e5..b4d035a1897e 100644 --- a/contrib/libcbor/src/cbor/ints.c +++ b/contrib/libcbor/src/cbor/ints.c @@ -8,36 +8,37 @@ #include "ints.h" cbor_int_width cbor_int_get_width(const cbor_item_t *item) { - assert(cbor_is_int(item)); + CBOR_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); + CBOR_ASSERT(cbor_is_int(item)); + CBOR_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); + CBOR_ASSERT(cbor_is_int(item)); + CBOR_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); + CBOR_ASSERT(cbor_is_int(item)); + CBOR_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); + CBOR_ASSERT(cbor_is_int(item)); + CBOR_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)); + CBOR_ASSERT(cbor_is_int(item)); + // cppcheck-suppress missingReturn switch (cbor_int_get_width(item)) { case CBOR_INT_8: return cbor_get_uint8(item); @@ -48,46 +49,44 @@ uint64_t cbor_get_int(const cbor_item_t *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); + CBOR_ASSERT(cbor_is_int(item)); + CBOR_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); + CBOR_ASSERT(cbor_is_int(item)); + CBOR_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); + CBOR_ASSERT(cbor_is_int(item)); + CBOR_ASSERT(cbor_int_get_width(item) == CBOR_INT_32); *(uint32_t *)item->data = value; } 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); + CBOR_ASSERT(cbor_is_int(item)); + CBOR_ASSERT(cbor_int_get_width(item) == CBOR_INT_64); *(uint64_t *)item->data = value; } void cbor_mark_uint(cbor_item_t *item) { - assert(cbor_is_int(item)); + CBOR_ASSERT(cbor_is_int(item)); item->type = CBOR_TYPE_UINT; } void cbor_mark_negint(cbor_item_t *item) { - assert(cbor_is_int(item)); + CBOR_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_item_t *cbor_new_int8(void) { + 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, @@ -96,8 +95,8 @@ cbor_item_t *cbor_new_int8() { return item; } -cbor_item_t *cbor_new_int16() { - cbor_item_t *item = _CBOR_MALLOC(sizeof(cbor_item_t) + 2); +cbor_item_t *cbor_new_int16(void) { + 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, @@ -106,8 +105,8 @@ cbor_item_t *cbor_new_int16() { return item; } -cbor_item_t *cbor_new_int32() { - cbor_item_t *item = _CBOR_MALLOC(sizeof(cbor_item_t) + 4); +cbor_item_t *cbor_new_int32(void) { + 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, @@ -116,8 +115,8 @@ cbor_item_t *cbor_new_int32() { return item; } -cbor_item_t *cbor_new_int64() { - cbor_item_t *item = _CBOR_MALLOC(sizeof(cbor_item_t) + 8); +cbor_item_t *cbor_new_int64(void) { + 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, diff --git a/contrib/libcbor/src/cbor/ints.h b/contrib/libcbor/src/cbor/ints.h index fc7de600102e..006aa428e0a5 100644 --- a/contrib/libcbor/src/cbor/ints.h +++ b/contrib/libcbor/src/cbor/ints.h @@ -23,42 +23,42 @@ extern "C" { /** Extracts the integer value * - * @param item[borrow] positive or negative integer + * @param item positive or negative integer * @return the value */ -CBOR_EXPORT uint8_t cbor_get_uint8(const cbor_item_t *item); +_CBOR_NODISCARD CBOR_EXPORT uint8_t cbor_get_uint8(const cbor_item_t *item); /** Extracts the integer value * - * @param item[borrow] positive or negative integer + * @param item positive or negative integer * @return the value */ -CBOR_EXPORT uint16_t cbor_get_uint16(const cbor_item_t *item); +_CBOR_NODISCARD CBOR_EXPORT uint16_t cbor_get_uint16(const cbor_item_t *item); /** Extracts the integer value * - * @param item[borrow] positive or negative integer + * @param item positive or negative integer * @return the value */ -CBOR_EXPORT uint32_t cbor_get_uint32(const cbor_item_t *item); +_CBOR_NODISCARD CBOR_EXPORT uint32_t cbor_get_uint32(const cbor_item_t *item); /** Extracts the integer value * - * @param item[borrow] positive or negative integer + * @param item positive or negative integer * @return the value */ -CBOR_EXPORT uint64_t cbor_get_uint64(const cbor_item_t *item); +_CBOR_NODISCARD CBOR_EXPORT uint64_t cbor_get_uint64(const cbor_item_t *item); /** Extracts the integer value * - * @param item[borrow] positive or negative integer + * @param item positive or negative integer * @return the value, extended to `uint64_t` */ -CBOR_EXPORT uint64_t cbor_get_int(const cbor_item_t *item); +_CBOR_NODISCARD CBOR_EXPORT uint64_t cbor_get_int(const cbor_item_t *item); /** Assigns the integer value * - * @param item[borrow] positive or negative integer item + * @param item positive or negative integer item * @param value the value to assign. For negative integer, the logical value is * `-value - 1` */ @@ -66,7 +66,7 @@ CBOR_EXPORT void cbor_set_uint8(cbor_item_t *item, uint8_t value); /** Assigns the integer value * - * @param item[borrow] positive or negative integer item + * @param item positive or negative integer item * @param value the value to assign. For negative integer, the logical value is * `-value - 1` */ @@ -74,7 +74,7 @@ CBOR_EXPORT void cbor_set_uint16(cbor_item_t *item, uint16_t value); /** Assigns the integer value * - * @param item[borrow] positive or negative integer item + * @param item positive or negative integer item * @param value the value to assign. For negative integer, the logical value is * `-value - 1` */ @@ -82,7 +82,7 @@ CBOR_EXPORT void cbor_set_uint32(cbor_item_t *item, uint32_t value); /** Assigns the integer value * - * @param item[borrow] positive or negative integer item + * @param item positive or negative integer item * @param value the value to assign. For negative integer, the logical value is * `-value - 1` */ @@ -90,16 +90,17 @@ CBOR_EXPORT void cbor_set_uint64(cbor_item_t *item, uint64_t value); /** Queries the integer width * - * @param item[borrow] positive or negative integer item + * @param item positive or negative integer item * @return the width */ -CBOR_EXPORT cbor_int_width cbor_int_get_width(const cbor_item_t *item); +_CBOR_NODISCARD CBOR_EXPORT cbor_int_width +cbor_int_get_width(const cbor_item_t *item); /** Marks the integer item as a positive integer * * The data value is not changed * - * @param item[borrow] positive or negative integer item + * @param item positive or negative integer item */ CBOR_EXPORT void cbor_mark_uint(cbor_item_t *item); @@ -107,7 +108,7 @@ CBOR_EXPORT void cbor_mark_uint(cbor_item_t *item); * * The data value is not changed * - * @param item[borrow] positive or negative integer item + * @param item positive or negative integer item */ CBOR_EXPORT void cbor_mark_negint(cbor_item_t *item); @@ -118,7 +119,7 @@ CBOR_EXPORT void cbor_mark_negint(cbor_item_t *item); * @return **new** positive integer or `NULL` on memory allocation failure. The * value is not initialized */ -CBOR_EXPORT cbor_item_t *cbor_new_int8(); +_CBOR_NODISCARD CBOR_EXPORT cbor_item_t *cbor_new_int8(void); /** Allocates new integer with 2B width * @@ -127,7 +128,7 @@ CBOR_EXPORT cbor_item_t *cbor_new_int8(); * @return **new** positive integer or `NULL` on memory allocation failure. The * value is not initialized */ -CBOR_EXPORT cbor_item_t *cbor_new_int16(); +_CBOR_NODISCARD CBOR_EXPORT cbor_item_t *cbor_new_int16(void); /** Allocates new integer with 4B width * @@ -136,7 +137,7 @@ CBOR_EXPORT cbor_item_t *cbor_new_int16(); * @return **new** positive integer or `NULL` on memory allocation failure. The * value is not initialized */ -CBOR_EXPORT cbor_item_t *cbor_new_int32(); +_CBOR_NODISCARD CBOR_EXPORT cbor_item_t *cbor_new_int32(void); /** Allocates new integer with 8B width * @@ -145,63 +146,63 @@ CBOR_EXPORT cbor_item_t *cbor_new_int32(); * @return **new** positive integer or `NULL` on memory allocation failure. The * value is not initialized */ -CBOR_EXPORT cbor_item_t *cbor_new_int64(); +_CBOR_NODISCARD CBOR_EXPORT cbor_item_t *cbor_new_int64(void); /** Constructs a new positive integer * * @param value the value to use * @return **new** positive integer or `NULL` on memory allocation failure */ -CBOR_EXPORT cbor_item_t *cbor_build_uint8(uint8_t value); +_CBOR_NODISCARD CBOR_EXPORT cbor_item_t *cbor_build_uint8(uint8_t value); /** Constructs a new positive integer * * @param value the value to use * @return **new** positive integer or `NULL` on memory allocation failure */ -CBOR_EXPORT cbor_item_t *cbor_build_uint16(uint16_t value); +_CBOR_NODISCARD CBOR_EXPORT cbor_item_t *cbor_build_uint16(uint16_t value); /** Constructs a new positive integer * * @param value the value to use * @return **new** positive integer or `NULL` on memory allocation failure */ -CBOR_EXPORT cbor_item_t *cbor_build_uint32(uint32_t value); +_CBOR_NODISCARD CBOR_EXPORT cbor_item_t *cbor_build_uint32(uint32_t value); /** Constructs a new positive integer * * @param value the value to use * @return **new** positive integer or `NULL` on memory allocation failure */ -CBOR_EXPORT cbor_item_t *cbor_build_uint64(uint64_t value); +_CBOR_NODISCARD CBOR_EXPORT cbor_item_t *cbor_build_uint64(uint64_t value); /** Constructs a new negative integer * * @param value the value to use * @return **new** negative integer or `NULL` on memory allocation failure */ -CBOR_EXPORT cbor_item_t *cbor_build_negint8(uint8_t value); +_CBOR_NODISCARD CBOR_EXPORT cbor_item_t *cbor_build_negint8(uint8_t value); /** Constructs a new negative integer * * @param value the value to use * @return **new** negative integer or `NULL` on memory allocation failure */ -CBOR_EXPORT cbor_item_t *cbor_build_negint16(uint16_t value); +_CBOR_NODISCARD CBOR_EXPORT cbor_item_t *cbor_build_negint16(uint16_t value); /** Constructs a new negative integer * * @param value the value to use * @return **new** negative integer or `NULL` on memory allocation failure */ -CBOR_EXPORT cbor_item_t *cbor_build_negint32(uint32_t value); +_CBOR_NODISCARD CBOR_EXPORT cbor_item_t *cbor_build_negint32(uint32_t value); /** Constructs a new negative integer * * @param value the value to use * @return **new** negative integer or `NULL` on memory allocation failure */ -CBOR_EXPORT cbor_item_t *cbor_build_negint64(uint64_t value); +_CBOR_NODISCARD CBOR_EXPORT cbor_item_t *cbor_build_negint64(uint64_t value); #ifdef __cplusplus } diff --git a/contrib/libcbor/src/cbor/maps.c b/contrib/libcbor/src/cbor/maps.c index 45140e2cfa2b..8711e57acb70 100644 --- a/contrib/libcbor/src/cbor/maps.c +++ b/contrib/libcbor/src/cbor/maps.c @@ -9,17 +9,17 @@ #include "internal/memory_utils.h" size_t cbor_map_size(const cbor_item_t *item) { - assert(cbor_isa_map(item)); + CBOR_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)); + CBOR_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)); + cbor_item_t *item = _cbor_malloc(sizeof(cbor_item_t)); _CBOR_NOTNULL(item); *item = (cbor_item_t){ @@ -34,8 +34,8 @@ cbor_item_t *cbor_new_definite_map(size_t size) { return item; } -cbor_item_t *cbor_new_indefinite_map() { - cbor_item_t *item = _CBOR_MALLOC(sizeof(cbor_item_t)); +cbor_item_t *cbor_new_indefinite_map(void) { + cbor_item_t *item = _cbor_malloc(sizeof(cbor_item_t)); _CBOR_NOTNULL(item); *item = (cbor_item_t){ @@ -50,7 +50,7 @@ cbor_item_t *cbor_new_indefinite_map() { } bool _cbor_map_add_key(cbor_item_t *item, cbor_item_t *key) { - assert(cbor_isa_map(item)); + CBOR_ASSERT(cbor_isa_map(item)); struct _cbor_map_metadata *metadata = (struct _cbor_map_metadata *)&item->metadata; if (cbor_map_is_definite(item)) { @@ -66,7 +66,6 @@ bool _cbor_map_add_key(cbor_item_t *item, cbor_item_t *key) { 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; } @@ -94,7 +93,7 @@ bool _cbor_map_add_key(cbor_item_t *item, cbor_item_t *key) { } bool _cbor_map_add_value(cbor_item_t *item, cbor_item_t *value) { - assert(cbor_isa_map(item)); + CBOR_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) @@ -105,13 +104,13 @@ bool _cbor_map_add_value(cbor_item_t *item, cbor_item_t *value) { } bool cbor_map_add(cbor_item_t *item, struct cbor_pair pair) { - assert(cbor_isa_map(item)); + CBOR_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)); + CBOR_ASSERT(cbor_isa_map(item)); return item->metadata.map_metadata.type == _CBOR_METADATA_DEFINITE; } @@ -120,6 +119,6 @@ bool cbor_map_is_indefinite(const cbor_item_t *item) { } struct cbor_pair *cbor_map_handle(const cbor_item_t *item) { - assert(cbor_isa_map(item)); + CBOR_ASSERT(cbor_isa_map(item)); return (struct cbor_pair *)item->data; } diff --git a/contrib/libcbor/src/cbor/maps.h b/contrib/libcbor/src/cbor/maps.h index 370c6fcd4336..5c05b542bd84 100644 --- a/contrib/libcbor/src/cbor/maps.h +++ b/contrib/libcbor/src/cbor/maps.h @@ -23,87 +23,96 @@ extern "C" { /** Get the number of pairs * - * @param item[borrow] A map + * @param item A map * @return The number of pairs */ -CBOR_EXPORT size_t cbor_map_size(const cbor_item_t *item); +_CBOR_NODISCARD CBOR_EXPORT size_t cbor_map_size(const cbor_item_t *item); /** Get the size of the allocated storage * - * @param item[borrow] A map + * @param item A map * @return Allocated storage size (as the number of #cbor_pair items) */ -CBOR_EXPORT size_t cbor_map_allocated(const cbor_item_t *item); +_CBOR_NODISCARD CBOR_EXPORT size_t cbor_map_allocated(const cbor_item_t *item); /** Create a new definite map * * @param size The number of slots to preallocate - * @return **new** definite map. `NULL` on malloc failure. + * @return Reference to the new map item. The item's reference count is + * initialized to one. + * @return `NULL` if memory allocation fails */ -CBOR_EXPORT cbor_item_t *cbor_new_definite_map(size_t size); +_CBOR_NODISCARD CBOR_EXPORT cbor_item_t *cbor_new_definite_map(size_t size); /** Create a new indefinite map * - * @param size The number of slots to preallocate - * @return **new** definite map. `NULL` on malloc failure. + * @return Reference to the new map item. The item's reference count is + * initialized to one. + * @return `NULL` if memory allocation fails */ -CBOR_EXPORT cbor_item_t *cbor_new_indefinite_map(); +_CBOR_NODISCARD CBOR_EXPORT cbor_item_t *cbor_new_indefinite_map(void); /** 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 * - * @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 + * @param item A map + * @param pair The key-value pair to add. Reference count of the #cbor_pair.key + * and #cbor_pair.value will be increased by one. + * @return `true` on success, `false` if memory allocation failed (indefinite + * maps) or the preallocated storage is full (definite maps) */ -CBOR_EXPORT bool cbor_map_add(cbor_item_t *item, struct cbor_pair pair); +_CBOR_NODISCARD CBOR_EXPORT bool cbor_map_add(cbor_item_t *item, + struct cbor_pair pair); /** Add a key to the map * * Sets the value to `NULL`. Internal API. * - * @param item[borrow] A map - * @param key[incref] The key + * @param item A map + * @param key The key, Its reference count will be be increased by one. * @return `true` on success, `false` if either reallocation failed or the - * preallcoated storage is full + * preallocated storage is full */ -CBOR_EXPORT bool _cbor_map_add_key(cbor_item_t *item, cbor_item_t *key); +_CBOR_NODISCARD CBOR_EXPORT bool _cbor_map_add_key(cbor_item_t *item, + cbor_item_t *key); /** Add a value to the map * * Assumes that #_cbor_map_add_key has been called. Internal API. * - * @param item[borrow] A map - * @param key[incref] The value + * @param item A map + * @param value The value. Its reference count will be be increased by one. * @return `true` on success, `false` if either reallocation failed or the - * preallcoated storage is full + * preallocated storage is full */ -CBOR_EXPORT bool _cbor_map_add_value(cbor_item_t *item, cbor_item_t *value); +_CBOR_NODISCARD CBOR_EXPORT bool _cbor_map_add_value(cbor_item_t *item, + cbor_item_t *value); /** Is this map definite? * - * @param item[borrow] A map + * @param item A map * @return Is this map definite? */ -CBOR_EXPORT bool cbor_map_is_definite(const cbor_item_t *item); +_CBOR_NODISCARD CBOR_EXPORT bool cbor_map_is_definite(const cbor_item_t *item); /** Is this map indefinite? * - * @param item[borrow] A map + * @param item A map * @return Is this map indefinite? */ -CBOR_EXPORT bool cbor_map_is_indefinite(const cbor_item_t *item); +_CBOR_NODISCARD CBOR_EXPORT bool cbor_map_is_indefinite( + const cbor_item_t *item); /** Get the pairs storage * - * @param item[borrow] A map + * @param item A map * @return Array of #cbor_map_size pairs. Manipulation is possible as long as * references remain valid. */ -CBOR_EXPORT struct cbor_pair *cbor_map_handle(const cbor_item_t *item); +_CBOR_NODISCARD CBOR_EXPORT struct cbor_pair *cbor_map_handle( + const cbor_item_t *item); #ifdef __cplusplus } diff --git a/contrib/libcbor/src/cbor/serialization.c b/contrib/libcbor/src/cbor/serialization.c index 56a48176aab4..40f4c531d575 100644 --- a/contrib/libcbor/src/cbor/serialization.c +++ b/contrib/libcbor/src/cbor/serialization.c @@ -19,6 +19,7 @@ size_t cbor_serialize(const cbor_item_t *item, unsigned char *buffer, size_t buffer_size) { + // cppcheck-suppress missingReturn switch (cbor_typeof(item)) { case CBOR_TYPE_UINT: return cbor_serialize_uint(item, buffer, buffer_size); @@ -36,44 +37,144 @@ size_t cbor_serialize(const cbor_item_t *item, unsigned char *buffer, 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; - } +/** Largest integer that can be encoded as embedded in the item leading byte. */ +const uint64_t kMaxEmbeddedInt = 23; - size_t written; +/** How many bytes will a tag for a nested item of a given `size` take when + * encoded.*/ +size_t _cbor_encoded_header_size(uint64_t size) { + if (size <= kMaxEmbeddedInt) + return 1; + else if (size <= UINT8_MAX) + return 2; + else if (size <= UINT16_MAX) + return 3; + else if (size <= UINT32_MAX) + return 5; + else + return 9; +} - /* 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; +size_t cbor_serialized_size(const cbor_item_t *item) { + // cppcheck-suppress missingReturn + switch (cbor_typeof(item)) { + case CBOR_TYPE_UINT: + case CBOR_TYPE_NEGINT: + switch (cbor_int_get_width(item)) { + case CBOR_INT_8: + if (cbor_get_uint8(item) <= kMaxEmbeddedInt) return 1; + return 2; + case CBOR_INT_16: + return 3; + case CBOR_INT_32: + return 5; + case CBOR_INT_64: + return 9; + } + // Note: We do not _cbor_safe_signaling_add zero-length definite strings, + // they would cause zeroes to propagate. All other items are at least one + // byte. + case CBOR_TYPE_BYTESTRING: { + if (cbor_bytestring_is_definite(item)) { + size_t header_size = + _cbor_encoded_header_size(cbor_bytestring_length(item)); + if (cbor_bytestring_length(item) == 0) return header_size; + return _cbor_safe_signaling_add(header_size, + cbor_bytestring_length(item)); + } + size_t indef_bytestring_size = 2; // Leading byte + break + cbor_item_t **chunks = cbor_bytestring_chunks_handle(item); + for (size_t i = 0; i < cbor_bytestring_chunk_count(item); i++) { + indef_bytestring_size = _cbor_safe_signaling_add( + indef_bytestring_size, cbor_serialized_size(chunks[i])); + } + return indef_bytestring_size; } - - tmp_bfr = _CBOR_REALLOC(bfr, bfr_size *= 2); - - if (tmp_bfr == NULL) { - _CBOR_FREE(bfr); - return 0; + case CBOR_TYPE_STRING: { + if (cbor_string_is_definite(item)) { + size_t header_size = + _cbor_encoded_header_size(cbor_string_length(item)); + if (cbor_string_length(item) == 0) return header_size; + return _cbor_safe_signaling_add(header_size, cbor_string_length(item)); + } + size_t indef_string_size = 2; // Leading byte + break + cbor_item_t **chunks = cbor_string_chunks_handle(item); + for (size_t i = 0; i < cbor_string_chunk_count(item); i++) { + indef_string_size = _cbor_safe_signaling_add( + indef_string_size, cbor_serialized_size(chunks[i])); + } + return indef_string_size; + } + case CBOR_TYPE_ARRAY: { + size_t array_size = cbor_array_is_definite(item) + ? _cbor_encoded_header_size(cbor_array_size(item)) + : 2; // Leading byte + break + cbor_item_t **items = cbor_array_handle(item); + for (size_t i = 0; i < cbor_array_size(item); i++) { + array_size = _cbor_safe_signaling_add(array_size, + cbor_serialized_size(items[i])); + } + return array_size; + } + case CBOR_TYPE_MAP: { + size_t map_size = cbor_map_is_definite(item) + ? _cbor_encoded_header_size(cbor_map_size(item)) + : 2; // Leading byte + break + struct cbor_pair *items = cbor_map_handle(item); + for (size_t i = 0; i < cbor_map_size(item); i++) { + map_size = _cbor_safe_signaling_add( + map_size, + _cbor_safe_signaling_add(cbor_serialized_size(items[i].key), + cbor_serialized_size(items[i].value))); + } + return map_size; } - bfr = tmp_bfr; + case CBOR_TYPE_TAG: { + return _cbor_safe_signaling_add( + _cbor_encoded_header_size(cbor_tag_value(item)), + cbor_serialized_size(cbor_move(cbor_tag_item(item)))); + } + case CBOR_TYPE_FLOAT_CTRL: + switch (cbor_float_get_width(item)) { + case CBOR_FLOAT_0: + return _cbor_encoded_header_size(cbor_ctrl_value(item)); + case CBOR_FLOAT_16: + return 3; + case CBOR_FLOAT_32: + return 5; + case CBOR_FLOAT_64: + return 9; + } + } +} + +size_t cbor_serialize_alloc(const cbor_item_t *item, unsigned char **buffer, + size_t *buffer_size) { + *buffer = NULL; + size_t serialized_size = cbor_serialized_size(item); + if (serialized_size == 0) { + if (buffer_size != NULL) *buffer_size = 0; + return 0; + } + *buffer = _cbor_malloc(serialized_size); + if (*buffer == NULL) { + if (buffer_size != NULL) *buffer_size = 0; + return 0; } - *buffer = bfr; - *buffer_size = bfr_size; + + size_t written = cbor_serialize(item, *buffer, serialized_size); + CBOR_ASSERT(written == serialized_size); + if (buffer_size != NULL) *buffer_size = serialized_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)); + CBOR_ASSERT(cbor_isa_uint(item)); + // cppcheck-suppress missingReturn switch (cbor_int_get_width(item)) { case CBOR_INT_8: return cbor_encode_uint8(cbor_get_uint8(item), buffer, buffer_size); @@ -83,14 +184,13 @@ size_t cbor_serialize_uint(const cbor_item_t *item, unsigned char *buffer, 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)); + CBOR_ASSERT(cbor_isa_negint(item)); + // cppcheck-suppress missingReturn switch (cbor_int_get_width(item)) { case CBOR_INT_8: return cbor_encode_negint8(cbor_get_uint8(item), buffer, buffer_size); @@ -100,173 +200,158 @@ size_t cbor_serialize_negint(const cbor_item_t *item, unsigned char *buffer, 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)); + CBOR_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)) { + if (written > 0 && (buffer_size - written >= length)) { memcpy(buffer + written, cbor_bytestring_handle(item), length); return written + length; - } else - return 0; + } + return 0; } else { - assert(cbor_bytestring_is_indefinite(item)); + CBOR_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; 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 (chunk_written == 0) return 0; + written += chunk_written; } - if (cbor_encode_break(buffer + written, buffer_size - written) > 0) - return written + 1; - else - return 0; + + size_t break_written = + cbor_encode_break(buffer + written, buffer_size - written); + if (break_written == 0) return 0; + return written + break_written; } } size_t cbor_serialize_string(const cbor_item_t *item, unsigned char *buffer, size_t buffer_size) { - assert(cbor_isa_string(item)); + CBOR_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; + } + return 0; } else { - assert(cbor_string_is_indefinite(item)); + CBOR_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; 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 (chunk_written == 0) return 0; + written += chunk_written; } - if (cbor_encode_break(buffer + written, buffer_size - written) > 0) - return written + 1; - else - return 0; + + size_t break_written = + cbor_encode_break(buffer + written, buffer_size - written); + if (break_written == 0) return 0; + return written + break_written; } } size_t cbor_serialize_array(const cbor_item_t *item, unsigned char *buffer, size_t buffer_size) { - assert(cbor_isa_array(item)); + CBOR_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)); + CBOR_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 = + size_t item_written = cbor_serialize(*(handle++), buffer + written, buffer_size - written); - if (item_written == 0) - return 0; - else - written += item_written; + if (item_written == 0) return 0; + 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; + CBOR_ASSERT(cbor_array_is_indefinite(item)); + size_t break_written = + cbor_encode_break(buffer + written, buffer_size - written); + if (break_written == 0) return 0; + return written + break_written; } } size_t cbor_serialize_map(const cbor_item_t *item, unsigned char *buffer, size_t buffer_size) { - assert(cbor_isa_map(item)); + CBOR_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)); + CBOR_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 = + size_t item_written = cbor_serialize(handle->key, buffer + written, buffer_size - written); - if (item_written == 0) + if (item_written == 0) { return 0; - else - written += item_written; + } + 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 (item_written == 0) return 0; + 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; + CBOR_ASSERT(cbor_map_is_indefinite(item)); + size_t break_written = + cbor_encode_break(buffer + written, buffer_size - written); + if (break_written == 0) return 0; + return written + break_written; } } size_t cbor_serialize_tag(const cbor_item_t *item, unsigned char *buffer, size_t buffer_size) { - assert(cbor_isa_tag(item)); + CBOR_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_move(cbor_tag_item(item)), buffer + written, buffer_size - written); - if (item_written == 0) - return 0; - else - return written + item_written; + if (item_written == 0) return 0; + 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)); + CBOR_ASSERT(cbor_isa_float_ctrl(item)); + // cppcheck-suppress missingReturn switch (cbor_float_get_width(item)) { case CBOR_FLOAT_0: /* CTRL - special treatment */ @@ -280,7 +365,4 @@ size_t cbor_serialize_float_ctrl(const cbor_item_t *item, unsigned char *buffer, return cbor_encode_double(cbor_float_get_float8(item), buffer, buffer_size); } - - /* Should never happen - make the compiler happy */ - return 0; } diff --git a/contrib/libcbor/src/cbor/serialization.h b/contrib/libcbor/src/cbor/serialization.h index 3f7707afca61..228ae75d6011 100644 --- a/contrib/libcbor/src/cbor/serialization.h +++ b/contrib/libcbor/src/cbor/serialization.h @@ -23,110 +23,143 @@ extern "C" { /** Serialize the given item * - * @param item[borrow] A data item + * @param item A data item * @param buffer Buffer to serialize to * @param buffer_size Size of the \p buffer * @return Length of the result. 0 on failure. */ -CBOR_EXPORT size_t cbor_serialize(const cbor_item_t *item, - cbor_mutable_data buffer, size_t buffer_size); +_CBOR_NODISCARD CBOR_EXPORT size_t cbor_serialize(const cbor_item_t *item, + cbor_mutable_data buffer, + size_t buffer_size); + +/** Compute the length (in bytes) of the item when serialized using + * `cbor_serialize`. + * + * Time complexity is proportional to the number of nested items. + * + * @param item A data item + * @return Length (>= 1) of the item when serialized. 0 if the length overflows + * `size_t`. + */ +_CBOR_NODISCARD CBOR_EXPORT size_t +cbor_serialized_size(const cbor_item_t *item); /** Serialize the given item, allocating buffers as needed * + * Since libcbor v0.10, the return value is always the same as `buffer_size` (if + * provided, see https://github.com/PJK/libcbor/pull/251/). New clients should + * ignore the return value. + * * \rst - * .. warning:: It is your responsibility to free the buffer using an + * .. warning:: It is the caller's 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``. + * @param item A data item + * @param[out] buffer Buffer containing the result + * @param[out] buffer_size Size of the \p buffer, or 0 on memory allocation + * failure. + * @return Length of the result in bytes + * @return 0 on memory allocation failure, in which case \p buffer is `NULL`. */ CBOR_EXPORT size_t cbor_serialize_alloc(const cbor_item_t *item, - cbor_mutable_data *buffer, + unsigned char **buffer, size_t *buffer_size); /** Serialize an uint * - * @param item[borrow] A uint - * @param buffer Buffer to serialize to + * @param item A uint + * @param[out] buffer Buffer to serialize to * @param buffer_size Size of the \p buffer - * @return Length of the result. 0 on failure. + * @return Length of the result + * @return 0 if the \p buffer_size doesn't fit the result */ -CBOR_EXPORT size_t cbor_serialize_uint(const cbor_item_t *, cbor_mutable_data, - size_t); +_CBOR_NODISCARD CBOR_EXPORT size_t cbor_serialize_uint(const cbor_item_t *item, + cbor_mutable_data buffer, + size_t buffer_size); /** Serialize a negint * - * @param item[borrow] A neging - * @param buffer Buffer to serialize to + * @param item A negint + * @param[out] buffer Buffer to serialize to * @param buffer_size Size of the \p buffer - * @return Length of the result. 0 on failure. + * @return Length of the result + * @return 0 if the \p buffer_size doesn't fit the result */ -CBOR_EXPORT size_t cbor_serialize_negint(const cbor_item_t *, cbor_mutable_data, - size_t); +_CBOR_NODISCARD CBOR_EXPORT size_t cbor_serialize_negint( + const cbor_item_t *item, cbor_mutable_data buffer, size_t buffer_size); /** Serialize a bytestring * - * @param item[borrow] A bytestring - * @param buffer Buffer to serialize to + * @param item A bytestring + * @param[out] buffer Buffer to serialize to * @param buffer_size Size of the \p buffer - * @return Length of the result. 0 on failure. + * @return Length of the result + * @return 0 if the \p buffer_size doesn't fit the result. The \p buffer may + * still be modified */ -CBOR_EXPORT size_t cbor_serialize_bytestring(const cbor_item_t *, - cbor_mutable_data, size_t); +_CBOR_NODISCARD CBOR_EXPORT size_t cbor_serialize_bytestring( + const cbor_item_t *item, cbor_mutable_data buffer, size_t buffer_size); /** Serialize a string * - * @param item[borrow] A string - * @param buffer Buffer to serialize to + * @param item A string + * @param[out] buffer Buffer to serialize to * @param buffer_size Size of the \p buffer - * @return Length of the result. 0 on failure. + * @return Length of the result + * @return 0 if the \p buffer_size doesn't fit the result. The \p buffer may + * still be modified */ -CBOR_EXPORT size_t cbor_serialize_string(const cbor_item_t *, cbor_mutable_data, - size_t); - +_CBOR_NODISCARD CBOR_EXPORT size_t cbor_serialize_string( + const cbor_item_t *item, cbor_mutable_data buffer, size_t buffer_size); /** Serialize an array * - * @param item[borrow] An array - * @param buffer Buffer to serialize to + * @param item An array + * @param[out] buffer Buffer to serialize to * @param buffer_size Size of the \p buffer - * @return Length of the result. 0 on failure. + * @return Length of the result + * @return 0 if the \p buffer_size doesn't fit the result. The \p buffer may + * still be modified */ -CBOR_EXPORT size_t cbor_serialize_array(const cbor_item_t *, cbor_mutable_data, - size_t); +_CBOR_NODISCARD CBOR_EXPORT size_t cbor_serialize_array( + const cbor_item_t *item, cbor_mutable_data buffer, size_t buffer_size); /** Serialize a map * - * @param item[borrow] A map - * @param buffer Buffer to serialize to + * @param item A map + * @param[out] buffer Buffer to serialize to * @param buffer_size Size of the \p buffer - * @return Length of the result. 0 on failure. + * @return Length of the result + * @return 0 if the \p buffer_size doesn't fit the result. The \p buffer may + * still be modified */ -CBOR_EXPORT size_t cbor_serialize_map(const cbor_item_t *, cbor_mutable_data, - size_t); +_CBOR_NODISCARD CBOR_EXPORT size_t cbor_serialize_map(const cbor_item_t *item, + cbor_mutable_data buffer, + size_t buffer_size); /** Serialize a tag * - * @param item[borrow] A tag - * @param buffer Buffer to serialize to + * @param item A tag + * @param[out] buffer Buffer to serialize to * @param buffer_size Size of the \p buffer - * @return Length of the result. 0 on failure. + * @return Length of the result + * @return 0 if the \p buffer_size doesn't fit the result. The \p buffer may + * still be modified */ -CBOR_EXPORT size_t cbor_serialize_tag(const cbor_item_t *, cbor_mutable_data, - size_t); +_CBOR_NODISCARD CBOR_EXPORT size_t cbor_serialize_tag(const cbor_item_t *item, + cbor_mutable_data buffer, + size_t buffer_size); /** Serialize a * - * @param item[borrow] A float or ctrl - * @param buffer Buffer to serialize to + * @param item A float or ctrl + * @param[out] buffer Buffer to serialize to * @param buffer_size Size of the \p buffer - * @return Length of the result. 0 on failure. + * @return Length of the result + * @return 0 if the \p buffer_size doesn't fit the result */ -CBOR_EXPORT size_t cbor_serialize_float_ctrl(const cbor_item_t *, - cbor_mutable_data, size_t); +_CBOR_NODISCARD CBOR_EXPORT size_t cbor_serialize_float_ctrl( + const cbor_item_t *item, cbor_mutable_data buffer, size_t buffer_size); #ifdef __cplusplus } diff --git a/contrib/libcbor/src/cbor/streaming.c b/contrib/libcbor/src/cbor/streaming.c index aa58abb3eaba..922a71d8e6b0 100644 --- a/contrib/libcbor/src/cbor/streaming.c +++ b/contrib/libcbor/src/cbor/streaming.c @@ -8,7 +8,7 @@ #include "streaming.h" #include "internal/loaders.h" -bool static claim_bytes(size_t required, size_t provided, +static bool claim_bytes(size_t required, size_t provided, struct cbor_decoder_result *result) { if (required > (provided - result->read)) { result->required = required + result->read; @@ -22,6 +22,24 @@ bool static claim_bytes(size_t required, size_t provided, } } +// Use implicit capture as an exception to avoid the super long parameter list +#define CLAIM_BYTES_AND_INVOKE(callback_name, length, source_extra_offset) \ + do { \ + if (claim_bytes(length, source_size, &result)) { \ + callbacks->callback_name(context, source + 1 + source_extra_offset, \ + length); \ + } \ + } while (0) + +#define READ_CLAIM_INVOKE(callback_name, length_reader, length_bytes) \ + do { \ + if (claim_bytes(length_bytes, source_size, &result)) { \ + uint64_t length = length_reader(source + 1); \ + CLAIM_BYTES_AND_INVOKE(callback_name, length, length_bytes); \ + } \ + return result; \ + } while (0) + struct cbor_decoder_result cbor_stream_decode( cbor_data source, size_t source_size, const struct cbor_callbacks *callbacks, void *context) { @@ -98,7 +116,7 @@ struct cbor_decoder_result cbor_stream_decode( case 0x1E: /* Fallthrough */ case 0x1F: /* Reserved */ - { return (struct cbor_decoder_result){0, CBOR_DECODER_ERROR}; } + { return (struct cbor_decoder_result){.status = CBOR_DECODER_ERROR}; } case 0x20: /* Fallthrough */ case 0x21: /* Fallthrough */ case 0x22: /* Fallthrough */ @@ -166,7 +184,7 @@ struct cbor_decoder_result cbor_stream_decode( case 0x3E: /* Fallthrough */ case 0x3F: /* Reserved */ - { return (struct cbor_decoder_result){0, CBOR_DECODER_ERROR}; } + { return (struct cbor_decoder_result){.status = CBOR_DECODER_ERROR}; } case 0x40: /* Fallthrough */ case 0x41: /* Fallthrough */ case 0x42: /* Fallthrough */ @@ -193,63 +211,27 @@ struct cbor_decoder_result cbor_stream_decode( case 0x57: /* Embedded length byte string */ { - size_t length = - (size_t)_cbor_load_uint8(source) - 0x40; /* 0x40 offset */ - if (claim_bytes(length, source_size, &result)) { - callbacks->byte_string(context, source + 1, length); - } + uint64_t length = _cbor_load_uint8(source) - 0x40; /* 0x40 offset */ + CLAIM_BYTES_AND_INVOKE(byte_string, length, 0); return result; } case 0x58: /* One byte length byte string */ - // TODO template this? - { - if (claim_bytes(1, source_size, &result)) { - size_t length = (size_t)_cbor_load_uint8(source + 1); - if (claim_bytes(length, source_size, &result)) { - callbacks->byte_string(context, source + 1 + 1, length); - } - } - return result; - } + READ_CLAIM_INVOKE(byte_string, _cbor_load_uint8, 1); case 0x59: /* Two bytes length byte string */ - { - if (claim_bytes(2, source_size, &result)) { - size_t length = (size_t)_cbor_load_uint16(source + 1); - if (claim_bytes(length, source_size, &result)) { - callbacks->byte_string(context, source + 1 + 2, length); - } - } - return result; - } + READ_CLAIM_INVOKE(byte_string, _cbor_load_uint16, 2); case 0x5A: /* Four bytes length byte string */ - { - if (claim_bytes(4, source_size, &result)) { - size_t length = (size_t)_cbor_load_uint32(source + 1); - if (claim_bytes(length, source_size, &result)) { - callbacks->byte_string(context, source + 1 + 4, length); - } - } - return result; - } + READ_CLAIM_INVOKE(byte_string, _cbor_load_uint32, 4); case 0x5B: /* Eight bytes length byte string */ - { - if (claim_bytes(8, source_size, &result)) { - size_t length = (size_t)_cbor_load_uint64(source + 1); - if (claim_bytes(length, source_size, &result)) { - callbacks->byte_string(context, source + 1 + 8, length); - } - } - return result; - } + READ_CLAIM_INVOKE(byte_string, _cbor_load_uint64, 8); case 0x5C: /* Fallthrough */ case 0x5D: /* Fallthrough */ case 0x5E: /* Reserved */ - { return (struct cbor_decoder_result){0, CBOR_DECODER_ERROR}; } + { return (struct cbor_decoder_result){.status = CBOR_DECODER_ERROR}; } case 0x5F: /* Indefinite byte string */ { @@ -282,62 +264,27 @@ struct cbor_decoder_result cbor_stream_decode( case 0x77: /* Embedded one byte length string */ { - size_t length = - (size_t)_cbor_load_uint8(source) - 0x60; /* 0x60 offset */ - if (claim_bytes(length, source_size, &result)) { - callbacks->string(context, source + 1, length); - } + uint64_t length = _cbor_load_uint8(source) - 0x60; /* 0x60 offset */ + CLAIM_BYTES_AND_INVOKE(string, length, 0); return result; } case 0x78: /* One byte length string */ - { - if (claim_bytes(1, source_size, &result)) { - size_t length = (size_t)_cbor_load_uint8(source + 1); - if (claim_bytes(length, source_size, &result)) { - callbacks->string(context, source + 1 + 1, length); - } - } - return result; - } + READ_CLAIM_INVOKE(string, _cbor_load_uint8, 1); case 0x79: /* Two bytes length string */ - { - if (claim_bytes(2, source_size, &result)) { - size_t length = (size_t)_cbor_load_uint16(source + 1); - if (claim_bytes(length, source_size, &result)) { - callbacks->string(context, source + 1 + 2, length); - } - } - return result; - } + READ_CLAIM_INVOKE(string, _cbor_load_uint16, 2); case 0x7A: /* Four bytes length string */ - { - if (claim_bytes(4, source_size, &result)) { - size_t length = (size_t)_cbor_load_uint32(source + 1); - if (claim_bytes(length, source_size, &result)) { - callbacks->string(context, source + 1 + 4, length); - } - } - return result; - } + READ_CLAIM_INVOKE(string, _cbor_load_uint32, 4); case 0x7B: /* Eight bytes length string */ - { - if (claim_bytes(8, source_size, &result)) { - size_t length = (size_t)_cbor_load_uint64(source + 1); - if (claim_bytes(length, source_size, &result)) { - callbacks->string(context, source + 1 + 8, length); - } - } - return result; - } + READ_CLAIM_INVOKE(string, _cbor_load_uint64, 8); case 0x7C: /* Fallthrough */ case 0x7D: /* Fallthrough */ case 0x7E: /* Reserved */ - { return (struct cbor_decoder_result){0, CBOR_DECODER_ERROR}; } + { return (struct cbor_decoder_result){.status = CBOR_DECODER_ERROR}; } case 0x7F: /* Indefinite length string */ { @@ -371,14 +318,14 @@ struct cbor_decoder_result cbor_stream_decode( /* Embedded one byte length array */ { callbacks->array_start( - context, (size_t)_cbor_load_uint8(source) - 0x80); /* 0x40 offset */ + context, _cbor_load_uint8(source) - 0x80); /* 0x40 offset */ return result; } case 0x98: /* One byte length array */ { if (claim_bytes(1, source_size, &result)) { - callbacks->array_start(context, (size_t)_cbor_load_uint8(source + 1)); + callbacks->array_start(context, _cbor_load_uint8(source + 1)); } return result; } @@ -386,8 +333,7 @@ struct cbor_decoder_result cbor_stream_decode( /* Two bytes length array */ { if (claim_bytes(2, source_size, &result)) { - callbacks->array_start(context, - (size_t)_cbor_load_uint16(source + 1)); + callbacks->array_start(context, _cbor_load_uint16(source + 1)); } return result; } @@ -395,8 +341,7 @@ struct cbor_decoder_result cbor_stream_decode( /* Four bytes length array */ { if (claim_bytes(4, source_size, &result)) { - callbacks->array_start(context, - (size_t)_cbor_load_uint32(source + 1)); + callbacks->array_start(context, _cbor_load_uint32(source + 1)); } return result; } @@ -404,8 +349,7 @@ struct cbor_decoder_result cbor_stream_decode( /* Eight bytes length array */ { if (claim_bytes(8, source_size, &result)) { - callbacks->array_start(context, - (size_t)_cbor_load_uint64(source + 1)); + callbacks->array_start(context, _cbor_load_uint64(source + 1)); } return result; } @@ -413,7 +357,7 @@ struct cbor_decoder_result cbor_stream_decode( case 0x9D: /* Fallthrough */ case 0x9E: /* Reserved */ - { return (struct cbor_decoder_result){0, CBOR_DECODER_ERROR}; } + { return (struct cbor_decoder_result){.status = CBOR_DECODER_ERROR}; } case 0x9F: /* Indefinite length array */ { @@ -446,15 +390,15 @@ struct cbor_decoder_result cbor_stream_decode( case 0xB7: /* Embedded one byte length map */ { - callbacks->map_start( - context, (size_t)_cbor_load_uint8(source) - 0xA0); /* 0xA0 offset */ + callbacks->map_start(context, + _cbor_load_uint8(source) - 0xA0); /* 0xA0 offset */ return result; } case 0xB8: /* One byte length map */ { if (claim_bytes(1, source_size, &result)) { - callbacks->map_start(context, (size_t)_cbor_load_uint8(source + 1)); + callbacks->map_start(context, _cbor_load_uint8(source + 1)); } return result; } @@ -462,7 +406,7 @@ struct cbor_decoder_result cbor_stream_decode( /* Two bytes length map */ { if (claim_bytes(2, source_size, &result)) { - callbacks->map_start(context, (size_t)_cbor_load_uint16(source + 1)); + callbacks->map_start(context, _cbor_load_uint16(source + 1)); } return result; } @@ -470,7 +414,7 @@ struct cbor_decoder_result cbor_stream_decode( /* Four bytes length map */ { if (claim_bytes(4, source_size, &result)) { - callbacks->map_start(context, (size_t)_cbor_load_uint32(source + 1)); + callbacks->map_start(context, _cbor_load_uint32(source + 1)); } return result; } @@ -478,7 +422,7 @@ struct cbor_decoder_result cbor_stream_decode( /* Eight bytes length map */ { if (claim_bytes(8, source_size, &result)) { - callbacks->map_start(context, (size_t)_cbor_load_uint64(source + 1)); + callbacks->map_start(context, _cbor_load_uint64(source + 1)); } return result; } @@ -486,7 +430,7 @@ struct cbor_decoder_result cbor_stream_decode( case 0xBD: /* Fallthrough */ case 0xBE: /* Reserved */ - { return (struct cbor_decoder_result){0, CBOR_DECODER_ERROR}; } + { return (struct cbor_decoder_result){.status = CBOR_DECODER_ERROR}; } case 0xBF: /* Indefinite length map */ { @@ -506,8 +450,8 @@ struct cbor_decoder_result cbor_stream_decode( case 0xC5: /* Big float */ { - callbacks->tag(context, - _cbor_load_uint8(source) - 0xC0); /* 0xC0 offset */ + callbacks->tag(context, (uint64_t)(_cbor_load_uint8(source) - + 0xC0)); /* 0xC0 offset */ return result; } case 0xC6: /* Fallthrough */ @@ -526,14 +470,14 @@ struct cbor_decoder_result cbor_stream_decode( case 0xD3: /* Fallthrough */ case 0xD4: /* Unassigned tag value */ { - return (struct cbor_decoder_result){0, CBOR_DECODER_ERROR}; + return (struct cbor_decoder_result){.status = 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 */ + callbacks->tag(context, (uint64_t)(_cbor_load_uint8(source) - + 0xC0)); /* 0xC0 offset */ return result; } case 0xD8: /* 1B tag */ @@ -569,7 +513,7 @@ struct cbor_decoder_result cbor_stream_decode( case 0xDE: /* Fallthrough */ case 0xDF: /* Reserved */ { - return (struct cbor_decoder_result){0, CBOR_DECODER_ERROR}; + return (struct cbor_decoder_result){.status = CBOR_DECODER_ERROR}; } case 0xE0: /* Fallthrough */ case 0xE1: /* Fallthrough */ @@ -592,7 +536,7 @@ struct cbor_decoder_result cbor_stream_decode( case 0xF2: /* Fallthrough */ case 0xF3: /* Simple value - unassigned */ { - return (struct cbor_decoder_result){0, CBOR_DECODER_ERROR}; + return (struct cbor_decoder_result){.status = CBOR_DECODER_ERROR}; } case 0xF4: /* False */ @@ -620,7 +564,7 @@ struct cbor_decoder_result cbor_stream_decode( } case 0xF8: /* 1B simple value, unassigned */ - { return (struct cbor_decoder_result){0, CBOR_DECODER_ERROR}; } + { return (struct cbor_decoder_result){.status = CBOR_DECODER_ERROR}; } case 0xF9: /* 2B float */ { @@ -649,16 +593,13 @@ struct cbor_decoder_result cbor_stream_decode( case 0xFD: /* Fallthrough */ case 0xFE: /* Reserved */ - { return (struct cbor_decoder_result){0, CBOR_DECODER_ERROR}; } + { return (struct cbor_decoder_result){.status = CBOR_DECODER_ERROR}; } case 0xFF: /* Break */ - { - callbacks->indef_break(context); - return result; - } - default: /* Never happens - this shuts up the compiler */ - { + callbacks->indef_break(context); + // Never happens, the switch statement is exhaustive on the 1B range; make + // compiler happy + default: return result; - } } } diff --git a/contrib/libcbor/src/cbor/streaming.h b/contrib/libcbor/src/cbor/streaming.h index 532d959b8b2e..cb908e17e9c9 100644 --- a/contrib/libcbor/src/cbor/streaming.h +++ b/contrib/libcbor/src/cbor/streaming.h @@ -18,16 +18,16 @@ extern "C" { /** Stateless decoder * - * Will try parsing the \p buffer and will invoke the appropriate callback on + * Will try parsing the \p source 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 source Input buffer + * @param source_size Length of the buffer * @param callbacks The callback bundle * @param context An arbitrary pointer to allow for maintaining context. */ -CBOR_EXPORT struct cbor_decoder_result cbor_stream_decode( - cbor_data buffer, size_t buffer_size, +_CBOR_NODISCARD CBOR_EXPORT struct cbor_decoder_result cbor_stream_decode( + cbor_data source, size_t source_size, const struct cbor_callbacks* callbacks, void* context); #ifdef __cplusplus diff --git a/contrib/libcbor/src/cbor/strings.c b/contrib/libcbor/src/cbor/strings.c index 209886b5f8c3..de2d1024bb4c 100644 --- a/contrib/libcbor/src/cbor/strings.c +++ b/contrib/libcbor/src/cbor/strings.c @@ -9,8 +9,8 @@ #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)); +cbor_item_t *cbor_new_definite_string(void) { + cbor_item_t *item = _cbor_malloc(sizeof(cbor_item_t)); _CBOR_NOTNULL(item); *item = (cbor_item_t){ .refcount = 1, @@ -19,15 +19,15 @@ cbor_item_t *cbor_new_definite_string() { return item; } -cbor_item_t *cbor_new_indefinite_string() { - cbor_item_t *item = _CBOR_MALLOC(sizeof(cbor_item_t)); +cbor_item_t *cbor_new_indefinite_string(void) { + 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))}; + .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){ @@ -42,7 +42,7 @@ 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); + unsigned char *handle = _cbor_malloc(len); _CBOR_DEPENDENT_NOTNULL(item, handle); memcpy(handle, val, len); cbor_string_set_handle(item, handle, len); @@ -52,7 +52,7 @@ cbor_item_t *cbor_build_string(const char *val) { 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); + unsigned char *handle = _cbor_malloc(length); _CBOR_DEPENDENT_NOTNULL(item, handle); memcpy(handle, val, length); cbor_string_set_handle(item, handle, length); @@ -62,31 +62,30 @@ cbor_item_t *cbor_build_stringn(const char *val, size_t 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)); + CBOR_ASSERT(cbor_isa_string(item)); + CBOR_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)); + CBOR_ASSERT(cbor_isa_string(item)); + CBOR_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)); + CBOR_ASSERT(cbor_isa_string(item)); + CBOR_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)); + CBOR_ASSERT(cbor_isa_string(item)); + CBOR_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; } @@ -109,22 +108,22 @@ bool cbor_string_add_chunk(cbor_item_t *item, cbor_item_t *chunk) { } size_t cbor_string_length(const cbor_item_t *item) { - assert(cbor_isa_string(item)); + CBOR_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)); + CBOR_ASSERT(cbor_isa_string(item)); return item->data; } size_t cbor_string_codepoint_count(const cbor_item_t *item) { - assert(cbor_isa_string(item)); + CBOR_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)); + CBOR_ASSERT(cbor_isa_string(item)); return item->metadata.string_metadata.type == _CBOR_METADATA_DEFINITE; } diff --git a/contrib/libcbor/src/cbor/strings.h b/contrib/libcbor/src/cbor/strings.h index 49398af842a0..7a18f95e29fa 100644 --- a/contrib/libcbor/src/cbor/strings.h +++ b/contrib/libcbor/src/cbor/strings.h @@ -21,48 +21,53 @@ extern "C" { * ============================================================================ */ -/** Returns the length of the underlying string +/** Returns the length of the underlying string in bytes * - * For definite strings only + * There can be fewer unicode character than bytes (see + * `cbor_string_codepoint_count`). For definite strings only. * - * @param item[borrow] a definite string + * @param item a definite string * @return length of the string. Zero if no chunk has been attached yet */ -CBOR_EXPORT size_t cbor_string_length(const cbor_item_t *item); +_CBOR_NODISCARD CBOR_EXPORT size_t cbor_string_length(const cbor_item_t *item); /** The number of codepoints in this string * * Might differ from length if there are multibyte ones * - * @param item[borrow] A string + * @param item A string * @return The number of codepoints in this string */ -CBOR_EXPORT size_t cbor_string_codepoint_count(const cbor_item_t *item); +_CBOR_NODISCARD CBOR_EXPORT size_t +cbor_string_codepoint_count(const cbor_item_t *item); /** Is the string definite? * - * @param item[borrow] a string + * @param item a string * @return Is the string definite? */ -CBOR_EXPORT bool cbor_string_is_definite(const cbor_item_t *item); +_CBOR_NODISCARD CBOR_EXPORT bool cbor_string_is_definite( + const cbor_item_t *item); /** Is the string indefinite? * - * @param item[borrow] a string + * @param item a string * @return Is the string indefinite? */ -CBOR_EXPORT bool cbor_string_is_indefinite(const cbor_item_t *item); +_CBOR_NODISCARD CBOR_EXPORT 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 * - * @param item[borrow] A definite string - * @return The address of the underlying string. `NULL` if no data have been - * assigned yet. + * @param item A definite string + * @return The address of the underlying string. + * @return `NULL` if no data have been assigned yet. */ -CBOR_EXPORT cbor_mutable_data cbor_string_handle(const cbor_item_t *item); +_CBOR_NODISCARD CBOR_EXPORT cbor_mutable_data +cbor_string_handle(const cbor_item_t *item); /** Set the handle to the underlying string * @@ -73,7 +78,7 @@ CBOR_EXPORT cbor_mutable_data cbor_string_handle(const cbor_item_t *item); * the CBOR item will be left inconsistent. * \endrst * - * @param item[borrow] A definite string + * @param item 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 length Length of the data block @@ -87,17 +92,19 @@ CBOR_EXPORT void cbor_string_set_handle( * 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 + * @param item A indefinite string * @return array of #cbor_string_chunk_count definite strings */ -CBOR_EXPORT cbor_item_t **cbor_string_chunks_handle(const cbor_item_t *item); +_CBOR_NODISCARD CBOR_EXPORT cbor_item_t **cbor_string_chunks_handle( + const cbor_item_t *item); /** Get the number of chunks this string consist of * - * @param item[borrow] A indefinite string + * @param item A indefinite string * @return The chunk count. 0 for freshly created items. */ -CBOR_EXPORT size_t cbor_string_chunk_count(const cbor_item_t *item); +_CBOR_NODISCARD CBOR_EXPORT size_t +cbor_string_chunk_count(const cbor_item_t *item); /** Appends a chunk to the string * @@ -105,46 +112,60 @@ CBOR_EXPORT size_t cbor_string_chunk_count(const cbor_item_t *item); * * May realloc the chunk storage. * - * @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. + * @param item An indefinite string + * @param chunk A definite string item. Its reference count will be increased + * by one. + * @return `true` on success. `false` on memory allocation failure. In that + * case, the refcount of @p `chunk` is not increased and the @p `item` is left + * intact. */ -CBOR_EXPORT bool cbor_string_add_chunk(cbor_item_t *item, cbor_item_t *chunk); +_CBOR_NODISCARD CBOR_EXPORT bool cbor_string_add_chunk(cbor_item_t *item, + cbor_item_t *chunk); /** Creates a new definite string * * The handle is initialized to `NULL` and length to 0 * - * @return **new** definite string. `NULL` on malloc failure. + * @return Reference to the new string item. The item's reference count is + * initialized to one. + * @return `NULL` if memory allocation fails */ -CBOR_EXPORT cbor_item_t *cbor_new_definite_string(); +_CBOR_NODISCARD CBOR_EXPORT cbor_item_t *cbor_new_definite_string(void); /** Creates a new indefinite string * * The chunks array is initialized to `NULL` and chunkcount to 0 * - * @return **new** indefinite string. `NULL` on malloc failure. + * @return Reference to the new string item. The item's reference count is + * initialized to one. + * @return `NULL` if memory allocation fails */ -CBOR_EXPORT cbor_item_t *cbor_new_indefinite_string(); +_CBOR_NODISCARD CBOR_EXPORT cbor_item_t *cbor_new_indefinite_string(void); /** Creates a new string and initializes it * * The `val` will be copied to a newly allocated block * * @param val A null-terminated UTF-8 string - * @return A **new** string with content `handle`. `NULL` on malloc failure. + * @return Reference to the new string item. The item's reference count is + * initialized to one. + * @return `NULL` if memory allocation fails */ -CBOR_EXPORT cbor_item_t *cbor_build_string(const char *val); +_CBOR_NODISCARD CBOR_EXPORT cbor_item_t *cbor_build_string(const char *val); /** Creates a new string and initializes it * * The `handle` will be copied to a newly allocated block * - * @param val A UTF-8 string, at least \p length long (excluding the null byte) - * @return A **new** string with content `handle`. `NULL` on malloc failure. + * @param val A UTF-8 string, at least @p `length` long (excluding the null + * byte) + * @param length Length (in bytes) of the string passed in @p `val`. + * @return Reference to the new string item. The item's reference count is + * initialized to one. + * @return `NULL` if memory allocation fails */ -CBOR_EXPORT cbor_item_t *cbor_build_stringn(const char *val, size_t length); +_CBOR_NODISCARD CBOR_EXPORT cbor_item_t *cbor_build_stringn(const char *val, + size_t length); #ifdef __cplusplus } diff --git a/contrib/libcbor/src/cbor/tags.c b/contrib/libcbor/src/cbor/tags.c index 60b3e69eacd4..3f3edb0b0e1d 100644 --- a/contrib/libcbor/src/cbor/tags.c +++ b/contrib/libcbor/src/cbor/tags.c @@ -8,7 +8,7 @@ #include "tags.h" cbor_item_t *cbor_new_tag(uint64_t value) { - cbor_item_t *item = _CBOR_MALLOC(sizeof(cbor_item_t)); + cbor_item_t *item = _cbor_malloc(sizeof(cbor_item_t)); _CBOR_NOTNULL(item); *item = (cbor_item_t){ @@ -21,23 +21,26 @@ cbor_item_t *cbor_new_tag(uint64_t value) { } cbor_item_t *cbor_tag_item(const cbor_item_t *item) { - assert(cbor_isa_tag(item)); + CBOR_ASSERT(cbor_isa_tag(item)); return cbor_incref(item->metadata.tag_metadata.tagged_item); } uint64_t cbor_tag_value(const cbor_item_t *item) { - assert(cbor_isa_tag(item)); + CBOR_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_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); + if (res == NULL) { + return NULL; + } cbor_tag_set_item(res, item); return res; } diff --git a/contrib/libcbor/src/cbor/tags.h b/contrib/libcbor/src/cbor/tags.h index f4b8028f7951..a7365df10208 100644 --- a/contrib/libcbor/src/cbor/tags.h +++ b/contrib/libcbor/src/cbor/tags.h @@ -24,39 +24,48 @@ extern "C" { /** Create a new tag * * @param value The tag value. Please consult the tag repository - * @return **new** tag. Item reference is `NULL`. Returns `NULL` upon - * memory allocation failure + * @return Reference to the new tag item. The item's reference count is + * initialized to one. + * @return `NULL` if memory allocation fails */ -CBOR_EXPORT cbor_item_t *cbor_new_tag(uint64_t value); +_CBOR_NODISCARD CBOR_EXPORT cbor_item_t *cbor_new_tag(uint64_t value); /** Get the tagged item * - * @param item[borrow] A tag - * @return **incref** the tagged item + * @param item A tag + * @return Reference to the tagged item + * + * Increases the reference count of the underlying item. The returned reference + * must be released using #cbor_decref. */ -CBOR_EXPORT cbor_item_t *cbor_tag_item(const cbor_item_t *item); +_CBOR_NODISCARD CBOR_EXPORT cbor_item_t *cbor_tag_item(const cbor_item_t *item); /** Get tag value * - * @param item[borrow] A tag + * @param item A tag * @return The tag value. Please consult the tag repository */ -CBOR_EXPORT uint64_t cbor_tag_value(const cbor_item_t *item); +_CBOR_NODISCARD CBOR_EXPORT uint64_t cbor_tag_value(const cbor_item_t *item); /** Set the tagged item * - * @param item[borrow] A tag - * @param tagged_item[incref] The item to tag + * @param item A tag + * @param tagged_item The item to tag. Its reference count will be increased + * by one. */ CBOR_EXPORT void cbor_tag_set_item(cbor_item_t *item, cbor_item_t *tagged_item); /** Build a new tag * - * @param item[incref] The tagee + * @param item The item to tag. Its reference count will be increased by + * one. * @param value Tag value - * @return **new** tag item + * @return Reference to the new tag item. The item's reference count is + * initialized to one. + * @return `NULL` if memory allocation fails */ -CBOR_EXPORT cbor_item_t *cbor_build_tag(uint64_t value, cbor_item_t *item); +_CBOR_NODISCARD CBOR_EXPORT cbor_item_t *cbor_build_tag(uint64_t value, + cbor_item_t *item); #ifdef __cplusplus } |