diff options
author | antirez <antirez@gmail.com> | 2017-07-20 15:17:35 +0200 |
---|---|---|
committer | antirez <antirez@gmail.com> | 2017-07-20 15:17:35 +0200 |
commit | a3778f3b0f0aacbb34ecc77541615a9eda251443 (patch) | |
tree | 67ec0063322d6bf84646e43b0e7a123e627ad80a | |
parent | b1c2e1a19c549a49cc124571849976e7ab91d4d1 (diff) | |
download | redis-a3778f3b0f0aacbb34ecc77541615a9eda251443.tar.gz |
Make representClusterNodeFlags() more robust.
This function failed when an internal-only flag was set as an only flag
in a node: the string was trimmed expecting a final comma before
exiting the function, causing a crash. See issue #4142.
Moreover generation of flags representation only needed at DEBUG log
level was always performed: a waste of CPU time. This is fixed as well
by this commit.
-rw-r--r-- | src/cluster.c | 35 |
1 files changed, 18 insertions, 17 deletions
diff --git a/src/cluster.c b/src/cluster.c index a516e911f..89765e37d 100644 --- a/src/cluster.c +++ b/src/cluster.c @@ -1323,14 +1323,16 @@ void clusterProcessGossipSection(clusterMsg *hdr, clusterLink *link) { clusterNode *node; sds ci; - ci = representClusterNodeFlags(sdsempty(), flags); - serverLog(LL_DEBUG,"GOSSIP %.40s %s:%d@%d %s", - g->nodename, - g->ip, - ntohs(g->port), - ntohs(g->cport), - ci); - sdsfree(ci); + if (server.verbosity == LL_DEBUG) { + ci = representClusterNodeFlags(sdsempty(), flags); + serverLog(LL_DEBUG,"GOSSIP %.40s %s:%d@%d %s", + g->nodename, + g->ip, + ntohs(g->port), + ntohs(g->cport), + ci); + sdsfree(ci); + } /* Update our state accordingly to the gossip sections */ node = clusterLookupNode(g->nodename); @@ -3835,15 +3837,14 @@ static struct redisNodeFlags redisNodeFlagsTable[] = { /* Concatenate the comma separated list of node flags to the given SDS * string 'ci'. */ sds representClusterNodeFlags(sds ci, uint16_t flags) { - if (flags == 0) { - ci = sdscat(ci,"noflags,"); - } else { - int i, size = sizeof(redisNodeFlagsTable)/sizeof(struct redisNodeFlags); - for (i = 0; i < size; i++) { - struct redisNodeFlags *nodeflag = redisNodeFlagsTable + i; - if (flags & nodeflag->flag) ci = sdscat(ci, nodeflag->name); - } - } + size_t orig_len = sdslen(ci); + int i, size = sizeof(redisNodeFlagsTable)/sizeof(struct redisNodeFlags); + for (i = 0; i < size; i++) { + struct redisNodeFlags *nodeflag = redisNodeFlagsTable + i; + if (flags & nodeflag->flag) ci = sdscat(ci, nodeflag->name); + } + /* If no flag was added, add the "noflags" special flag. */ + if (sdslen(ci) == orig_len) ci = sdscat(ci,"noflags,"); sdsIncrLen(ci,-1); /* Remove trailing comma. */ return ci; } |