bug(server): Fix crash in ZPOPMIN (#977)

* Fix crash in ZPOPMIN

Crash was due to an attempt to access nullptr[-1], which is bad :)

* Add test to repro crash.

There's some leftover debugging statements, they're somewhat useful so I
kept them as the bug is not yet fixed.

* Copy patch by romange to solve the crash

Also re-enable (uncomment) the test in utility.py.

Signed-off-by: chakaz <chakaz@chakaz>

---------

Signed-off-by: chakaz <chakaz@chakaz>
Signed-off-by: Chaka <chakaz@users.noreply.github.com>
Co-authored-by: chakaz <chakaz@chakaz>
This commit is contained in:
Chaka 2023-03-25 10:05:41 +03:00 committed by GitHub
parent 82121a205b
commit 7be98d906d
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
4 changed files with 16 additions and 5 deletions

View file

@ -1157,9 +1157,10 @@ void zsetConvert(robj *zobj, int encoding) {
zs->zsl = zslCreate();
eptr = lpSeek(zl,0);
serverAssertWithInfo(NULL,zobj,eptr != NULL);
sptr = lpNext(zl,eptr);
serverAssertWithInfo(NULL,zobj,sptr != NULL);
if (eptr != NULL) {
sptr = lpNext(zl,eptr);
serverAssertWithInfo(NULL,zobj,sptr != NULL);
}
while (eptr != NULL) {
score = zzlGetScore(sptr);

View file

@ -558,7 +558,7 @@ void IntervalVisitor::PopSkipList(ZSetFamily::TopNScored sc) {
if (params_.reverse) {
ln = zsl->tail;
} else {
ln = zsl->header;
ln = zsl->header->level[0].forward;
}
while (ln && sc--) {

View file

@ -478,6 +478,16 @@ TEST_F(ZSetFamilyTest, ZPopMax) {
ASSERT_THAT(resp, ArrLen(0));
}
TEST_F(ZSetFamilyTest, ZAddPopCrash) {
for (int i = 0; i < 129; ++i) {
auto resp = Run({"zadd", "key", absl::StrCat(i), absl::StrCat("element:", i)});
EXPECT_THAT(resp, IntArg(1));
}
auto resp = Run({"zpopmin", "key"});
EXPECT_EQ(resp, "element:0");
}
TEST_F(ZSetFamilyTest, Resp3) {
Run({"hello", "3"});
Run({"zadd", "x", "1", "a", "2", "b"});

View file

@ -199,7 +199,7 @@ class CommandGenerator:
('SPOP {k}', ValueType.SET),
('HSETNX {k} v0 {val}', ValueType.HSET),
('HINCRBY {k} v1 1', ValueType.HSET),
# ('ZPOPMIN {k} 1', ValueType.ZSET), https://github.com/dragonflydb/dragonfly/issues/949
('ZPOPMIN {k} 1', ValueType.ZSET),
('ZADD {k} 0 {val}', ValueType.ZSET),
('JSON.NUMINCRBY {k} $..i 1', ValueType.JSON),
('JSON.ARRPOP {k} $.arr', ValueType.JSON),