Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

bug fixes for indefinite containers #31

Open
wants to merge 5 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 21 additions & 0 deletions include/nanocbor/nanocbor.h
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,17 @@ extern "C" {
#define NANOCBOR_SIZE_WORD 26U /**< Value contained in a word */
#define NANOCBOR_SIZE_LONG 27U /**< Value contained in a long */
#define NANOCBOR_SIZE_INDEFINITE 31U /**< Indefinite sized container */
#define NANOCBOR_END_MARKER (0xFFU) /**< Indefinite end */
/** @} */

/**
* @name CBOR tag types
* @{
*/
#define NANOCBOR_TAG_TSTR 0U /**< Standard date/time string */
#define NANOCBOR_TAG_EPOCH 1U /**< Epoch-based date/time */
#define NANOCBOR_TAG_UBIGNUM 2U /**< Unsigned bignum */
#define NANOCBOR_TAG_NBIGNUM 3U /**< Negative bignum */
/** @} */

/**
Expand Down Expand Up @@ -187,6 +198,16 @@ void nanocbor_decoder_init(nanocbor_value_t *value,
*/
int nanocbor_get_type(const nanocbor_value_t *value);

/**
* @brief Retrieve the CBOR value at the current position
*
* @param[in] value decoder value context
*
* @return value
* @return NANOCBOR_ERR_OVERFLOW if the buffer is exhausted
*/
int nanocbor_get_value(const nanocbor_value_t *value);

/**
* @brief Check if the current buffer or container is exhausted
*
Expand Down
13 changes: 10 additions & 3 deletions src/decoder.c
Original file line number Diff line number Diff line change
Expand Up @@ -75,8 +75,7 @@ bool nanocbor_at_end(const nanocbor_value_t *it)
/* The container is at the end when */
if (_over_end(it) || /* Number of items exhausted */
/* Indefinite container and the current item is the end marker */
((nanocbor_container_indefinite(it) &&
*it->cur == (NANOCBOR_TYPE_FLOAT | NANOCBOR_SIZE_INDEFINITE))) ||
((nanocbor_container_indefinite(it) && *it->cur == (NANOCBOR_END_MARKER))) ||
/* Or the remaining number of items is zero */
(nanocbor_in_container(it) && it->remaining == 0)
) {
Expand All @@ -93,6 +92,14 @@ int nanocbor_get_type(const nanocbor_value_t *value)
return (_get_type(value) >> NANOCBOR_TYPE_OFFSET);
}

int nanocbor_get_value(const nanocbor_value_t *value)
{
if (nanocbor_at_end(value)) {
return NANOCBOR_ERR_END;
}
return (*value->cur & NANOCBOR_VALUE_MASK);
}

static int _get_uint64(nanocbor_value_t *cvalue, uint32_t *value, uint8_t max, int type)
{
int ctype = nanocbor_get_type(cvalue);
Expand Down Expand Up @@ -279,7 +286,7 @@ int _enter_container(nanocbor_value_t *it, nanocbor_value_t *container,
container->end = it->end;
container->remaining = 0;

if (_value_match_exact(it, type | NANOCBOR_VALUE_MASK) == 1) {
if (_value_match_exact(it, (type << NANOCBOR_TYPE_OFFSET) | NANOCBOR_VALUE_MASK) == 1) {
container->flags = NANOCBOR_DECODER_FLAG_INDEFINITE |
NANOCBOR_DECODER_FLAG_CONTAINER;
container->cur = it->cur;
Expand Down
1 change: 1 addition & 0 deletions tests/fuzz/inputs/tagged_date.cbor
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
�t2013-03-21T20:04:00Z
34 changes: 34 additions & 0 deletions tests/fuzz/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,35 @@ void _parse_map(nanocbor_value_t *it, unsigned indent)
}
}

static int _parse_tag(nanocbor_value_t *value, unsigned indent)
{
if (indent > 10) {
return -2;
}
switch (nanocbor_get_value(value)) {
case NANOCBOR_TAG_TSTR:
{
const uint8_t *buf;
size_t len;
if (nanocbor_skip_simple(value) <= 0) {
return -1;
}
if (nanocbor_get_tstr(value, &buf, &len) >= 0) {
printf("\"%.*s\"", (int)len, buf);
}
else {
return -1;
}
}
break;
default:
printf("Unsupported type\n");
return -1;

}
return 1;
}

static int _parse_type(nanocbor_value_t *value, unsigned indent)
{
uint8_t type = nanocbor_get_type(value);
Expand Down Expand Up @@ -159,6 +188,11 @@ static int _parse_type(nanocbor_value_t *value, unsigned indent)
}
break;
}
case NANOCBOR_TYPE_TAG:
{
_parse_tag(value, indent);
}
break;
default:
printf("Unsupported type\n");
return -1;
Expand Down