Use correct type when calling va_arg in formatter
This commit is contained in:
parent
4ac55be9b5
commit
27c96dde77
90
hiredis.c
90
hiredis.c
@ -770,33 +770,81 @@ int redisvFormatCommand(char **target, const char *format, va_list ap) {
|
||||
while (*_p != '\0' && isdigit(*_p)) _p++;
|
||||
}
|
||||
|
||||
/* Modifiers */
|
||||
if (*_p != '\0') {
|
||||
if (*_p == 'h' || *_p == 'l') {
|
||||
/* Allow a single repetition for these modifiers */
|
||||
if (_p[0] == _p[1]) _p++;
|
||||
_p++;
|
||||
}
|
||||
/* Copy va_list before consuming with va_arg */
|
||||
va_copy(_cpy,ap);
|
||||
|
||||
/* Integer conversion (without modifiers) */
|
||||
if (strchr("diouxX",*_p) != NULL) {
|
||||
va_arg(ap,int);
|
||||
goto fmt_valid;
|
||||
}
|
||||
|
||||
/* Conversion specifier */
|
||||
if (*_p != '\0' && strchr("diouxXeEfFgGaA",*_p) != NULL) {
|
||||
_l = (_p+1)-c;
|
||||
if (_l < sizeof(_format)-2) {
|
||||
memcpy(_format,c,_l);
|
||||
_format[_l] = '\0';
|
||||
va_copy(_cpy,ap);
|
||||
newarg = sdscatvprintf(curarg,_format,_cpy);
|
||||
va_end(_cpy);
|
||||
|
||||
/* Update current position (note: outer blocks
|
||||
* increment c twice so compensate here) */
|
||||
c = _p-1;
|
||||
}
|
||||
/* Double conversion (without modifiers) */
|
||||
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;
|
||||
if (_l < sizeof(_format)-2) {
|
||||
memcpy(_format,c,_l);
|
||||
_format[_l] = '\0';
|
||||
newarg = sdscatvprintf(curarg,_format,_cpy);
|
||||
|
||||
/* Update current position (note: outer blocks
|
||||
* increment c twice so compensate here) */
|
||||
c = _p-1;
|
||||
}
|
||||
|
||||
va_end(_cpy);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user