diff --git a/pkg/nanocbor/Makefile b/pkg/nanocbor/Makefile index 854f1f81204c..91d6ac229f59 100644 --- a/pkg/nanocbor/Makefile +++ b/pkg/nanocbor/Makefile @@ -1,6 +1,6 @@ PKG_NAME = nanocbor PKG_URL = https://github.com/bergzand/nanocbor -PKG_VERSION = 3a672f79b2458a96393447e50a41174f741eadc5 +PKG_VERSION = 16e5a838b97fc3c912b8f419497e3fff2210994e PKG_LICENSE = LGPL-2.1 include $(RIOTBASE)/pkg/pkg.mk diff --git a/pkg/nanocbor/patches/0001-decoder-fix-decoding-of-indefinite-arrays-and-maps.patch b/pkg/nanocbor/patches/0001-decoder-fix-decoding-of-indefinite-arrays-and-maps.patch new file mode 100644 index 000000000000..6027f4ee649c --- /dev/null +++ b/pkg/nanocbor/patches/0001-decoder-fix-decoding-of-indefinite-arrays-and-maps.patch @@ -0,0 +1,37 @@ +From 8f7e2123998b5444128ea907aaba0d847c502cde Mon Sep 17 00:00:00 2001 +From: Nishchay-sopho +Date: Tue, 18 Aug 2020 14:34:55 +0200 +Subject: [PATCH] decoder: fix decoding of indefinite arrays and maps + +--- + src/decoder.c | 6 +++--- + 1 file changed, 3 insertions(+), 3 deletions(-) + +diff --git a/src/decoder.c b/src/decoder.c +index 244a6b1..9cd27b8 100644 +--- a/src/decoder.c ++++ b/src/decoder.c +@@ -76,9 +76,9 @@ bool nanocbor_at_end(const nanocbor_value_t *it) + 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))) || ++ *it->cur == (NANOCBOR_TYPE_FLOAT << NANOCBOR_TYPE_OFFSET | NANOCBOR_VALUE_MASK))) || + /* Or the remaining number of items is zero */ +- (nanocbor_in_container(it) && it->remaining == 0) ++ (!nanocbor_container_indefinite(it) && nanocbor_in_container(it) && it->remaining == 0) + ) { + end = true; + } +@@ -279,7 +279,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, (((unsigned)type << NANOCBOR_TYPE_OFFSET) | NANOCBOR_SIZE_INDEFINITE)) == 1) { + container->flags = NANOCBOR_DECODER_FLAG_INDEFINITE | + NANOCBOR_DECODER_FLAG_CONTAINER; + container->cur = it->cur; +-- +2.25.1 + diff --git a/tests/pkg_nanocbor/main.c b/tests/pkg_nanocbor/main.c index 9168e50a5a34..12c8bc9d1351 100644 --- a/tests/pkg_nanocbor/main.c +++ b/tests/pkg_nanocbor/main.c @@ -61,10 +61,143 @@ void test_nanocbor_encode(void) TEST_ASSERT_EQUAL_INT(0, memcmp(buf, expected, sizeof(expected))); } +enum { + CFG_FOO, + CFG_BAR, + CFG_RANGE, +}; + +typedef struct { + uint32_t foo; + uint32_t bar; + uint32_t min; + uint32_t mean; + uint32_t max; +} test_cfg_t; + +static size_t _serialize_config(uint8_t *buffer, size_t len, const test_cfg_t *cfg) +{ + nanocbor_encoder_t enc; + nanocbor_encoder_init(&enc, buffer, len); + + nanocbor_fmt_map_indefinite(&enc); + + /* write key - value pair*/ + nanocbor_fmt_uint(&enc, CFG_FOO); + nanocbor_fmt_uint(&enc, cfg->foo); + + /* write key - value pair*/ + nanocbor_fmt_uint(&enc, CFG_BAR); + nanocbor_fmt_uint(&enc, cfg->bar); + + /* write key - value pair*/ + nanocbor_fmt_uint(&enc, CFG_RANGE); + nanocbor_fmt_array(&enc, 3); + nanocbor_fmt_uint(&enc, cfg->min); + nanocbor_fmt_uint(&enc, cfg->mean); + nanocbor_fmt_uint(&enc, cfg->max); + + nanocbor_fmt_end_indefinite(&enc); + + return nanocbor_encoded_len(&enc); +} + +static bool _decode_period(nanocbor_value_t *it, test_cfg_t *cfg) +{ + nanocbor_value_t array; + + if (nanocbor_enter_array(it, &array) <= 0) { + return false; + } + + if (nanocbor_get_uint32(&array, &cfg->min) <= 0) { + return false; + } + + if (nanocbor_get_uint32(&array, &cfg->mean) <= 0) { + return false; + } + + if (nanocbor_get_uint32(&array, &cfg->max) <= 0) { + return false; + } + + nanocbor_leave_container(it, &array); + + return true; +} + +static bool _cfg_cb(nanocbor_value_t *map, uint32_t key, void *dst) +{ + test_cfg_t *cfg = dst; + + switch (key) { + case CFG_FOO: + return nanocbor_get_uint32(map, &cfg->foo) > 0; + case CFG_BAR: + return nanocbor_get_uint32(map, &cfg->bar) > 0; + case CFG_RANGE: + return _decode_period(map, cfg); + default: + nanocbor_skip(map); + } + + return true; +} + +static bool _parse_config(const uint8_t *buffer, size_t len, test_cfg_t *cfg) +{ + nanocbor_value_t msg, map; + nanocbor_decoder_init(&msg, buffer, len); + + if (nanocbor_enter_map(&msg, &map) < 0) { + return false; + } + + while (!nanocbor_at_end(&map)) { + uint32_t key; + if (nanocbor_get_uint32(&map, &key) < 0) { + return false; + } + + if (!_cfg_cb(&map, key, cfg)) { + return false; + } + } + + return true; +} + +void test_nanocbor_encode_decode_cfg(void) +{ + uint8_t buffer[64]; + + test_cfg_t cfg = { + .foo = 23, + .bar = 42, + .min = 5, + .mean = 30, + .max = 60, + }; + + size_t len = _serialize_config(buffer, sizeof(buffer), &cfg); + TEST_ASSERT(len < sizeof(buffer)); + + test_cfg_t new_cfg; + TEST_ASSERT(_parse_config(buffer, len, &new_cfg)); + + TEST_ASSERT_EQUAL_INT(cfg.foo, new_cfg.foo); + TEST_ASSERT_EQUAL_INT(cfg.bar, new_cfg.bar); + TEST_ASSERT_EQUAL_INT(cfg.min, new_cfg.min); + TEST_ASSERT_EQUAL_INT(cfg.mean, new_cfg.mean); + TEST_ASSERT_EQUAL_INT(cfg.max, new_cfg.max); +} + Test *tests_nanocbor(void) { EMB_UNIT_TESTFIXTURES(fixtures) { new_TestFixture(test_nanocbor_encode), + new_TestFixture(test_nanocbor_encode_decode_cfg), }; EMB_UNIT_TESTCALLER(nanocbor_tests, NULL, NULL, fixtures); return (Test *)&nanocbor_tests;