Fix CLIENT KILL kill all clients with id 0 (#9853)

* Fix CLIENT KILL kill all clients with id 0 or with skipme
CLIENT KILL with ID argument should only kill the client with the provided ID. In old code, 
CLIENT KILL with id 0 will kill all the connected clients.

Co-authored-by: Ofir Luzon <ofirluzon@gmail.com>
This commit is contained in:
Binbin 2021-11-30 05:35:36 +08:00 committed by GitHub
parent 2386e54182
commit 3119a3aeb5
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 41 additions and 3 deletions

View File

@ -2741,10 +2741,11 @@ NULL
int moreargs = c->argc > i+1;
if (!strcasecmp(c->argv[i]->ptr,"id") && moreargs) {
long long tmp;
long tmp;
if (getLongLongFromObjectOrReply(c,c->argv[i+1],&tmp,NULL)
!= C_OK) return;
if (getRangeLongFromObjectOrReply(c, c->argv[i+1], 1, LONG_MAX, &tmp,
"client-id should be greater than 0") != C_OK)
return;
id = tmp;
} else if (!strcasecmp(c->argv[i]->ptr,"type") && moreargs) {
type = getClientTypeByName(c->argv[i+1]->ptr);

View File

@ -13,6 +13,43 @@ start_server {tags {"introspection"}} {
r client info
} {*addr=*:* fd=* age=* idle=* flags=N db=* sub=0 psub=0 multi=-1 qbuf=26 qbuf-free=* argv-mem=* obl=0 oll=0 omem=0 tot-mem=* events=r cmd=client*}
test {CLIENT KILL with illegal arguments} {
assert_error "ERR wrong number*" {r client kill}
assert_error "ERR syntax error*" {r client kill id 10 wrong_arg}
assert_error "ERR*greater than 0*" {r client kill id str}
assert_error "ERR*greater than 0*" {r client kill id -1}
assert_error "ERR*greater than 0*" {r client kill id 0}
assert_error "ERR Unknown client type*" {r client kill type wrong_type}
assert_error "ERR No such user*" {r client kill user wrong_user}
assert_error "ERR syntax error*" {r client kill skipme yes_or_no}
}
test {CLIENT KILL SKIPME YES/NO will kill all clients} {
# Kill all clients except `me`
set rd1 [redis_deferring_client]
set rd2 [redis_deferring_client]
set connected_clients [s connected_clients]
assert {$connected_clients >= 3}
set res [r client kill skipme yes]
assert {$res == $connected_clients - 1}
# Kill all clients, including `me`
set rd3 [redis_deferring_client]
set rd4 [redis_deferring_client]
set connected_clients [s connected_clients]
assert {$connected_clients == 3}
set res [r client kill skipme no]
assert_equal $res $connected_clients
# After killing `me`, the first ping will throw an error
assert_error "*I/O error*" {r ping}
assert_equal "PONG" [r ping]
}
test {MONITOR can log executed commands} {
set rd [redis_deferring_client]
$rd monitor