Skip to content

Commit fe64960

Browse files
committed
More BITFIELD fixes. Overflow conditional simplified.
See issue redis#3114.
1 parent 235f553 commit fe64960

1 file changed

Lines changed: 8 additions & 9 deletions

File tree

src/bitops.c

Lines changed: 8 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -203,7 +203,7 @@ void setUnsignedBitfield(unsigned char *p, uint64_t offset, uint64_t bits, uint6
203203
uint64_t byte, bit, byteval, bitval, j;
204204

205205
for (j = 0; j < bits; j++) {
206-
bitval = (value & (1<<(bits-1-j))) != 0;
206+
bitval = (value & ((uint64_t)1<<(bits-1-j))) != 0;
207207
byte = offset >> 3;
208208
bit = 7 - (offset & 0x7);
209209
byteval = p[byte];
@@ -243,7 +243,7 @@ int64_t getSignedBitfield(unsigned char *p, uint64_t offset, uint64_t bits) {
243243
/* If the top significant bit is 1, propagate it to all the
244244
* higher bits for two complement representation of signed
245245
* integers. */
246-
if (value & (1 << (bits-1)))
246+
if (value & ((uint64_t)1 << (bits-1)))
247247
value |= ((uint64_t)-1) << bits;
248248
return value;
249249
}
@@ -272,7 +272,7 @@ int64_t getSignedBitfield(unsigned char *p, uint64_t offset, uint64_t bits) {
272272
#define BFOVERFLOW_FAIL 2 /* Used by the BITFIELD command implementation. */
273273

274274
int checkUnsignedBitfieldOverflow(uint64_t value, int64_t incr, uint64_t bits, int owtype, uint64_t *limit) {
275-
uint64_t max = (bits == 64) ? UINT64_MAX : ((1<<bits)-1);
275+
uint64_t max = (bits == 64) ? UINT64_MAX : (((uint64_t)1<<bits)-1);
276276
int64_t maxincr = max-value;
277277
int64_t minincr = -value;
278278

@@ -309,7 +309,7 @@ int checkUnsignedBitfieldOverflow(uint64_t value, int64_t incr, uint64_t bits, i
309309
}
310310

311311
int checkSignedBitfieldOverflow(int64_t value, int64_t incr, uint64_t bits, int owtype, int64_t *limit) {
312-
int64_t max = (bits == 64) ? INT64_MAX : ((1<<(bits-1))-1);
312+
int64_t max = (bits == 64) ? INT64_MAX : (((int64_t)1<<(bits-1))-1);
313313
int64_t min = (-max)-1;
314314

315315
/* Note that maxincr and minincr could overflow, but we use the values
@@ -318,8 +318,8 @@ int checkSignedBitfieldOverflow(int64_t value, int64_t incr, uint64_t bits, int
318318
int64_t maxincr = max-value;
319319
int64_t minincr = min-value;
320320

321-
if (value > max || (bits == 64 && value >= 0 && incr > 0 && incr > maxincr)
322-
|| (bits < 64 && incr > 0 && incr > maxincr)) {
321+
if (value > max || (bits != 64 && incr > maxincr) || (value >= 0 && incr > 0 && incr > maxincr))
322+
{
323323
if (limit) {
324324
if (owtype == BFOVERFLOW_WRAP) {
325325
goto handle_wrap;
@@ -328,8 +328,7 @@ int checkSignedBitfieldOverflow(int64_t value, int64_t incr, uint64_t bits, int
328328
}
329329
}
330330
return 1;
331-
} else if (value < min || (bits == 64 && value < 0 && incr < 0 && incr < minincr)
332-
|| (bits < 64 && incr < 0 && incr < minincr)) {
331+
} else if (value < min || (bits != 64 && incr < minincr) || (value < 0 && incr < 0 && incr < minincr)) {
333332
if (limit) {
334333
if (owtype == BFOVERFLOW_WRAP) {
335334
goto handle_wrap;
@@ -966,7 +965,7 @@ void bitfieldCommand(client *c) {
966965
* we need fetch & store as well. */
967966

968967
if ((o = lookupStringForBitCommand(c,thisop->offset + thisop->bits))
969-
== NULL) return;
968+
== NULL) return;
970969

971970
/* We need two different but very similar code paths for signed
972971
* and unsigned operations, since the set of functions to get/set

0 commit comments

Comments
 (0)