Fixed some subtle bug in the command processing code almost impossible to spot in the real world, thanks to gcov

This commit is contained in:
antirez 2009-12-15 09:14:40 -05:00
parent f4d9b3c62a
commit 7c49733ce3
2 changed files with 62 additions and 5 deletions

View File

@ -1880,6 +1880,7 @@ again:
if (sdslen(query) == 0) { if (sdslen(query) == 0) {
/* Ignore empty query */ /* Ignore empty query */
sdsfree(query); sdsfree(query);
if (sdslen(c->querybuf)) goto again;
return; return;
} }
argv = sdssplitlen(query,sdslen(query)," ",1,&argc); argv = sdssplitlen(query,sdslen(query)," ",1,&argc);
@ -1897,10 +1898,16 @@ again:
} }
} }
zfree(argv); zfree(argv);
if (c->argc) {
/* Execute the command. If the client is still valid /* Execute the command. If the client is still valid
* after processCommand() return and there is something * after processCommand() return and there is something
* on the query buffer try to process the next command. */ * on the query buffer try to process the next command. */
if (c->argc && processCommand(c) && sdslen(c->querybuf)) goto again; 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; return;
} else if (sdslen(c->querybuf) >= REDIS_REQUEST_MAX_SIZE) { } else if (sdslen(c->querybuf) >= REDIS_REQUEST_MAX_SIZE) {
redisLog(REDIS_DEBUG, "Client protocol error"); redisLog(REDIS_DEBUG, "Client protocol error");

View File

@ -89,6 +89,11 @@ proc main {server port} {
$r get x $r get x
} {foobar} } {foobar}
test {SET and GET an empty item} {
$r set x {}
$r get x
} {}
test {DEL against a single item} { test {DEL against a single item} {
$r del x $r del x
$r get x $r get x
@ -1229,6 +1234,51 @@ proc main {server port} {
$r get x $r get x
} {10} } {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 # Leave the user with a clean DB before to exit
test {FLUSHDB} { test {FLUSHDB} {
set aux {} set aux {}
@ -1322,7 +1372,7 @@ for {set j 0} {$j < [llength $argv]} {incr j} {
set ::last $arg set ::last $arg
incr j incr j
} else { } else {
echo "Wrong argument: $opt" puts "Wrong argument: $opt"
exit 1 exit 1
} }
} }