Describe the bug

ZRANDMEMBER returns an invalid score when requesting a COUNT of 1. Increasing the count to 2 lets the bug disappear.

To reproduce

Redis version 6.2.4.

Reproduce with:

Prepare:

"ZADD" "\xac\xed\x00\x05t\x00$19259914-acda-4fe1-93ae-e2aa4495838e" "1.9" "\xac\xed\x00\x05sr\x00%org.springframework.data.redis.Person\x01I\x199\xf2\xd4>m\x02\x00\x04L\x00\aaddresst\x00(Lorg/springframework/data/redis/Address;L\x00\x03aget\x00\x13Ljava/lang/Integer;L\x00\tfirstNamet\x00\x12Ljava/lang/String;L\x00\blastNameq\x00~\x00\x03xpsr\x00&org.springframework.data.redis.AddressDU\xb9?\x9d\x9b\x85{\x02\x00\x02L\x00\x06numberq\x00~\x00\x02L\x00\x06streetq\x00~\x00\x03xpsr\x00\x11java.lang.Integer\x12\xe2\xa0\xa4\xf7\x81\x878\x02\x00\x01I\x00\x05valuexr\x00\x10java.lang.Number\x86\xac\x95\x1d\x0b\x94\xe0\x8b\x02\x00\x00xp\x00\x00\x00\x01t\x00$965ab474-b659-41c9-9e6e-80c6aa76300fq\x00~\x00\tq\x00~\x00\nq\x00~\x00\n"
"ZADD" "\xac\xed\x00\x05t\x00$19259914-acda-4fe1-93ae-e2aa4495838e" "3.7" "\xac\xed\x00\x05sr\x00%org.springframework.data.redis.Person\x01I\x199\xf2\xd4>m\x02\x00\x04L\x00\aaddresst\x00(Lorg/springframework/data/redis/Address;L\x00\x03aget\x00\x13Ljava/lang/Integer;L\x00\tfirstNamet\x00\x12Ljava/lang/String;L\x00\blastNameq\x00~\x00\x03xpsr\x00&org.springframework.data.redis.AddressDU\xb9?\x9d\x9b\x85{\x02\x00\x02L\x00\x06numberq\x00~\x00\x02L\x00\x06streetq\x00~\x00\x03xpsr\x00\x11java.lang.Integer\x12\xe2\xa0\xa4\xf7\x81\x878\x02\x00\x01I\x00\x05valuexr\x00\x10java.lang.Number\x86\xac\x95\x1d\x0b\x94\xe0\x8b\x02\x00\x00xp\x00\x00\x00\x02t\x00$07284f46-77c1-40bc-85cc-7c223696e43fq\x00~\x00\tq\x00~\x00\nq\x00~\x00\n"
"ZADD" "\xac\xed\x00\x05t\x00$19259914-acda-4fe1-93ae-e2aa4495838e" "5.8" "\xac\xed\x00\x05sr\x00%org.springframework.data.redis.Person\x01I\x199\xf2\xd4>m\x02\x00\x04L\x00\aaddresst\x00(Lorg/springframework/data/redis/Address;L\x00\x03aget\x00\x13Ljava/lang/Integer;L\x00\tfirstNamet\x00\x12Ljava/lang/String;L\x00\blastNameq\x00~\x00\x03xpsr\x00&org.springframework.data.redis.AddressDU\xb9?\x9d\x9b\x85{\x02\x00\x02L\x00\x06numberq\x00~\x00\x02L\x00\x06streetq\x00~\x00\x03xpsr\x00\x11java.lang.Integer\x12\xe2\xa0\xa4\xf7\x81\x878\x02\x00\x01I\x00\x05valuexr\x00\x10java.lang.Number\x86\xac\x95\x1d\x0b\x94\xe0\x8b\x02\x00\x00xp\x00\x00\x00\x03t\x00$60824f22-c393-4039-aaf3-8688ecab691eq\x00~\x00\tq\x00~\x00\nq\x00~\x00\n"

Reproduce:

zrandmember "\xac\xed\x00\x05t\x00$19259914-acda-4fe1-93ae-e2aa4495838e" 1 withscores
1) "\xac\xed\x00\x05sr\x00%org.springframework.data.redis.Person\x01I\x199\xf2\xd4>m\x02\x00\x04L\x00\aaddresst\x00(Lorg/springframework/data/redis/Address;L\x00\x03aget\x00\x13Ljava/lang/Integer;L\x00\tfirstNamet\x00\x12Ljava/lang/String;L\x00\blastNameq\x00~\x00\x03xpsr\x00&org.springframework.data.redis.AddressDU\xb9?\x9d\x9b\x85{\x02\x00\x02L\x00\x06numberq\x00~\x00\x02L\x00\x06streetq\x00~\x00\x03xpsr\x00\x11java.lang.Integer\x12\xe2\xa0\xa4\xf7\x81\x878\x02\x00\x01I\x00\x05valuexr\x00\x10java.lang.Number\x86\xac\x95\x1d\x0b\x94\xe0\x8b\x02\x00\x00xp\x00\x00\x00\x01t\x00$965ab474-b659-41c9-9e6e-80c6aa76300fq\x00~\x00\tq\x00~\x00\nq\x00~\x00\n"
2) "6.9357086902918174e-310"

ZRANDMEMBER with COUNT greater 1:

