]> git.saurik.com Git - redis.git/commitdiff
Fixed undefined behavior in *INCR style functions overflow detection. Sorry clang!
authorantirez <antirez@gmail.com>
Tue, 21 Feb 2012 17:25:49 +0000 (18:25 +0100)
committerantirez <antirez@gmail.com>
Tue, 21 Feb 2012 17:26:11 +0000 (18:26 +0100)
src/t_hash.c
src/t_string.c

index b8e2ad312d8508a8da332916e8c9b90b2f018ba8..f97fc9926a8078d9830268f8098b4ab925403bc9 100644 (file)
@@ -337,11 +337,12 @@ void hincrbyCommand(redisClient *c) {
     }
 
     oldvalue = value;
-    value += incr;
-    if ((incr < 0 && value > oldvalue) || (incr > 0 && value < oldvalue)) {
+    if ((incr < 0 && oldvalue < 0 && incr < (LLONG_MIN-oldvalue)) ||
+        (incr > 0 && oldvalue > 0 && incr > (LLONG_MAX-oldvalue))) {
         addReplyError(c,"increment or decrement would overflow");
         return;
     }
+    value += incr;
     new = createStringObjectFromLongLong(value);
     hashTypeTryObjectEncoding(o,&c->argv[2],NULL);
     hashTypeSet(o,c->argv[2],new);
index 2bd1646e305627ecab073893553a40f48444c2bf..d6143ed27dccc3d9c62c4acd1d0b6dd69bc187f4 100644 (file)
@@ -344,11 +344,12 @@ void incrDecrCommand(redisClient *c, long long incr) {
     if (getLongLongFromObjectOrReply(c,o,&value,NULL) != REDIS_OK) return;
 
     oldvalue = value;
-    value += incr;
-    if ((incr < 0 && value > oldvalue) || (incr > 0 && value < oldvalue)) {
+    if ((incr < 0 && oldvalue < 0 && incr < (LLONG_MIN-oldvalue)) ||
+        (incr > 0 && oldvalue > 0 && incr > (LLONG_MAX-oldvalue))) {
         addReplyError(c,"increment or decrement would overflow");
         return;
     }
+    value += incr;
     new = createStringObjectFromLongLong(value);
     if (o)
         dbOverwrite(c->db,c->argv[1],new);