Hello community,

here is the log from the commit of package redis for openSUSE:Leap:15.2 checked 
in at 2020-03-26 05:42:01
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Leap:15.2/redis (Old)
 and      /work/SRC/openSUSE:Leap:15.2/.redis.new.3160 (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Package is "redis"

Thu Mar 26 05:42:01 2020 rev:42 rq:788371 version:5.0.8

Changes:
--------
--- /work/SRC/openSUSE:Leap:15.2/redis/redis.changes    2020-02-29 
17:16:30.589050595 +0100
+++ /work/SRC/openSUSE:Leap:15.2/.redis.new.3160/redis.changes  2020-03-26 
05:42:17.935307401 +0100
@@ -1,0 +2,36 @@
+Tue Mar 24 19:04:42 UTC 2020 - Thorsten Kukuk <ku...@suse.com>
+
+- Use the tmpfiles macros instead of calling systemd-tempfiles
+  direct and build wrong macro paths.
+
+-------------------------------------------------------------------
+Wed Mar 18 02:18:24 UTC 2020 - Илья Индиго <i...@ilya.pp.ua>
+- Refresh spec-file with spec-cleaner and manual optimizations
+  * Remove Group tag.
+  * Replace make by %make_build macros.
+- Update to 5.0.8
+  * https://raw.githubusercontent.com/antirez/redis/5.0.8/00-RELEASENOTES
+  * Fix Pi building needing -latomic, backport.
+  * Fix impl of aof-child whitelist SIGUSR1 feature.
+  * Fix ThreadSafeContext lock/unlock function names.
+  * XREADGROUP should propagate XCALIM/SETID in MULTI/EXEC.
+  * Fix client flags to be int64 in module.c.
+  * Fix small bugs related to replica and monitor ambiguity.
+  * Fix lua related memory leak.
+  * Simplify #6379 changes.
+  * Free allocated sds in pfdebugCommand() to avoid memory leak.
+  * Jump to right label on AOF parsing error.
+  * Free fakeclient argv on AOF error.
+  * Fix potential memory leak of rioWriteBulkStreamID().
+  * Fix potential memory leak of clusterLoadConfig().
+  * Fix bug on KEYS command where pattern starts with * followed by \x00.
+  * Blocking XREAD[GROUP] should always reply with valid data.
+  * XCLAIM: Create the consumer only on successful claims.
+  * Stream: Handle streamID-related edge cases.
+  * Fix ip and missing mode in RM_GetClusterNodeInfo().
+  * Inline protocol: handle empty strings well.
+  * Mark extern definition of SDS_NOINIT in sds.h.
+  * Fix revisit CVE-2015-8080 vulnerability.
+  * Avoid sentinel changes promoted_slave to be its own replica.
+
+-------------------------------------------------------------------
@@ -1252 +1287,0 @@
-

Old:
----
  redis-5.0.7.tar.gz

New:
----
  redis-5.0.8.tar.gz

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

Other differences:
------------------
++++++ redis.spec ++++++
--- /var/tmp/diff_new_pack.zWja6L/_old  2020-03-26 05:42:18.999307953 +0100
+++ /var/tmp/diff_new_pack.zWja6L/_new  2020-03-26 05:42:19.007307957 +0100
@@ -20,11 +20,10 @@
 %define _log_dir        %{_localstatedir}/log/%{name}
 %define _conf_dir       %{_sysconfdir}/%{name}
 Name:           redis
-Version:        5.0.7
+Version:        5.0.8
 Release:        0
 Summary:        Persistent key-value database
 License:        BSD-3-Clause
-Group:          Productivity/Databases/Servers
 URL:            https://redis.io
 Source0:        http://download.redis.io/releases/redis-%{version}.tar.gz
 Source1:        %{name}.logrotate
@@ -68,7 +67,7 @@
 
 %build
 export HOST=OBS # for reproducible builds
-make %{?_smp_mflags} CFLAGS="%{optflags}" V=1
+%make_build CFLAGS="%{optflags}"
 %sysusers_generate_pre %{SOURCE9} redis
 
 %install
@@ -100,7 +99,7 @@
 install -Dm 0644 %{SOURCE1} %{buildroot}%{_sysconfdir}/logrotate.d/%{name}
 install -Dm 0644 %{SOURCE2} %{buildroot}%{_unitdir}/%{name}.target
 install -Dm 0644 %{SOURCE3} %{buildroot}%{_unitdir}/%{name}@.service
-install -Dm 0644 %{SOURCE4} %{buildroot}%{_libexecdir}/tmpfiles.d/%{name}.conf
+install -Dm 0644 %{SOURCE4} %{buildroot}%{_tmpfilesdir}/%{name}.conf
 install -Dm 0644 %{SOURCE7} %{buildroot}%{_unitdir}/%{name}-sentinel@.service
 install -Dm 0644 %{SOURCE8} %{buildroot}%{_unitdir}/%{name}-sentinel.target
 
@@ -118,14 +117,14 @@
 'child process exited abnormally' -- sometimes it works.
 ---------------------------------------------------
 EOF
-make %{?_smp_mflags} test || true
+%make_build test || true
 %endif
 
 %pre -f redis.pre
 %service_add_pre redis.target redis@.service redis-sentinel.target 
redis-sentinel@.service
 
 %post
-systemd-tmpfiles --create %{_libexecdir}/tmpfiles.d/%{name}.conf || true
+%tmpfiles_create %{_tmpfilesdir}/%{name}.conf
 %service_add_post redis.target redis@.service redis-sentinel.target 
redis-sentinel@.service
 echo "See %{_docdir}/%{name}/README.SUSE to continue"
 
@@ -143,7 +142,7 @@
 %{_bindir}/%{name}-*
 %{_sbindir}/%{name}-*
 %{_sbindir}/rc%{name}
-%{_libexecdir}/tmpfiles.d/%{name}.conf
+%{_tmpfilesdir}/%{name}.conf
 %{_sysusersdir}/redis-user.conf
 %{_unitdir}/%{name}@.service
 %{_unitdir}/%{name}.target

++++++ redis-5.0.7.tar.gz -> redis-5.0.8.tar.gz ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/redis-5.0.7/00-RELEASENOTES 
new/redis-5.0.8/00-RELEASENOTES
--- old/redis-5.0.7/00-RELEASENOTES     2019-11-19 18:05:52.000000000 +0100
+++ new/redis-5.0.8/00-RELEASENOTES     2020-03-12 16:07:44.000000000 +0100
@@ -12,6 +12,104 @@
 
--------------------------------------------------------------------------------
 
 
================================================================================
+Redis 5.0.8     Released Thu Mar 12 16:05:41 CET 2020
+================================================================================
+
+Upgrade urgency HIGH: This release fixes security issues.
+
+This is a list of fixes in this release:
+
+Salvatore Sanfilippo in commit 2bea502d:
+ Merge pull request #6975 from dustinmm80/add-arm-latomic-linking
+Dustin Collins in commit b5931405:
+ Fix Pi building needing -latomic, backport
+ 1 file changed, 9 insertions(+)
+
+srzhao in commit fd441300:
+ fix impl of aof-child whitelist SIGUSR1 feature.
+ 1 file changed, 5 insertions(+), 4 deletions(-)
+
+Ariel in commit 77ff332b:
+ fix ThreadSafeContext lock/unlock function names
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+Guy Benoish in commit 4f0f799c:
+ XREADGROUP should propagate XCALIM/SETID in MULTI/EXEC
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+Oran Agra in commit 0c1273c3:
+ Fix client flags to be int64 in module.c
+ 1 file changed, 3 insertions(+), 3 deletions(-)
+
+Guy Benoish in commit 708a4e8a:
+ Fix small bugs related to replica and monitor ambiguity
+ 2 files changed, 8 insertions(+), 6 deletions(-)
+
+WuYunlong in commit eac4115d:
+ Fix lua related memory leak.
+ 1 file changed, 1 insertion(+)
+
+antirez in commit d075df17:
+ Simplify #6379 changes.
+ 2 files changed, 4 insertions(+), 9 deletions(-)
+
+WuYunlong in commit 80a49c37:
+ Free allocated sds in pfdebugCommand() to avoid memory leak.
+ 1 file changed, 1 insertion(+)
+
+antirez in commit 60870d3a:
+ Jump to right label on AOF parsing error.
+ 1 file changed, 6 insertions(+), 4 deletions(-)
+
+antirez in commit d90f599b:
+ Free fakeclient argv on AOF error.
+ 1 file changed, 11 insertions(+), 3 deletions(-)
+
+WuYunlong in commit 8ee3bddf:
+ Fix potential memory leak of rioWriteBulkStreamID().
+ 1 file changed, 4 insertions(+), 1 deletion(-)
+
+WuYunlong in commit 4780fe78:
+ Fix potential memory leak of clusterLoadConfig().
+ 1 file changed, 20 insertions(+), 5 deletions(-)
+
+Leo Murillo in commit f3b77510:
+ Fix bug on KEYS command where pattern starts with * followed by \x00 (null 
char).
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+Guy Benoish in commit 7f3fcedb:
+ Blocking XREAD[GROUP] should always reply with valid data (or timeout)
+ 3 files changed, 44 insertions(+), 10 deletions(-)
+
+antirez in commit f93b2fa5:
+ XCLAIM: Create the consumer only on successful claims.
+ 1 file changed, 4 insertions(+), 2 deletions(-)
+
+Guy Benoish in commit 89682d96:
+ Stream: Handle streamID-related edge cases
+ 4 files changed, 54 insertions(+), 4 deletions(-)
+
+antirez in commit 920e108f:
+ Fix ip and missing mode in RM_GetClusterNodeInfo().
+ 1 file changed, 5 insertions(+), 2 deletions(-)
+
+antirez in commit 7569b210:
+ Inline protocol: handle empty strings well.
+ 1 file changed, 2 insertions(+), 6 deletions(-)
+
+Khem Raj in commit 3c610b4e:
+ Mark extern definition of SDS_NOINIT in sds.h
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+Seunghoon Woo in commit 16b2d07f:
+ [FIX] revisit CVE-2015-8080 vulnerability
+ 1 file changed, 6 insertions(+), 4 deletions(-)
+
+yz1509 in commit 19f33585:
+ avoid sentinel changes promoted_slave to be its own replica.
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+================================================================================
 Redis 5.0.7     Released Tue Nov 19 17:52:44 CET 2019
 
================================================================================
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/redis-5.0.7/deps/lua/src/lua_struct.c 
new/redis-5.0.8/deps/lua/src/lua_struct.c
--- old/redis-5.0.7/deps/lua/src/lua_struct.c   2019-11-19 18:05:52.000000000 
+0100
+++ new/redis-5.0.8/deps/lua/src/lua_struct.c   2020-03-12 16:07:44.000000000 
+0100
@@ -89,12 +89,14 @@
 } Header;
 
 
