summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPieter Noordhuis <pcnoordhuis@gmail.com>2010-11-22 09:55:54 +0100
committerPieter Noordhuis <pcnoordhuis@gmail.com>2010-11-22 09:55:54 +0100
commit9d9b8e1c79130610b48415a0b0f385e1ac1919e2 (patch)
tree2d93a2ecb3e749e28c8be656393e77c46cb9456f
parent4f4d1ed7b536f2358830751d2501c1147f5a4dad (diff)
Correctly format commands with empty interpolated values
-rw-r--r--hiredis.c13
-rw-r--r--test.c12
2 files changed, 22 insertions, 3 deletions
diff --git a/hiredis.c b/hiredis.c
index f0d78a0..36ee6d9 100644
--- a/hiredis.c
+++ b/hiredis.c
@@ -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);
diff --git a/test.c b/test.c
index 9da4522..e8289ba 100644
--- a/test.c
+++ b/test.c
@@ -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";