Script 'mail_helper' called by obssrc
Hello community,

here is the log from the commit of package redis for openSUSE:Factory checked 
in at 2024-01-10 21:50:57
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/redis (Old)
 and      /work/SRC/openSUSE:Factory/.redis.new.21961 (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Package is "redis"

Wed Jan 10 21:50:57 2024 rev:93 rq:1137732 version:7.2.4

Changes:
--------
--- /work/SRC/openSUSE:Factory/redis/redis.changes      2023-11-05 
12:19:19.714313876 +0100
+++ /work/SRC/openSUSE:Factory/.redis.new.21961/redis.changes   2024-01-10 
21:51:07.829643722 +0100
@@ -1,0 +2,17 @@
+Tue Jan  9 13:02:41 UTC 2024 - Marcus Rueckert <mrueck...@suse.de>
+
+- redis 7.2.4: (boo#1218646)
+  - Security fixes
+    - (CVE-2023-41056) In some cases, Redis may incorrectly handle
+      resizing of memory buffers which can result in incorrect
+      accounting of buffer sizes and lead to heap overflow and
+      potential remote code execution.
+  - Bug fixes
+    - Fix crashes of cluster commands clusters with mixed versions
+      of 7.0 and 7.2 (#12805, #12832)
+    - Fix slot ownership not being properly handled when deleting a
+      slot from a node (#12564)
+    - Fix atomicity issues with the RedisModuleEvent_Key module API
+      event (#12733)
+
+-------------------------------------------------------------------

Old:
----
  redis-7.2.3.tar.gz

New:
----
  redis-7.2.4.tar.gz

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Other differences:
------------------
++++++ redis.spec ++++++
--- /var/tmp/diff_new_pack.HSSY6Q/_old  2024-01-10 21:51:08.453666383 +0100
+++ /var/tmp/diff_new_pack.HSSY6Q/_new  2024-01-10 21:51:08.453666383 +0100
@@ -1,7 +1,7 @@
 #
 # spec file for package redis
 #
-# Copyright (c) 2023 SUSE LLC
+# Copyright (c) 2024 SUSE LLC
 #
 # All modifications and additions to the file contributed by third parties
 # remain the property of their copyright owners, unless otherwise agreed
@@ -20,7 +20,7 @@
 %define _log_dir        %{_localstatedir}/log/%{name}
 %define _conf_dir       %{_sysconfdir}/%{name}
 Name:           redis
-Version:        7.2.3
+Version:        7.2.4
 Release:        0
 Summary:        Persistent key-value database
 License:        BSD-3-Clause

++++++ redis-7.2.3.tar.gz -> redis-7.2.4.tar.gz ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/redis-7.2.3/00-RELEASENOTES 
new/redis-7.2.4/00-RELEASENOTES
--- old/redis-7.2.3/00-RELEASENOTES     2023-11-01 13:38:13.000000000 +0100
+++ new/redis-7.2.4/00-RELEASENOTES     2024-01-09 12:51:49.000000000 +0100
@@ -13,6 +13,26 @@
 
 
 
================================================================================
+Redis 7.2.4    Released Tue 09 Jan 2024 10:45:52 IST
+================================================================================
+
+Upgrade urgency SECURITY: See security fixes below.
+
+Security fixes
+==============
+* (CVE-2023-41056) In some cases, Redis may incorrectly handle resizing of 
memory
+  buffers which can result in incorrect accounting of buffer sizes and lead to
+  heap overflow and potential remote code execution.
+
+Bug fixes
+=========
+
+* Fix crashes of cluster commands clusters with mixed versions of 7.0 and 7.2 
(#12805, #12832)
+* Fix slot ownership not being properly handled when deleting a slot from a 
node (#12564)
+* Fix atomicity issues with the RedisModuleEvent_Key module API event (#12733)
+
+
+================================================================================
 Redis 7.2.3    Released Wed 01 Nov 2023 12:00:00 IST
 
================================================================================
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/redis-7.2.3/src/cluster.c 
new/redis-7.2.4/src/cluster.c
--- old/redis-7.2.3/src/cluster.c       2023-11-01 13:38:13.000000000 +0100
+++ new/redis-7.2.4/src/cluster.c       2024-01-09 12:51:49.000000000 +0100
@@ -1687,6 +1687,7 @@
     serverAssert(retval == DICT_OK);
     memcpy(node->name, newname, CLUSTER_NAMELEN);
     clusterAddNode(node);
+    clusterAddNodeToShard(node->shard_id, node);
 }
 
 void clusterAddNodeToShard(const char *shard_id, clusterNode *node) {
@@ -2234,6 +2235,7 @@
                 node->tls_port = msg_tls_port;
                 node->cport = ntohs(g->cport);
                 clusterAddNode(node);
+                clusterAddNodeToShard(node->shard_id, node);
             }
         }
 
@@ -2411,7 +2413,6 @@
                 }
                 clusterDelSlot(j);
                 clusterAddSlot(sender,j);
-                bitmapClearBit(server.cluster->owner_not_claiming_slot, j);
                 clusterDoBeforeSleep(CLUSTER_TODO_SAVE_CONFIG|
                                      CLUSTER_TODO_UPDATE_STATE|
                                      CLUSTER_TODO_FSYNC_CONFIG);
@@ -2676,11 +2677,24 @@
         /* We know this will be valid since we validated it ahead of time */
         ext = getNextPingExt(ext);
     }
+
     /* If the node did not send us a hostname extension, assume
      * they don't have an announced hostname. Otherwise, we'll
      * set it now. */
     updateAnnouncedHostname(sender, ext_hostname);
     updateAnnouncedHumanNodename(sender, ext_humannodename);
+
+    /* If the node did not send us a shard-id extension, it means the sender
+     * does not support it (old version), node->shard_id is randomly generated.
+     * A cluster-wide consensus for the node's shard_id is not necessary.
+     * The key is maintaining consistency of the shard_id on each individual 
7.2 node.
+     * As the cluster progressively upgrades to version 7.2, we can expect the 
shard_ids
+     * across all nodes to naturally converge and align.
+     *
+     * If sender is a replica, set the shard_id to the shard_id of its master.
+     * Otherwise, we'll set it now. */
+    if (ext_shardid == NULL) ext_shardid = 
clusterNodeGetMaster(sender)->shard_id;
+
     updateShardId(sender, ext_shardid);
 }
 
@@ -3024,6 +3038,10 @@
                     clusterNodeAddSlave(master,sender);
                     sender->slaveof = master;
 
+                    /* Update the shard_id when a replica is connected to its
+                     * primary in the very first time. */
+                    updateShardId(sender, master->shard_id);
+
                     /* Update config. */
                     clusterDoBeforeSleep(CLUSTER_TODO_SAVE_CONFIG);
                 }
@@ -4942,6 +4960,8 @@
     /* Clear the slot bit. */
     serverAssert(clusterNodeClearSlotBit(n,slot) == 1);
     server.cluster->slots[slot] = NULL;
+    /* Make owner_not_claiming_slot flag consistent with slot ownership 
information. */
+    bitmapClearBit(server.cluster->owner_not_claiming_slot, slot);
     return C_OK;
 }
 
@@ -5709,7 +5729,7 @@
     addReplyBulkCString(c, "slots");
 
     /* Use slot_info_pairs from the primary only */
-    while (n->slaveof != NULL) n = n->slaveof;
+    n = clusterNodeGetMaster(n);
 
     if (n->slot_info_pairs != NULL) {
         serverAssert((n->slot_info_pairs_count % 2) == 0);
@@ -7643,6 +7663,11 @@
     return (*server.db->slots_to_keys).by_slot[hashslot].count;
 }
 
+clusterNode *clusterNodeGetMaster(clusterNode *node) {
+    while (node->slaveof != NULL) node = node->slaveof;
+    return node;
+}
+
 /* 
-----------------------------------------------------------------------------
  * Operation(s) on channel rax tree.
  * -------------------------------------------------------------------------- 
*/
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/redis-7.2.3/src/cluster.h 
new/redis-7.2.4/src/cluster.h
--- old/redis-7.2.3/src/cluster.h       2023-11-01 13:38:13.000000000 +0100
+++ new/redis-7.2.4/src/cluster.h       2024-01-09 12:51:49.000000000 +0100
@@ -413,6 +413,7 @@
 void clusterInitListeners(void);
 void clusterCron(void);
 void clusterBeforeSleep(void);
+clusterNode *clusterNodeGetMaster(clusterNode *node);
 clusterNode *getNodeByQuery(client *c, struct redisCommand *cmd, robj **argv, 
int argc, int *hashslot, int *ask);
 int verifyClusterNodeId(const char *name, int length);
 clusterNode *clusterLookupNode(const char *name, int length);
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/redis-7.2.3/src/dict.c new/redis-7.2.4/src/dict.c
--- old/redis-7.2.3/src/dict.c  2023-11-01 13:38:13.000000000 +0100
+++ new/redis-7.2.4/src/dict.c  2024-01-09 12:51:49.000000000 +0100
@@ -1414,30 +1414,25 @@
      * table (global setting) or we should avoid it but the ratio between
      * elements/buckets is over the "safe" threshold, we resize doubling
      * the number of buckets. */
-    if (!dictTypeExpandAllowed(d))
-        return DICT_OK;
     if ((dict_can_resize == DICT_RESIZE_ENABLE &&
          d->ht_used[0] >= DICTHT_SIZE(d->ht_size_exp[0])) ||
         (dict_can_resize != DICT_RESIZE_FORBID &&
          d->ht_used[0] / DICTHT_SIZE(d->ht_size_exp[0]) > 
dict_force_resize_ratio))
     {
+        if (!dictTypeExpandAllowed(d))
+            return DICT_OK;
         return dictExpand(d, d->ht_used[0] + 1);
     }
     return DICT_OK;
 }
 
