Fix memory leak in moduleFreeCommand (#11147)

Currently, we call zfree(cmd->args), but the argument array
needs to be freed recursively (there might be sub-args).
Also fixed memory leaks on cmd->tips and cmd->history.

Fixes #11145
This commit is contained in:
Binbin 2022-08-18 17:36:01 +08:00 committed by GitHub
parent 508a138885
commit fc3956e8f4
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 22 additions and 1 deletions

View File

@ -11039,6 +11039,21 @@ void moduleFreeModuleStructure(struct RedisModule *module) {
zfree(module);
}
void moduleFreeArgs(struct redisCommandArg *args, int num_args) {
for (int j = 0; j < num_args; j++) {
zfree((char *)args[j].name);
zfree((char *)args[j].token);
zfree((char *)args[j].summary);
zfree((char *)args[j].since);
zfree((char *)args[j].deprecated_since);
if (args[j].subargs) {
moduleFreeArgs(args[j].subargs, args[j].num_args);
}
}
zfree(args);
}
/* Free the command registered with the specified module.
* On success C_OK is returned, otherwise C_ERR is returned.
*
@ -11064,10 +11079,12 @@ int moduleFreeCommand(struct RedisModule *module, struct redisCommand *cmd) {
zfree(cmd->key_specs);
for (int j = 0; cmd->tips && cmd->tips[j]; j++)
zfree((char *)cmd->tips[j]);
zfree(cmd->tips);
for (int j = 0; cmd->history && cmd->history[j].since; j++) {
zfree((char *)cmd->history[j].since);
zfree((char *)cmd->history[j].changes);
}
zfree(cmd->history);
zfree((char *)cmd->summary);
zfree((char *)cmd->since);
zfree((char *)cmd->deprecated_since);
@ -11076,7 +11093,7 @@ int moduleFreeCommand(struct RedisModule *module, struct redisCommand *cmd) {
hdr_close(cmd->latency_histogram);
cmd->latency_histogram = NULL;
}
zfree(cmd->args);
moduleFreeArgs(cmd->args, cmd->num_args);
zfree(cp);
if (cmd->subcommands_dict) {

View File

@ -40,4 +40,8 @@ start_server {tags {"modules"}} {
assert_equal $redis_reply $module_reply
}
test "Unload the module - cmdintrospection" {
assert_equal {OK} [r module unload cmdintrospection]
}
}