bswap: convert to unsigned before shifting in get_be32

The pointer p is dereferenced and we get an unsigned char. Before shifting it's automatically promoted to int. Left-shifting a signed 32-bit value bigger than 127 by 24 places is undefined. Explicitly convert to a 32-bit unsigned type to avoid undefined behaviour if the highest bit is set. Found with Clang's UBSan. Signed-off-by: Rene Scharfe <l.s.r@web.de> Signed-off-by: Junio C Hamano <gitster@pobox.com>

René Scharfe committed Jul 15, 2017 at 21:11 UTC 7780af1e8edf158f503794dbdb87787999daa086
1 file changed +4 -4
compat/bswap.h
+4 -4
@@ -166,10 +166,10 @@ static inline uint64_t git_bswap64(uint64_t x)
166 (*((unsigned char *)(p) + 0) << 8) | \
167 (*((unsigned char *)(p) + 1) << 0) )
168 #define get_be32(p) ( \
169 - (*((unsigned char *)(p) + 0) << 24) | \
170 - (*((unsigned char *)(p) + 1) << 16) | \
171 - (*((unsigned char *)(p) + 2) << 8) | \
172 - (*((unsigned char *)(p) + 3) << 0) )
169 + ((uint32_t)*((unsigned char *)(p) + 0) << 24) | \
170 + ((uint32_t)*((unsigned char *)(p) + 1) << 16) | \
171 + ((uint32_t)*((unsigned char *)(p) + 2) << 8) | \
172 + ((uint32_t)*((unsigned char *)(p) + 3) << 0) )
173 #define put_be32(p, v) do { \
174 unsigned int __v = (v); \
175 *((unsigned char *)(p) + 0) = __v >> 24; \