-
Notifications
You must be signed in to change notification settings - Fork 120
Description
Version
5.0.1
Context
Description
MultiType
class design assumes that RESP3 map
type responses from redis must always contain valid UTF-8 keys. While redis docs (and actual behavior) clearly say that keys in map
responses may be of any type including BulkStrings (binary) (https://redis.io/docs/latest/develop/reference/protocol-spec/#maps).
So if you try to retrieve maps with binary keys (redis HASH in the reproducer project), negative bytes will get replaced with the same UTF codepoint 65533
(question mark). I.e. keys gets scrambled, it's impossible to restore original received binary data (which is correct by the way in the received buffer) from the MultiType
object returned to the user of redis-client.
So there are two inter-related parts of this bug:
MultiType
class does not support binary keys by design- binary data gets scrambled when it's being decoded as UTF8 string, here: key = reply.toString();
See attached reproducer project for more details.
I'd like to fix this myself, please let me know if it's fine for me to contribute.
Workarounds
I didn't find any direct workaround since the root cause sits very deep inside the parser. If you already have HASHES in redis with binary fields, then it seems that it's impossible to read them with vertx-redis client (with HGETALL
of course). And this can be extrapolated to any commands+data-structures that have map
resp3 response types.
I can see only 2 indirect and limited workarounds though:
- avoid using binary keys in cases where you have control over it
- store binary keys as base64 encoded strings, if we have control over the writing process
Steps to reproduce
(see reproducer project, it contains reproducible easy to run out-of-the-box test)
- Create
HASH
redis entry with binary fields (keys). Values are irrelevant for this bug. Binary keys should contain negative bytes (bytes greater than 127 if you interpret them as unsigned ones). - Call
HGETALL
using vertx-redis-client. - There's no direct support to get keys of returned response object as binary. Only as UTF8 strings.
- There's no way to reverse UTF8 string keys back into bytes.
Do you have a reproducer?
https://github.com/dburyak/vertx-redis-resp3-map-keys-decoding-bug