From eea5626bb144328eb60e9ea8a29bd5b1f100ecd9 Mon Sep 17 00:00:00 2001 From: Jim Warner Date: Sat, 26 Dec 2020 00:00:00 -0600 Subject: [PATCH] library: help ensure 'escape_str' isn't executed twice Now that the ps program is using 'escape_str' for most of the library's returned strings, this patch tries to lessen the prospects of executing that function twice. Our newlib branch has achieved such a goal through the elimination of nearly all escape.c code. However, here we avoid API change by trading some 'escape_str' calls (with wide character overhead) for a slightly extended 'escaped_copy' call (which incurs no multibyte costs). Note: until we migrate to the newlib version, there is a remaining call to 'escape_str' which we can't avoid. Such code involves the 'escape_command' function call. [ As we prepare for this new (final?) release, there ] [ were already internal library changes that require ] [ a new 'revision'. This patch won't impact the API! ] Signed-off-by: Jim Warner --- proc/escape.c | 10 ++++++++-- proc/readproc.c | 6 +++--- 2 files changed, 11 insertions(+), 5 deletions(-) diff --git a/proc/escape.c b/proc/escape.c index 62131d12..880dfd95 100644 --- a/proc/escape.c +++ b/proc/escape.c @@ -222,10 +222,10 @@ int escape_command(char *restrict const outbuf, const proc_t *restrict const pp, ///////////////////////////////////////////////// -// copy an already 'escaped' string, +// copy a string, but 'escape' any control characters // using the traditional escape.h calling conventions int escaped_copy(char *restrict dst, const char *restrict src, int bufsize, int *maxroom){ - int n; + int i, n; SECURE_ESCAPE_ARGS(dst, bufsize, *maxroom); if (bufsize > *maxroom+1) bufsize = *maxroom+1; @@ -236,6 +236,12 @@ int escaped_copy(char *restrict dst, const char *restrict src, int bufsize, int return 0; } if (n >= bufsize) n = bufsize-1; + + // control chars, especially tabs, create alignment problems for ps & top ... + for (i = 0; i < n; i++) + if ((unsigned char)dst[i] < 0x20 || dst[i] == 0x7f) + dst[i] = '?'; + *maxroom -= n; return n; } diff --git a/proc/readproc.c b/proc/readproc.c index 1c503a50..84ad9af2 100644 --- a/proc/readproc.c +++ b/proc/readproc.c @@ -844,7 +844,7 @@ static void fill_cgroup_cvt (const char* directory, proc_t *restrict p) { len = snprintf(dst, vMAX, "%s", (dst > dst_buffer) ? "," : ""); if (len < 0 || len >= vMAX) break; dst += len; - dst += escape_str(dst, grp, vMAX, &whackable_int); + dst += escaped_copy(dst, grp, vMAX, &whackable_int); } p->cgroup = vectorize_this_str(dst_buffer[0] ? dst_buffer : "-"); @@ -862,7 +862,7 @@ static void fill_cmdline_cvt (const char* directory, proc_t *restrict p) { int whackable_int = MAX_BUFSZ; if (read_unvectored(src_buffer, MAX_BUFSZ, directory, "cmdline", ' ')) - escape_str(dst_buffer, src_buffer, MAX_BUFSZ, &whackable_int); + escaped_copy(dst_buffer, src_buffer, MAX_BUFSZ, &whackable_int); else escape_command(dst_buffer, p, MAX_BUFSZ, &whackable_int, uFLG); p->cmdline = vectorize_this_str(dst_buffer); @@ -876,7 +876,7 @@ static void fill_environ_cvt (const char* directory, proc_t *restrict p) { dst_buffer[0] = '\0'; if (read_unvectored(src_buffer, MAX_BUFSZ, directory, "environ", ' ')) - escape_str(dst_buffer, src_buffer, MAX_BUFSZ, &whackable_int); + escaped_copy(dst_buffer, src_buffer, MAX_BUFSZ, &whackable_int); p->environ = vectorize_this_str(dst_buffer[0] ? dst_buffer : "-"); }