mirror of https://mirror.osredm.com/root/redis.git
Fix hscan return value (#13297)
In the last step of hscan, while replying to client, we assume all items in the result list are keys which are mstr instances. Though, there might be values which are sds instances. Added a check to avoid calling mstrlen() for value objects. To reproduce: ``` 127.0.0.1:6379> hset myhash1 a 11111111111111111111111111111111111111111111111111111111111111111 (integer) 0 127.0.0.1:6379> hscan myhash1 0 1) "0" 2) 1) "a" 2) "11111111111111111111111111111111111111111111111111111111111111111\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" ```
This commit is contained in:
parent
e2918705c8
commit
6a11d458be
6
src/db.c
6
src/db.c
|
@ -1299,10 +1299,14 @@ void scanGenericCommand(client *c, robj *o, unsigned long long cursor) {
|
|||
addReplyArrayLen(c, 2);
|
||||
addReplyBulkLongLong(c,cursor);
|
||||
|
||||
unsigned long long idx = 0;
|
||||
addReplyArrayLen(c, listLength(keys));
|
||||
while ((node = listFirst(keys)) != NULL) {
|
||||
void *key = listNodeValue(node);
|
||||
addReplyBulkCBuffer(c, key, (isKeysHfield) ? mstrlen(key) : sdslen(key));
|
||||
/* For HSCAN, list will contain keys value pairs unless no_values arg
|
||||
* was given. We should call mstrlen for the keys only. */
|
||||
int hfieldkey = isKeysHfield && (no_values || (idx++ % 2 == 0));
|
||||
addReplyBulkCBuffer(c, key, hfieldkey ? mstrlen(key) : sdslen(key));
|
||||
listDelNode(keys, node);
|
||||
}
|
||||
|
||||
|
|
|
@ -277,6 +277,32 @@ proc test_scan {type} {
|
|||
set res [r hscan hash 0 count 1000 novalues]
|
||||
assert_equal [lsort $keys2] [lsort [lindex $res 1]]
|
||||
}
|
||||
|
||||
test "{$type} HSCAN with large value $enc" {
|
||||
r del hash
|
||||
|
||||
if {$enc eq {listpack}} {
|
||||
set count 60
|
||||
} else {
|
||||
set count 170
|
||||
}
|
||||
|
||||
set val1 [string repeat "1" $count]
|
||||
r hset hash $val1 $val1
|
||||
|
||||
set val2 [string repeat "2" $count]
|
||||
r hset hash $val2 $val2
|
||||
|
||||
set res [lsort [lindex [r hscan hash 0] 1]]
|
||||
assert_equal $val1 [lindex $res 0]
|
||||
assert_equal $val1 [lindex $res 1]
|
||||
assert_equal $val2 [lindex $res 2]
|
||||
assert_equal $val2 [lindex $res 3]
|
||||
|
||||
set res [lsort [lindex [r hscan hash 0 novalues] 1]]
|
||||
assert_equal $val1 [lindex $res 0]
|
||||
assert_equal $val2 [lindex $res 1]
|
||||
}
|
||||
}
|
||||
|
||||
foreach enc {listpack skiplist} {
|
||||
|
|
Loading…
Reference in New Issue