Unverified Commit 03357883 authored by Binbin's avatar Binbin Committed by GitHub
Browse files

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.
parent 215b909c
...@@ -1198,7 +1198,7 @@ void lmpopGenericCommand(client *c, int numkeys_idx, int is_block) { ...@@ -1198,7 +1198,7 @@ void lmpopGenericCommand(client *c, int numkeys_idx, int is_block) {
long j; long j;
long numkeys = 0; /* Number of keys. */ long numkeys = 0; /* Number of keys. */
int where = 0; /* HEAD for LEFT, TAIL for RIGHT. */ 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. */ /* Parse the numkeys. */
if (getRangeLongFromObjectOrReply(c, c->argv[numkeys_idx], 1, LONG_MAX, if (getRangeLongFromObjectOrReply(c, c->argv[numkeys_idx], 1, LONG_MAX,
...@@ -1219,7 +1219,7 @@ void lmpopGenericCommand(client *c, int numkeys_idx, int is_block) { ...@@ -1219,7 +1219,7 @@ void lmpopGenericCommand(client *c, int numkeys_idx, int is_block) {
char *opt = c->argv[j]->ptr; char *opt = c->argv[j]->ptr;
int moreargs = (c->argc - 1) - j; int moreargs = (c->argc - 1) - j;
if (!strcasecmp(opt, "COUNT") && moreargs) { if (count == 0 && !strcasecmp(opt, "COUNT") && moreargs) {
j++; j++;
if (getRangeLongFromObjectOrReply(c, c->argv[j], 1, LONG_MAX, if (getRangeLongFromObjectOrReply(c, c->argv[j], 1, LONG_MAX,
&count,"count should be greater than 0") != C_OK) &count,"count should be greater than 0") != C_OK)
...@@ -1230,6 +1230,8 @@ void lmpopGenericCommand(client *c, int numkeys_idx, int is_block) { ...@@ -1230,6 +1230,8 @@ void lmpopGenericCommand(client *c, int numkeys_idx, int is_block) {
} }
} }
if (count == 0) count = 1;
if (is_block) { if (is_block) {
/* BLOCK. We will handle CLIENT_DENY_BLOCKING flag in blockingPopGenericCommand. */ /* BLOCK. We will handle CLIENT_DENY_BLOCKING flag in blockingPopGenericCommand. */
blockingPopGenericCommand(c, c->argv+numkeys_idx+1, numkeys, where, 1, count); blockingPopGenericCommand(c, c->argv+numkeys_idx+1, numkeys, where, 1, count);
......
...@@ -4287,7 +4287,7 @@ void zmpopGenericCommand(client *c, int numkeys_idx, int is_block) { ...@@ -4287,7 +4287,7 @@ void zmpopGenericCommand(client *c, int numkeys_idx, int is_block) {
long j; long j;
long numkeys = 0; /* Number of keys. */ long numkeys = 0; /* Number of keys. */
int where = 0; /* ZSET_MIN or ZSET_MAX. */ 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. */ /* Parse the numkeys. */
if (getRangeLongFromObjectOrReply(c, c->argv[numkeys_idx], 1, LONG_MAX, if (getRangeLongFromObjectOrReply(c, c->argv[numkeys_idx], 1, LONG_MAX,
...@@ -4314,7 +4314,7 @@ void zmpopGenericCommand(client *c, int numkeys_idx, int is_block) { ...@@ -4314,7 +4314,7 @@ void zmpopGenericCommand(client *c, int numkeys_idx, int is_block) {
char *opt = c->argv[j]->ptr; char *opt = c->argv[j]->ptr;
int moreargs = (c->argc - 1) - j; int moreargs = (c->argc - 1) - j;
if (!strcasecmp(opt, "COUNT") && moreargs) { if (count == 0 && !strcasecmp(opt, "COUNT") && moreargs) {
j++; j++;
if (getRangeLongFromObjectOrReply(c, c->argv[j], 1, LONG_MAX, if (getRangeLongFromObjectOrReply(c, c->argv[j], 1, LONG_MAX,
&count,"count should be greater than 0") != C_OK) &count,"count should be greater than 0") != C_OK)
...@@ -4325,6 +4325,8 @@ void zmpopGenericCommand(client *c, int numkeys_idx, int is_block) { ...@@ -4325,6 +4325,8 @@ void zmpopGenericCommand(client *c, int numkeys_idx, int is_block) {
} }
} }
if (count == 0) count = 1;
if (is_block) { if (is_block) {
/* BLOCK. We will handle CLIENT_DENY_BLOCKING flag in blockingGenericZpopCommand. */ /* BLOCK. We will handle CLIENT_DENY_BLOCKING flag in blockingGenericZpopCommand. */
blockingGenericZpopCommand(c, c->argv+numkeys_idx+1, numkeys, where, 1, count, 1, 1); blockingGenericZpopCommand(c, c->argv+numkeys_idx+1, numkeys, where, 1, count, 1, 1);
......
...@@ -1076,6 +1076,7 @@ foreach {pop} {BLPOP BLMPOP_LEFT} { ...@@ -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} 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} RIGHT LEFT}
assert_error "ERR syntax error*" {r lmpop 1 mylist{t} COUNT} 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 syntax error*" {r lmpop 2 mylist{t} mylist2{t} bad_arg}
assert_error "ERR count*" {r lmpop 1 mylist{t} LEFT COUNT 0} assert_error "ERR count*" {r lmpop 1 mylist{t} LEFT COUNT 0}
......
...@@ -1137,6 +1137,7 @@ start_server {tags {"zset"}} { ...@@ -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} 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} MAX MIN}
assert_error "ERR syntax error*" {r zmpop 1 myzset{t} COUNT} 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 syntax error*" {r zmpop 2 myzset{t} myzset2{t} bad_arg}
assert_error "ERR count*" {r zmpop 1 myzset{t} MIN COUNT 0} assert_error "ERR count*" {r zmpop 1 myzset{t} MIN COUNT 0}
...@@ -1922,6 +1923,7 @@ start_server {tags {"zset"}} { ...@@ -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} 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} 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} 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 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} assert_error "ERR count*" {r bzmpop 1 1 myzset{t} MIN COUNT 0}
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment