aboutsummaryrefslogtreecommitdiff
path: root/compat
diff options
context:
space:
mode:
authorRené Scharfe <l.s.r@web.de>2017-07-15 21:11:14 +0200
committerJunio C Hamano <gitster@pobox.com>2017-07-17 14:54:13 -0700
commit7780af1e8edf158f503794dbdb87787999daa086 (patch)
tree9deaeb85b2986fdc9ba4921414be3f103c92d1c6 /compat
parent95d67879735cfecfdd85f89e59d993c5b4de8835 (diff)
downloadgit-7780af1e8edf158f503794dbdb87787999daa086.tar.gz
git-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.h8
1 files changed, 4 insertions, 4 deletions
diff --git a/compat/bswap.h b/compat/bswap.h
index d47c00354..4582c1107 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; \