diff --git a/sys/cbor/cbor.c b/sys/cbor/cbor.c index 1665d79bee..bbb7c65e74 100644 --- a/sys/cbor/cbor.c +++ b/sys/cbor/cbor.c @@ -95,7 +95,20 @@ #define NAN (0.0/0.0) #endif + +/* pack to force aligned access on ARMv7 (buggy GCC) */ +#pragma GCC diagnostic error "-Wcast-align" +typedef struct __attribute__((packed)) { + unsigned char u8; + union { + uint16_t u16; + uint32_t u32; + uint64_t u64; + } u; +} cast_align_u8_t; + #ifndef CBOR_NO_FLOAT + /** * Convert float @p x to network format */ @@ -345,15 +358,15 @@ static size_t decode_int(const cbor_stream_t *s, size_t offset, uint64_t *val) break; case 2: - *val = HTONS(*((uint16_t *)&in[1])); + *val = HTONS(((cast_align_u8_t *)in)->u.u16); break; case 4: - *val = HTONL(*((uint32_t *)&in[1])); + *val = HTONL(((cast_align_u8_t *)in)->u.u32); break; default: - *val = HTONLL(*((uint64_t *)&in[1])); + *val = HTONLL(((cast_align_u8_t *)in)->u.u64); break; } @@ -565,7 +578,7 @@ size_t cbor_deserialize_float(const cbor_stream_t *stream, size_t offset, float unsigned char *data = &stream->data[offset]; if (*data == CBOR_FLOAT32) { - *val = ntohf(*(uint32_t *)(data + 1)); + *val = ntohf(((cast_align_u8_t *)data)->u.u32); return 5; } @@ -594,7 +607,7 @@ size_t cbor_deserialize_double(const cbor_stream_t *stream, size_t offset, doubl if (*data == CBOR_FLOAT64) { CBOR_ENSURE_SIZE_READ(stream, offset + 9); - *val = ntohd(*(uint64_t *)(data + 1)); + *val = ntohd(((cast_align_u8_t *)data)->u.u64); return 9; }