]> granicus.if.org Git - procps-ng/commitdiff
library: make that 'escape_str' private to our library
authorJim Warner <james.warner@comcast.net>
Tue, 30 Jun 2020 05:00:00 +0000 (00:00 -0500)
committerCraig Small <csmall@dropbear.xyz>
Sun, 5 Jul 2020 11:13:01 +0000 (21:13 +1000)
In that commit referenced below, a promise was made to
revisit an 'escape_str' function in efforts to make it
private to the library. The problem was it's needed by
both ps plus the library which is why it was exported.

So, in an effort to remove it from libprocps.sym, this
patch duplicates all the required code in ps/output.c.
Now, each version can be made private to their caller.

[ along the way we'll use this opportunity to remove ]
[ the 'restrict' qualifiers from function parameters ]
[ while swatting a compiler warning referenced below ]

Reference(s):
. April 2016, most escape functions made private
commit d916d5db86cbbf552401026aab15c3663412d662

proc/escape.c: In function `escape_command':
proc/escape.c:182:23: warning: initialization of `const char **' from incompatible pointer type `char **' [-Wincompatible-pointer-types]
  182 |     const char **lc = (char**)pp->cmdline;
      |                       ^

Signed-off-by: Jim Warner <james.warner@comcast.net>
Makefile.am
proc/escape.c
proc/escape.h
proc/libprocps.sym
ps/common.h
ps/output.c

index 3c21658ec576aad1375973ba36f4b3f52fab4921..e49dc10fbe9b7eb66d13a4fb1652f881a3ce80e0 100644 (file)
@@ -276,7 +276,6 @@ proc_libprocps_la_includedir = $(includedir)/procps/
 proc_libprocps_la_include_HEADERS = \
        proc/devname.h \
        proc/diskstats.h \
-       proc/escape.h \
        proc/meminfo.h \
        proc/namespace.h \
        proc/numa.h \
index 9546ed77557dfa57779d96279c8f51ad2a8bd98d..8d3584034ec068e87336bdeaccba532109747189 100644 (file)
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
  */
 
+#include <ctype.h>
+#include <langinfo.h>
 #include <limits.h>
 #include <stdio.h>
-#include <sys/types.h>
+#include <stdlib.h>  /* MB_CUR_MAX */
 #include <string.h>
+#include <wchar.h>
+#include <wctype.h>
+#include <sys/types.h>
 
 #include "escape.h"
 #include "readproc.h"
 
-#if (__GNU_LIBRARY__ >= 6) && (!defined(__UCLIBC__) || defined(__UCLIBC_HAS_WCHAR__))
-# include <wchar.h>
-# include <wctype.h>
-# include <stdlib.h>  /* MB_CUR_MAX */
-# include <ctype.h>
-# include <langinfo.h>
-#endif
 
 #define SECURE_ESCAPE_ARGS(dst, bytes, cells) do { \
   if ((bytes) <= 0) return 0; \
@@ -42,8 +40,7 @@
 } while (0)
 
 
