]> git.saurik.com Git - redis.git/commitdiff
Fixed some subtle bug in the command processing code almost impossible to spot in...
authorantirez <antirez@gmail.com>
Tue, 15 Dec 2009 14:14:40 +0000 (09:14 -0500)
committerantirez <antirez@gmail.com>
Tue, 15 Dec 2009 14:14:40 +0000 (09:14 -0500)
redis.c
test-redis.tcl

diff --git a/redis.c b/redis.c
index f28b940adf4a17478704475634e5950b30216d56..61bb81cfa71f523ecdc0bbff354d46b6d42005d6 100644 (file)
--- a/redis.c
+++ b/redis.c
@@ -1880,6 +1880,7 @@ again:
             if (sdslen(query) == 0) {
                 /* Ignore empty query */
                 sdsfree(query);
+                if (sdslen(c->querybuf)) goto again;
                 return;
             }
             argv = sdssplitlen(query,sdslen(query)," ",1,&argc);
@@ -1897,10 +1898,16 @@ again:
                 }
             }
             zfree(argv);
-            /* Execute the command. If the client is still valid
-             * after processCommand() return and there is something
-             * on the query buffer try to process the next command. */
-            if (c->argc && processCommand(c) && sdslen(c->querybuf)) goto again;
+            if (c->argc) {
+                /* Execute the command. If the client is still valid
+                 * after processCommand() return and there is something
+                 * on the query buffer try to process the next command. */
+                if (processCommand(c) && sdslen(c->querybuf)) goto again;
+            } else {
+                /* Nothing to process, argc == 0. Just process the query
+                 * buffer if it's not empty or return to the caller */
+                if (sdslen(c->querybuf)) goto again;
+            }
             return;
         } else if (sdslen(c->querybuf) >= REDIS_REQUEST_MAX_SIZE) {
             redisLog(REDIS_DEBUG, "Client protocol error");
index abaecbea47647a93faebceb05eabd2d90fab76b0..8568a60d27a10b3bf631d6116a6e194796ca08cd 100644 (file)
@@ -89,6 +89,11 @@ proc main {server port} {
         $r get x
     } {foobar}
 
+    test {SET and GET an empty item} {
+        $r set x {}
+        $r get x
+    } {}
+
     test {DEL against a single item} {
         $r del x
         $r get x
@@ -1229,6 +1234,51 @@ proc main {server port} {
         $r get x
     } {10}
 
+    test {Handle an empty query well} {
+        set fd [$r channel]
+        puts -nonewline $fd "\r\n"
+        flush $fd
+        $r ping
+    } {PONG}
+
+    test {Negative multi bulk command does not create problems} {
+        set fd [$r channel]
+        puts -nonewline $fd "*-10\r\n"
+        flush $fd
+        $r ping
+    } {PONG}
+
+    test {Negative multi bulk payload} {
+        set fd [$r channel]
+        puts -nonewline $fd "SET x -10\r\n"
+        flush $fd
+        gets $fd
+    } {*invalid bulk*}
+
+    test {Too big bulk payload} {
+        set fd [$r channel]
+        puts -nonewline $fd "SET x 2000000000\r\n"
+        flush $fd
+        gets $fd
+    } {*invalid bulk*count*}
+
+    test {Multi bulk request not followed by bulk args} {
+        set fd [$r channel]
+        puts -nonewline $fd "*1\r\nfoo\r\n"
+        flush $fd
+        gets $fd
+    } {*protocol error*}
+
+    test {Generic wrong number of args} {
+        catch {$r ping x y z} err
+        set _ $err
+    } {*wrong*arguments*ping*}
+
+    test {SELECT an out of range DB} {
+        catch {$r select 1000000} err
+        set _ $err
+    } {*invalid*}
+
     # Leave the user with a clean DB before to exit
     test {FLUSHDB} {
         set aux {}
@@ -1322,7 +1372,7 @@ for {set j 0} {$j < [llength $argv]} {incr j} {
         set ::last $arg
         incr j
     } else {
-        echo "Wrong argument: $opt"
+        puts "Wrong argument: $opt"
         exit 1
     }
 }