diff options
author | Paul Eggert <eggert@cs.ucla.edu> | 2022-12-18 19:01:10 -0800 |
---|---|---|
committer | Paul Eggert <eggert@cs.ucla.edu> | 2022-12-19 12:33:57 -0800 |
commit | 03488eeea9cef99e2fa6c29d43b4befcc3e6ce40 (patch) | |
tree | 38f1a4047055a41fd4a98ffff45b13966b67b962 | |
parent | 2aa368b97046554c5841ef69d05458854a753252 (diff) | |
download | sed-03488eeea9cef99e2fa6c29d43b4befcc3e6ce40.tar.gz |
sed: do octal escapes ourselves
* sed/execute.c (do_list): Simplify by doing octal escapes
by hand (!) instead of having sprintf do it. This makes it
easier for compilers and humans see that buffer overflow
is impossible. And it’s quite a bit faster if the input
consists mostly of odd control bytes.
-rw-r--r-- | sed/execute.c | 13 |
1 files changed, 6 insertions, 7 deletions
diff --git a/sed/execute.c b/sed/execute.c index 485bca7..529ae47 100644 --- a/sed/execute.c +++ b/sed/execute.c @@ -905,14 +905,12 @@ do_list (int line_len) unsigned char *p = (unsigned char *)line.active; countT len = line.length; countT width = 0; - char obuf[180]; /* just in case we encounter a 512-bit char (;-) */ - char *o; - size_t olen; FILE *fp = output_file.fp; output_missing_newline (&output_file); for (; len--; ++p) { - o = obuf; + char obuf[sizeof "\\377" - 1]; + char *o = obuf; /* Some locales define 8-bit characters as printable. This makes the testsuite fail at 8to7.sed because the `l' command in fact will not @@ -940,12 +938,13 @@ do_list (int line_len) case '\t': *o++ = 't'; break; case '\v': *o++ = 'v'; break; default: - sprintf (o, "%03o", *p); - o += strlen (o); + *o++ = '0' + ((*p & 0300) >> 6); + *o++ = '0' + ((*p & 0070) >> 3); + *o++ = '0' + ((*p & 0007) >> 0); break; } } - olen = o - obuf; + size_t olen = o - obuf; if (width+olen >= line_len && line_len > 0) { ck_fwrite ("\\", 1, 1, fp); ck_fwrite (&buffer_delimiter, 1, 1, fp); |