-/* TODO: clz optimization */
 /* Our hash table capability is a power of two */
 static signed char _dictNextExp(unsigned long size)
 {
-    unsigned char e = DICT_HT_INITIAL_EXP;
-
+    if (size <= DICT_HT_INITIAL_SIZE) return DICT_HT_INITIAL_EXP;
     if (size >= LONG_MAX) return (8*sizeof(long)-1);
-    while(1) {
-        if (((unsigned long)1<<e) >= size)
-            return e;
-        e++;
-    }
+
+    return 8*sizeof(long) - __builtin_clzl(size-1);
 }
 
 /* Finds and returns the position within the dict where the provided key should
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/redis-7.2.3/src/evict.c new/redis-7.2.4/src/evict.c
--- old/redis-7.2.3/src/evict.c 2023-11-01 13:38:13.000000000 +0100
+++ new/redis-7.2.4/src/evict.c 2024-01-09 12:51:49.000000000 +0100
@@ -667,6 +667,7 @@
              *
              * AOF and Output buffer memory will be freed eventually so
              * we only care about memory used by the key space. */
+            enterExecutionUnit(1, 0);
             delta = (long long) zmalloc_used_memory();
             latencyStartMonitor(eviction_latency);
             
dbGenericDelete(db,keyobj,server.lazyfree_lazy_eviction,DB_FLAG_KEY_EVICTED);
@@ -679,6 +680,7 @@
             notifyKeyspaceEvent(NOTIFY_EVICTED, "evicted",
                 keyobj, db->id);
             propagateDeletion(db,keyobj,server.lazyfree_lazy_eviction);
