aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--lib/doh.c10
1 files changed, 8 insertions, 2 deletions
diff --git a/lib/doh.c b/lib/doh.c
index e84c9b0ad..6f06d0a35 100644
--- a/lib/doh.c
+++ b/lib/doh.c
@@ -432,8 +432,14 @@ static unsigned short get16bit(unsigned char *doh, int index)
static unsigned int get32bit(unsigned char *doh, int index)
{
- return (doh[index] << 24) | (doh[index + 1] << 16) |
- (doh[index + 2] << 8) | doh[index + 3];
+ /* make clang and gcc optimize this to bswap by incrementing
+ the pointer first. */
+ doh += index;
+
+ /* avoid undefined behaviour by casting to unsigned before shifting
+ 24 bits, possibly into the sign bit. codegen is same, but
+ ub sanitizer won't be upset */
+ return ( (unsigned)doh[0] << 24) | (doh[1] << 16) |(doh[2] << 8) | doh[3];
}
static DOHcode store_a(unsigned char *doh, int index, struct dohentry *d)