summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorantirez <antirez@gmail.com>2020-06-22 11:41:19 +0200
committerantirez <antirez@gmail.com>2020-06-22 11:41:19 +0200
commit746297314f3c198a90ceab8462a40abd9fc69f26 (patch)
tree4737b16642939af46d26c6e9a6f164139bfcd389
parent59fd178014c7cca1b0c668b30ab0d991dd3030f3 (diff)
downloadredis-746297314f3c198a90ceab8462a40abd9fc69f26.tar.gz
Fix BITFIELD i64 type handling, see #7417.
-rw-r--r--src/bitops.c14
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;
}