aboutsummaryrefslogtreecommitdiff
path: root/contrib/libcbor/src/cbor
diff options
context:
space:
mode:
Diffstat (limited to 'contrib/libcbor/src/cbor')
-rw-r--r--contrib/libcbor/src/cbor/arrays.c22
-rw-r--r--contrib/libcbor/src/cbor/arrays.h71
-rw-r--r--contrib/libcbor/src/cbor/bytestrings.c40
-rw-r--r--contrib/libcbor/src/cbor/bytestrings.h54
-rw-r--r--contrib/libcbor/src/cbor/callbacks.c153
-rw-r--r--contrib/libcbor/src/cbor/callbacks.h14
-rw-r--r--contrib/libcbor/src/cbor/common.c29
-rw-r--r--contrib/libcbor/src/cbor/common.h152
-rw-r--r--contrib/libcbor/src/cbor/configuration.h.in1
-rw-r--r--contrib/libcbor/src/cbor/data.h11
-rw-r--r--contrib/libcbor/src/cbor/encoding.c20
-rw-r--r--contrib/libcbor/src/cbor/encoding.h103
-rw-r--r--contrib/libcbor/src/cbor/floats_ctrls.c64
-rw-r--r--contrib/libcbor/src/cbor/floats_ctrls.h114
-rw-r--r--contrib/libcbor/src/cbor/internal/builder_callbacks.c230
-rw-r--r--contrib/libcbor/src/cbor/internal/builder_callbacks.h12
-rw-r--r--contrib/libcbor/src/cbor/internal/encoders.c28
-rw-r--r--contrib/libcbor/src/cbor/internal/encoders.h5
-rw-r--r--contrib/libcbor/src/cbor/internal/loaders.c2
-rw-r--r--contrib/libcbor/src/cbor/internal/loaders.h9
-rw-r--r--contrib/libcbor/src/cbor/internal/memory_utils.c17
-rw-r--r--contrib/libcbor/src/cbor/internal/memory_utils.h13
-rw-r--r--contrib/libcbor/src/cbor/internal/stack.c6
-rw-r--r--contrib/libcbor/src/cbor/internal/stack.h14
-rw-r--r--contrib/libcbor/src/cbor/internal/unicode.c9
-rw-r--r--contrib/libcbor/src/cbor/internal/unicode.h7
-rw-r--r--contrib/libcbor/src/cbor/ints.c59
-rw-r--r--contrib/libcbor/src/cbor/ints.h61
-rw-r--r--contrib/libcbor/src/cbor/maps.c21
-rw-r--r--contrib/libcbor/src/cbor/maps.h65
-rw-r--r--contrib/libcbor/src/cbor/serialization.c276
-rw-r--r--contrib/libcbor/src/cbor/serialization.h135
-rw-r--r--contrib/libcbor/src/cbor/streaming.c181
-rw-r--r--contrib/libcbor/src/cbor/streaming.h10
-rw-r--r--contrib/libcbor/src/cbor/strings.c39
-rw-r--r--contrib/libcbor/src/cbor/strings.h87
-rw-r--r--contrib/libcbor/src/cbor/tags.c11
-rw-r--r--contrib/libcbor/src/cbor/tags.h35
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
}