zrangeGenericCommand add check for negative offset (#9052)
Now we will check the offset in zrangeGenericCommand. With a negative offset, we will throw an error and return. This also resolve the issue of zeroing the destination key in case of the "store" variant when we input a negative offset. ``` 127.0.0.1:6379> set key value OK 127.0.0.1:6379> zrangestore key myzset 0 10 byscore limit -1 10 (integer) 0 127.0.0.1:6379> exists key (integer) 0 ``` This change affects the following commands: - ZRANGE / ZRANGESTORE / ZRANGEBYLEX / ZRANGEBYSCORE - ZREVRANGE / ZREVRANGEBYSCORE / ZREVRANGEBYLEX
This commit is contained in:
parent
66ea178cb6
commit
d9c2ef8a72
11
src/t_zset.c
11
src/t_zset.c
@ -3630,7 +3630,7 @@ void zrangeGenericCommand(zrange_result_handler *handler, int argc_start, int st
|
||||
long opt_end = 0;
|
||||
int opt_withscores = 0;
|
||||
long opt_offset = 0;
|
||||
long opt_limit = -1;
|
||||
long opt_limit = -1; /* A negative limit returns all elements from the offset. */
|
||||
|
||||
/* Step 1: Skip the <src> <min> <max> args and parse remaining optional arguments. */
|
||||
for (int j=argc_start + 3; j < c->argc; j++) {
|
||||
@ -3638,11 +3638,12 @@ void zrangeGenericCommand(zrange_result_handler *handler, int argc_start, int st
|
||||
if (!store && !strcasecmp(c->argv[j]->ptr,"withscores")) {
|
||||
opt_withscores = 1;
|
||||
} else if (!strcasecmp(c->argv[j]->ptr,"limit") && leftargs >= 2) {
|
||||
if ((getLongFromObjectOrReply(c, c->argv[j+1], &opt_offset, NULL) != C_OK) ||
|
||||
(getLongFromObjectOrReply(c, c->argv[j+2], &opt_limit, NULL) != C_OK))
|
||||
{
|
||||
if (getRangeLongFromObjectOrReply(c, c->argv[j+1], 0, LONG_MAX,
|
||||
&opt_offset, "offset should be greater than or equal to 0") != C_OK)
|
||||
return;
|
||||
|
||||
if (getLongFromObjectOrReply(c, c->argv[j+2], &opt_limit, NULL) != C_OK)
|
||||
return;
|
||||
}
|
||||
j += 2;
|
||||
} else if (direction == ZRANGE_DIRECTION_AUTO &&
|
||||
!strcasecmp(c->argv[j]->ptr,"rev"))
|
||||
|
@ -370,6 +370,28 @@ start_server {tags {"zset"}} {
|
||||
r zrem ztmp a b c d e f g
|
||||
} {3}
|
||||
|
||||
test "ZRANGE* with wrong offset or limit should throw error" {
|
||||
r del src{t} dst{t}
|
||||
|
||||
foreach offset {-1 -100 str NaN} {
|
||||
assert_error "ERR*offset*" {r ZRANGE src{t} 0 -1 byscore limit $offset 1}
|
||||
assert_error "ERR*offset*" {r ZRANGESTORE dst{t} src{t} 0 -1 byscore limit $offset 4}
|
||||
assert_error "ERR*offset*" {r ZRANGEBYLEX src{t} (az (b limit $offset 5}
|
||||
assert_error "ERR*offset*" {r ZRANGEBYSCORE src{t} 0 -1 limit $offset 2}
|
||||
assert_error "ERR*offset*" {r ZREVRANGEBYLEX src{t} (az (b limit $offset 6}
|
||||
assert_error "ERR*offset*" {r ZREVRANGEBYSCORE src{t} -1 0 limit $offset 3}
|
||||
}
|
||||
|
||||
foreach limit {str NaN} {
|
||||
assert_error "ERR value*" {r ZRANGE src{t} 0 -1 byscore limit 0 $limit}
|
||||
assert_error "ERR value*" {r ZRANGESTORE dst{t} src{t} 0 -1 byscore limit 0 $limit}
|
||||
assert_error "ERR value*" {r ZRANGEBYLEX src{t} (az (b limit 0 $limit}
|
||||
assert_error "ERR value*" {r ZRANGEBYSCORE src{t} 0 -1 limit 0 $limit}
|
||||
assert_error "ERR value*" {r ZREVRANGEBYLEX src{t} (az (b limit 0 $limit}
|
||||
assert_error "ERR value*" {r ZREVRANGEBYSCORE src{t} -1 0 limit 0 $limit}
|
||||
}
|
||||
}
|
||||
|
||||
test "ZRANGE basics - $encoding" {
|
||||
r del ztmp
|
||||
r zadd ztmp 1 a
|
||||
|
Loading…
x
Reference in New Issue
Block a user