From c2ce1adfd78bc36c5fca1ff9d7dd368ba4c2d24f Mon Sep 17 00:00:00 2001 From: Carsten Bormann Date: Wed, 27 May 2015 13:44:55 +0200 Subject: [PATCH 1/6] Temporary fix for #29 --- src/cn-cbor.c | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/src/cn-cbor.c b/src/cn-cbor.c index a0cd06c..250db49 100644 --- a/src/cn-cbor.c +++ b/src/cn-cbor.c @@ -50,8 +50,23 @@ static double decode_half(int half) { /* Fix these if you can't do non-aligned reads */ #define ntoh8p(p) (*(unsigned char*)(p)) +#ifdef CBOR_CAN_DO_UNALIGNED_READS #define ntoh16p(p) (ntohs(*(unsigned short*)(p))) #define ntoh32p(p) (ntohl(*(unsigned long*)(p))) +#else +static uint16_t ntoh16p(unsigned char *p) { + uint16_t ret = ntoh8p(p); + ret <<= 8; + ret += ntoh8p(p+1); + return ret; +} +static uint32_t ntoh32p(unsigned char *p) { + uint64_t ret = ntoh16p(p); + ret <<= 16; + ret += ntoh16p(p+2); + return ret; +} +#endif static uint64_t ntoh64p(unsigned char *p) { uint64_t ret = ntoh32p(p); ret <<= 32; From 7c9d7ae9a7650b4ab679e11d0aa36c7bfbebe42e Mon Sep 17 00:00:00 2001 From: Carsten Bormann Date: Wed, 27 May 2015 13:47:57 +0200 Subject: [PATCH 2/6] ... and work around the original problem of #29, as well. --- src/cn-cbor.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/cn-cbor.c b/src/cn-cbor.c index 250db49..996de1a 100644 --- a/src/cn-cbor.c +++ b/src/cn-cbor.c @@ -13,7 +13,9 @@ extern "C" { #include #include #include +#ifdef CBOR_CAN_DO_UNALIGNED_READS #include // needed for ntohl (e.g.) on Linux +#endif #include "cn-cbor/cn-cbor.h" #include "cbor.h" From a6e59627ae138b6a3eb3ce787737d33e76ae8f55 Mon Sep 17 00:00:00 2001 From: Olaf Bergmann Date: Tue, 26 May 2015 19:51:35 +0200 Subject: [PATCH 3/6] Rename cbor_encoder_write() to cn_cbor_encoder_write() The public API prefixes all symbols with cn_cbor_, so it seems reasonable to rename cbor_encoder_write() to cn_cbor_encoder_write(). --- include/cn-cbor/cn-cbor.h | 8 ++++---- src/cn-encoder.c | 8 ++++---- test/cbor_test.c | 12 ++++++------ 3 files changed, 14 insertions(+), 14 deletions(-) diff --git a/include/cn-cbor/cn-cbor.h b/include/cn-cbor/cn-cbor.h index 7dc67a3..86e4a4c 100644 --- a/include/cn-cbor/cn-cbor.h +++ b/include/cn-cbor/cn-cbor.h @@ -263,10 +263,10 @@ void cn_cbor_free(const cn_cbor* cb CBOR_CONTEXT); * @param[in] cb [description] * @return -1 on fail, or number of bytes written */ -ssize_t cbor_encoder_write(uint8_t *buf, - size_t buf_offset, - size_t buf_size, - const cn_cbor *cb); +ssize_t cn_cbor_encoder_write(uint8_t *buf, + size_t buf_offset, + size_t buf_size, + const cn_cbor *cb); /** * Create a CBOR map. diff --git a/src/cn-encoder.c b/src/cn-encoder.c index f53e2c6..8593b39 100644 --- a/src/cn-encoder.c +++ b/src/cn-encoder.c @@ -291,10 +291,10 @@ void _encoder_breaker(const cn_cbor *cb, int depth, void *context) write_byte_ensured(IB_BREAK); } -ssize_t cbor_encoder_write(uint8_t *buf, - size_t buf_offset, - size_t buf_size, - const cn_cbor *cb) +ssize_t cn_cbor_encoder_write(uint8_t *buf, + size_t buf_offset, + size_t buf_size, + const cn_cbor *cb) { cn_write_state ws = { buf, buf_offset, buf_size }; _visit(cb, _encoder_visitor, _encoder_breaker, &ws); diff --git a/test/cbor_test.c b/test/cbor_test.c index 43f73a4..ebd5edd 100644 --- a/test/cbor_test.c +++ b/test/cbor_test.c @@ -125,7 +125,7 @@ CTEST(cbor, parse) ASSERT_EQUAL(err.err, CN_CBOR_NO_ERROR); ASSERT_NOT_NULL(cb); - enc_sz = cbor_encoder_write(encoded, 0, sizeof(encoded), cb); + enc_sz = cn_cbor_encoder_write(encoded, 0, sizeof(encoded), cb); ASSERT_DATA(b.ptr, b.sz, encoded, enc_sz); free(b.ptr); cn_cbor_free(cb CONTEXT_NULL); @@ -174,7 +174,7 @@ CTEST(cbor, parse_normalize) ASSERT_EQUAL(err.err, CN_CBOR_NO_ERROR); ASSERT_NOT_NULL(cb); - enc_sz = cbor_encoder_write(encoded, 0, sizeof(encoded), cb); + enc_sz = cn_cbor_encoder_write(encoded, 0, sizeof(encoded), cb); ASSERT_DATA(b2.ptr, b2.sz, encoded, enc_sz); free(b.ptr); free(b2.ptr); @@ -195,7 +195,7 @@ CTEST(cbor, parse_normalize) ASSERT_NULL(cb); #endif /* CBOR_NO_FLOAT */ - /* enc_sz = cbor_encoder_write(encoded, 0, sizeof(encoded), cb); */ + /* enc_sz = cn_cbor_encoder_write(encoded, 0, sizeof(encoded), cb); */ /* ASSERT_DATA(b2.ptr, b2.sz, encoded, enc_sz); */ free(b.ptr); free(b2.ptr); @@ -227,7 +227,7 @@ CTEST(cbor, fail) uint8_t buf[10]; cn_cbor inv = {CN_CBOR_INVALID, 0, {0}, 0, NULL, NULL, NULL, NULL}; - ASSERT_EQUAL(-1, cbor_encoder_write(buf, 0, sizeof(buf), &inv)); + ASSERT_EQUAL(-1, cn_cbor_encoder_write(buf, 0, sizeof(buf), &inv)); for (i=0; i Date: Wed, 26 Aug 2015 10:35:15 -0600 Subject: [PATCH 4/6] Missing scratchbang somehow. --- build.sh | 1 + 1 file changed, 1 insertion(+) diff --git a/build.sh b/build.sh index a07f37f..69dd2e9 100755 --- a/build.sh +++ b/build.sh @@ -1,3 +1,4 @@ +#!/bin/sh if [ ! -d "build" ]; then mkdir build fi From 94e901fc34f81190e1b9df43417ac99d3db05b95 Mon Sep 17 00:00:00 2001 From: Joe Hildebrand Date: Wed, 26 Aug 2015 10:37:02 -0600 Subject: [PATCH 5/6] Remove extraneous const's, fix tests to match, and add an assert to cn_cbor_free to ensure we're at the root. Freeing NULL is still allowed as a no-op. --- include/cn-cbor/cn-cbor.h | 10 +++++----- src/cn-cbor.c | 7 ++++--- src/cn-get.c | 6 +++--- test/cbor_test.c | 12 ++++++------ test/test.c | 2 +- 5 files changed, 19 insertions(+), 18 deletions(-) diff --git a/include/cn-cbor/cn-cbor.h b/include/cn-cbor/cn-cbor.h index 86e4a4c..97ff420 100644 --- a/include/cn-cbor/cn-cbor.h +++ b/include/cn-cbor/cn-cbor.h @@ -216,7 +216,7 @@ typedef struct cn_cbor_context { * @param[out] errp Error, if NULL is returned * @return The parsed CBOR structure, or NULL on error */ -const cn_cbor* cn_cbor_decode(const uint8_t *buf, size_t len CBOR_CONTEXT, cn_cbor_errback *errp); +cn_cbor* cn_cbor_decode(const uint8_t *buf, size_t len CBOR_CONTEXT, cn_cbor_errback *errp); /** * Get a value from a CBOR map that has the given string as a key. @@ -225,7 +225,7 @@ const cn_cbor* cn_cbor_decode(const uint8_t *buf, size_t len CBOR_CONTEXT, cn_cb * @param[in] key The string to look up in the map * @return The matching value, or NULL if the key is not found */ -const cn_cbor* cn_cbor_mapget_string(const cn_cbor* cb, const char* key); +cn_cbor* cn_cbor_mapget_string(const cn_cbor* cb, const char* key); /** * Get a value from a CBOR map that has the given integer as a key. @@ -234,7 +234,7 @@ const cn_cbor* cn_cbor_mapget_string(const cn_cbor* cb, const char* key); * @param[in] key The int to look up in the map * @return The matching value, or NULL if the key is not found */ -const cn_cbor* cn_cbor_mapget_int(const cn_cbor* cb, int key); +cn_cbor* cn_cbor_mapget_int(const cn_cbor* cb, int key); /** * Get the item with the given index from a CBOR array. @@ -243,7 +243,7 @@ const cn_cbor* cn_cbor_mapget_int(const cn_cbor* cb, int key); * @param[in] idx The array index * @return The matching value, or NULL if the index is invalid */ -const cn_cbor* cn_cbor_index(const cn_cbor* cb, unsigned int idx); +cn_cbor* cn_cbor_index(const cn_cbor* cb, unsigned int idx); /** * Free the given CBOR structure. @@ -251,7 +251,7 @@ const cn_cbor* cn_cbor_index(const cn_cbor* cb, unsigned int idx); * @param[in] cb The CBOR value to free * @param[in] CBOR_CONTEXT Allocation context (only if USE_CBOR_CONTEXT is defined) */ -void cn_cbor_free(const cn_cbor* cb CBOR_CONTEXT); +void cn_cbor_free(cn_cbor* cb CBOR_CONTEXT); /** * Write a CBOR value and all of the child values. diff --git a/src/cn-cbor.c b/src/cn-cbor.c index 996de1a..84c524c 100644 --- a/src/cn-cbor.c +++ b/src/cn-cbor.c @@ -22,8 +22,9 @@ extern "C" { #define CN_CBOR_FAIL(code) do { pb->err = code; goto fail; } while(0) -void cn_cbor_free(const cn_cbor* cb CBOR_CONTEXT) { - cn_cbor* p = (cn_cbor*) cb; +void cn_cbor_free(cn_cbor* cb CBOR_CONTEXT) { + cn_cbor* p = cb; + assert(!p || !p->parent); while (p) { cn_cbor* p1; while ((p1 = p->first_child)) { /* go down */ @@ -254,7 +255,7 @@ static cn_cbor *decode_item (struct parse_buf *pb CBOR_CONTEXT, cn_cbor* top_par return 0; } -const cn_cbor* cn_cbor_decode(const unsigned char* buf, size_t len CBOR_CONTEXT, cn_cbor_errback *errp) { +cn_cbor* cn_cbor_decode(const unsigned char* buf, size_t len CBOR_CONTEXT, cn_cbor_errback *errp) { cn_cbor catcher = {CN_CBOR_INVALID, 0, {0}, 0, NULL, NULL, NULL, NULL}; struct parse_buf pb; cn_cbor* ret; diff --git a/src/cn-get.c b/src/cn-get.c index f4585b9..cc276a5 100644 --- a/src/cn-get.c +++ b/src/cn-get.c @@ -4,7 +4,7 @@ #include "cn-cbor/cn-cbor.h" -const cn_cbor* cn_cbor_mapget_int(const cn_cbor* cb, int key) { +cn_cbor* cn_cbor_mapget_int(const cn_cbor* cb, int key) { cn_cbor* cp; assert(cb); for (cp = cb->first_child; cp && cp->next; cp = cp->next->next) { @@ -25,7 +25,7 @@ const cn_cbor* cn_cbor_mapget_int(const cn_cbor* cb, int key) { return NULL; } -const cn_cbor* cn_cbor_mapget_string(const cn_cbor* cb, const char* key) { +cn_cbor* cn_cbor_mapget_string(const cn_cbor* cb, const char* key) { cn_cbor *cp; int keylen; assert(cb); @@ -48,7 +48,7 @@ const cn_cbor* cn_cbor_mapget_string(const cn_cbor* cb, const char* key) { return NULL; } -const cn_cbor* cn_cbor_index(const cn_cbor* cb, unsigned int idx) { +cn_cbor* cn_cbor_index(const cn_cbor* cb, unsigned int idx) { cn_cbor *cp; unsigned int i = 0; assert(cb); diff --git a/test/cbor_test.c b/test/cbor_test.c index ebd5edd..3326497 100644 --- a/test/cbor_test.c +++ b/test/cbor_test.c @@ -111,7 +111,7 @@ CTEST(cbor, parse) "9f009f00ff00ff", // [_ 0, [_ 0], 0] "bf61610161629f0203ffff", // {_ "a": 1, "b": [_ 2, 3]} }; - const cn_cbor *cb; + cn_cbor *cb; buffer b; size_t i; unsigned char encoded[1024]; @@ -159,7 +159,7 @@ CTEST(cbor, parse_normalize) "fb3e78000000000000", "fa33c00000", // 8.940696716308594e-08 "fb3e80000000000000", "f90002", // 1.1920928955078125e-07 }; - const cn_cbor *cb; + cn_cbor *cb; buffer b, b2; size_t i; unsigned char encoded[1024]; @@ -221,7 +221,7 @@ CTEST(cbor, fail) {"1c", CN_CBOR_ERR_RESERVED_AI}, {"7f4100", CN_CBOR_ERR_WRONG_NESTING_IN_INDEF_STRING}, }; - const cn_cbor *cb; + cn_cbor *cb; buffer b; size_t i; uint8_t buf[10]; @@ -253,7 +253,7 @@ CTEST(cbor, float) "f9fc00", // -Inf "f97c00", // Inf }; - const cn_cbor *cb; + cn_cbor *cb; buffer b; size_t i; unsigned char encoded[1024]; @@ -276,8 +276,8 @@ CTEST(cbor, float) CTEST(cbor, getset) { buffer b; - const cn_cbor *cb; - const cn_cbor *val; + cn_cbor *cb; + cn_cbor *val; cn_cbor_errback err; ASSERT_TRUE(parse_hex("a40000436363630262626201616100", &b)); diff --git a/test/test.c b/test/test.c index 263f9fe..d24992f 100644 --- a/test/test.c +++ b/test/test.c @@ -115,7 +115,7 @@ int main() { char *bufend; unsigned char *s = load_file("cases.cbor", &end); printf("%zd\n", end-s); - const cn_cbor *cb = cn_cbor_decode(s, end-s CBOR_CONTEXT_PARAM, 0); + cn_cbor *cb = cn_cbor_decode(s, end-s CBOR_CONTEXT_PARAM, 0); if (cb) { dump(cb, buf, &bufend, 0); *bufend = 0; From b4d14cde7718874cec37a3901b976c7d759e3ee6 Mon Sep 17 00:00:00 2001 From: Joe Hildebrand Date: Wed, 26 Aug 2015 10:42:07 -0600 Subject: [PATCH 6/6] docfix --- include/cn-cbor/cn-cbor.h | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/include/cn-cbor/cn-cbor.h b/include/cn-cbor/cn-cbor.h index 97ff420..2973581 100644 --- a/include/cn-cbor/cn-cbor.h +++ b/include/cn-cbor/cn-cbor.h @@ -247,8 +247,10 @@ cn_cbor* cn_cbor_index(const cn_cbor* cb, unsigned int idx); /** * Free the given CBOR structure. + * You MUST NOT try to free a cn_cbor structure with a parent (i.e., one + * that is not a root in the tree). * - * @param[in] cb The CBOR value to free + * @param[in] cb The CBOR value to free. May be NULL, or a root object. * @param[in] CBOR_CONTEXT Allocation context (only if USE_CBOR_CONTEXT is defined) */ void cn_cbor_free(cn_cbor* cb CBOR_CONTEXT);