+            exitExecutionUnit();
             postExecutionUnitOperations();
             decrRefCount(keyobj);
             keys_freed++;
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/redis-7.2.3/src/expire.c new/redis-7.2.4/src/expire.c
--- old/redis-7.2.3/src/expire.c        2023-11-01 13:38:13.000000000 +0100
+++ new/redis-7.2.4/src/expire.c        2024-01-09 12:51:49.000000000 +0100
@@ -54,10 +54,12 @@
 int activeExpireCycleTryExpire(redisDb *db, dictEntry *de, long long now) {
     long long t = dictGetSignedIntegerVal(de);
     if (now > t) {
+        enterExecutionUnit(1, 0);
         sds key = dictGetKey(de);
         robj *keyobj = createStringObject(key,sdslen(key));
         deleteExpiredKeyAndPropagate(db,keyobj);
         decrRefCount(keyobj);
+        exitExecutionUnit();
         return 1;
     } else {
         return 0;
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/redis-7.2.3/src/module.c new/redis-7.2.4/src/module.c
--- old/redis-7.2.3/src/module.c        2023-11-01 13:38:13.000000000 +0100
+++ new/redis-7.2.4/src/module.c        2024-01-09 12:51:49.000000000 +0100
@@ -12115,6 +12115,19 @@
     return REDISMODULE_OK;
 }
 
+/* Unregister module-related things, called when moduleLoad fails or 
moduleUnload. */
+void moduleUnregisterCleanup(RedisModule *module) {
+    moduleFreeAuthenticatedClients(module);
+    moduleUnregisterCommands(module);
+    moduleUnsubscribeNotifications(module);
+    moduleUnregisterSharedAPI(module);
+    moduleUnregisterUsedAPI(module);
+    moduleUnregisterFilters(module);
+    moduleUnsubscribeAllServerEvents(module);
+    moduleRemoveConfigs(module);
+    moduleUnregisterAuthCBs(module);
+}
+
 /* Load a module and initialize it. On success C_OK is returned, otherwise
  * C_ERR is returned. */
 int moduleLoad(const char *path, void **module_argv, int module_argc, int 
is_loadex) {
@@ -12149,11 +12162,7 @@
         serverLog(LL_WARNING,
             "Module %s initialization failed. Module not loaded",path);
         if (ctx.module) {
-            moduleUnregisterCommands(ctx.module);
-            moduleUnregisterSharedAPI(ctx.module);
-            moduleUnregisterUsedAPI(ctx.module);
-            moduleRemoveConfigs(ctx.module);
-            moduleUnregisterAuthCBs(ctx.module);
+            moduleUnregisterCleanup(ctx.module);
             moduleFreeModuleStructure(ctx.module);
         }
         moduleFreeContext(&ctx);
@@ -12194,8 +12203,6 @@
     }
 
     if (post_load_err) {
-        /* Unregister module auth callbacks (if any exist) that this Module 
registered onload. */
-        moduleUnregisterAuthCBs(ctx.module);
         moduleUnload(ctx.module->name, NULL);
         moduleFreeContext(&ctx);
         return C_ERR;
@@ -12253,17 +12260,7 @@
         }
     }
 
