summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/ecbor.c16
-rw-r--r--src/ecbor_decoder.c55
2 files changed, 40 insertions, 31 deletions
diff --git a/src/ecbor.c b/src/ecbor.c
index 9612605..cb489f8 100644
--- a/src/ecbor.c
+++ b/src/ecbor.c
@@ -41,7 +41,10 @@ ecbor_get_value (ecbor_item_t *item, void *value)
case ECBOR_MT_BSTR:
case ECBOR_MT_STR:
- *((uint8_t **)value) = (uint8_t *) item->value.string;
+ if (item->is_indefinite) {
+ return ECBOR_ERR_WONT_RETURN_INDEFINITE;
+ }
+ *((uint8_t **)value) = (uint8_t *) item->value.string.str;
break;
case ECBOR_MT_TAG:
@@ -68,15 +71,12 @@ ecbor_get_length (ecbor_item_t *item, uint64_t *length)
switch (item->major_type) {
case ECBOR_MT_BSTR:
case ECBOR_MT_STR:
- *length = item->size;
- break;
-
case ECBOR_MT_ARRAY:
- *length = item->n_chunks;
+ *length = item->length;
break;
case ECBOR_MT_MAP:
- *length = item->n_chunks / 2;
+ *length = item->length / 2;
break;
default:
@@ -100,7 +100,7 @@ ecbor_get_array_item (ecbor_item_t *array, uint64_t index,
if (array->major_type != ECBOR_MT_ARRAY) {
return ECBOR_ERR_INVALID_TYPE;
}
- if (array->n_chunks <= index) {
+ if (array->length <= index) {
return ECBOR_ERR_INDEX_OUT_OF_BOUNDS;
}
if (!item) {
@@ -140,7 +140,7 @@ ecbor_get_map_item (ecbor_item_t *map, uint64_t index, ecbor_item_t *key,
if (map->major_type != ECBOR_MT_ARRAY) {
return ECBOR_ERR_INVALID_TYPE;
}
- if (map->n_chunks <= (index * 2)) {
+ if (map->length <= (index * 2)) {
return ECBOR_ERR_INDEX_OUT_OF_BOUNDS;
}
if (!key || !value) {
diff --git a/src/ecbor_decoder.c b/src/ecbor_decoder.c
index c53dc2f..dfd3cad 100644
--- a/src/ecbor_decoder.c
+++ b/src/ecbor_decoder.c
@@ -134,6 +134,9 @@ ecbor_decode_uint (ecbor_decode_context_t *context,
/* advance buffer */
context->in_position += (*size);
context->bytes_left -= (*size);
+
+ /* meter the first byte */
+ (*size) ++;
}
return ECBOR_OK;
@@ -160,7 +163,7 @@ ecbor_decode_next_internal (ecbor_decode_context_t *context,
/* clear item, just so we do not leave garbage on partial read */
item->major_type = ECBOR_MT_UNDEFINED;
item->size = 0;
- item->n_chunks = 0;
+ item->length = 0;
item->is_indefinite = false;
/* extract major type (most significant three bits) and additional info */
@@ -213,7 +216,8 @@ ecbor_decode_next_internal (ecbor_decode_context_t *context,
case ECBOR_MT_BSTR:
case ECBOR_MT_STR:
/* keep buffer pointer from current pointer */
- item->value.string = context->in_position;
+ item->value.string.str = context->in_position;
+ item->value.string.n_chunks = 0;
/* discriminate between definite and indefinite strings; we do not treat
* indefinite strings as we do indefinite maps and arrays, in the sense
@@ -225,6 +229,7 @@ ecbor_decode_next_internal (ecbor_decode_context_t *context,
/* mark accordingly */
item->is_indefinite = true;
+ item->size = 1; /* already processed first byte */
/* do not allow nested indefinite length strings */
if (is_chunk) {
@@ -232,7 +237,7 @@ ecbor_decode_next_internal (ecbor_decode_context_t *context,
}
/* indefinite lenght string; read through all blocks to compute size */
- item->value.string = context->in_position;
+ item->value.string.str = context->in_position;
while (true) {
/* read next chunk */
@@ -241,6 +246,7 @@ ecbor_decode_next_internal (ecbor_decode_context_t *context,
if (rc != ECBOR_OK) {
if (rc == ECBOR_END_OF_INDEFINITE) {
/* stop code found, break from loop */
+ item->size += chunk.size; /* meter stop code as well */
break;
} else if (rc == ECBOR_END_OF_BUFFER) {
/* treat a valid end of buffer as invalid since we did not yet
@@ -252,26 +258,28 @@ ecbor_decode_next_internal (ecbor_decode_context_t *context,
}
}
- /* add chunk size to item size */
+ /* add chunk size and length to item */
item->size += chunk.size;
- item->n_chunks ++;
+ item->length += chunk.length;
+ item->value.string.n_chunks ++;
}
} else {
- uint64_t foo;
-
/* read size of buffer */
- ecbor_error_t rc = ecbor_decode_uint (context, &item->size, &foo,
- additional);
+ ecbor_error_t rc = ecbor_decode_uint (context, &item->length,
+ &item->size, additional);
if (rc != ECBOR_OK) {
return rc;
}
/* advance */
- if (context->bytes_left < item->size) {
+ if (context->bytes_left < item->length) {
return ECBOR_ERR_INVALID_END_OF_BUFFER;
}
- context->in_position += item->size;
- context->bytes_left -= item->size;
+ context->in_position += item->length;
+ context->bytes_left -= item->length;
+
+ /* meter length of string to size of item */
+ item->size += item->length;
}
break;
@@ -287,6 +295,7 @@ ecbor_decode_next_internal (ecbor_decode_context_t *context,
if (additional == ECBOR_ADDITIONAL_INDEFINITE) {
/* mark accordingly */
item->is_indefinite = true;
+ item->size = 1; /* already processed first byte */
if (context->mode != ECBOR_MODE_DECODE_STREAMED) {
/* we have an indefinite map or array and we're not in streamed mode;
@@ -301,6 +310,7 @@ ecbor_decode_next_internal (ecbor_decode_context_t *context,
if (rc != ECBOR_OK) {
if (rc == ECBOR_END_OF_INDEFINITE) {
/* stop code found, break from loop */
+ item->size += child.size; /* meter stop code as well */
break;
} else if (rc == ECBOR_END_OF_BUFFER) {
/* treat a valid end of buffer as invalid since we did not yet
@@ -314,29 +324,27 @@ ecbor_decode_next_internal (ecbor_decode_context_t *context,
/* add chunk size to item size */
item->size += child.size;
- item->n_chunks ++;
+ item->length ++;
}
- if ((item->major_type == ECBOR_MT_MAP) && (item->n_chunks % 2 != 0)) {
+ if ((item->major_type == ECBOR_MT_MAP) && (item->length % 2 != 0)) {
/* incomplete key-value pair; we expect maps to have even number of
items */
return ECBOR_ERR_INVALID_KEY_VALUE_PAIR;
}
}
} else {
- uint64_t foo;
-
/* read size of map or array */
- ecbor_error_t rc = ecbor_decode_uint (context, &item->n_chunks, &foo,
- additional);
+ ecbor_error_t rc = ecbor_decode_uint (context, &item->length,
+ &item->size, additional);
if (rc != ECBOR_OK) {
return rc;
}
if (item->major_type == ECBOR_MT_MAP) {
- /* we keep the total number of items in n_chunks, yet the map has the
+ /* we keep the total number of items in length, yet the map has the
number of key-value pairs encoded in the length */
- item->n_chunks *= 2;
+ item->length *= 2;
}
if (context->mode != ECBOR_MODE_DECODE_STREAMED) {
@@ -345,7 +353,7 @@ ecbor_decode_next_internal (ecbor_decode_context_t *context,
uint64_t child_no;
/* not in streamed mode; compute size so we can advance */
- for (child_no = 0; child_no < item->n_chunks; child_no ++) {
+ for (child_no = 0; child_no < item->length; child_no ++) {
/* read next child */
rc = ecbor_decode_next_internal (context, &child, false,
ECBOR_MT_UNDEFINED);
@@ -383,7 +391,7 @@ ecbor_decode_next_internal (ecbor_decode_context_t *context,
/* keep child pointer */
item->value.tag.child = context->in_position;
- item->n_chunks = 1;
+ item->length = 1;
if (context->mode != ECBOR_MODE_DECODE_STREAMED) {
ecbor_item_t child;
@@ -398,6 +406,7 @@ ecbor_decode_next_internal (ecbor_decode_context_t *context,
case ECBOR_MT_SPECIAL:
if (additional == ECBOR_ADDITIONAL_INDEFINITE) {
/* stop code */
+ item->size = 1;
return ECBOR_END_OF_INDEFINITE;
} else {
return ECBOR_ERR_CURRENTLY_NOT_SUPPORTED;
@@ -540,7 +549,7 @@ ecbor_decode_tree (ecbor_decode_context_t *context)
|| par_node->item.major_type == ECBOR_MT_ARRAY
|| par_node->item.major_type == ECBOR_MT_TAG)
&& !par_node->item.is_indefinite
- && par_node->item.n_chunks == (curr_node->index + 1)) {
+ && par_node->item.length == (curr_node->index + 1)) {
/* parent has filled all items, jump a level up */
curr_node = par_node;
par_node = curr_node->parent;