diff options
author | René Scharfe <l.s.r@web.de> | 2017-07-15 21:11:14 +0200 |
---|---|---|
committer | Junio C Hamano <gitster@pobox.com> | 2017-07-17 14:54:13 -0700 |
commit | 7780af1e8edf158f503794dbdb87787999daa086 (patch) | |
tree | 9deaeb85b2986fdc9ba4921414be3f103c92d1c6 /compat | |
parent | Git 2.12.3 (diff) | |
download | tgif-7780af1e8edf158f503794dbdb87787999daa086.tar.xz |
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>
Diffstat (limited to 'compat')
-rw-r--r-- | compat/bswap.h | 8 |
1 files changed, 4 insertions, 4 deletions
diff --git a/compat/bswap.h b/compat/bswap.h index d47c003544..4582c1107a 100644 --- a/compat/bswap.h +++ b/compat/bswap.h @@ -166,10 +166,10 @@ static inline uint64_t git_bswap64(uint64_t x) (*((unsigned char *)(p) + 0) << 8) | \ (*((unsigned char *)(p) + 1) << 0) ) #define get_be32(p) ( \ - (*((unsigned char *)(p) + 0) << 24) | \ - (*((unsigned char *)(p) + 1) << 16) | \ - (*((unsigned char *)(p) + 2) << 8) | \ - (*((unsigned char *)(p) + 3) << 0) ) + ((uint32_t)*((unsigned char *)(p) + 0) << 24) | \ + ((uint32_t)*((unsigned char *)(p) + 1) << 16) | \ + ((uint32_t)*((unsigned char *)(p) + 2) << 8) | \ + ((uint32_t)*((unsigned char *)(p) + 3) << 0) ) #define put_be32(p, v) do { \ unsigned int __v = (v); \ *((unsigned char *)(p) + 0) = __v >> 24; \ |