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:
parent
1a89f8a178
commit
57173bd289
39
src/util.c
39
src/util.c
|
@ -225,25 +225,6 @@ xvasprintf( const char *fmt, va_list ap )
|
||||||
break;
|
break;
|
||||||
uint maxlen = UINT_MAX;
|
uint maxlen = UINT_MAX;
|
||||||
c = *++fmt;
|
c = *++fmt;
|
||||||
if (c == '\\') {
|
|
||||||
c = *++fmt;
|
|
||||||
if (c != 's') {
|
|
||||||
fputs( "Fatal: unsupported escaped format specifier. Please report a bug.\n", stderr );
|
|
||||||
abort();
|
|
||||||
}
|
|
||||||
char *bd = d;
|
|
||||||
s = va_arg( ap, const char * );
|
|
||||||
while ((c = *s++)) {
|
|
||||||
if (d + 2 > ed)
|
|
||||||
oob();
|
|
||||||
if (c == '\\' || c == '"')
|
|
||||||
*d++ = '\\';
|
|
||||||
*d++ = c;
|
|
||||||
}
|
|
||||||
l = d - bd;
|
|
||||||
if (l)
|
|
||||||
ADD_SEG( bd, l );
|
|
||||||
} else { // \\ cannot be combined with anything else.
|
|
||||||
if (c == '.') {
|
if (c == '.') {
|
||||||
c = *++fmt;
|
c = *++fmt;
|
||||||
if (c != '*') {
|
if (c != '*') {
|
||||||
|
@ -253,6 +234,11 @@ xvasprintf( const char *fmt, va_list ap )
|
||||||
maxlen = va_arg( ap, uint );
|
maxlen = va_arg( ap, uint );
|
||||||
c = *++fmt;
|
c = *++fmt;
|
||||||
}
|
}
|
||||||
|
int escaped = 0;
|
||||||
|
if (c == '\\') {
|
||||||
|
escaped = 1;
|
||||||
|
c = *++fmt;
|
||||||
|
}
|
||||||
if (c == 'c') {
|
if (c == 'c') {
|
||||||
if (d + 1 > ed)
|
if (d + 1 > ed)
|
||||||
oob();
|
oob();
|
||||||
|
@ -260,9 +246,23 @@ xvasprintf( const char *fmt, va_list ap )
|
||||||
*d++ = (char)va_arg( ap, int );
|
*d++ = (char)va_arg( ap, int );
|
||||||
} else if (c == 's') {
|
} else if (c == 's') {
|
||||||
s = va_arg( ap, const char * );
|
s = va_arg( ap, const char * );
|
||||||
|
if (escaped) {
|
||||||
|
char *bd = d;
|
||||||
|
for (l = 0; l < maxlen && (c = *s); l++, s++) {
|
||||||
|
if (d + 2 > ed)
|
||||||
|
oob();
|
||||||
|
if (c == '\\' || c == '"')
|
||||||
|
*d++ = '\\';
|
||||||
|
*d++ = c;
|
||||||
|
}
|
||||||
|
l = d - bd;
|
||||||
|
if (l)
|
||||||
|
ADD_SEG( bd, l );
|
||||||
|
} else {
|
||||||
l = strnlen( s, maxlen );
|
l = strnlen( s, maxlen );
|
||||||
if (l)
|
if (l)
|
||||||
ADD_SEG( s, l );
|
ADD_SEG( s, l );
|
||||||
|
}
|
||||||
} else if (c == 'd') {
|
} else if (c == 'd') {
|
||||||
l = nfsnprintf( d, ed - d, "%d", va_arg( ap, int ) );
|
l = nfsnprintf( d, ed - d, "%d", va_arg( ap, int ) );
|
||||||
ADD_SEG( d, l );
|
ADD_SEG( d, l );
|
||||||
|
@ -275,7 +275,6 @@ xvasprintf( const char *fmt, va_list ap )
|
||||||
fputs( "Fatal: unsupported format specifier. Please report a bug.\n", stderr );
|
fputs( "Fatal: unsupported format specifier. Please report a bug.\n", stderr );
|
||||||
abort();
|
abort();
|
||||||
}
|
}
|
||||||
}
|
|
||||||
s = ++fmt;
|
s = ++fmt;
|
||||||
} else {
|
} else {
|
||||||
fmt++;
|
fmt++;
|
||||||
|
|
Loading…
Reference in New Issue
Block a user