summaryrefslogtreecommitdiff
path: root/lib/stream.h
diff options
context:
space:
mode:
authorDavid Lamparter <equinox@opensourcerouting.org>2017-09-07 15:58:18 +0200
committerDavid Lamparter <equinox@opensourcerouting.org>2017-09-09 19:50:58 +0200
commit937652c6e43fc74ba969bbace475bdf929cdc5d0 (patch)
treef2cdea6d59fa9e2f20eafc512fe21203f6acdd6b /lib/stream.h
parentb1eec2516a9b7cca8d85e35e58aad5f896be12eb (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.h18
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 */