Unverified Commit fc3956e8 authored by Binbin's avatar Binbin Committed by GitHub
Browse files

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
parent 508a1388
...@@ -11039,6 +11039,21 @@ void moduleFreeModuleStructure(struct RedisModule *module) { ...@@ -11039,6 +11039,21 @@ void moduleFreeModuleStructure(struct RedisModule *module) {
zfree(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. /* Free the command registered with the specified module.
* On success C_OK is returned, otherwise C_ERR is returned. * On success C_OK is returned, otherwise C_ERR is returned.
* *
...@@ -11064,10 +11079,12 @@ int moduleFreeCommand(struct RedisModule *module, struct redisCommand *cmd) { ...@@ -11064,10 +11079,12 @@ int moduleFreeCommand(struct RedisModule *module, struct redisCommand *cmd) {
zfree(cmd->key_specs); zfree(cmd->key_specs);
for (int j = 0; cmd->tips && cmd->tips[j]; j++) for (int j = 0; cmd->tips && cmd->tips[j]; j++)
zfree((char *)cmd->tips[j]); zfree((char *)cmd->tips[j]);
zfree(cmd->tips);
for (int j = 0; cmd->history && cmd->history[j].since; j++) { for (int j = 0; cmd->history && cmd->history[j].since; j++) {
zfree((char *)cmd->history[j].since); zfree((char *)cmd->history[j].since);
zfree((char *)cmd->history[j].changes); zfree((char *)cmd->history[j].changes);
} }
zfree(cmd->history);
zfree((char *)cmd->summary); zfree((char *)cmd->summary);
zfree((char *)cmd->since); zfree((char *)cmd->since);
zfree((char *)cmd->deprecated_since); zfree((char *)cmd->deprecated_since);
...@@ -11076,7 +11093,7 @@ int moduleFreeCommand(struct RedisModule *module, struct redisCommand *cmd) { ...@@ -11076,7 +11093,7 @@ int moduleFreeCommand(struct RedisModule *module, struct redisCommand *cmd) {
hdr_close(cmd->latency_histogram); hdr_close(cmd->latency_histogram);
cmd->latency_histogram = NULL; cmd->latency_histogram = NULL;
} }
zfree(cmd->args); moduleFreeArgs(cmd->args, cmd->num_args);
zfree(cp); zfree(cp);
if (cmd->subcommands_dict) { if (cmd->subcommands_dict) {
......
...@@ -40,4 +40,8 @@ start_server {tags {"modules"}} { ...@@ -40,4 +40,8 @@ start_server {tags {"modules"}} {
assert_equal $redis_reply $module_reply assert_equal $redis_reply $module_reply
} }
test "Unload the module - cmdintrospection" {
assert_equal {OK} [r module unload cmdintrospection]
}
} }
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment