diff options
author | antirez <antirez@gmail.com> | 2020-06-22 11:41:19 +0200 |
---|---|---|
committer | antirez <antirez@gmail.com> | 2020-06-22 11:41:19 +0200 |
commit | 746297314f3c198a90ceab8462a40abd9fc69f26 (patch) | |
tree | 4737b16642939af46d26c6e9a6f164139bfcd389 | |
parent | 59fd178014c7cca1b0c668b30ab0d991dd3030f3 (diff) | |
download | redis-746297314f3c198a90ceab8462a40abd9fc69f26.tar.gz |
Fix BITFIELD i64 type handling, see #7417.
-rw-r--r-- | src/bitops.c | 14 |
1 files changed, 8 insertions, 6 deletions
diff --git a/src/bitops.c b/src/bitops.c index f506a881b..b37bea2bf 100644 --- a/src/bitops.c +++ b/src/bitops.c @@ -257,7 +257,7 @@ int64_t getSignedBitfield(unsigned char *p, uint64_t offset, uint64_t bits) { /* If the top significant bit is 1, propagate it to all the * higher bits for two's complement representation of signed * integers. */ - if (value & ((uint64_t)1 << (bits-1))) + if (bits < 64 && (value & ((uint64_t)1 << (bits-1)))) value |= ((uint64_t)-1) << bits; return value; } @@ -356,7 +356,6 @@ int checkSignedBitfieldOverflow(int64_t value, int64_t incr, uint64_t bits, int handle_wrap: { - uint64_t mask = ((uint64_t)-1) << bits; uint64_t msb = (uint64_t)1 << (bits-1); uint64_t a = value, b = incr, c; c = a+b; /* Perform addition as unsigned so that's defined. */ @@ -364,10 +363,13 @@ handle_wrap: /* If the sign bit is set, propagate to all the higher order * bits, to cap the negative value. If it's clear, mask to * the positive integer limit. */ - if (c & msb) { - c |= mask; - } else { - c &= ~mask; + if (bits < 64) { + uint64_t mask = ((uint64_t)-1) << bits; + if (c & msb) { + c |= mask; + } else { + c &= ~mask; + } } *limit = c; } |