-    moduleFreeAuthenticatedClients(module);
-    moduleUnregisterCommands(module);
-    moduleUnregisterSharedAPI(module);
-    moduleUnregisterUsedAPI(module);
-    moduleUnregisterFilters(module);
-    moduleUnregisterAuthCBs(module);
-    moduleRemoveConfigs(module);
-
-    /* Remove any notification subscribers this module might have */
-    moduleUnsubscribeNotifications(module);
-    moduleUnsubscribeAllServerEvents(module);
+    moduleUnregisterCleanup(module);
 
     /* Unload the dynamic library. */
     if (dlclose(module->handle) == -1) {
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/redis-7.2.3/src/sds.c new/redis-7.2.4/src/sds.c
--- old/redis-7.2.3/src/sds.c   2023-11-01 13:38:13.000000000 +0100
+++ new/redis-7.2.4/src/sds.c   2024-01-09 12:51:49.000000000 +0100
@@ -349,20 +349,22 @@
      * type. */
     int use_realloc = (oldtype==type || (type < oldtype && type > SDS_TYPE_8));
     size_t newlen = use_realloc ? oldhdrlen+size+1 : hdrlen+size+1;
-    int alloc_already_optimal = 0;
-    #if defined(USE_JEMALLOC)
-        /* je_nallocx returns the expected allocation size for the newlen.
-         * We aim to avoid calling realloc() when using Jemalloc if there is no
-         * change in the allocation size, as it incurs a cost even if the
-         * allocation size stays the same. */
-        alloc_already_optimal = (je_nallocx(newlen, 0) == zmalloc_size(sh));
-    #endif
 
-    if (use_realloc && !alloc_already_optimal) {
-        newsh = s_realloc(sh, newlen);
-        if (newsh == NULL) return NULL;
-        s = (char*)newsh+oldhdrlen;
-    } else if (!alloc_already_optimal) {
+    if (use_realloc) {
+        int alloc_already_optimal = 0;
+        #if defined(USE_JEMALLOC)
+            /* je_nallocx returns the expected allocation size for the newlen.
+             * We aim to avoid calling realloc() when using Jemalloc if there 
is no
+             * change in the allocation size, as it incurs a cost even if the
+             * allocation size stays the same. */
+            alloc_already_optimal = (je_nallocx(newlen, 0) == 
zmalloc_size(sh));
+        #endif
+        if (!alloc_already_optimal) {
+            newsh = s_realloc(sh, newlen);
+            if (newsh == NULL) return NULL;
+            s = (char*)newsh+oldhdrlen;
+        }
+    } else {
         newsh = s_malloc(newlen);
         if (newsh == NULL) return NULL;
         memcpy((char*)newsh+hdrlen, s, len);
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/redis-7.2.3/src/version.h 
new/redis-7.2.4/src/version.h
--- old/redis-7.2.3/src/version.h       2023-11-01 13:38:13.000000000 +0100
+++ new/redis-7.2.4/src/version.h       2024-01-09 12:51:49.000000000 +0100
@@ -1,2 +1,2 @@
-#define REDIS_VERSION "7.2.3"
-#define REDIS_VERSION_NUM 0x00070203
+#define REDIS_VERSION "7.2.4"
+#define REDIS_VERSION_NUM 0x00070204
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/redis-7.2.3/tests/modules/commandfilter.c 
new/redis-7.2.4/tests/modules/commandfilter.c
--- old/redis-7.2.3/tests/modules/commandfilter.c       2023-11-01 
13:38:13.000000000 +0100
+++ new/redis-7.2.4/tests/modules/commandfilter.c       2024-01-09 
12:51:49.000000000 +0100
@@ -1,6 +1,7 @@
 #include "redismodule.h"
 
 #include <string.h>
+#include <strings.h>
 
 static RedisModuleString *log_key_name;
 
@@ -92,7 +93,7 @@
     return REDISMODULE_OK;
 }
 
-int CommandFilter_UnfilteredClientdId(RedisModuleCtx *ctx, RedisModuleString 
**argv, int argc)
+int CommandFilter_UnfilteredClientId(RedisModuleCtx *ctx, RedisModuleString 
**argv, int argc)
 {
     if (argc < 2)
         return RedisModule_WrongArity(ctx);
@@ -192,7 +193,7 @@
     if (RedisModule_Init(ctx,"commandfilter",1,REDISMODULE_APIVER_1)
             == REDISMODULE_ERR) return REDISMODULE_ERR;
 
-    if (argc != 2) {
+    if (argc != 2 && argc != 3) {
         RedisModule_Log(ctx, "warning", "Log key name not specified");
         return REDISMODULE_ERR;
     }
@@ -219,7 +220,7 @@
             return REDISMODULE_ERR;
 
     if (RedisModule_CreateCommand(ctx, unfiltered_clientid_name,
-                CommandFilter_UnfilteredClientdId, "admin", 1,1,1) == 
REDISMODULE_ERR)
+                CommandFilter_UnfilteredClientId, "admin", 1,1,1) == 
REDISMODULE_ERR)
             return REDISMODULE_ERR;
 
     if ((filter = RedisModule_RegisterCommandFilter(ctx, 
CommandFilter_CommandFilter, 
@@ -229,6 +230,16 @@
     if ((filter1 = RedisModule_RegisterCommandFilter(ctx, 
CommandFilter_BlmoveSwap, 0)) == NULL)
         return REDISMODULE_ERR;
 
+    if (argc == 3) {
+        const char *ptr = RedisModule_StringPtrLen(argv[2], NULL);
+        if (!strcasecmp(ptr, "noload")) {
+            /* This is a hint that we return ERR at the last moment of OnLoad. 
*/
+            RedisModule_FreeString(ctx, log_key_name);
+            if (retained) RedisModule_FreeString(NULL, retained);
+            return REDISMODULE_ERR;
+        }
+    }
+
     return REDISMODULE_OK;
 }
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/redis-7.2.3/tests/modules/hooks.c 
new/redis-7.2.4/tests/modules/hooks.c
--- old/redis-7.2.3/tests/modules/hooks.c       2023-11-01 13:38:13.000000000 
+0100
+++ new/redis-7.2.4/tests/modules/hooks.c       2024-01-09 12:51:49.000000000 
+0100
@@ -33,6 +33,7 @@
 #include "redismodule.h"
 #include <stdio.h>
 #include <string.h>
+#include <strings.h>
 #include <assert.h>
 
 /* We need to store events to be able to test and see what we got, and we can't
@@ -407,9 +408,6 @@
         return REDISMODULE_ERR; \
     }
 
-    REDISMODULE_NOT_USED(argv);
-    REDISMODULE_NOT_USED(argc);
-
     if (RedisModule_Init(ctx,"testhook",1,REDISMODULE_APIVER_1)
         == REDISMODULE_ERR) return REDISMODULE_ERR;
 
@@ -471,6 +469,18 @@
     if (RedisModule_CreateCommand(ctx,"hooks.pexpireat", 
cmdKeyExpiry,"",0,0,0) == REDISMODULE_ERR)
         return REDISMODULE_ERR;
 
+    if (argc == 1) {
+        const char *ptr = RedisModule_StringPtrLen(argv[0], NULL);
+        if (!strcasecmp(ptr, "noload")) {
+            /* This is a hint that we return ERR at the last moment of OnLoad. 
*/
+            RedisModule_FreeDict(ctx, event_log);
+            RedisModule_FreeDict(ctx, removed_event_log);
+            RedisModule_FreeDict(ctx, removed_subevent_type);
+            RedisModule_FreeDict(ctx, removed_expiry_log);
+            return REDISMODULE_ERR;
+        }
+    }
+
     return REDISMODULE_OK;
 }
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/redis-7.2.3/tests/modules/keyspace_events.c 
new/redis-7.2.4/tests/modules/keyspace_events.c
--- old/redis-7.2.3/tests/modules/keyspace_events.c     2023-11-01 
13:38:13.000000000 +0100
+++ new/redis-7.2.4/tests/modules/keyspace_events.c     2024-01-09 
12:51:49.000000000 +0100
@@ -36,6 +36,7 @@
 #include "redismodule.h"
 #include <stdio.h>
 #include <string.h>
+#include <strings.h>
 #include <unistd.h>
 
 ustime_t cached_time = 0;
@@ -318,9 +319,6 @@
 /* This function must be present on each Redis module. It is used in order to
  * register the commands into the Redis server. */
 int RedisModule_OnLoad(RedisModuleCtx *ctx, RedisModuleString **argv, int 
argc) {
-    REDISMODULE_NOT_USED(argv);
-    REDISMODULE_NOT_USED(argc);
-
     if (RedisModule_Init(ctx,"testkeyspace",1,REDISMODULE_APIVER_1) == 
REDISMODULE_ERR){
         return REDISMODULE_ERR;
     }
@@ -405,6 +403,16 @@
         return REDISMODULE_ERR;
     }
 
+    if (argc == 1) {
+        const char *ptr = RedisModule_StringPtrLen(argv[0], NULL);
+        if (!strcasecmp(ptr, "noload")) {
+            /* This is a hint that we return ERR at the last moment of OnLoad. 
*/
+            RedisModule_FreeDict(ctx, loaded_event_log);
+            RedisModule_FreeDict(ctx, module_event_log);
+            return REDISMODULE_ERR;
+        }
+    }
+
     return REDISMODULE_OK;
 }
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/redis-7.2.3/tests/modules/postnotifications.c 
new/redis-7.2.4/tests/modules/postnotifications.c
--- old/redis-7.2.3/tests/modules/postnotifications.c   2023-11-01 
13:38:13.000000000 +0100
+++ new/redis-7.2.4/tests/modules/postnotifications.c   2024-01-09 
12:51:49.000000000 +0100
@@ -90,6 +90,10 @@
         return REDISMODULE_OK; /* do not count the evicted key */
     }
 
