From 7c49733ce3f550a96f60a9213911fdc9265cedc8 Mon Sep 17 00:00:00 2001 From: antirez Date: Tue, 15 Dec 2009 09:14:40 -0500 Subject: [PATCH] Fixed some subtle bug in the command processing code almost impossible to spot in the real world, thanks to gcov --- redis.c | 15 +++++++++++---- test-redis.tcl | 52 +++++++++++++++++++++++++++++++++++++++++++++++++- 2 files changed, 62 insertions(+), 5 deletions(-) diff --git a/redis.c b/redis.c index f28b940ad..61bb81cfa 100644 --- 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"); diff --git a/test-redis.tcl b/test-redis.tcl index abaecbea4..8568a60d2 100644 --- a/test-redis.tcl +++ b/test-redis.tcl @@ -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 } } -- GitLab