isync

mailbox synchronization program
git clone https://git.code.sf.net/p/isync/isync
Log | Files | Refs | README | LICENSE

commit 0079ec774a6e79b417a1f2daa1220d1c5df6e5b8
parent 57173bd289b370eeac8982bd2410144c3c1f87c3
Author: Oswald Buddenhagen <ossi@users.sf.net>
Date:   Tue,  3 May 2022 19:28:26 +0200

add escaping of non-printable & non-ASCII characters to xvasprintf()

Diffstat:
Msrc/util.c | 46+++++++++++++++++++++++++++++++++++++++++++---
1 file changed, 43 insertions(+), 3 deletions(-)

diff --git a/src/util.c b/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) - oob(); - if (c == '\\' || c == '"') + if (c == '\\' || c == '"') { + if (d >= ed) + oob(); *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;