From 8e2c39200d2a643180b1bc07aaa234056d5354f4 Mon Sep 17 00:00:00 2001 From: Pieter Noordhuis Date: Sun, 6 Mar 2011 11:38:07 +0100 Subject: [PATCH] Fix formatCommand to work with all empty interpolations --- hiredis.c | 13 ++++++------- test.c | 6 ++++++ 2 files changed, 12 insertions(+), 7 deletions(-) diff --git a/hiredis.c b/hiredis.c index 3d6b421..636597f 100644 --- a/hiredis.c +++ b/hiredis.c @@ -596,7 +596,7 @@ int redisvFormatCommand(char **target, const char *format, va_list ap) { char *cmd = NULL; /* final command */ int pos; /* position in final command */ sds current; /* current argument */ - int interpolated = 0; /* did we do interpolation on an argument? */ + int touched = 0; /* was the current argument touched? */ char **argv = NULL; int argc = 0, j; int totlen = 0; @@ -610,13 +610,14 @@ int redisvFormatCommand(char **target, const char *format, va_list ap) { while(*c != '\0') { if (*c != '%' || c[1] == '\0') { if (*c == ' ') { - if (sdslen(current) != 0) { + if (touched) { addArgument(current, &argv, &argc, &totlen); current = sdsempty(); - interpolated = 0; + touched = 0; } } else { current = sdscatlen(current,c,1); + touched = 1; } } else { switch(c[1]) { @@ -625,14 +626,12 @@ int redisvFormatCommand(char **target, const char *format, va_list ap) { size = strlen(arg); if (size > 0) current = sdscatlen(current,arg,size); - interpolated = 1; break; case 'b': arg = va_arg(ap,char*); size = va_arg(ap,size_t); if (size > 0) current = sdscatlen(current,arg,size); - interpolated = 1; break; case '%': current = sdscat(current,"%"); @@ -678,7 +677,6 @@ int redisvFormatCommand(char **target, const char *format, va_list ap) { _format[_l] = '\0'; va_copy(_cpy,ap); current = sdscatvprintf(current,_format,_cpy); - interpolated = 1; va_end(_cpy); /* Update current position (note: outer blocks @@ -691,13 +689,14 @@ int redisvFormatCommand(char **target, const char *format, va_list ap) { va_arg(ap,void); } } + touched = 1; c++; } c++; } /* Add the last argument if needed */ - if (interpolated || sdslen(current) != 0) { + if (touched) { addArgument(current, &argv, &argc, &totlen); } else { sdsfree(current); diff --git a/test.c b/test.c index bc82a1e..e9173a0 100644 --- a/test.c +++ b/test.c @@ -54,6 +54,12 @@ static void test_format_commands(void) { len == 4+4+(3+2)+4+(3+2)+4+(0+2)); free(cmd); + test("Format command with an empty string in between proper interpolations: "); + len = redisFormatCommand(&cmd,"SET %s %s","","foo"); + test_cond(strncmp(cmd,"*3\r\n$3\r\nSET\r\n$0\r\n\r\n$3\r\nfoo\r\n",len) == 0 && + len == 4+4+(3+2)+4+(0+2)+4+(3+2)); + free(cmd); + test("Format command with %%b string interpolation: "); 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 &&