Fix formatCommand to work with all empty interpolations
This commit is contained in:
parent
bf544ce81c
commit
8e2c39200d
13
hiredis.c
13
hiredis.c
@ -596,7 +596,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? */
|
int touched = 0; /* was the current argument touched? */
|
||||||
char **argv = NULL;
|
char **argv = NULL;
|
||||||
int argc = 0, j;
|
int argc = 0, j;
|
||||||
int totlen = 0;
|
int totlen = 0;
|
||||||
@ -610,13 +610,14 @@ int redisvFormatCommand(char **target, const char *format, va_list ap) {
|
|||||||
while(*c != '\0') {
|
while(*c != '\0') {
|
||||||
if (*c != '%' || c[1] == '\0') {
|
if (*c != '%' || c[1] == '\0') {
|
||||||
if (*c == ' ') {
|
if (*c == ' ') {
|
||||||
if (sdslen(current) != 0) {
|
if (touched) {
|
||||||
addArgument(current, &argv, &argc, &totlen);
|
addArgument(current, &argv, &argc, &totlen);
|
||||||
current = sdsempty();
|
current = sdsempty();
|
||||||
interpolated = 0;
|
touched = 0;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
current = sdscatlen(current,c,1);
|
current = sdscatlen(current,c,1);
|
||||||
|
touched = 1;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
switch(c[1]) {
|
switch(c[1]) {
|
||||||
@ -625,14 +626,12 @@ int redisvFormatCommand(char **target, const char *format, va_list ap) {
|
|||||||
size = strlen(arg);
|
size = strlen(arg);
|
||||||
if (size > 0)
|
if (size > 0)
|
||||||
current = sdscatlen(current,arg,size);
|
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)
|
if (size > 0)
|
||||||
current = sdscatlen(current,arg,size);
|
current = sdscatlen(current,arg,size);
|
||||||
interpolated = 1;
|
|
||||||
break;
|
break;
|
||||||
case '%':
|
case '%':
|
||||||
current = sdscat(current,"%");
|
current = sdscat(current,"%");
|
||||||
@ -678,7 +677,6 @@ int redisvFormatCommand(char **target, const char *format, va_list ap) {
|
|||||||
_format[_l] = '\0';
|
_format[_l] = '\0';
|
||||||
va_copy(_cpy,ap);
|
va_copy(_cpy,ap);
|
||||||
current = sdscatvprintf(current,_format,_cpy);
|
current = sdscatvprintf(current,_format,_cpy);
|
||||||
interpolated = 1;
|
|
||||||
va_end(_cpy);
|
va_end(_cpy);
|
||||||
|
|
||||||
/* Update current position (note: outer blocks
|
/* Update current position (note: outer blocks
|
||||||
@ -691,13 +689,14 @@ int redisvFormatCommand(char **target, const char *format, va_list ap) {
|
|||||||
va_arg(ap,void);
|
va_arg(ap,void);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
touched = 1;
|
||||||
c++;
|
c++;
|
||||||
}
|
}
|
||||||
c++;
|
c++;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Add the last argument if needed */
|
/* Add the last argument if needed */
|
||||||
if (interpolated || sdslen(current) != 0) {
|
if (touched) {
|
||||||
addArgument(current, &argv, &argc, &totlen);
|
addArgument(current, &argv, &argc, &totlen);
|
||||||
} else {
|
} else {
|
||||||
sdsfree(current);
|
sdsfree(current);
|
||||||
|
6
test.c
6
test.c
@ -54,6 +54,12 @@ static void test_format_commands(void) {
|
|||||||
len == 4+4+(3+2)+4+(3+2)+4+(0+2));
|
len == 4+4+(3+2)+4+(3+2)+4+(0+2));
|
||||||
free(cmd);
|
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: ");
|
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 &&
|
||||||
|
Loading…
Reference in New Issue
Block a user