Unverified Commit 44352bee authored by Ozan Tezcan's avatar Ozan Tezcan Committed by GitHub
Browse files

Fix crash in RM_ScanKey() when used with hexpire (#13320)

RM_ScanKey() was overlooked while introducing hash field expiration. 
An assert is triggered when it is called on a hash key with
OBJ_ENCODING_LISTPACK_EX encoding.

I've changed to code to handle listpackex encoding properly.
parent 56169112
......@@ -11188,22 +11188,32 @@ int RM_ScanKey(RedisModuleKey *key, RedisModuleScanCursor *cursor, RedisModuleSc
cursor->done = 1;
ret = 0;
} else if (o->type == OBJ_ZSET || o->type == OBJ_HASH) {
unsigned char *p = lpSeek(o->ptr,0);
unsigned char *lp, *p;
unsigned char *vstr;
unsigned int vlen;
long long vll;
if (o->type == OBJ_HASH)
lp = hashTypeListpackGetLp(o);
else
lp = o->ptr;
p = lpSeek(lp,0);
while(p) {
vstr = lpGetValue(p,&vlen,&vll);
robj *field = (vstr != NULL) ?
createStringObject((char*)vstr,vlen) :
createStringObjectFromLongLongWithSds(vll);
p = lpNext(o->ptr,p);
p = lpNext(lp,p);
vstr = lpGetValue(p,&vlen,&vll);
robj *value = (vstr != NULL) ?
createStringObject((char*)vstr,vlen) :
createStringObjectFromLongLongWithSds(vll);
fn(key, field, value, privdata);
p = lpNext(o->ptr,p);
p = lpNext(lp,p);
if (o->type == OBJ_HASH && o->encoding == OBJ_ENCODING_LISTPACK_EX)
p = lpNext(lp, p); /* Skip expire time */
decrRefCount(field);
decrRefCount(value);
}
......
......@@ -24,6 +24,14 @@ start_server {tags {"modules"}} {
lsort [r scan.scan_key hh1]
} {{f1 1}}
test {Module scan hash listpack with hexpire} {
r hmset hh f1 v1 f2 v2
r hexpire hh 100000 fields 1 f1
assert_range [r httl hh fields 1 f1] 10000 100000
assert_encoding listpackex hh
lsort [r scan.scan_key hh]
} {{f1 v1} {f2 v2}}
test {Module scan hash dict} {
r config set hash-max-ziplist-entries 2
r hmset hh f3 v3
......@@ -31,6 +39,16 @@ start_server {tags {"modules"}} {
lsort [r scan.scan_key hh]
} {{f1 v1} {f2 v2} {f3 v3}}
test {Module scan hash dict with hexpire} {
r config set hash-max-listpack-entries 1
r del hh
r hmset hh f1 v1 f2 v2 f3 v3
r hexpire hh 100000 fields 1 f2
assert_range [r httl hh fields 1 f2] 10000 100000
assert_encoding hashtable hh
lsort [r scan.scan_key hh]
} {{f1 v1} {f2 v2} {f3 v3}}
test {Module scan zset listpack} {
r zadd zz 1 f1 2 f2
assert_encoding listpack zz
......
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