diff options
author | Vitaly <Vitaly.Arbuzov@gmail.com> | 2022-05-27 12:34:00 -0700 |
---|---|---|
committer | Oran Agra <oran@redislabs.com> | 2022-12-12 17:02:54 +0200 |
commit | fd7bde5726e197fe4550bf604dc945556674d76c (patch) | |
tree | baa102032b2154ee337f0852238a62cabb964cda | |
parent | 9d40f1cbb5b424b4a138edb2254e371826e99978 (diff) | |
download | redis-fd7bde5726e197fe4550bf604dc945556674d76c.tar.gz |
Fix ZRANGESTORE crash when zset_max_listpack_entries is 0 (#10767)
When `zrangestore` is called container destination object is created.
Before this PR we used to create a listpack based object even if `zset-max-ziplist-entries`
or equivalent`zset-max-listpack-entries` was set to 0.
This triggered immediate conversion of the listpack into a skiplist in `zrangestore`, which hits
an assertion resulting in an engine crash.
Added a TCL test that reproduces this issue.
(cherry picked from commit 6461f09f433b78e3d69650a1377ac0574cb87378)
-rw-r--r-- | src/t_zset.c | 7 | ||||
-rw-r--r-- | tests/unit/type/zset.tcl | 9 |
2 files changed, 13 insertions, 3 deletions
diff --git a/src/t_zset.c b/src/t_zset.c index f313b8850..5660b3c7d 100644 --- a/src/t_zset.c +++ b/src/t_zset.c @@ -1192,9 +1192,10 @@ void zsetConvert(robj *zobj, int encoding) { zs->zsl = zslCreate(); eptr = ziplistIndex(zl,0); - serverAssertWithInfo(NULL,zobj,eptr != NULL); - sptr = ziplistNext(zl,eptr); - serverAssertWithInfo(NULL,zobj,sptr != NULL); + if (eptr != NULL) { + sptr = ziplistNext(zl,eptr); + serverAssertWithInfo(NULL,zobj,sptr != NULL); + } while (eptr != NULL) { score = zzlGetScore(sptr); diff --git a/tests/unit/type/zset.tcl b/tests/unit/type/zset.tcl index 94b2ab480..ec5fc2e5b 100644 --- a/tests/unit/type/zset.tcl +++ b/tests/unit/type/zset.tcl @@ -1643,6 +1643,15 @@ start_server {tags {"zset"}} { assert_match "*syntax*" $err } + test {ZRANGESTORE with zset-max-listpack-entries 0 dst key should use skiplist encoding} { + set original_max [lindex [r config get zset-max-ziplist-entries] 1] + r config set zset-max-ziplist-entries 0 + r del z1{t} z2{t} + r zadd z1{t} 1 a + assert_equal 1 [r zrangestore z2{t} z1{t} 0 -1] + r config set zset-max-ziplist-entries $original_max + } + test {ZRANGE invalid syntax} { catch {r zrange z1 0 -1 limit 1 2} err assert_match "*syntax*" $err |