+    if (strncmp(key_str, "before_evicted", 14) == 0) {
+        return REDISMODULE_OK; /* do not count the before_evicted key */
+    }
+
     RedisModuleString *new_key = RedisModule_CreateString(NULL, "evicted", 7);
     RedisModule_AddPostNotificationJob(ctx, KeySpace_PostNotificationString, 
new_key, KeySpace_PostNotificationStringFreePD);
     return REDISMODULE_OK;
@@ -186,6 +190,55 @@
     return REDISMODULE_OK;
 }
 
+typedef struct KeySpace_EventPostNotificationCtx {
+    RedisModuleString *triggered_on;
+    RedisModuleString *new_key;
+} KeySpace_EventPostNotificationCtx;
+
+static void KeySpace_ServerEventPostNotificationFree(void *pd) {
+    KeySpace_EventPostNotificationCtx *pn_ctx = pd;
+    RedisModule_FreeString(NULL, pn_ctx->new_key);
+    RedisModule_FreeString(NULL, pn_ctx->triggered_on);
+    RedisModule_Free(pn_ctx);
+}
+
+static void KeySpace_ServerEventPostNotification(RedisModuleCtx *ctx, void 
*pd) {
+    REDISMODULE_NOT_USED(ctx);
+    KeySpace_EventPostNotificationCtx *pn_ctx = pd;
+    RedisModuleCallReply* rep = RedisModule_Call(ctx, "lpush", "!ss", 
pn_ctx->new_key, pn_ctx->triggered_on);
+    RedisModule_FreeCallReply(rep);
+}
+
+static void KeySpace_ServerEventCallback(RedisModuleCtx *ctx, RedisModuleEvent 
eid, uint64_t subevent, void *data) {
+    REDISMODULE_NOT_USED(eid);
+    REDISMODULE_NOT_USED(data);
+    if (subevent > 3) {
+        RedisModule_Log(ctx, "warning", "Got an unexpected subevent '%ld'", 
subevent);
+        return;
+    }
+    static const char* events[] = {
+            "before_deleted",
+            "before_expired",
+            "before_evicted",
+            "before_overwritten",
+    };
+
+    const RedisModuleString *key_name = 
RedisModule_GetKeyNameFromModuleKey(((RedisModuleKeyInfo*)data)->key);
+    const char *key_str = RedisModule_StringPtrLen(key_name, NULL);
+
+    for (int i = 0 ; i < 4 ; ++i) {
+        const char *event = events[i];
+        if (strncmp(key_str, event , strlen(event)) == 0) {
+            return; /* don't log any event on our tracking keys */
+        }
+    }
+
+    KeySpace_EventPostNotificationCtx *pn_ctx = 
RedisModule_Alloc(sizeof(*pn_ctx));
+    pn_ctx->triggered_on = RedisModule_HoldString(NULL, 
(RedisModuleString*)key_name);
+    pn_ctx->new_key = RedisModule_CreateString(NULL, events[subevent], 
strlen(events[subevent]));
+    RedisModule_AddPostNotificationJob(ctx, 
KeySpace_ServerEventPostNotification, pn_ctx, 
KeySpace_ServerEventPostNotificationFree);
+}
+
 /* This function must be present on each Redis module. It is used in order to
  * register the commands into the Redis server. */
 int RedisModule_OnLoad(RedisModuleCtx *ctx, RedisModuleString **argv, int 
argc) {
@@ -200,6 +253,14 @@
         return REDISMODULE_ERR;
     }
 