-#if (__GNU_LIBRARY__ >= 6) && (!defined(__UCLIBC__) || defined(__UCLIBC_HAS_WCHAR__))
-static int escape_str_utf8(char *restrict dst, const char *restrict src, int bufsize, int *maxcells){
+static int escape_str_utf8 (char *dst, const char *src, int bufsize, int *maxcells) {
   int my_cells = 0;
   int my_bytes = 0;
   mbstate_t s;
@@ -107,10 +104,9 @@ static int escape_str_utf8(char *restrict dst, const char *restrict src, int buf
   return my_bytes;        // bytes of text, excluding the NUL
 }
 
-#endif /* __GNU_LIBRARY__  */
 
 /* sanitize a string via one-way mangle */
-int escape_str(char *restrict dst, const char *restrict src, int bufsize, int *maxcells){
+int escape_str (char *dst, const char *src, int bufsize, int *maxcells) {
   unsigned char c;
   int my_cells = 0;
   int my_bytes = 0;
@@ -124,7 +120,6 @@ int escape_str(char *restrict dst, const char *restrict src, int bufsize, int *m
   "????????????????????????????????"
   "????????????????????????????????";
 
-#if (__GNU_LIBRARY__ >= 6) && (!defined(__UCLIBC__) || defined(__UCLIBC_HAS_WCHAR__))
   static int utf_init=0;
 
   if(utf_init==0){
@@ -136,7 +131,6 @@ int escape_str(char *restrict dst, const char *restrict src, int bufsize, int *m
      /* UTF8 locales */
      return escape_str_utf8(dst, src, bufsize, maxcells);
   }
-#endif
 
   SECURE_ESCAPE_ARGS(dst, bufsize, *maxcells);
 
@@ -163,7 +157,7 @@ int escape_str(char *restrict dst, const char *restrict src, int bufsize, int *m
 // escape an argv or environment string array
 //
 // bytes arg means sizeof(buf)
-static int escape_strlist(char *restrict dst, char *restrict const *restrict src, size_t bytes, int *cells){
+static int escape_strlist (char *dst, const char **src, size_t bytes, int *cells) {
   size_t i = 0;
 
   for(;;){
@@ -180,12 +174,12 @@ static int escape_strlist(char *restrict dst, char *restrict const *restrict src
 
 ///////////////////////////////////////////////////
 
-int escape_command(char *restrict const outbuf, const proc_t *restrict const pp, int bytes, int *cells, unsigned flags){
+int escape_command (char *const outbuf, const proc_t *pp, int bytes, int *cells, unsigned flags) {
   int overhead = 0;
   int end = 0;
 
   if(flags & ESC_ARGS){
-    char **lc = (char**)pp->cmdline;
+    const char **lc = (const char**)pp->cmdline;
     if(lc && *lc) return escape_strlist(outbuf, lc, bytes, cells);
   }
   if(flags & ESC_BRACKETS){
@@ -217,4 +211,3 @@ int escape_command(char *restrict const outbuf, const proc_t *restrict const pp,
   outbuf[end] = '\0';
   return end;  // bytes, not including the NUL
 }
-
index 75e830bffd713ebbdc1d6839b3b591f2ec554100..684eba1de2c6ab7a585cd0472d47ecc0f07f49f1 100644 (file)
@@ -3,14 +3,12 @@
 
 #include "readproc.h"
 
-
 #define ESC_ARGS     0x1  // try to use cmdline instead of cmd
 #define ESC_BRACKETS 0x2  // if using cmd, put '[' and ']' around it
 #define ESC_DEFUNCT  0x4  // mark zombies with " <defunct>"
 
-int escape_command(char *__restrict const outbuf, const proc_t *__restrict const pp, int bytes, int *cells, unsigned flags);
+int escape_command (char *outbuf, const proc_t *pp, int bytes, int *cells, unsigned flags);
 
-#define ESC_STRETCH 1  // since we mangle to '?' this is 1 (would be 4 for octal escapes)
-int escape_str(char *__restrict dst, const char *__restrict src, int bufsize, int *maxcells);
+int escape_str (char *dst, const char *src, int bufsize, int *maxcells);
 
 #endif
index 8853048de843fa7538fa47cde5ff15cb63e3d331..9cdbd24842093dd1ca5e013240bae12790c3ede7 100644 (file)
@@ -1,6 +1,5 @@
 LIBPROCPS_0 {
 global:
-       escape_str;
        fatal_proc_unmounted;
        procps_cpu_count;
        procps_diskstats_new;
index 097b89d2dcaf9bb71bf92eb798b2052093fd2994..9511c32c371a595d516e1c1e9de484c0671d8e24 100644 (file)
@@ -13,7 +13,6 @@
 #define PROCPS_PS_H
 
 #include "../include/nls.h"
-#include <proc/escape.h>
 #include <proc/meminfo.h>
 #include <proc/pids.h>
 #include <proc/stat.h>
@@ -204,7 +203,6 @@ makEXT(noop)
  * Try not to overflow the output buffer:
  *    32 pages for env+cmd
  *    64 kB pages on IA-64
- *    4 chars for "\377", or 1 when mangling to '?'  (ESC_STRETCH)
  *    plus some slack for other stuff
  * That is about 8.5 MB on IA-64, or 0.6 MB on i386
  *
@@ -214,7 +212,7 @@ makEXT(noop)
  */
 
 /* output buffer size */
-#define OUTBUF_SIZE (2 * 64*1024 * ESC_STRETCH)
+#define OUTBUF_SIZE (2 * 64*1024)
 
 /******************* PS DEFINE *******************/
 
index b5945924c4f70a9546012f6f97c0aa615d711613..20f9a5340dff486d7e00125a30e9e201ada94459 100644 (file)
 #if ENABLE_LIBSELINUX
 #include <dlfcn.h>
 #endif
+#include <ctype.h>
 #include <fcntl.h>
 #include <grp.h>
+#include <langinfo.h>
 #include <limits.h>
 #include <pwd.h>
 #include <stdio.h>
 #include <string.h>
 #include <time.h>
 #include <unistd.h>
+#include <wchar.h>
+#include <wctype.h>
 
 #include <sys/ioctl.h>
 #include <sys/mman.h>
 #include <sys/resource.h>
 #include <sys/types.h>
 
-
 #include "../include/c.h"
 
 #include "common.h"
@@ -79,7 +82,6 @@ static unsigned max_rightward = OUTBUF_SIZE-1; /* space for RIGHT stuff */
 static unsigned max_leftward = OUTBUF_SIZE-1; /* space for LEFT stuff */
 
 
-
 static int wide_signals;  /* true if we have room */
 
 static time_t seconds_since_1970;
@@ -135,6 +137,117 @@ static int escaped_copy(char *restrict dst, const char *restrict src, int bufsiz
     return n;
 }
 
+// duplicated from proc/escape.c so both can be made private
+static int escape_str_utf8 (char *dst, const char *src, int bufsize, int *maxcells) {
+  int my_cells = 0;
+  int my_bytes = 0;
+  mbstate_t s;
+
+  SECURE_ESCAPE_ARGS(dst, bufsize, *maxcells);
+
+  memset(&s, 0, sizeof (s));
+
+  for(;;) {
+    wchar_t wc;
+    int len = 0;
+
+    if(my_cells >= *maxcells || my_bytes+1 >= bufsize)
+      break;
+
+    if (!(len = mbrtowc (&wc, src, MB_CUR_MAX, &s)))
+      /* 'str' contains \0 */
+      break;
+
+    if (len < 0) {
+      /* invalid multibyte sequence -- zeroize state */
+      memset (&s, 0, sizeof (s));
+      *(dst++) = '?';
+      src++;
+      my_cells++;
+      my_bytes++;
+
+    } else if (len==1) {
+      /* non-multibyte */
+      *(dst++) = isprint(*src) ? *src : '?';
+      src++;
+      my_cells++;
+      my_bytes++;
+
+    } else if (!iswprint(wc)) {
+      /* multibyte - no printable */
+      *(dst++) = '?';
+      src+=len;
+      my_cells++;
+      my_bytes++;
+
+    } else {
+      /* multibyte - maybe, kinda "printable" */
+      int wlen = wcwidth(wc);
+      // Got space?
+      if (wlen > *maxcells-my_cells || len >= bufsize-(my_bytes+1)) break;
+      // safe multibyte
+      memcpy(dst, src, len);
+      dst += len;
+      src += len;
+      my_bytes += len;
+      if (wlen > 0) my_cells += wlen;
+    }
+    //fprintf(stdout, "cells: %d\n", my_cells);
+  }
+  *dst = '\0';
+
+  // fprintf(stderr, "maxcells: %d, my_cells; %d\n", *maxcells, my_cells);
+
+  *maxcells -= my_cells;
+  return my_bytes;        // bytes of text, excluding the NUL
+}
+
+// duplicated from proc/escape.c so both can be made private
+static int escape_str (char *dst, const char *src, int bufsize, int *maxcells) {
+  unsigned char c;
+  int my_cells = 0;
+  int my_bytes = 0;
+  const char codes[] =
+  "Z..............................."
+  "||||||||||||||||||||||||||||||||"
+  "||||||||||||||||||||||||||||||||"
+  "|||||||||||||||||||||||||||||||."
+  "????????????????????????????????"
+  "????????????????????????????????"
+  "????????????????????????????????"
+  "????????????????????????????????";
+  static int utf_init=0;
+
+  if(utf_init==0){
+     /* first call -- check if UTF stuff is usable */
+     char *enc = nl_langinfo(CODESET);
+     utf_init = enc && strcasecmp(enc, "UTF-8")==0 ? 1 : -1;
+  }
+  if (utf_init==1 && MB_CUR_MAX>1) {
+     /* UTF8 locales */
+     return escape_str_utf8(dst, src, bufsize, maxcells);
+  }
+
+  SECURE_ESCAPE_ARGS(dst, bufsize, *maxcells);
+
+  if(bufsize > *maxcells+1) bufsize=*maxcells+1; // FIXME: assumes 8-bit locale
+
+  for(;;){
+    if(my_cells >= *maxcells || my_bytes+1 >= bufsize)
+      break;
+    c = (unsigned char) *(src++);
+    if(!c) break;
+    if(codes[c]!='|') c=codes[c];
+    my_cells++;
+    my_bytes++;
+    *(dst++) = c;
+  }
+  *dst = '\0';
+
+  *maxcells -= my_cells;
+  return my_bytes;        // bytes of text, excluding the NUL
+}
+
 /***************************************************************************/
 /************ Lots of format functions, starting with the NOP **************/