]> granicus.if.org Git - procps-ng/commitdiff
library: help ensure 'escape_str' isn't executed twice
authorJim Warner <james.warner@comcast.net>
Sat, 26 Dec 2020 06:00:00 +0000 (00:00 -0600)
committerCraig Small <csmall@dropbear.xyz>
Mon, 28 Dec 2020 21:42:28 +0000 (08:42 +1100)
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 <james.warner@comcast.net>
proc/escape.c
proc/readproc.c

index 62131d12f4c2734292a9f7a478d1b431f2556da3..880dfd959d30ad0d130021f9946a884435d8daf8 100644 (file)
@@ -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;
 }
index 1c503a50d4971992e920d11dc9cc3156c14b15f0..84ad9af2cfc2419d698ae4d136752d8e2b8a86cc 100644 (file)
@@ -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 : "-");
 }