restructure xvasprintf() for uniformity

%\\s now supports length limitations, and \\ on other format specifiers
is now ignored (like .* already was on non-strings).
This commit is contained in:
Oswald Buddenhagen 2022-05-03 15:57:23 +02:00
parent 1a89f8a178
commit 57173bd289

View File

@ -225,56 +225,55 @@ xvasprintf( const char *fmt, va_list ap )
break; break;
uint maxlen = UINT_MAX; uint maxlen = UINT_MAX;
c = *++fmt; c = *++fmt;
if (c == '\\') { if (c == '.') {
c = *++fmt; c = *++fmt;
if (c != 's') { if (c != '*') {
fputs( "Fatal: unsupported escaped format specifier. Please report a bug.\n", stderr ); fputs( "Fatal: unsupported string length specification. Please report a bug.\n", stderr );
abort(); abort();
} }
char *bd = d; maxlen = va_arg( ap, uint );
c = *++fmt;
}
int escaped = 0;
if (c == '\\') {
escaped = 1;
c = *++fmt;
}
if (c == 'c') {
if (d + 1 > ed)
oob();
ADD_SEG( d, 1 );
*d++ = (char)va_arg( ap, int );
} else if (c == 's') {
s = va_arg( ap, const char * ); s = va_arg( ap, const char * );
while ((c = *s++)) { if (escaped) {
if (d + 2 > ed) char *bd = d;
oob(); for (l = 0; l < maxlen && (c = *s); l++, s++) {
if (c == '\\' || c == '"') if (d + 2 > ed)
*d++ = '\\'; oob();
*d++ = c; if (c == '\\' || c == '"')
} *d++ = '\\';
l = d - bd; *d++ = c;
if (l)
ADD_SEG( bd, l );
} else { // \\ cannot be combined with anything else.
if (c == '.') {
c = *++fmt;
if (c != '*') {
fputs( "Fatal: unsupported string length specification. Please report a bug.\n", stderr );
abort();
} }
maxlen = va_arg( ap, uint ); l = d - bd;
c = *++fmt; if (l)
} ADD_SEG( bd, l );
if (c == 'c') { } else {
if (d + 1 > ed)
oob();
ADD_SEG( d, 1 );
*d++ = (char)va_arg( ap, int );
} else if (c == 's') {
s = va_arg( ap, const char * );
l = strnlen( s, maxlen ); l = strnlen( s, maxlen );
if (l) if (l)
ADD_SEG( s, l ); ADD_SEG( s, l );
} else if (c == 'd') {
l = nfsnprintf( d, ed - d, "%d", va_arg( ap, int ) );
ADD_SEG( d, l );
d += l;
} else if (c == 'u') {
l = nfsnprintf( d, ed - d, "%u", va_arg( ap, uint ) );
ADD_SEG( d, l );
d += l;
} else {
fputs( "Fatal: unsupported format specifier. Please report a bug.\n", stderr );
abort();
} }
} else if (c == 'd') {
l = nfsnprintf( d, ed - d, "%d", va_arg( ap, int ) );
ADD_SEG( d, l );
d += l;
} else if (c == 'u') {
l = nfsnprintf( d, ed - d, "%u", va_arg( ap, uint ) );
ADD_SEG( d, l );
d += l;
} else {
fputs( "Fatal: unsupported format specifier. Please report a bug.\n", stderr );
abort();
} }
s = ++fmt; s = ++fmt;
} else { } else {