diff options
| author | David Lamparter <equinox@opensourcerouting.org> | 2017-09-07 15:58:18 +0200 |
|---|---|---|
| committer | David Lamparter <equinox@opensourcerouting.org> | 2017-09-09 19:50:58 +0200 |
| commit | 937652c6e43fc74ba969bbace475bdf929cdc5d0 (patch) | |
| tree | f2cdea6d59fa9e2f20eafc512fe21203f6acdd6b /lib/stream.h | |
| parent | b1eec2516a9b7cca8d85e35e58aad5f896be12eb (diff) | |
*: fix be32 reading / 24-bit left shift
Signed-off-by: David Lamparter <equinox@opensourcerouting.org>
Diffstat (limited to 'lib/stream.h')
| -rw-r--r-- | lib/stream.h | 18 |
1 files changed, 18 insertions, 0 deletions
diff --git a/lib/stream.h b/lib/stream.h index 33dd64c4a3..7dcdca69f6 100644 --- a/lib/stream.h +++ b/lib/stream.h @@ -239,4 +239,22 @@ extern struct stream *stream_fifo_head(struct stream_fifo *fifo); extern void stream_fifo_clean(struct stream_fifo *fifo); extern void stream_fifo_free(struct stream_fifo *fifo); +/* This is here because "<< 24" is particularly problematic in C. + * This is because the left operand of << is integer-promoted, which means + * an uint8_t gets converted into a *signed* int. Shifting into the sign + * bit of a signed int is theoretically undefined behaviour, so - the left + * operand needs to be cast to unsigned. + * + * This is not a problem for 16- or 8-bit values (they don't reach the sign + * bit), for 64-bit values (you need to cast them anyway), and neither for + * encoding (because it's downcasted.) + */ +static inline uint8_t *ptr_get_be32(uint8_t *ptr, uint32_t *out) +{ + uint32_t tmp; + memcpy(&tmp, ptr, sizeof(tmp)); + *out = ntohl(tmp); + return ptr + 4; +} + #endif /* _ZEBRA_STREAM_H */ |
