diff options
author | Pieter Noordhuis <pcnoordhuis@gmail.com> | 2010-11-22 09:55:54 +0100 |
---|---|---|
committer | Pieter Noordhuis <pcnoordhuis@gmail.com> | 2010-11-22 09:55:54 +0100 |
commit | 9d9b8e1c79130610b48415a0b0f385e1ac1919e2 (patch) | |
tree | 2d93a2ecb3e749e28c8be656393e77c46cb9456f | |
parent | 4f4d1ed7b536f2358830751d2501c1147f5a4dad (diff) |
Correctly format commands with empty interpolated values
-rw-r--r-- | hiredis.c | 13 | ||||
-rw-r--r-- | test.c | 12 |
2 files changed, 22 insertions, 3 deletions
@@ -525,6 +525,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? */ char **argv = NULL; int argc = 0, j; int totlen = 0; @@ -541,6 +542,7 @@ int redisvFormatCommand(char **target, const char *format, va_list ap) { if (sdslen(current) != 0) { addArgument(current, &argv, &argc, &totlen); current = sdsempty(); + interpolated = 0; } } else { current = sdscatlen(current,c,1); @@ -549,12 +551,17 @@ int redisvFormatCommand(char **target, const char *format, va_list ap) { switch(c[1]) { case 's': arg = va_arg(ap,char*); - current = sdscat(current,arg); + 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); - current = sdscatlen(current,arg,size); + if (size > 0) + current = sdscatlen(current,arg,size); + interpolated = 1; break; case '%': cmd = sdscat(cmd,"%"); @@ -566,7 +573,7 @@ int redisvFormatCommand(char **target, const char *format, va_list ap) { } /* Add the last argument if needed */ - if (sdslen(current) != 0) { + if (interpolated || sdslen(current) != 0) { addArgument(current, &argv, &argc, &totlen); } else { sdsfree(current); @@ -47,12 +47,24 @@ static void test_format_commands() { len == 4+4+(3+2)+4+(3+2)+4+(3+2)); 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: "); 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 && len == 4+4+(3+2)+4+(3+2)+4+(3+2)); 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]; argv[0] = "SET"; argv[1] = "foo"; |