+    int with_key_events = 0;
+    if (argc >= 1) {
+        const char *arg = RedisModule_StringPtrLen(argv[0], 0);
+        if (strcmp(arg, "with_key_events") == 0) {
+            with_key_events = 1;
+        }
+    }
+
     RedisModule_SetModuleOptions(ctx, 
REDISMODULE_OPTIONS_ALLOW_NESTED_KEYSPACE_NOTIFICATIONS);
 
     if(RedisModule_SubscribeToKeyspaceEvents(ctx, REDISMODULE_NOTIFY_STRING, 
KeySpace_NotificationString) != REDISMODULE_OK){
@@ -222,6 +283,12 @@
         return REDISMODULE_ERR;
     }
 
+    if (with_key_events) {
+        if(RedisModule_SubscribeToServerEvent(ctx, RedisModuleEvent_Key, 
KeySpace_ServerEventCallback) != REDISMODULE_OK){
+            return REDISMODULE_ERR;
+        }
+    }
+
     if (RedisModule_CreateCommand(ctx, "postnotification.async_set", 
KeySpace_PostNotificationsAsyncSet,
                                       "write", 0, 0, 0) == REDISMODULE_ERR){
         return REDISMODULE_ERR;
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/redis-7.2.3/tests/unit/moduleapi/async_rm_call.tcl 
new/redis-7.2.4/tests/unit/moduleapi/async_rm_call.tcl
--- old/redis-7.2.3/tests/unit/moduleapi/async_rm_call.tcl      2023-11-01 
13:38:13.000000000 +0100
+++ new/redis-7.2.4/tests/unit/moduleapi/async_rm_call.tcl      2024-01-09 
12:51:49.000000000 +0100
@@ -314,6 +314,14 @@
         r lpush l a
         assert_equal [$rd read] {OK}
 
+        # Explanation of the first multi exec block:
+        # {lpop l} - pop the value by our blocking command 
'blpop_and_set_multiple_keys'
+        # {set string_foo 1} - the action of our blocking command 
'blpop_and_set_multiple_keys'
+        # {set string_bar 2} - the action of our blocking command 
'blpop_and_set_multiple_keys'
+        # {incr string_changed{string_foo}} - post notification job that was 
registered when 'string_foo' changed
+        # {incr string_changed{string_bar}} - post notification job that was 
registered when 'string_bar' changed
+        # {incr string_total} - post notification job that was registered when 
string_changed{string_foo} changed
+        # {incr string_total} - post notification job that was registered when 
string_changed{string_bar} changed
         assert_replication_stream $repl {
             {select *}
             {lpush l a}
@@ -355,6 +363,25 @@
         r lpush l a
         assert_equal [$rd read] {OK}
 
+        # Explanation of the first multi exec block:
+        # {lpop l} - pop the value by our blocking command 
'blpop_and_set_multiple_keys'
+        # {set string_foo 1} - the action of our blocking command 
'blpop_and_set_multiple_keys'
+        # {set string_bar 2} - the action of our blocking command 
'blpop_and_set_multiple_keys'
+        # {incr string_changed{string_foo}} - post notification job that was 
registered when 'string_foo' changed
+        # {incr string_changed{string_bar}} - post notification job that was 
registered when 'string_bar' changed
+        # {incr string_total} - post notification job that was registered when 
string_changed{string_foo} changed
+        # {incr string_total} - post notification job that was registered when 
string_changed{string_bar} changed
+        #
+        # Explanation of the second multi exec block:
+        # {lpop l} - pop the value by our blocking command 
'blpop_and_set_multiple_keys'
+        # {del string_foo} - lazy expiration of string_foo when 
'blpop_and_set_multiple_keys' tries to write to it. 
+        # {set string_foo 1} - the action of our blocking command 
'blpop_and_set_multiple_keys'
+        # {set string_bar 2} - the action of our blocking command 
'blpop_and_set_multiple_keys'
+        # {incr expired} - the post notification job, registered after 
string_foo got expired
+        # {incr string_changed{string_foo}} - post notification job triggered 
when we set string_foo
+        # {incr string_changed{string_bar}} - post notification job triggered 
when we set string_bar
+        # {incr string_total} - post notification job triggered when we incr 
'string_changed{string_foo}'
+        # {incr string_total} - post notification job triggered when we incr 
'string_changed{string_bar}'
         assert_replication_stream $repl {
             {select *}
             {lpush l a}
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/redis-7.2.3/tests/unit/moduleapi/commandfilter.tcl 
new/redis-7.2.4/tests/unit/moduleapi/commandfilter.tcl
--- old/redis-7.2.3/tests/unit/moduleapi/commandfilter.tcl      2023-11-01 
13:38:13.000000000 +0100
+++ new/redis-7.2.4/tests/unit/moduleapi/commandfilter.tcl      2024-01-09 
12:51:49.000000000 +0100
@@ -95,7 +95,7 @@
     test "Unload the module - commandfilter" {
         assert_equal {OK} [r module unload commandfilter]
     }
-} 
+}
 
 test {RM_CommandFilterArgInsert and script argv caching} {
     # coverage for scripts calling commands that expand the argv array
@@ -162,4 +162,14 @@
 
         $rr close
     }
-}
\ No newline at end of file
+}
+
+start_server {} {
+    test {OnLoad failure will handle un-registration} {
+        catch {r module load $testmodule log-key 0 noload}
+        r set mykey @log
+        assert_equal [r lrange log-key 0 -1] {}
+        r rpush mylist elem1 @delme elem2
+        assert_equal [r lrange mylist 0 -1] {elem1 @delme elem2}
+    }
+}
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/redis-7.2.3/tests/unit/moduleapi/hooks.tcl 
new/redis-7.2.4/tests/unit/moduleapi/hooks.tcl
--- old/redis-7.2.3/tests/unit/moduleapi/hooks.tcl      2023-11-01 
13:38:13.000000000 +0100
+++ new/redis-7.2.4/tests/unit/moduleapi/hooks.tcl      2024-01-09 
12:51:49.000000000 +0100
@@ -310,4 +310,12 @@
             assert_equal [string match {*module-event-shutdown*} [exec tail -5 
< $replica_stdout]] 1
         }
     }
