Fix sentinel commands, ACL dictIter leak (#9661)
This commit is contained in:
parent
8bf4c2e38c
commit
8f745da159
@ -426,6 +426,7 @@ void ACLChangeCommandPerm(user *u, struct redisCommand *cmd, int allow) {
|
||||
struct redisCommand *sub = (struct redisCommand *)dictGetVal(de);
|
||||
ACLSetUserCommandBit(u,sub->id,allow);
|
||||
}
|
||||
dictReleaseIterator(di);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -944,10 +944,10 @@ RedisModuleCommandProxy *moduleCreateCommandProxy(RedisModuleCtx *ctx, const cha
|
||||
*
|
||||
* Note that we use the Redis command table 'getkeys_proc' in order to
|
||||
* pass a reference to the command proxy structure. */
|
||||
cp = zmalloc(sizeof(*cp));
|
||||
cp = zcalloc(sizeof(*cp));
|
||||
cp->module = ctx->module;
|
||||
cp->func = cmdfunc;
|
||||
cp->rediscmd = zmalloc(sizeof(*rediscmd));
|
||||
cp->rediscmd = zcalloc(sizeof(*rediscmd));
|
||||
cp->rediscmd->name = cmdname;
|
||||
cp->rediscmd->proc = RedisModuleCommandDispatcher;
|
||||
cp->rediscmd->flags = flags | CMD_MODULE;
|
||||
|
52
src/server.c
52
src/server.c
@ -628,7 +628,7 @@ struct redisCommand sentinelSubcommands[] = {
|
||||
{"config",sentinelCommand,-3,
|
||||
"admin only-sentinel"},
|
||||
|
||||
{"debug",sentinelCommand,2,
|
||||
{"debug",sentinelCommand,-2,
|
||||
"admin only-sentinel"},
|
||||
|
||||
{"get-master-addr-by-name",sentinelCommand,3,
|
||||
@ -673,7 +673,7 @@ struct redisCommand sentinelSubcommands[] = {
|
||||
{"sentinels",sentinelCommand,3,
|
||||
"admin only-sentinel"},
|
||||
|
||||
{"set",sentinelCommand,5,
|
||||
{"set",sentinelCommand,-3,
|
||||
"admin only-sentinel"},
|
||||
|
||||
{"simulate-failure",sentinelCommand,3,
|
||||
@ -2027,7 +2027,7 @@ struct redisCommand redisCommandTable[] = {
|
||||
"read-only fast"},
|
||||
|
||||
{"acl",NULL,-2,
|
||||
"",
|
||||
"sentinel",
|
||||
.subcommands=aclSubcommands},
|
||||
|
||||
{"stralgo",NULL,-2,
|
||||
@ -4449,16 +4449,17 @@ void commandAddSubcommand(struct redisCommand *parent, struct redisCommand *subc
|
||||
serverAssert(dictAdd(parent->subcommands_dict, sdsnew(subcommand->name), subcommand) == DICT_OK);
|
||||
}
|
||||
|
||||
|
||||
/* Parse the flags string description 'strflags' and set them to the
|
||||
* command 'c'. If the flags are all valid C_OK is returned, otherwise
|
||||
* C_ERR is returned (yet the recognized flags are set in the command). */
|
||||
int populateSingleCommand(struct redisCommand *c, char *strflags) {
|
||||
* command 'c'. Abort on error. */
|
||||
void parseCommandFlags(struct redisCommand *c, char *strflags) {
|
||||
int argc;
|
||||
sds *argv;
|
||||
|
||||
/* Split the line into arguments for processing. */
|
||||
argv = sdssplitargs(strflags,&argc);
|
||||
if (argv == NULL) return C_ERR;
|
||||
if (argv == NULL)
|
||||
serverPanic("Failed splitting strflags!");
|
||||
|
||||
for (int j = 0; j < argc; j++) {
|
||||
char *flag = argv[j];
|
||||
@ -4497,6 +4498,7 @@ int populateSingleCommand(struct redisCommand *c, char *strflags) {
|
||||
} else if (!strcasecmp(flag,"sentinel")) {
|
||||
c->flags |= CMD_SENTINEL;
|
||||
} else if (!strcasecmp(flag,"only-sentinel")) {
|
||||
c->flags |= CMD_SENTINEL; /* Obviously it's s sentinel command */
|
||||
c->flags |= CMD_ONLY_SENTINEL;
|
||||
} else {
|
||||
/* Parse ACL categories here if the flag name starts with @. */
|
||||
@ -4507,7 +4509,7 @@ int populateSingleCommand(struct redisCommand *c, char *strflags) {
|
||||
c->flags |= catflag;
|
||||
} else {
|
||||
sdsfreesplitres(argv,argc);
|
||||
return C_ERR;
|
||||
serverPanic("Unsupported command flag %s", flag);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -4515,8 +4517,11 @@ int populateSingleCommand(struct redisCommand *c, char *strflags) {
|
||||
if (!(c->flags & CMD_CATEGORY_FAST)) c->flags |= CMD_CATEGORY_SLOW;
|
||||
|
||||
sdsfreesplitres(argv,argc);
|
||||
}
|
||||
|
||||
/* Now handle the key arguments spec flags */
|
||||
void populateCommandStructure(struct redisCommand *c) {
|
||||
int argc;
|
||||
sds *argv;
|
||||
|
||||
/* Redis commands don't need more args than STATIC_KEY_SPECS_NUM (Number of keys
|
||||
* specs can be greater than STATIC_KEY_SPECS_NUM only for module commands) */
|
||||
@ -4530,7 +4535,7 @@ int populateSingleCommand(struct redisCommand *c, char *strflags) {
|
||||
/* Split the line into arguments for processing. */
|
||||
argv = sdssplitargs(c->key_specs[i].sflags,&argc);
|
||||
if (argv == NULL)
|
||||
return C_ERR;
|
||||
serverPanic("Failed splitting key sflags!");
|
||||
|
||||
for (int j = 0; j < argc; j++) {
|
||||
char *flag = argv[j];
|
||||
@ -4540,6 +4545,8 @@ int populateSingleCommand(struct redisCommand *c, char *strflags) {
|
||||
c->key_specs[i].flags |= CMD_KEY_READ;
|
||||
} else if (!strcasecmp(flag,"incomplete")) {
|
||||
c->key_specs[i].flags |= CMD_KEY_INCOMPLETE;
|
||||
} else {
|
||||
serverPanic("Unsupported key-arg flag %s", flag);
|
||||
}
|
||||
}
|
||||
|
||||
@ -4552,6 +4559,9 @@ int populateSingleCommand(struct redisCommand *c, char *strflags) {
|
||||
/* Handle the "movablekeys" flag (must be done after populating all key specs). */
|
||||
populateCommandMovableKeys(c);
|
||||
|
||||
/* Assign the ID used for ACL. */
|
||||
c->id = ACLGetCommandID(c->name);
|
||||
|
||||
/* Handle subcommands */
|
||||
if (c->subcommands) {
|
||||
for (int j = 0; c->subcommands[j].name; j++) {
|
||||
@ -4559,14 +4569,11 @@ int populateSingleCommand(struct redisCommand *c, char *strflags) {
|
||||
|
||||
/* Translate the command string flags description into an actual
|
||||
* set of flags. */
|
||||
if (populateSingleCommand(sub,sub->sflags) == C_ERR)
|
||||
serverPanic("Unsupported command flag or key spec flag");
|
||||
|
||||
parseCommandFlags(sub,sub->sflags);
|
||||
populateCommandStructure(sub);
|
||||
commandAddSubcommand(c,sub);
|
||||
}
|
||||
}
|
||||
|
||||
return C_OK;
|
||||
}
|
||||
|
||||
/* Populates the Redis Command Table starting from the hard coded list
|
||||
@ -4577,6 +4584,11 @@ void populateCommandTable(void) {
|
||||
|
||||
for (j = 0; j < numcommands; j++) {
|
||||
struct redisCommand *c = redisCommandTable+j;
|
||||
int retval1, retval2;
|
||||
|
||||
/* Translate the command string flags description into an actual
|
||||
* set of flags. */
|
||||
parseCommandFlags(c,c->sflags);
|
||||
|
||||
if (!(c->flags & CMD_SENTINEL) && server.sentinel_mode)
|
||||
continue;
|
||||
@ -4584,15 +4596,7 @@ void populateCommandTable(void) {
|
||||
if (c->flags & CMD_ONLY_SENTINEL && !server.sentinel_mode)
|
||||
continue;
|
||||
|
||||
int retval1, retval2;
|
||||
|
||||
/* Assign the ID used for ACL. */
|
||||
c->id = ACLGetCommandID(c->name);
|
||||
|
||||
/* Translate the command string flags description into an actual
|
||||
* set of flags. */
|
||||
if (populateSingleCommand(c,c->sflags) == C_ERR)
|
||||
serverPanic("Unsupported command flag or key spec flag");
|
||||
populateCommandStructure(c);
|
||||
|
||||
retval1 = dictAdd(server.commands, sdsnew(c->name), c);
|
||||
/* Populate an additional dictionary that will be unaffected
|
||||
|
Loading…
x
Reference in New Issue
Block a user