Fix BITFIELD i64 type handling, see #7417.

This commit is contained in:
antirez 2020-06-22 11:41:19 +02:00
parent 59fd178014
commit 746297314f

View File

@ -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 /* If the top significant bit is 1, propagate it to all the
* higher bits for two's complement representation of signed * higher bits for two's complement representation of signed
* integers. */ * integers. */
if (value & ((uint64_t)1 << (bits-1))) if (bits < 64 && (value & ((uint64_t)1 << (bits-1))))
value |= ((uint64_t)-1) << bits; value |= ((uint64_t)-1) << bits;
return value; return value;
} }
@ -356,7 +356,6 @@ int checkSignedBitfieldOverflow(int64_t value, int64_t incr, uint64_t bits, int
handle_wrap: handle_wrap:
{ {
uint64_t mask = ((uint64_t)-1) << bits;
uint64_t msb = (uint64_t)1 << (bits-1); uint64_t msb = (uint64_t)1 << (bits-1);
uint64_t a = value, b = incr, c; uint64_t a = value, b = incr, c;
c = a+b; /* Perform addition as unsigned so that's defined. */ 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 /* If the sign bit is set, propagate to all the higher order
* bits, to cap the negative value. If it's clear, mask to * bits, to cap the negative value. If it's clear, mask to
* the positive integer limit. */ * the positive integer limit. */
if (c & msb) { if (bits < 64) {
c |= mask; uint64_t mask = ((uint64_t)-1) << bits;
} else { if (c & msb) {
c &= ~mask; c |= mask;
} else {
c &= ~mask;
}
} }
*limit = c; *limit = c;
} }