Unverified Commit 83478e61 authored by yoav-steinberg's avatar yoav-steinberg Committed by GitHub
Browse files

argv mem leak during multi command execution. (#9598)

Changes in #9528 lead to memory leak if the command implementation
used rewriteClientCommandArgument inside MULTI-EXEC.

Adding an explicit test for that case since the test that uncovered it
didn't specifically target this scenario
parent 0f8b634c
...@@ -159,7 +159,7 @@ void execCommandAbort(client *c, sds error) { ...@@ -159,7 +159,7 @@ void execCommandAbort(client *c, sds error) {
void execCommand(client *c) { void execCommand(client *c) {
int j; int j;
robj **orig_argv; robj **orig_argv;
int orig_argc; int orig_argc, orig_argv_len;
struct redisCommand *orig_cmd; struct redisCommand *orig_cmd;
int was_master = server.masterhost == NULL; int was_master = server.masterhost == NULL;
...@@ -201,11 +201,12 @@ void execCommand(client *c) { ...@@ -201,11 +201,12 @@ void execCommand(client *c) {
server.in_exec = 1; server.in_exec = 1;
orig_argv = c->argv; orig_argv = c->argv;
orig_argv_len = c->argv_len;
orig_argc = c->argc; orig_argc = c->argc;
orig_cmd = c->cmd; orig_cmd = c->cmd;
addReplyArrayLen(c,c->mstate.count); addReplyArrayLen(c,c->mstate.count);
for (j = 0; j < c->mstate.count; j++) { for (j = 0; j < c->mstate.count; j++) {
c->argc = c->mstate.commands[j].argc; c->argv_len = c->argc = c->mstate.commands[j].argc;
c->argv = c->mstate.commands[j].argv; c->argv = c->mstate.commands[j].argv;
c->cmd = c->mstate.commands[j].cmd; c->cmd = c->mstate.commands[j].cmd;
...@@ -252,6 +253,7 @@ void execCommand(client *c) { ...@@ -252,6 +253,7 @@ void execCommand(client *c) {
c->flags &= ~CLIENT_DENY_BLOCKING; c->flags &= ~CLIENT_DENY_BLOCKING;
c->argv = orig_argv; c->argv = orig_argv;
c->argv_len = orig_argv_len;
c->argc = orig_argc; c->argc = orig_argc;
c->cmd = orig_cmd; c->cmd = orig_cmd;
discardTransaction(c); discardTransaction(c);
......
...@@ -203,6 +203,23 @@ start_server {tags {"protocol network"}} { ...@@ -203,6 +203,23 @@ start_server {tags {"protocol network"}} {
r mset {*}$args r mset {*}$args
assert_equal [r get "{k}2"] v2 assert_equal [r get "{k}2"] v2
} }
test "test argument rewriting - issue 9598" {
# INCRBYFLOAT uses argument rewriting for correct float value propagation.
# We use it to make sure argument rewriting works properly. It's important
# this test is run under valgrind to verify there are no memory leaks in
# arg buffer handling.
r flushdb
# Test normal argument handling
r set k 0
assert_equal [r incrbyfloat k 1.0] 1
# Test argument handing in multi-state buffers
r multi
r incrbyfloat k 1.0
assert_equal [r exec] 2
}
} }
......
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