add escaping of non-printable & non-ASCII characters to xvasprintf()
This commit is contained in:
parent
57173bd289
commit
0079ec774a
44
src/util.c
44
src/util.c
|
@ -189,6 +189,10 @@ sys_error( const char *msg, ... )
|
|||
// Print backslash-escaped string literals. Note that this does not
|
||||
// automatically add quotes around the printed string, so it is
|
||||
// possible to concatenate multiple segments.
|
||||
// - %!s
|
||||
// Same as %\\s, but non-ASCII characters are (hex-)escaped as well.
|
||||
// - %!&s
|
||||
// Same as %!s, but linefeeds are also printed verbatim for legibility.
|
||||
|
||||
// TODO: Trade off segments vs. buffer capacity dynamically.
|
||||
#define QPRINTF_SEGS 16
|
||||
|
@ -238,6 +242,13 @@ xvasprintf( const char *fmt, va_list ap )
|
|||
if (c == '\\') {
|
||||
escaped = 1;
|
||||
c = *++fmt;
|
||||
} else if (c == '!') {
|
||||
escaped = 2;
|
||||
c = *++fmt;
|
||||
if (c == '&') {
|
||||
escaped = 3;
|
||||
c = *++fmt;
|
||||
}
|
||||
}
|
||||
if (c == 'c') {
|
||||
if (d + 1 > ed)
|
||||
|
@ -249,10 +260,39 @@ xvasprintf( const char *fmt, va_list ap )
|
|||
if (escaped) {
|
||||
char *bd = d;
|
||||
for (l = 0; l < maxlen && (c = *s); l++, s++) {
|
||||
if (d + 2 > ed)
|
||||
if (c == '\\' || c == '"') {
|
||||
if (d >= ed)
|
||||
oob();
|
||||
if (c == '\\' || c == '"')
|
||||
*d++ = '\\';
|
||||
} else if (escaped >= 2 && (c < 32 || c > 126)) {
|
||||
switch (c) {
|
||||
case '\r': c = 'r'; break;
|
||||
case '\t': c = 't'; break;
|
||||
case '\a': c = 'a'; break;
|
||||
case '\b': c = 'b'; break;
|
||||
case '\v': c = 'v'; break;
|
||||
case '\f': c = 'f'; break;
|
||||
case '\n':
|
||||
if (escaped == 2) {
|
||||
c = 'n';
|
||||
break;
|
||||
}
|
||||
if (d + 2 >= ed)
|
||||
oob();
|
||||
*d++ = '\\';
|
||||
*d++ = 'n';
|
||||
*d++ = c; // Keep the actual line break for legibility.
|
||||
continue;
|
||||
default:
|
||||
d += nfsnprintf( d, ed - d, "\\x%02x", (uchar)c );
|
||||
continue;
|
||||
}
|
||||
if (d >= ed)
|
||||
oob();
|
||||
*d++ = '\\';
|
||||
}
|
||||
if (d >= ed)
|
||||
oob();
|
||||
*d++ = c;
|
||||
}
|
||||
l = d - bd;
|
||||
|
|
Loading…
Reference in New Issue
Block a user