]> git.saurik.com Git - redis.git/commitdiff
BITCOUNT: fix segmentation fault.
authorHaruto Otake <trapezoid.g@gmail.com>
Sun, 15 Jul 2012 09:38:30 +0000 (18:38 +0900)
committerantirez <antirez@gmail.com>
Wed, 5 Sep 2012 14:19:04 +0000 (16:19 +0200)
remove unsafe and unnecessary cast.
until now, this cast may lead segmentation fault when end > UINT_MAX

setbit foo 0 1
bitcount  0 4294967295
=> ok
bitcount  0 4294967296
=> cause segmentation fault.

Note by @antirez: the commit was modified a bit to also change the
string length type to long, since it's guaranteed to be at max 512 MB in
size, so we can work with the same type across all the code path.

A regression test was also added.

src/bitops.c
tests/unit/bitops.tcl

index deec0971d3001876cdadc4661a940f1dd518e3b2..39d24ab7d43182c8d0bfe58f72d8edb32969ca44 100644 (file)
@@ -327,10 +327,9 @@ void bitopCommand(redisClient *c) {
 /* BITCOUNT key [start end] */
 void bitcountCommand(redisClient *c) {
     robj *o;
-    long start, end;
+    long start, end, strlen;
     unsigned char *p;
     char llbuf[32];
-    size_t strlen;
 
     /* Lookup, check for type, and return 0 for non existing keys. */
     if ((o = lookupKeyReadOrReply(c,c->argv[1],shared.czero)) == NULL ||
@@ -357,7 +356,7 @@ void bitcountCommand(redisClient *c) {
         if (end < 0) end = strlen+end;
         if (start < 0) start = 0;
         if (end < 0) end = 0;
-        if ((unsigned)end >= strlen) end = strlen-1;
+        if (end >= strlen) end = strlen-1;
     } else if (c->argc == 2) {
         /* The whole string. */
         start = 0;
index 0e3403bfe1818ee043788127f6cf430902418497..5945d32d710c5024e89cc189e665f06734fbeb6e 100644 (file)
@@ -73,6 +73,12 @@ start_server {tags {"bitops"}} {
         set e
     } {ERR*syntax*}
 
+    test {BITCOUNT regression test for github issue #582} {
+        r del str
+        r setbit foo 0 1
+        r bitcount foo 0 4294967296
+    } {1}
+
     test {BITOP NOT (empty string)} {
         r set s ""
         r bitop not dest s