Use correct type when calling va_arg in formatter

This commit is contained in:
Pieter Noordhuis 2011-07-09 15:03:00 +02:00
parent 4ac55be9b5
commit 27c96dde77

View File

@ -770,33 +770,81 @@ int redisvFormatCommand(char **target, const char *format, va_list ap) {
while (*_p != '\0' && isdigit(*_p)) _p++; while (*_p != '\0' && isdigit(*_p)) _p++;
} }
/* Modifiers */ /* Copy va_list before consuming with va_arg */
if (*_p != '\0') { va_copy(_cpy,ap);
if (*_p == 'h' || *_p == 'l') {
/* Allow a single repetition for these modifiers */ /* Integer conversion (without modifiers) */
if (_p[0] == _p[1]) _p++; if (strchr("diouxX",*_p) != NULL) {
_p++; va_arg(ap,int);
} goto fmt_valid;
} }
/* Conversion specifier */ /* Double conversion (without modifiers) */
if (*_p != '\0' && strchr("diouxXeEfFgGaA",*_p) != NULL) { if (strchr("eEfFgGaA",*_p) != NULL) {
va_arg(ap,double);
goto fmt_valid;
}
/* Size: char */
if (_p[0] == 'h' && _p[1] == 'h') {
_p += 2;
if (*_p != '\0' && strchr("diouxX",*_p) != NULL) {
va_arg(ap,int); /* char gets promoted to int */
goto fmt_valid;
}
goto fmt_invalid;
}
/* Size: short */
if (_p[0] == 'h') {
_p += 1;
if (*_p != '\0' && strchr("diouxX",*_p) != NULL) {
va_arg(ap,int); /* short gets promoted to int */
goto fmt_valid;
}
goto fmt_invalid;
}
/* Size: long long */
if (_p[0] == 'l' && _p[1] == 'l') {
_p += 2;
if (*_p != '\0' && strchr("diouxX",*_p) != NULL) {
va_arg(ap,long long);
goto fmt_valid;
}
goto fmt_invalid;
}
/* Size: long */
if (_p[0] == 'l') {
_p += 1;
if (*_p != '\0' && strchr("diouxX",*_p) != NULL) {
va_arg(ap,long);
goto fmt_valid;
}
goto fmt_invalid;
}
fmt_invalid:
/* Consume and discard vararg */
va_arg(ap,void);
va_end(_cpy);
break;
fmt_valid:
_l = (_p+1)-c; _l = (_p+1)-c;
if (_l < sizeof(_format)-2) { if (_l < sizeof(_format)-2) {
memcpy(_format,c,_l); memcpy(_format,c,_l);
_format[_l] = '\0'; _format[_l] = '\0';
va_copy(_cpy,ap);
newarg = sdscatvprintf(curarg,_format,_cpy); newarg = sdscatvprintf(curarg,_format,_cpy);
va_end(_cpy);
/* Update current position (note: outer blocks /* Update current position (note: outer blocks
* increment c twice so compensate here) */ * increment c twice so compensate here) */
c = _p-1; c = _p-1;
} }
}
/* Consume and discard vararg */ va_end(_cpy);
va_arg(ap,void); break;
} }
} }