diff --git a/include/nanocbor/nanocbor.h b/include/nanocbor/nanocbor.h index 6ccf7d1..85aa80d 100644 --- a/include/nanocbor/nanocbor.h +++ b/include/nanocbor/nanocbor.h @@ -482,8 +482,11 @@ int nanocbor_enter_map(const nanocbor_value_t *it, nanocbor_value_t *map); * * @param[in] it parent CBOR structure * @param[in] container exhausted CBOR container + * + * @return NANOCBOR_OK on success + * @return negative on error */ -void nanocbor_leave_container(nanocbor_value_t *it, +int nanocbor_leave_container(nanocbor_value_t *it, nanocbor_value_t *container); /** diff --git a/src/decoder.c b/src/decoder.c index de06302..5c279bc 100644 --- a/src/decoder.c +++ b/src/decoder.c @@ -513,8 +513,15 @@ int nanocbor_enter_map(const nanocbor_value_t *it, nanocbor_value_t *map) return res; } -void nanocbor_leave_container(nanocbor_value_t *it, nanocbor_value_t *container) +int nanocbor_leave_container(nanocbor_value_t *it, nanocbor_value_t *container) { + /* check `container` to be a valid, fully consumed container that is plausible to have been entered from `it` */ + if (!nanocbor_in_container(container) || + !nanocbor_at_end(container) || + container->cur <= it->cur || + container->cur > it->end) { + return NANOCBOR_ERR_INVALID_TYPE; + } if (it->remaining) { it->remaining--; } @@ -524,6 +531,7 @@ void nanocbor_leave_container(nanocbor_value_t *it, nanocbor_value_t *container) else { it->cur = container->cur; } + return NANOCBOR_OK; } static int _skip_simple(nanocbor_value_t *it) diff --git a/tests/automated/test_decoder.c b/tests/automated/test_decoder.c index 3f156c1..d60c2a1 100644 --- a/tests/automated/test_decoder.c +++ b/tests/automated/test_decoder.c @@ -52,7 +52,7 @@ static void test_decode_map(void) nanocbor_decoder_init(&val, map_empty, sizeof(map_empty)); CU_ASSERT_EQUAL(nanocbor_enter_map(&val, &cont), NANOCBOR_OK); CU_ASSERT_EQUAL(nanocbor_at_end(&cont), true); - nanocbor_leave_container(&val, &cont); + CU_ASSERT_EQUAL(nanocbor_leave_container(&val, &cont), NANOCBOR_OK); CU_ASSERT_EQUAL(nanocbor_at_end(&val), true); /* Init the decoder and verify the decoding of the map elements */ @@ -63,7 +63,7 @@ static void test_decode_map(void) CU_ASSERT(nanocbor_get_uint32(&cont, &tmp) > 0); CU_ASSERT_EQUAL(tmp, 2); CU_ASSERT_EQUAL(nanocbor_at_end(&cont), true); - nanocbor_leave_container(&val, &cont); + CU_ASSERT_EQUAL(nanocbor_leave_container(&val, &cont), NANOCBOR_OK); CU_ASSERT_EQUAL(nanocbor_at_end(&val), true); /* Init the decoder and skip over the empty map */ @@ -89,21 +89,21 @@ static void test_decode_map(void) CU_ASSERT_EQUAL(tmp, 3); CU_ASSERT_EQUAL(nanocbor_enter_array(&cont, &array), NANOCBOR_OK); CU_ASSERT_EQUAL(nanocbor_at_end(&array), true); - nanocbor_leave_container(&cont, &array); + CU_ASSERT_EQUAL(nanocbor_leave_container(&cont, &array), NANOCBOR_OK); CU_ASSERT_EQUAL(nanocbor_at_end(&cont), false); CU_ASSERT(nanocbor_get_uint32(&cont, &tmp) > 0); CU_ASSERT_EQUAL(tmp, 4); CU_ASSERT_EQUAL(nanocbor_enter_array(&cont, &array), NANOCBOR_OK); CU_ASSERT_EQUAL(nanocbor_at_end(&array), true); - nanocbor_leave_container(&cont, &array); + CU_ASSERT_EQUAL(nanocbor_leave_container(&cont, &array), NANOCBOR_OK); CU_ASSERT_EQUAL(nanocbor_at_end(&cont), false); CU_ASSERT(nanocbor_get_uint32(&cont, &tmp) > 0); CU_ASSERT_EQUAL(tmp, 5); CU_ASSERT_EQUAL(nanocbor_enter_array(&cont, &array), NANOCBOR_OK); CU_ASSERT_EQUAL(nanocbor_at_end(&array), true); - nanocbor_leave_container(&cont, &array); + CU_ASSERT_EQUAL(nanocbor_leave_container(&cont, &array), NANOCBOR_OK); CU_ASSERT_EQUAL(nanocbor_at_end(&cont), false); CU_ASSERT(nanocbor_get_uint32(&cont, &tmp) > 0);