Fix multiple COUNT in LMPOP/BLMPOP/ZMPOP/BZMPOP (#9701)

The previous code did not check whether COUNT is set.
So we can use `lmpop 2 key1 key2 left count 1 count 2`.

This situation can occur in LMPOP/BLMPOP/ZMPOP/BZMPOP commands.
LMPOP/BLMPOP introduced in #9373, ZMPOP/BZMPOP introduced in #9484.
This commit is contained in:
Binbin 2021-10-31 22:10:29 +08:00 committed by GitHub
parent 215b909c1f
commit 033578839b
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 11 additions and 4 deletions

View File

@ -1198,7 +1198,7 @@ void lmpopGenericCommand(client *c, int numkeys_idx, int is_block) {
long j;
long numkeys = 0; /* Number of keys. */
int where = 0; /* HEAD for LEFT, TAIL for RIGHT. */
long count = 1; /* Reply will consist of up to count elements, depending on the list's length. */
long count = 0; /* Reply will consist of up to count elements, depending on the list's length. */
/* Parse the numkeys. */
if (getRangeLongFromObjectOrReply(c, c->argv[numkeys_idx], 1, LONG_MAX,
@ -1219,7 +1219,7 @@ void lmpopGenericCommand(client *c, int numkeys_idx, int is_block) {
char *opt = c->argv[j]->ptr;
int moreargs = (c->argc - 1) - j;
if (!strcasecmp(opt, "COUNT") && moreargs) {
if (count == 0 && !strcasecmp(opt, "COUNT") && moreargs) {
j++;
if (getRangeLongFromObjectOrReply(c, c->argv[j], 1, LONG_MAX,
&count,"count should be greater than 0") != C_OK)
@ -1230,6 +1230,8 @@ void lmpopGenericCommand(client *c, int numkeys_idx, int is_block) {
}
}
if (count == 0) count = 1;
if (is_block) {
/* BLOCK. We will handle CLIENT_DENY_BLOCKING flag in blockingPopGenericCommand. */
blockingPopGenericCommand(c, c->argv+numkeys_idx+1, numkeys, where, 1, count);

View File

@ -4287,7 +4287,7 @@ void zmpopGenericCommand(client *c, int numkeys_idx, int is_block) {
long j;
long numkeys = 0; /* Number of keys. */
int where = 0; /* ZSET_MIN or ZSET_MAX. */
long count = 1; /* Reply will consist of up to count elements, depending on the zset's length. */
long count = 0; /* Reply will consist of up to count elements, depending on the zset's length. */
/* Parse the numkeys. */
if (getRangeLongFromObjectOrReply(c, c->argv[numkeys_idx], 1, LONG_MAX,
@ -4314,7 +4314,7 @@ void zmpopGenericCommand(client *c, int numkeys_idx, int is_block) {
char *opt = c->argv[j]->ptr;
int moreargs = (c->argc - 1) - j;
if (!strcasecmp(opt, "COUNT") && moreargs) {
if (count == 0 && !strcasecmp(opt, "COUNT") && moreargs) {
j++;
if (getRangeLongFromObjectOrReply(c, c->argv[j], 1, LONG_MAX,
&count,"count should be greater than 0") != C_OK)
@ -4325,6 +4325,8 @@ void zmpopGenericCommand(client *c, int numkeys_idx, int is_block) {
}
}
if (count == 0) count = 1;
if (is_block) {
/* BLOCK. We will handle CLIENT_DENY_BLOCKING flag in blockingGenericZpopCommand. */
blockingGenericZpopCommand(c, c->argv+numkeys_idx+1, numkeys, where, 1, count, 1, 1);

View File

@ -1076,6 +1076,7 @@ foreach {pop} {BLPOP BLMPOP_LEFT} {
assert_error "ERR syntax error*" {r lmpop 1 mylist{t} LEFT bar_arg}
assert_error "ERR syntax error*" {r lmpop 1 mylist{t} RIGHT LEFT}
assert_error "ERR syntax error*" {r lmpop 1 mylist{t} COUNT}
assert_error "ERR syntax error*" {r lmpop 1 mylist{t} LEFT COUNT 1 COUNT 2}
assert_error "ERR syntax error*" {r lmpop 2 mylist{t} mylist2{t} bad_arg}
assert_error "ERR count*" {r lmpop 1 mylist{t} LEFT COUNT 0}

View File

@ -1137,6 +1137,7 @@ start_server {tags {"zset"}} {
assert_error "ERR syntax error*" {r zmpop 1 myzset{t} MIN bar_arg}
assert_error "ERR syntax error*" {r zmpop 1 myzset{t} MAX MIN}
assert_error "ERR syntax error*" {r zmpop 1 myzset{t} COUNT}
assert_error "ERR syntax error*" {r zmpop 1 myzset{t} MAX COUNT 1 COUNT 2}
assert_error "ERR syntax error*" {r zmpop 2 myzset{t} myzset2{t} bad_arg}
assert_error "ERR count*" {r zmpop 1 myzset{t} MIN COUNT 0}
@ -1922,6 +1923,7 @@ start_server {tags {"zset"}} {
assert_error "ERR syntax error*" {r bzmpop 1 1 myzset{t} MIN bar_arg}
assert_error "ERR syntax error*" {r bzmpop 1 1 myzset{t} MAX MIN}
assert_error "ERR syntax error*" {r bzmpop 1 1 myzset{t} COUNT}
assert_error "ERR syntax error*" {r bzmpop 1 1 myzset{t} MIN COUNT 1 COUNT 2}
assert_error "ERR syntax error*" {r bzmpop 1 2 myzset{t} myzset2{t} bad_arg}
assert_error "ERR count*" {r bzmpop 1 1 myzset{t} MIN COUNT 0}