From 5b9aa5026204fb6c8b0098d4e47c2e001cf06151 Mon Sep 17 00:00:00 2001 From: Sun He Date: Wed, 2 Mar 2016 18:11:30 +0800 Subject: bitops/bitfield: fix length, overflow condition and *sign --- src/bitops.c | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/src/bitops.c b/src/bitops.c index 51f9cc00f..28405a3bf 100644 --- a/src/bitops.c +++ b/src/bitops.c @@ -318,7 +318,8 @@ int checkSignedBitfieldOverflow(int64_t value, int64_t incr, uint64_t bits, int int64_t maxincr = max-value; int64_t minincr = min-value; - if (value > max || (value >= 0 && incr > 0 && incr > maxincr)) { + if (value > max || (bits == 64 && value >= 0 && incr > 0 && incr > maxincr) + || (bits < 64 && incr > 0 && incr > maxincr)) { if (limit) { if (owtype == BFOVERFLOW_WRAP) { goto handle_wrap; @@ -327,7 +328,8 @@ int checkSignedBitfieldOverflow(int64_t value, int64_t incr, uint64_t bits, int } } return 1; - } else if (value < min || (value < 0 && incr < 0 && incr < minincr)) { + } else if (value < min || (bits == 64 && value < 0 && incr < 0 && incr < minincr) + || (bits < 64 && incr < 0 && incr < minincr)) { if (limit) { if (owtype == BFOVERFLOW_WRAP) { goto handle_wrap; @@ -445,8 +447,8 @@ int getBitfieldTypeFromArgument(client *c, robj *o, int *sign, int *bits) { if ((string2ll(p+1,strlen(p+1),&llbits)) == 0 || llbits < 1 || - (*sign == 1 && llbits > 63) || - (*sign == 0 && llbits > 64)) + (*sign == 1 && llbits > 64) || + (*sign == 0 && llbits > 63)) { addReplyError(c,err); return C_ERR; @@ -963,7 +965,8 @@ void bitfieldCommand(client *c) { * for simplicity. SET return value is the previous value so * we need fetch & store as well. */ - if ((o = lookupStringForBitCommand(c,bitoffset)) == NULL) return; + if ((o = lookupStringForBitCommand(c,thisop->offset + thisop->bits)) + == NULL) return; /* We need two different but very similar code paths for signed * and unsigned operations, since the set of functions to get/set -- cgit v1.2.1