summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPieter Noordhuis <pcnoordhuis@gmail.com>2011-03-06 11:38:07 +0100
committerPieter Noordhuis <pcnoordhuis@gmail.com>2011-03-06 11:38:07 +0100
commit8e2c39200d2a643180b1bc07aaa234056d5354f4 (patch)
treecb3dc0066b572aa36ce6d943d4bb4f2496c2afd1
parentbf544ce81c55f6ae64470efeec04f368dec9ac3d (diff)
Fix formatCommand to work with all empty interpolations
-rw-r--r--hiredis.c13
-rw-r--r--test.c6
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 &&