+
+    start_server {} {
+        test {OnLoad failure will handle un-registration} {
+            catch {r module load $testmodule noload}
+            r flushall
+            r ping
+        }
+    }
 }
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/redis-7.2.3/tests/unit/moduleapi/keyspace_events.tcl 
new/redis-7.2.4/tests/unit/moduleapi/keyspace_events.tcl
--- old/redis-7.2.3/tests/unit/moduleapi/keyspace_events.tcl    2023-11-01 
13:38:13.000000000 +0100
+++ new/redis-7.2.4/tests/unit/moduleapi/keyspace_events.tcl    2024-01-09 
12:51:49.000000000 +0100
@@ -102,4 +102,17 @@
             assert_equal {OK} [r set x 1 EX 1]
         }
     }
+
+    start_server {} {
+        test {OnLoad failure will handle un-registration} {
+            catch {r module load $testmodule noload}
+            r set x 1
+            r hset y f v
+            r lpush z 1 2 3
+            r sadd p 1 2 3
+            r zadd t 1 f1 2 f2
+            r xadd s * f v
+            r ping
+        }
+    }
 }
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/redis-7.2.3/tests/unit/moduleapi/postnotifications.tcl 
new/redis-7.2.4/tests/unit/moduleapi/postnotifications.tcl
--- old/redis-7.2.3/tests/unit/moduleapi/postnotifications.tcl  2023-11-01 
13:38:13.000000000 +0100
+++ new/redis-7.2.4/tests/unit/moduleapi/postnotifications.tcl  2024-01-09 
12:51:49.000000000 +0100
@@ -1,7 +1,8 @@
 set testmodule [file normalize tests/modules/postnotifications.so]
 
 tags "modules" {
-    start_server [list overrides [list loadmodule "$testmodule"]] {
+    start_server {} {
+        r module load $testmodule with_key_events
 
         test {Test write on post notification callback} {
             set repl [attach_to_replication_stream]
@@ -9,11 +10,12 @@
             r set string_x 1
             assert_equal {1} [r get string_changed{string_x}]
             assert_equal {1} [r get string_total]
-            
+
             r set string_x 2
             assert_equal {2} [r get string_changed{string_x}]
             assert_equal {2} [r get string_total]
 
+            # the {lpush before_overwritten string_x} is a post notification 
job registered when 'string_x' was overwritten
             assert_replication_stream $repl {
                 {multi}
                 {select *}
@@ -23,6 +25,7 @@
                 {exec}
                 {multi}
                 {set string_x 2}
+                {lpush before_overwritten string_x}
                 {incr string_changed{string_x}}
                 {incr string_total}
                 {exec}
@@ -37,7 +40,7 @@
             assert_equal {OK} [r postnotification.async_set]
             assert_equal {1} [r get string_changed{string_x}]
             assert_equal {1} [r get string_total]
-            
+
             assert_replication_stream $repl {
                 {multi}
                 {select *}
@@ -63,12 +66,14 @@
                 fail "Failed waiting for x to expired"
             }
 
+            # the {lpush before_expired x} is a post notification job 
registered before 'x' got expired
             assert_replication_stream $repl {
                 {select *}
                 {set x 1}
                 {pexpireat x *}
                 {multi}
                 {del x}
+                {lpush before_expired x}
                 {incr expired}
                 {exec}
             }
@@ -85,12 +90,14 @@
             after 10
             assert_equal {} [r get x]
 
+            # the {lpush before_expired x} is a post notification job 
registered before 'x' got expired
             assert_replication_stream $repl {
                 {select *}
                 {set x 1}
                 {pexpireat x *}
                 {multi}
                 {del x}
+                {lpush before_expired x}
                 {incr expired}
                 {exec}
             }
@@ -108,6 +115,7 @@
             after 10
             assert_equal {OK} [r set read_x 1]
 
+            # the {lpush before_expired x} is a post notification job 
registered before 'x' got expired
             assert_replication_stream $repl {
                 {select *}
                 {set x 1}
@@ -115,6 +123,7 @@
                 {multi}
                 {set read_x 1}
                 {del x}
+                {lpush before_expired x}
                 {incr expired}
                 {exec}
             }
@@ -143,16 +152,18 @@
             r flushall
             set repl [attach_to_replication_stream]
             r set x 1
-            r config set maxmemory-policy allkeys-random 
+            r config set maxmemory-policy allkeys-random
             r config set maxmemory 1
 
             assert_error {OOM *} {r set y 1}
 
+            # the {lpush before_evicted x} is a post notification job 
registered before 'x' got evicted
             assert_replication_stream $repl {
                 {select *}
                 {set x 1}
                 {multi}
                 {del x}
+                {lpush before_evicted x}
                 {incr evicted}
                 {exec}
             }
@@ -164,7 +175,8 @@
 set testmodule2 [file normalize tests/modules/keyspace_events.so]
 
 tags "modules" {
-    start_server [list overrides [list loadmodule "$testmodule"]] {
+    start_server {} {
+        r module load $testmodule with_key_events
         r module load $testmodule2
         test {Test write on post notification callback} {
             set repl [attach_to_replication_stream]
@@ -172,7 +184,7 @@
             r set string_x 1
             assert_equal {1} [r get string_changed{string_x}]
             assert_equal {1} [r get string_total]
-            
+
             r set string_x 2
             assert_equal {2} [r get string_changed{string_x}]
             assert_equal {2} [r get string_total]
@@ -181,6 +193,7 @@
             assert_equal {1} [r get string_changed{string1_x}]
             assert_equal {3} [r get string_total]
 
+            # the {lpush before_overwritten string_x} is a post notification 
job registered before 'string_x' got overwritten
             assert_replication_stream $repl {
                 {multi}
                 {select *}
@@ -190,6 +203,7 @@
                 {exec}
                 {multi}
                 {set string_x 2}
+                {lpush before_overwritten string_x}
                 {incr string_changed{string_x}}
                 {incr string_total}
                 {exec}
@@ -202,4 +216,4 @@
             close_replication_stream $repl
         }
     }
-}
\ No newline at end of file
+}

++++++ redis.hashes ++++++
--- /var/tmp/diff_new_pack.HSSY6Q/_old  2024-01-10 21:51:09.037687591 +0100
+++ /var/tmp/diff_new_pack.HSSY6Q/_new  2024-01-10 21:51:09.041687737 +0100
@@ -170,4 +170,6 @@
 hash redis-7.0.14.tar.gz sha256 
7e1cdf347f4970ea39d5b7fdb19aedec4c21942e202de65bdeb782d38d2f299f 
http://download.redis.io/releases/redis-7.0.14.tar.gz
 hash redis-7.2.2.tar.gz sha256 
ca999be08800edc6d265379c4c7aafad92f0ee400692e4e2d69829ab4b4c3d08 
http://download.redis.io/releases/redis-7.2.2.tar.gz
 hash redis-7.2.3.tar.gz sha256 
3e2b196d6eb4ddb9e743088bfc2915ccbb42d40f5a8a3edd8cb69c716ec34be7 
http://download.redis.io/releases/redis-7.2.3.tar.gz
+hash redis-7.0.15.tar.gz sha256 
98066f5363504b26c34dd20fbcc3c957990d764cdf42576c836fc021073f4341 
http://download.redis.io/releases/redis-7.0.15.tar.gz
+hash redis-7.2.4.tar.gz sha256 
8d104c26a154b29fd67d6568b4f375212212ad41e0c2caa3d66480e78dbd3b59 
http://download.redis.io/releases/redis-7.2.4.tar.gz
 

Reply via email to