Fix negative offset issue for ZRANGEBY[SCORE|LEX] command (#14043)

Fix #13952

This PR ensures that ZRANGE_SCORE/LEX command with a negative offset
will return empty.
This commit is contained in:
yzc-yzc 2025-06-20 13:51:52 +08:00 committed by YaacovHazan
parent 08961e16db
commit 4c6ffd5125
2 changed files with 16 additions and 2 deletions

View File

@ -3277,7 +3277,7 @@ void genericZrangebyscoreCommand(zrange_result_handler *handler,
handler->beginResultEmission(handler, -1);
/* For invalid offset, return directly. */
if (offset > 0 && offset >= (long)zsetLength(zobj)) {
if (offset < 0 || (offset > 0 && offset >= (long)zsetLength(zobj))) {
handler->finalizeResultEmission(handler, 0);
return;
}
@ -3551,6 +3551,12 @@ void genericZrangebylexCommand(zrange_result_handler *handler,
handler->beginResultEmission(handler, -1);
/* For invalid offset, return directly. */
if (offset < 0 || (offset > 0 && offset >= (long)zsetLength(zobj))) {
handler->finalizeResultEmission(handler, 0);
return;
}
if (zobj->encoding == OBJ_ENCODING_LISTPACK) {
unsigned char *zl = zobj->ptr;
unsigned char *eptr, *sptr;

View File

@ -583,20 +583,24 @@ start_server {tags {"zset"}} {
assert_equal {d e f} [r zrangebyscore zset 0 10 LIMIT 2 3]
assert_equal {d e f} [r zrangebyscore zset 0 10 LIMIT 2 10]
assert_equal {} [r zrangebyscore zset 0 10 LIMIT 20 10]
assert_equal {} [r zrangebyscore zset 0 10 LIMIT -1 2]
assert_equal {f e} [r zrevrangebyscore zset 10 0 LIMIT 0 2]
assert_equal {d c b} [r zrevrangebyscore zset 10 0 LIMIT 2 3]
assert_equal {d c b} [r zrevrangebyscore zset 10 0 LIMIT 2 10]
assert_equal {} [r zrevrangebyscore zset 10 0 LIMIT 20 10]
assert_equal {} [r zrevrangebyscore zset 10 0 LIMIT -1 2]
# zrangebyscore uses different logic when offset > ZSKIPLIST_MAX_SEARCH
create_long_zset zset 30
assert_equal {i12 i13 i14} [r zrangebyscore zset 0 20 LIMIT 12 3]
assert_equal {i14 i15} [r zrangebyscore zset 0 20 LIMIT 14 2]
assert_equal {i19 i20 i21} [r zrangebyscore zset 0 30 LIMIT 19 3]
assert_equal {i29} [r zrangebyscore zset 10 30 LIMIT 19 2]
assert_equal {i29} [r zrangebyscore zset 10 30 LIMIT 19 2]
assert_equal {} [r zrangebyscore zset 0 20 LIMIT -1 3]
assert_equal {i17 i16 i15} [r zrevrangebyscore zset 30 10 LIMIT 12 3]
assert_equal {i6 i5} [r zrevrangebyscore zset 20 0 LIMIT 14 2]
assert_equal {i2 i1 i0} [r zrevrangebyscore zset 20 0 LIMIT 18 5]
assert_equal {i0} [r zrevrangebyscore zset 20 0 LIMIT 20 5]
assert_equal {} [r zrevrangebyscore zset 30 10 LIMIT -1 3]
}
test "ZRANGEBYSCORE with LIMIT and WITHSCORES - $encoding" {
@ -680,9 +684,11 @@ start_server {tags {"zset"}} {
assert_equal {bar} [r zrangebylex zset \[bar \[down LIMIT 0 1]
assert_equal {cool} [r zrangebylex zset \[bar \[down LIMIT 1 1]
assert_equal {bar cool down} [r zrangebylex zset \[bar \[down LIMIT 0 100]
assert_equal {} [r zrangebylex zset - \[cool LIMIT -1 2]
assert_equal {omega hill great foo elephant} [r zrevrangebylex zset + \[d LIMIT 0 5]
assert_equal {omega hill great foo} [r zrevrangebylex zset + \[d LIMIT 0 4]
assert_equal {great foo elephant} [r zrevrangebylex zset + \[d LIMIT 2 3]
assert_equal {} [r zrevrangebylex zset + \[d LIMIT -1 5]
# zrangebylex uses different logic when offset > ZSKIPLIST_MAX_SEARCH
create_long_lex_zset
assert_equal {max null} [r zrangebylex zset - \[tree LIMIT 12 2]
@ -692,12 +698,14 @@ start_server {tags {"zset"}} {
assert_equal {max} [r zrangebylex zset \[max \[null LIMIT 0 1]
assert_equal {null} [r zrangebylex zset \[max \[null LIMIT 1 1]
assert_equal {max null omega point} [r zrangebylex zset \[max \[point LIMIT 0 100]
assert_equal {} [r zrangebylex zset - \[tree LIMIT -1 2]
assert_equal {tree sea result query point} [r zrevrangebylex zset + \[o LIMIT 0 5]
assert_equal {tree sea result query} [r zrevrangebylex zset + \[o LIMIT 0 4]
assert_equal {omega null max lip} [r zrevrangebylex zset + \[l LIMIT 5 4]
assert_equal {elephant down} [r zrevrangebylex zset + \[a LIMIT 15 2]
assert_equal {bar alpha} [r zrevrangebylex zset + - LIMIT 18 6]
assert_equal {hill great foo} [r zrevrangebylex zset + \[c LIMIT 12 3]
assert_equal {} [r zrevrangebylex zset + \[o LIMIT -1 5]
}
test "ZRANGEBYLEX with invalid lex range specifiers - $encoding" {