127.0.0.1:6379> zrandmember "\xac\xed\x00\x05t\x00$19259914-acda-4fe1-93ae-e2aa4495838e" 2 withscores
1) "\xac\xed\x00\x05sr\x00%org.springframework.data.redis.Person\x01I\x199\xf2\xd4>m\x02\x00\x04L\x00\aaddresst\x00(Lorg/springframework/data/redis/Address;L\x00\x03aget\x00\x13Ljava/lang/Integer;L\x00\tfirstNamet\x00\x12Ljava/lang/String;L\x00\blastNameq\x00~\x00\x03xpsr\x00&org.springframework.data.redis.AddressDU\xb9?\x9d\x9b\x85{\x02\x00\x02L\x00\x06numberq\x00~\x00\x02L\x00\x06streetq\x00~\x00\x03xpsr\x00\x11java.lang.Integer\x12\xe2\xa0\xa4\xf7\x81\x878\x02\x00\x01I\x00\x05valuexr\x00\x10java.lang.Number\x86\xac\x95\x1d\x0b\x94\xe0\x8b\x02\x00\x00xp\x00\x00\x00\x03t\x00$60824f22-c393-4039-aaf3-8688ecab691eq\x00~\x00\tq\x00~\x00\nq\x00~\x00\n"
2) "5.7999999999999998"
3) "\xac\xed\x00\x05sr\x00%org.springframework.data.redis.Person\x01I\x199\xf2\xd4>m\x02\x00\x04L\x00\aaddresst\x00(Lorg/springframework/data/redis/Address;L\x00\x03aget\x00\x13Ljava/lang/Integer;L\x00\tfirstNamet\x00\x12Ljava/lang/String;L\x00\blastNameq\x00~\x00\x03xpsr\x00&org.springframework.data.redis.AddressDU\xb9?\x9d\x9b\x85{\x02\x00\x02L\x00\x06numberq\x00~\x00\x02L\x00\x06streetq\x00~\x00\x03xpsr\x00\x11java.lang.Integer\x12\xe2\xa0\xa4\xf7\x81\x878\x02\x00\x01I\x00\x05valuexr\x00\x10java.lang.Number\x86\xac\x95\x1d\x0b\x94\xe0\x8b\x02\x00\x00xp\x00\x00\x00\x02t\x00$07284f46-77c1-40bc-85cc-7c223696e43fq\x00~\x00\tq\x00~\x00\nq\x00~\x00\n"
4) "3.7000000000000002"



127.0.0.1:6379> zrandmember "\xac\xed\x00\x05t\x00$19259914-acda-4fe1-93ae-e2aa4495838e" 2 withscores
1) "\xac\xed\x00\x05sr\x00%org.springframework.data.redis.Person\x01I\x199\xf2\xd4>m\x02\x00\x04L\x00\aaddresst\x00(Lorg/springframework/data/redis/Address;L\x00\x03aget\x00\x13Ljava/lang/Integer;L\x00\tfirstNamet\x00\x12Ljava/lang/String;L\x00\blastNameq\x00~\x00\x03xpsr\x00&org.springframework.data.redis.AddressDU\xb9?\x9d\x9b\x85{\x02\x00\x02L\x00\x06numberq\x00~\x00\x02L\x00\x06streetq\x00~\x00\x03xpsr\x00\x11java.lang.Integer\x12\xe2\xa0\xa4\xf7\x81\x878\x02\x00\x01I\x00\x05valuexr\x00\x10java.lang.Number\x86\xac\x95\x1d\x0b\x94\xe0\x8b\x02\x00\x00xp\x00\x00\x00\x01t\x00$965ab474-b659-41c9-9e6e-80c6aa76300fq\x00~\x00\tq\x00~\x00\nq\x00~\x00\n"
2) "1.8999999999999999"
3) "\xac\xed\x00\x05sr\x00%org.springframework.data.redis.Person\x01I\x199\xf2\xd4>m\x02\x00\x04L\x00\aaddresst\x00(Lorg/springframework/data/redis/Address;L\x00\x03aget\x00\x13Ljava/lang/Integer;L\x00\tfirstNamet\x00\x12Ljava/lang/String;L\x00\blastNameq\x00~\x00\x03xpsr\x00&org.springframework.data.redis.AddressDU\xb9?\x9d\x9b\x85{\x02\x00\x02L\x00\x06numberq\x00~\x00\x02L\x00\x06streetq\x00~\x00\x03xpsr\x00\x11java.lang.Integer\x12\xe2\xa0\xa4\xf7\x81\x878\x02\x00\x01I\x00\x05valuexr\x00\x10java.lang.Number\x86\xac\x95\x1d\x0b\x94\xe0\x8b\x02\x00\x00xp\x00\x00\x00\x03t\x00$60824f22-c393-4039-aaf3-8688ecab691eq\x00~\x00\tq\x00~\x00\nq\x00~\x00\n"
4) "5.7999999999999998"

Additional information

The issue seems related to the actual key or value. It doesn't seem to happen with plain strings.

Comment From: sundb

@mp911de This is indeed a bug, the use of zset->dict is wrong, can you create a pr to fix it? https://github.com/redis/redis/blob/4fa3e23092d642f0c67116d9f7616f4f1173a1cf/src/t_zset.c#L4034 It should be addReplyDouble(c, *(double *)dictGetVal(de));

Comment From: mp911de

I'm not familiar with the Redis codebase at all, so I'd be happy to have someone else looking into it.

Comment From: enjoy-binbin

I read it wrong before (deleted the comment), made a pr for it

(-count or count == 1) and skiplist will have this problem