-static int getnum (const char **fmt, int df) {
+static int getnum (lua_State *L, const char **fmt, int df) {
   if (!isdigit(**fmt))  /* no number? */
     return df;  /* return default value */
   else {
     int a = 0;
     do {
+      if (a > (INT_MAX / 10) || a * 10 > (INT_MAX - (**fmt - '0')))
+        luaL_error(L, "integral size overflow");
       a = a*10 + *((*fmt)++) - '0';
     } while (isdigit(**fmt));
     return a;
@@ -115,9 +117,9 @@
     case 'f':  return sizeof(float);
     case 'd':  return sizeof(double);
     case 'x': return 1;
-    case 'c': return getnum(fmt, 1);
+    case 'c': return getnum(L, fmt, 1);
     case 'i': case 'I': {
-      int sz = getnum(fmt, sizeof(int));
+      int sz = getnum(L, fmt, sizeof(int));
       if (sz > MAXINTSIZE)
         luaL_error(L, "integral size %d is larger than limit of %d",
                        sz, MAXINTSIZE);
@@ -150,7 +152,7 @@
     case '>': h->endian = BIG; return;
     case '<': h->endian = LITTLE; return;
     case '!': {
-      int a = getnum(fmt, MAXALIGN);
+      int a = getnum(L, fmt, MAXALIGN);
       if (!isp2(a))
         luaL_error(L, "alignment %d is not a power of 2", a);
       h->align = a;
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/redis-5.0.7/src/Makefile new/redis-5.0.8/src/Makefile
--- old/redis-5.0.7/src/Makefile        2019-11-19 18:05:52.000000000 +0100
+++ new/redis-5.0.8/src/Makefile        2020-03-12 16:07:44.000000000 +0100
@@ -77,6 +77,15 @@
 FINAL_LIBS=-lm
 DEBUG=-g -ggdb
 
+# Linux ARM needs -latomic at linking time
+ifneq (,$(filter aarch64 armv,$(uname_M)))
+        FINAL_LIBS+=-latomic
+else
+ifneq (,$(findstring armv,$(uname_M)))
+        FINAL_LIBS+=-latomic
+endif
+endif
+
 ifeq ($(uname_S),SunOS)
        # SunOS
         ifneq ($(@@),32bit)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/redis-5.0.7/src/aof.c new/redis-5.0.8/src/aof.c
--- old/redis-5.0.7/src/aof.c   2019-11-19 18:05:52.000000000 +0100
+++ new/redis-5.0.8/src/aof.c   2020-03-12 16:07:44.000000000 +0100
@@ -774,18 +774,26 @@
         argc = atoi(buf+1);
         if (argc < 1) goto fmterr;
 
+        /* Load the next command in the AOF as our fake client
+         * argv. */
         argv = zmalloc(sizeof(robj*)*argc);
         fakeClient->argc = argc;
         fakeClient->argv = argv;
 
         for (j = 0; j < argc; j++) {
-            if (fgets(buf,sizeof(buf),fp) == NULL) {
+            /* Parse the argument len. */
+            char *readres = fgets(buf,sizeof(buf),fp);
+            if (readres == NULL || buf[0] != '$') {
                 fakeClient->argc = j; /* Free up to j-1. */
                 freeFakeClientArgv(fakeClient);
-                goto readerr;
+                if (readres == NULL)
+                    goto readerr;
+                else
+                    goto fmterr;
             }
-            if (buf[0] != '$') goto fmterr;
             len = strtol(buf+1,NULL,10);
+
+            /* Read it into a string object. */
             argsds = sdsnewlen(SDS_NOINIT,len);
             if (len && fread(argsds,len,1,fp) == 0) {
                 sdsfree(argsds);
@@ -794,10 +802,12 @@
                 goto readerr;
             }
             argv[j] = createObject(OBJ_STRING,argsds);
+
+            /* Discard CRLF. */
             if (fread(buf,2,1,fp) == 0) {
                 fakeClient->argc = j+1; /* Free up to j. */
                 freeFakeClientArgv(fakeClient);
-                goto readerr; /* discard CRLF */
+                goto readerr;
             }
         }
 
@@ -1127,7 +1137,7 @@
     int retval;
 
     sds replyid = sdscatfmt(sdsempty(),"%U-%U",id->ms,id->seq);
-    if ((retval = rioWriteBulkString(r,replyid,sdslen(replyid))) == 0) return 
0;
+    retval = rioWriteBulkString(r,replyid,sdslen(replyid));
     sdsfree(replyid);
     return retval;
 }
@@ -1782,14 +1792,15 @@
         serverLog(LL_VERBOSE,
             "Background AOF rewrite signal handler took %lldus", ustime()-now);
     } else if (!bysignal && exitcode != 0) {
+        server.aof_lastbgrewrite_status = C_ERR;
+
+        serverLog(LL_WARNING,
+            "Background AOF rewrite terminated with error");
+    } else {
         /* SIGUSR1 is whitelisted, so we have a way to kill a child without
          * tirggering an error condition. */
         if (bysignal != SIGUSR1)
             server.aof_lastbgrewrite_status = C_ERR;
-        serverLog(LL_WARNING,
-            "Background AOF rewrite terminated with error");
-    } else {
-        server.aof_lastbgrewrite_status = C_ERR;
 
         serverLog(LL_WARNING,
             "Background AOF rewrite terminated by signal %d", bysignal);
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/redis-5.0.7/src/blocked.c 
new/redis-5.0.8/src/blocked.c
--- old/redis-5.0.7/src/blocked.c       2019-11-19 18:05:52.000000000 +0100
+++ new/redis-5.0.8/src/blocked.c       2020-03-12 16:07:44.000000000 +0100
@@ -429,7 +429,7 @@
 
                         if (streamCompareID(&s->last_id, gt) > 0) {
                             streamID start = *gt;
-                            start.seq++; /* Can't overflow, it's an uint64_t */
+                            streamIncrID(&start);
 
                             /* Lookup the consumer for the group, if any. */
                             streamConsumer *consumer = NULL;
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/redis-5.0.7/src/cluster.c 
new/redis-5.0.8/src/cluster.c
--- old/redis-5.0.7/src/cluster.c       2019-11-19 18:05:52.000000000 +0100
+++ new/redis-5.0.8/src/cluster.c       2020-03-12 16:07:44.000000000 +0100
@@ -157,7 +157,10 @@
         }
 
         /* Regular config lines have at least eight fields */
-        if (argc < 8) goto fmterr;
+        if (argc < 8) {
+            sdsfreesplitres(argv,argc);
+            goto fmterr;
+        }
 
         /* Create this node if it does not exist */
         n = clusterLookupNode(argv[0]);
@@ -166,7 +169,10 @@
             clusterAddNode(n);
         }
         /* Address and port */
-        if ((p = strrchr(argv[1],':')) == NULL) goto fmterr;
+        if ((p = strrchr(argv[1],':')) == NULL) {
+            sdsfreesplitres(argv,argc);
+            goto fmterr;
+        }
         *p = '\0';
         memcpy(n->ip,argv[1],strlen(argv[1])+1);
         char *port = p+1;
@@ -247,7 +253,10 @@
                 *p = '\0';
                 direction = p[1]; /* Either '>' or '<' */
                 slot = atoi(argv[j]+1);
-                if (slot < 0 || slot >= CLUSTER_SLOTS) goto fmterr;
+                if (slot < 0 || slot >= CLUSTER_SLOTS) {
+                    sdsfreesplitres(argv,argc);
+                    goto fmterr;
+                }
                 p += 3;
                 cn = clusterLookupNode(p);
                 if (!cn) {
@@ -267,8 +276,12 @@
             } else {
                 start = stop = atoi(argv[j]);
             }
-            if (start < 0 || start >= CLUSTER_SLOTS) goto fmterr;
-            if (stop < 0 || stop >= CLUSTER_SLOTS) goto fmterr;
+            if (start < 0 || start >= CLUSTER_SLOTS ||
+                stop < 0 || stop >= CLUSTER_SLOTS)
+            {
+                sdsfreesplitres(argv,argc);
+                goto fmterr;
+            }
             while(start <= stop) clusterAddSlot(n, start++);
         }
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/redis-5.0.7/src/db.c new/redis-5.0.8/src/db.c
--- old/redis-5.0.7/src/db.c    2019-11-19 18:05:52.000000000 +0100
+++ new/redis-5.0.8/src/db.c    2020-03-12 16:07:44.000000000 +0100
@@ -542,7 +542,7 @@
     void *replylen = addDeferredMultiBulkLength(c);
 
     di = dictGetSafeIterator(c->db->dict);
-    allkeys = (pattern[0] == '*' && pattern[1] == '\0');
+    allkeys = (pattern[0] == '*' && plen == 1);
     while((de = dictNext(di)) != NULL) {
         sds key = dictGetKey(de);
         robj *keyobj;
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/redis-5.0.7/src/hyperloglog.c 
new/redis-5.0.8/src/hyperloglog.c
--- old/redis-5.0.7/src/hyperloglog.c   2019-11-19 18:05:52.000000000 +0100
+++ new/redis-5.0.8/src/hyperloglog.c   2020-03-12 16:07:44.000000000 +0100
@@ -1535,6 +1535,7 @@
         sds decoded = sdsempty();
 
         if (hdr->encoding != HLL_SPARSE) {
+            sdsfree(decoded);
             addReplyError(c,"HLL encoding is not sparse");
             return;
         }
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/redis-5.0.7/src/module.c new/redis-5.0.8/src/module.c
--- old/redis-5.0.7/src/module.c        2019-11-19 18:05:52.000000000 +0100
+++ new/redis-5.0.8/src/module.c        2020-03-12 16:07:44.000000000 +0100
@@ -647,9 +647,9 @@
  * flags into the command flags used by the Redis core.
  *
  * It returns the set of flags, or -1 if unknown flags are found. */
-int commandFlagsFromString(char *s) {
+int64_t commandFlagsFromString(char *s) {
     int count, j;
-    int flags = 0;
+    int64_t flags = 0;
     sds *tokens = sdssplitlen(s,strlen(s)," ",1,&count);
     for (j = 0; j < count; j++) {
         char *t = tokens[j];
@@ -727,7 +727,7 @@
  *                     other reason.
  */
 int RM_CreateCommand(RedisModuleCtx *ctx, const char *name, RedisModuleCmdFunc 
cmdfunc, const char *strflags, int firstkey, int lastkey, int keystep) {
-    int flags = strflags ? commandFlagsFromString((char*)strflags) : 0;
+    int64_t flags = strflags ? commandFlagsFromString((char*)strflags) : 0;
     if (flags == -1) return REDISMODULE_ERR;
     if ((flags & CMD_MODULE_NO_CLUSTER) && server.cluster_enabled)
         return REDISMODULE_ERR;
@@ -4008,9 +4008,9 @@
  *
  * To call non-reply APIs, the thread safe context must be prepared with:
  *
- *     RedisModule_ThreadSafeCallStart(ctx);
+ *     RedisModule_ThreadSafeContextLock(ctx);
  *     ... make your call here ...
- *     RedisModule_ThreadSafeCallStop(ctx);
+ *     RedisModule_ThreadSafeContextUnlock(ctx);
  *
  * This is not needed when using `RedisModule_Reply*` functions, assuming
  * that a blocked client was used when the context was created, otherwise
@@ -4378,10 +4378,13 @@
     UNUSED(ctx);
 
     clusterNode *node = clusterLookupNode(id);
-    if (node->flags & (CLUSTER_NODE_NOADDR|CLUSTER_NODE_HANDSHAKE))
+    if (node == NULL ||
+        node->flags & (CLUSTER_NODE_NOADDR|CLUSTER_NODE_HANDSHAKE))
+    {
         return REDISMODULE_ERR;
+    }
 
-    if (ip) memcpy(ip,node->name,REDISMODULE_NODE_ID_LEN);
+    if (ip) strncpy(ip,node->ip,NET_IP_STR_LEN);
 
     if (master_id) {
         /* If the information is not available, the function will set the
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/redis-5.0.7/src/networking.c 
new/redis-5.0.8/src/networking.c
--- old/redis-5.0.7/src/networking.c    2019-11-19 18:05:52.000000000 +0100
+++ new/redis-5.0.8/src/networking.c    2020-03-12 16:07:44.000000000 +0100
@@ -918,7 +918,7 @@
         /* We need to remember the time when we started to have zero
          * attached slaves, as after some time we'll free the replication
          * backlog. */
-        if (c->flags & CLIENT_SLAVE && listLength(server.slaves) == 0)
+        if (getClientType(c) == CLIENT_TYPE_SLAVE && listLength(server.slaves) 
== 0)
             server.repl_no_slaves_since = server.unixtime;
         refreshGoodSlavesCount();
     }
@@ -1030,8 +1030,8 @@
          * just deliver as much data as it is possible to deliver.
          *
          * Moreover, we also send as much as possible if the client is
-         * a slave (otherwise, on high-speed traffic, the replication
-         * buffer will grow indefinitely) */
+         * a slave or a monitor (otherwise, on high-speed traffic, the
+         * replication/output buffer will grow indefinitely) */
         if (totwritten > NET_MAX_WRITES_PER_EVENT &&
             (server.maxmemory == 0 ||
              zmalloc_used_memory() < server.maxmemory) &&
@@ -1216,7 +1216,7 @@
     /* Newline from slaves can be used to refresh the last ACK time.
      * This is useful for a slave to ping back while loading a big
      * RDB file. */
-    if (querylen == 0 && c->flags & CLIENT_SLAVE)
+    if (querylen == 0 && getClientType(c) == CLIENT_TYPE_SLAVE)
         c->repl_ack_time = server.unixtime;
 
     /* Move querybuffer position to the next query in the buffer. */
@@ -1230,12 +1230,8 @@
 
     /* Create redis objects for all arguments. */
     for (c->argc = 0, j = 0; j < argc; j++) {
-        if (sdslen(argv[j])) {
-            c->argv[c->argc] = createObject(OBJ_STRING,argv[j]);
-            c->argc++;
-        } else {
-            sdsfree(argv[j]);
-        }
+        c->argv[c->argc] = createObject(OBJ_STRING,argv[j]);
+        c->argc++;
     }
     zfree(argv);
     return C_OK;
@@ -2037,12 +2033,14 @@
  *
  * The function will return one of the following:
  * CLIENT_TYPE_NORMAL -> Normal client
- * CLIENT_TYPE_SLAVE  -> Slave or client executing MONITOR command
+ * CLIENT_TYPE_SLAVE  -> Slave
  * CLIENT_TYPE_PUBSUB -> Client subscribed to Pub/Sub channels
  * CLIENT_TYPE_MASTER -> The client representing our replication master.
  */
 int getClientType(client *c) {
     if (c->flags & CLIENT_MASTER) return CLIENT_TYPE_MASTER;
+    /* Even though MONITOR clients are marked as replicas, we
+     * want the expose them as normal clients. */
     if ((c->flags & CLIENT_SLAVE) && !(c->flags & CLIENT_MONITOR))
         return CLIENT_TYPE_SLAVE;
     if (c->flags & CLIENT_PUBSUB) return CLIENT_TYPE_PUBSUB;
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/redis-5.0.7/src/scripting.c 
new/redis-5.0.8/src/scripting.c
--- old/redis-5.0.7/src/scripting.c     2019-11-19 18:05:52.000000000 +0100
+++ new/redis-5.0.8/src/scripting.c     2020-03-12 16:07:44.000000000 +0100
@@ -2213,6 +2213,7 @@
             ldbLog(sdscatfmt(sdsempty(),"<error> %s",lua_tostring(lua,-1)));
             lua_pop(lua,1);
             sdsfree(code);
+            sdsfree(expr);
             return;
         }
     }
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/redis-5.0.7/src/sds.h new/redis-5.0.8/src/sds.h
--- old/redis-5.0.7/src/sds.h   2019-11-19 18:05:52.000000000 +0100
+++ new/redis-5.0.8/src/sds.h   2020-03-12 16:07:44.000000000 +0100
@@ -34,7 +34,7 @@
 #define __SDS_H
 
 #define SDS_MAX_PREALLOC (1024*1024)
-const char *SDS_NOINIT;
+extern const char *SDS_NOINIT;
 
 #include <sys/types.h>
 #include <stdarg.h>
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/redis-5.0.7/src/sentinel.c 
new/redis-5.0.8/src/sentinel.c
--- old/redis-5.0.7/src/sentinel.c      2019-11-19 18:05:52.000000000 +0100
+++ new/redis-5.0.8/src/sentinel.c      2020-03-12 16:07:44.000000000 +0100
@@ -4270,7 +4270,7 @@
             sentinelRedisInstance *slave = dictGetVal(de);
             int retval;
 
-            if (slave->flags & (SRI_RECONF_DONE|SRI_RECONF_SENT)) continue;
+            if (slave->flags & (SRI_PROMOTED|SRI_RECONF_DONE|SRI_RECONF_SENT)) 
continue;
             if (slave->link->disconnected) continue;
 
             retval = sentinelSendSlaveOf(slave,
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/redis-5.0.7/src/server.c new/redis-5.0.8/src/server.c
--- old/redis-5.0.7/src/server.c        2019-11-19 18:05:52.000000000 +0100
+++ new/redis-5.0.8/src/server.c        2020-03-12 16:07:44.000000000 +0100
@@ -821,7 +821,7 @@
     time_t now = now_ms/1000;
 
     if (server.maxidletime &&
-        !(c->flags & CLIENT_SLAVE) &&    /* no timeout for slaves */
+        !(c->flags & CLIENT_SLAVE) &&    /* no timeout for slaves and monitors 
*/
         !(c->flags & CLIENT_MASTER) &&   /* no timeout for masters */
         !(c->flags & CLIENT_BLOCKED) &&  /* no timeout for BLPOP */
         !(c->flags & CLIENT_PUBSUB) &&   /* no timeout for Pub/Sub clients */
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/redis-5.0.7/src/stream.h new/redis-5.0.8/src/stream.h
--- old/redis-5.0.7/src/stream.h        2019-11-19 18:05:52.000000000 +0100
+++ new/redis-5.0.8/src/stream.h        2020-03-12 16:07:44.000000000 +0100
@@ -109,5 +109,6 @@
 streamNACK *streamCreateNACK(streamConsumer *consumer);
 void streamDecodeID(void *buf, streamID *id);
 int streamCompareID(streamID *a, streamID *b);
+void streamIncrID(streamID *id);
 
 #endif
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/redis-5.0.7/src/t_stream.c 
new/redis-5.0.8/src/t_stream.c
--- old/redis-5.0.7/src/t_stream.c      2019-11-19 18:05:52.000000000 +0100
+++ new/redis-5.0.8/src/t_stream.c      2020-03-12 16:07:44.000000000 +0100
@@ -67,6 +67,21 @@
     zfree(s);
 }
 
+/* Set 'id' to be its successor streamID */
+void streamIncrID(streamID *id) {
+    if (id->seq == UINT64_MAX) {
+        if (id->ms == UINT64_MAX) {
+            /* Special case where 'id' is the last possible streamID... */
+            id->ms = id->seq = 0;
+        } else {
+            id->ms++;
+            id->seq = 0;
+        }
+    } else {
+        id->seq++;
+    }
+}
+
 /* Generate the next stream item ID given the previous one. If the current
  * milliseconds Unix time is greater than the previous one, just use this
  * as time part and start with sequence part of zero. Otherwise we use the
@@ -77,8 +92,8 @@
         new_id->ms = ms;
         new_id->seq = 0;
     } else {
-        new_id->ms = last_id->ms;
-        new_id->seq = last_id->seq+1;
+        *new_id = *last_id;
+        streamIncrID(new_id);
     }
 }
 
@@ -776,6 +791,16 @@
     return deleted;
 }
 
+/* Get the last valid (non-tombstone) streamID of 's'. */
+void streamLastValidID(stream *s, streamID *maxid)
+{
+    streamIterator si;
+    streamIteratorStart(&si,s,NULL,NULL,1);
+    int64_t numfields;
+    streamIteratorGetID(&si,maxid,&numfields);
+    streamIteratorStop(&si);
+}
+
 /* Emit a reply in the client output buffer by formatting a Stream ID
  * in the standard <ms>-<seq> format, using the simple string protocol
  * of REPL. */
@@ -817,7 +842,7 @@
     argv[11] = createStringObject("JUSTID",6);
     argv[12] = createStringObject("LASTID",6);
     argv[13] = createObjectFromStreamID(&group->last_id);
-    
propagate(server.xclaimCommand,c->db->id,argv,14,PROPAGATE_AOF|PROPAGATE_REPL);
+    
alsoPropagate(server.xclaimCommand,c->db->id,argv,14,PROPAGATE_AOF|PROPAGATE_REPL);
     decrRefCount(argv[0]);
     decrRefCount(argv[3]);
     decrRefCount(argv[4]);
@@ -844,7 +869,7 @@
     argv[2] = key;
     argv[3] = groupname;
     argv[4] = createObjectFromStreamID(&group->last_id);
-    
propagate(server.xgroupCommand,c->db->id,argv,5,PROPAGATE_AOF|PROPAGATE_REPL);
+    
alsoPropagate(server.xgroupCommand,c->db->id,argv,5,PROPAGATE_AOF|PROPAGATE_REPL);
     decrRefCount(argv[0]);
     decrRefCount(argv[1]);
     decrRefCount(argv[4]);
@@ -1233,6 +1258,13 @@
     if ((o = streamTypeLookupWriteOrCreate(c,c->argv[1])) == NULL) return;
     s = o->ptr;
 
+    /* Return ASAP if the stream has reached the last possible ID */
+    if (s->last_id.ms == UINT64_MAX && s->last_id.seq == UINT64_MAX) {
+        addReplyError(c,"The stream has exhausted the last possible ID, "
+                        "unable to add more items");
+        return;
+    }
+
     /* Append using the low level function and return the ID. */
     if (streamAppendItem(s,c->argv+field_pos,(c->argc-field_pos)/2,
         &id, id_given ? &id : NULL)
@@ -1496,20 +1528,23 @@
             {
                 serve_synchronously = 1;
                 serve_history = 1;
-            } else {
+            } else if (s->length) {
                 /* We also want to serve a consumer in a consumer group
                  * synchronously in case the group top item delivered is 
smaller
                  * than what the stream has inside. */
-                streamID *last = &groups[i]->last_id;
-                if (s->length && (streamCompareID(&s->last_id, last) > 0)) {
+                streamID maxid, *last = &groups[i]->last_id;
+                streamLastValidID(s, &maxid);
+                if (streamCompareID(&maxid, last) > 0) {
                     serve_synchronously = 1;
                     *gt = *last;
                 }
             }
-        } else {
+        } else if (s->length) {
             /* For consumers without a group, we serve synchronously if we can
              * actually provide at least one item from the stream. */
-            if (s->length && (streamCompareID(&s->last_id, gt) > 0)) {
+            streamID maxid;
+            streamLastValidID(s, &maxid);
+            if (streamCompareID(&maxid, gt) > 0) {
                 serve_synchronously = 1;
             }
         }
@@ -1521,7 +1556,7 @@
              * so start from the next ID, since we want only messages with
              * IDs greater than start. */
             streamID start = *gt;
-            start.seq++; /* uint64_t can't overflow in this context. */
+            streamIncrID(&start);
 
             /* Emit the two elements sub-array consisting of the name
              * of the stream and the data we extracted from it. */
@@ -1858,11 +1893,7 @@
      * item, otherwise the fundamental ID monotonicity assumption is violated. 
*/
     if (s->length > 0) {
         streamID maxid;
-        streamIterator si;
-        streamIteratorStart(&si,s,NULL,NULL,1);
-        int64_t numfields;
-        streamIteratorGetID(&si,&maxid,&numfields);
-        streamIteratorStop(&si);
+        streamLastValidID(s,&maxid);
 
         if (streamCompareID(&id,&maxid) < 0) {
             addReplyError(c,"The ID specified in XSETID is smaller than the "
@@ -2233,7 +2264,7 @@
     }
 
     /* Do the actual claiming. */
-    streamConsumer *consumer = streamLookupConsumer(group,c->argv[3]->ptr,1);
+    streamConsumer *consumer = NULL;
     void *arraylenptr = addDeferredMultiBulkLength(c);
     size_t arraylen = 0;
     for (int j = 5; j <= last_id_arg; j++) {
@@ -2285,9 +2316,11 @@
             if (nack->consumer)
                 raxRemove(nack->consumer->pel,buf,sizeof(buf),NULL);
             /* Update the consumer and idle time. */
+            if (consumer == NULL)
+                consumer = streamLookupConsumer(group,c->argv[3]->ptr,1);
             nack->consumer = consumer;
             nack->delivery_time = deliverytime;
-            /* Set the delivery attempts counter if given, otherwise 
+            /* Set the delivery attempts counter if given, otherwise
              * autoincrement unless JUSTID option provided */
             if (retrycount >= 0) {
                 nack->delivery_count = retrycount;
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/redis-5.0.7/src/version.h 
new/redis-5.0.8/src/version.h
--- old/redis-5.0.7/src/version.h       2019-11-19 18:05:52.000000000 +0100
+++ new/redis-5.0.8/src/version.h       2020-03-12 16:07:44.000000000 +0100
@@ -1 +1 @@
-#define REDIS_VERSION "5.0.7"
+#define REDIS_VERSION "5.0.8"
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/redis-5.0.7/tests/unit/type/stream-cgroups.tcl 
new/redis-5.0.8/tests/unit/type/stream-cgroups.tcl
--- old/redis-5.0.7/tests/unit/type/stream-cgroups.tcl  2019-11-19 
18:05:52.000000000 +0100
+++ new/redis-5.0.8/tests/unit/type/stream-cgroups.tcl  2020-03-12 
16:07:44.000000000 +0100
@@ -147,6 +147,20 @@
         assert {[lindex $res 0 1 1] == {2-0 {field1 B}}}
     }
 
+    test {Blocking XREADGROUP will not reply with an empty array} {
+        r del mystream
+        r XGROUP CREATE mystream mygroup $ MKSTREAM
+        r XADD mystream 666 f v
+        set res [r XREADGROUP GROUP mygroup Alice BLOCK 10 STREAMS mystream 
">"]
+        assert {[lindex $res 0 1 0] == {666-0 {f v}}}
+        r XADD mystream 667 f2 v2
+        r XDEL mystream 667
+        set rd [redis_deferring_client]
+        $rd XREADGROUP GROUP mygroup Alice BLOCK 10 STREAMS mystream ">"
+        after 20
+        assert {[$rd read] == {}} ;# before the fix, client didn't even block, 
but was served synchronously with {mystream {}}
+    }
+
     test {XCLAIM can claim PEL items from another consumer} {
         # Add 3 items into the stream, and create a consumer group
         r del mystream
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/redis-5.0.7/tests/unit/type/stream.tcl 
new/redis-5.0.8/tests/unit/type/stream.tcl
--- old/redis-5.0.7/tests/unit/type/stream.tcl  2019-11-19 18:05:52.000000000 
+0100
+++ new/redis-5.0.8/tests/unit/type/stream.tcl  2020-03-12 16:07:44.000000000 
+0100
@@ -191,6 +191,17 @@
         assert {[lindex $res 0 1 0 1] eq {old abcd1234}}
     }
 
+    test {Blocking XREAD will not reply with an empty array} {
+        r del s1
+        r XADD s1 666 f v
+        r XADD s1 667 f2 v2
+        r XDEL s1 667
+        set rd [redis_deferring_client]
+        $rd XREAD BLOCK 10 STREAMS s1 666
+        after 20
+        assert {[$rd read] == {}} ;# before the fix, client didn't even block, 
but was served synchronously with {s1 {}}
+    }
+
     test "XREAD: XADD + DEL should not awake client" {
         set rd [redis_deferring_client]
         r del s1
@@ -328,6 +339,33 @@
 
         assert_equal [r xrevrange teststream2 1234567891245 -] 
{{1234567891240-0 {key1 value2}} {1234567891230-0 {key1 value1}}}
     }
+
+    test {XREAD streamID edge (no-blocking)} {
+        r del x
+        r XADD x 1-1 f v
+        r XADD x 1-18446744073709551615 f v
+        r XADD x 2-1 f v
+        set res [r XREAD BLOCK 0 STREAMS x 1-18446744073709551615]
+        assert {[lindex $res 0 1 0] == {2-1 {f v}}}
+    }
+
+    test {XREAD streamID edge (blocking)} {
+        r del x
+        set rd [redis_deferring_client]
+        $rd XREAD BLOCK 0 STREAMS x 1-18446744073709551615
+        r XADD x 1-1 f v
+        r XADD x 1-18446744073709551615 f v
+        r XADD x 2-1 f v
+        set res [$rd read]
+        assert {[lindex $res 0 1 0] == {2-1 {f v}}}
+    }
+
+    test {XADD streamID edge} {
+        r del x
+        r XADD x 2577343934890-18446744073709551615 f v ;# we need the 
timestamp to be in the future
+        r XADD x * f2 v2
+        assert_equal [r XRANGE x - +] {{2577343934890-18446744073709551615 {f 
v}} {2577343934891-0 {f2 v2}}}
+    }
 }
 
 start_server {tags {"stream"} overrides {appendonly yes}} {


Reply via email to