From 99c468c38c597400f84df2128153e3abebe5e9f0 Mon Sep 17 00:00:00 2001 From: Binbin Date: Thu, 28 Dec 2023 14:32:51 +0800 Subject: [PATCH] Fix crash caused by pubsubShardUnsubscribeAllChannelsInSlot not deleting the client (#12896) The code does not delete the corresponding node when traversing clients, resulting in a loop, causing the dictDelete() == DICT_OK assertion to fail. In addition, did a cleanup, in the dictCreate scenario, we can avoid a dictFind call since the dict is empty. Issue was introduced in #12804. --- src/pubsub.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/pubsub.c b/src/pubsub.c index f8910ee4f..6c69431b8 100644 --- a/src/pubsub.c +++ b/src/pubsub.c @@ -295,8 +295,10 @@ int pubsubSubscribeChannel(client *c, robj *channel, pubsubtype type) { d_ptr = type.serverPubSubChannels(slot); if (*d_ptr == NULL) { *d_ptr = dictCreate(&keylistDictType); + de = NULL; + } else { + de = dictFind(*d_ptr, channel); } - de = dictFind(*d_ptr, channel); if (de == NULL) { clients = listCreate(); dictAdd(*d_ptr, channel, clients); @@ -387,6 +389,7 @@ void pubsubShardUnsubscribeAllChannelsInSlot(unsigned int slot) { if (clientTotalPubSubSubscriptionCount(c) == 0) { unmarkClientAsPubSub(c); } + listDelNode(clients, ln); } server.shard_channel_count--; dictDelete(d, channel);