Commit 9d9b8e1c authored by Pieter Noordhuis's avatar Pieter Noordhuis
Browse files

Correctly format commands with empty interpolated values

parent 4f4d1ed7
...@@ -525,6 +525,7 @@ int redisvFormatCommand(char **target, const char *format, va_list ap) { ...@@ -525,6 +525,7 @@ int redisvFormatCommand(char **target, const char *format, va_list ap) {
char *cmd = NULL; /* final command */ char *cmd = NULL; /* final command */
int pos; /* position in final command */ int pos; /* position in final command */
sds current; /* current argument */ sds current; /* current argument */
int interpolated = 0; /* did we do interpolation on an argument? */
char **argv = NULL; char **argv = NULL;
int argc = 0, j; int argc = 0, j;
int totlen = 0; int totlen = 0;
...@@ -541,6 +542,7 @@ int redisvFormatCommand(char **target, const char *format, va_list ap) { ...@@ -541,6 +542,7 @@ int redisvFormatCommand(char **target, const char *format, va_list ap) {
if (sdslen(current) != 0) { if (sdslen(current) != 0) {
addArgument(current, &argv, &argc, &totlen); addArgument(current, &argv, &argc, &totlen);
current = sdsempty(); current = sdsempty();
interpolated = 0;
} }
} else { } else {
current = sdscatlen(current,c,1); current = sdscatlen(current,c,1);
...@@ -549,12 +551,17 @@ int redisvFormatCommand(char **target, const char *format, va_list ap) { ...@@ -549,12 +551,17 @@ int redisvFormatCommand(char **target, const char *format, va_list ap) {
switch(c[1]) { switch(c[1]) {
case 's': case 's':
arg = va_arg(ap,char*); arg = va_arg(ap,char*);
current = sdscat(current,arg); size = strlen(arg);
if (size > 0)
current = sdscatlen(current,arg,size);
interpolated = 1;
break; break;
case 'b': case 'b':
arg = va_arg(ap,char*); arg = va_arg(ap,char*);
size = va_arg(ap,size_t); size = va_arg(ap,size_t);
if (size > 0)
current = sdscatlen(current,arg,size); current = sdscatlen(current,arg,size);
interpolated = 1;
break; break;
case '%': case '%':
cmd = sdscat(cmd,"%"); cmd = sdscat(cmd,"%");
...@@ -566,7 +573,7 @@ int redisvFormatCommand(char **target, const char *format, va_list ap) { ...@@ -566,7 +573,7 @@ int redisvFormatCommand(char **target, const char *format, va_list ap) {
} }
/* Add the last argument if needed */ /* Add the last argument if needed */
if (sdslen(current) != 0) { if (interpolated || sdslen(current) != 0) {
addArgument(current, &argv, &argc, &totlen); addArgument(current, &argv, &argc, &totlen);
} else { } else {
sdsfree(current); sdsfree(current);
......
...@@ -47,12 +47,24 @@ static void test_format_commands() { ...@@ -47,12 +47,24 @@ static void test_format_commands() {
len == 4+4+(3+2)+4+(3+2)+4+(3+2)); len == 4+4+(3+2)+4+(3+2)+4+(3+2));
free(cmd); free(cmd);
test("Format command with %%s and an empty string: ");
len = redisFormatCommand(&cmd,"SET %s %s","foo","");
test_cond(strncmp(cmd,"*3\r\n$3\r\nSET\r\n$3\r\nfoo\r\n$0\r\n\r\n",len) == 0 &&
len == 4+4+(3+2)+4+(3+2)+4+(0+2));
free(cmd);
test("Format command with %%b string interpolation: "); test("Format command with %%b string interpolation: ");
len = redisFormatCommand(&cmd,"SET %b %b","foo",3,"b\0r",3); len = redisFormatCommand(&cmd,"SET %b %b","foo",3,"b\0r",3);
test_cond(strncmp(cmd,"*3\r\n$3\r\nSET\r\n$3\r\nfoo\r\n$3\r\nb\0r\r\n",len) == 0 && test_cond(strncmp(cmd,"*3\r\n$3\r\nSET\r\n$3\r\nfoo\r\n$3\r\nb\0r\r\n",len) == 0 &&
len == 4+4+(3+2)+4+(3+2)+4+(3+2)); len == 4+4+(3+2)+4+(3+2)+4+(3+2));
free(cmd); free(cmd);
test("Format command with %%b and an empty string: ");
len = redisFormatCommand(&cmd,"SET %b %b","foo",3,"",0);
test_cond(strncmp(cmd,"*3\r\n$3\r\nSET\r\n$3\r\nfoo\r\n$0\r\n\r\n",len) == 0 &&
len == 4+4+(3+2)+4+(3+2)+4+(0+2));
free(cmd);
const char *argv[3]; const char *argv[3];
argv[0] = "SET"; argv[0] = "SET";
argv[1] = "foo"; argv[1] = "foo";
......
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