diff options
author | David Robillard <d@drobilla.net> | 2016-05-17 11:58:47 -0400 |
---|---|---|
committer | David Robillard <d@drobilla.net> | 2016-05-17 11:58:47 -0400 |
commit | e2d1f43bc10172272a74e2bcf2460b0dbc91aeea (patch) | |
tree | f16f51f759e9a14e7e9d3f6e0fac425200c1af68 /src/serd_internal.h | |
parent | 4177848a044eead797dfa3262c1781491cc6a56f (diff) | |
download | serd-e2d1f43bc10172272a74e2bcf2460b0dbc91aeea.tar.gz serd-e2d1f43bc10172272a74e2bcf2460b0dbc91aeea.tar.bz2 serd-e2d1f43bc10172272a74e2bcf2460b0dbc91aeea.zip |
Fix unaligned memory access (UB which breaks ARM)
With this fix, the test suite runs cleanly with UBSan.
Diffstat (limited to 'src/serd_internal.h')
-rw-r--r-- | src/serd_internal.h | 34 |
1 files changed, 33 insertions, 1 deletions
diff --git a/src/serd_internal.h b/src/serd_internal.h index 20700bb8..23fd75b4 100644 --- a/src/serd_internal.h +++ b/src/serd_internal.h @@ -1,5 +1,5 @@ /* - Copyright 2011-2014 David Robillard <http://drobilla.net> + Copyright 2011-2016 David Robillard <http://drobilla.net> Permission to use, copy, modify, and/or distribute this software for any purpose with or without fee is hereby granted, provided that the above @@ -123,6 +123,38 @@ serd_stack_pop(SerdStack* stack, size_t n_bytes) stack->size -= n_bytes; } +static inline void* +serd_stack_push_aligned(SerdStack* stack, size_t n_bytes, size_t align) +{ + // Push one byte to ensure space for a pad count + serd_stack_push(stack, 1); + + // Push padding if necessary + const uint8_t pad = align - stack->size % align; + if (pad > 0) { + serd_stack_push(stack, pad); + } + + // Set top of stack to pad count so we can properly pop later + stack->buf[stack->size - 1] = pad; + + // Push requested space at aligned location + return serd_stack_push(stack, n_bytes); +} + +static inline void +serd_stack_pop_aligned(SerdStack* stack, size_t n_bytes) +{ + // Pop requested space down to aligned location + serd_stack_pop(stack, n_bytes); + + // Get amount of padding from top of stack + const uint8_t pad = stack->buf[stack->size - 1]; + + // Pop padding and pad count + serd_stack_pop(stack, pad + 1); +} + /* Bulk Sink */ typedef struct SerdBulkSinkImpl { |