Unverified Commit 6a11d458 authored by Ozan Tezcan's avatar Ozan Tezcan Committed by GitHub
Browse files

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"
```
parent e2918705
......@@ -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} {
......
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