library: make that 'escape_str' private to our library

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 d916d5db86

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>
This commit is contained in:
Jim Warner 2020-06-30 00:00:00 -05:00 committed by Craig Small
parent 1aa8b16441
commit 605ea4a8f7
6 changed files with 129 additions and 29 deletions

View File

@ -276,7 +276,6 @@ proc_libprocps_la_includedir = $(includedir)/procps/
proc_libprocps_la_include_HEADERS = \ proc_libprocps_la_include_HEADERS = \
proc/devname.h \ proc/devname.h \
proc/diskstats.h \ proc/diskstats.h \
proc/escape.h \
proc/meminfo.h \ proc/meminfo.h \
proc/namespace.h \ proc/namespace.h \
proc/numa.h \ proc/numa.h \

View File

@ -17,21 +17,19 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/ */
#include <ctype.h>
#include <langinfo.h>
#include <limits.h> #include <limits.h>
#include <stdio.h> #include <stdio.h>
#include <sys/types.h> #include <stdlib.h> /* MB_CUR_MAX */
#include <string.h> #include <string.h>
#include <wchar.h>
#include <wctype.h>
#include <sys/types.h>
#include "escape.h" #include "escape.h"
#include "readproc.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 { \ #define SECURE_ESCAPE_ARGS(dst, bytes, cells) do { \
if ((bytes) <= 0) return 0; \ if ((bytes) <= 0) return 0; \
@ -42,8 +40,7 @@
} while (0) } while (0)
#if (__GNU_LIBRARY__ >= 6) && (!defined(__UCLIBC__) || defined(__UCLIBC_HAS_WCHAR__)) static int escape_str_utf8 (char *dst, const char *src, int bufsize, int *maxcells) {
static int escape_str_utf8(char *restrict dst, const char *restrict src, int bufsize, int *maxcells){
int my_cells = 0; int my_cells = 0;
int my_bytes = 0; int my_bytes = 0;
mbstate_t s; 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 return my_bytes; // bytes of text, excluding the NUL
} }
#endif /* __GNU_LIBRARY__ */
/* sanitize a string via one-way mangle */ /* 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; unsigned char c;
int my_cells = 0; int my_cells = 0;
int my_bytes = 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; static int utf_init=0;
if(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 */ /* UTF8 locales */
return escape_str_utf8(dst, src, bufsize, maxcells); return escape_str_utf8(dst, src, bufsize, maxcells);
} }
#endif
SECURE_ESCAPE_ARGS(dst, bufsize, *maxcells); 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 // escape an argv or environment string array
// //
// bytes arg means sizeof(buf) // 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; size_t i = 0;
for(;;){ 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 overhead = 0;
int end = 0; int end = 0;
if(flags & ESC_ARGS){ 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(lc && *lc) return escape_strlist(outbuf, lc, bytes, cells);
} }
if(flags & ESC_BRACKETS){ if(flags & ESC_BRACKETS){
@ -217,4 +211,3 @@ int escape_command(char *restrict const outbuf, const proc_t *restrict const pp,
outbuf[end] = '\0'; outbuf[end] = '\0';
return end; // bytes, not including the NUL return end; // bytes, not including the NUL
} }

View File

@ -3,14 +3,12 @@
#include "readproc.h" #include "readproc.h"
#define ESC_ARGS 0x1 // try to use cmdline instead of cmd #define ESC_ARGS 0x1 // try to use cmdline instead of cmd
#define ESC_BRACKETS 0x2 // if using cmd, put '[' and ']' around it #define ESC_BRACKETS 0x2 // if using cmd, put '[' and ']' around it
#define ESC_DEFUNCT 0x4 // mark zombies with " <defunct>" #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 *dst, const char *src, int bufsize, int *maxcells);
int escape_str(char *__restrict dst, const char *__restrict src, int bufsize, int *maxcells);
#endif #endif

View File

@ -1,6 +1,5 @@
LIBPROCPS_0 { LIBPROCPS_0 {
global: global:
escape_str;
fatal_proc_unmounted; fatal_proc_unmounted;
procps_cpu_count; procps_cpu_count;
procps_diskstats_new; procps_diskstats_new;

View File

@ -13,7 +13,6 @@
#define PROCPS_PS_H #define PROCPS_PS_H
#include "../include/nls.h" #include "../include/nls.h"
#include <proc/escape.h>
#include <proc/meminfo.h> #include <proc/meminfo.h>
#include <proc/pids.h> #include <proc/pids.h>
#include <proc/stat.h> #include <proc/stat.h>
@ -204,7 +203,6 @@ makEXT(noop)
* Try not to overflow the output buffer: * Try not to overflow the output buffer:
* 32 pages for env+cmd * 32 pages for env+cmd
* 64 kB pages on IA-64 * 64 kB pages on IA-64
* 4 chars for "\377", or 1 when mangling to '?' (ESC_STRETCH)
* plus some slack for other stuff * plus some slack for other stuff
* That is about 8.5 MB on IA-64, or 0.6 MB on i386 * That is about 8.5 MB on IA-64, or 0.6 MB on i386
* *
@ -214,7 +212,7 @@ makEXT(noop)
*/ */
/* output buffer size */ /* output buffer size */
#define OUTBUF_SIZE (2 * 64*1024 * ESC_STRETCH) #define OUTBUF_SIZE (2 * 64*1024)
/******************* PS DEFINE *******************/ /******************* PS DEFINE *******************/

View File

@ -49,8 +49,10 @@
#if ENABLE_LIBSELINUX #if ENABLE_LIBSELINUX
#include <dlfcn.h> #include <dlfcn.h>
#endif #endif
#include <ctype.h>
#include <fcntl.h> #include <fcntl.h>
#include <grp.h> #include <grp.h>
#include <langinfo.h>
#include <limits.h> #include <limits.h>
#include <pwd.h> #include <pwd.h>
#include <stdio.h> #include <stdio.h>
@ -58,13 +60,14 @@
#include <string.h> #include <string.h>
#include <time.h> #include <time.h>
#include <unistd.h> #include <unistd.h>
#include <wchar.h>
#include <wctype.h>
#include <sys/ioctl.h> #include <sys/ioctl.h>
#include <sys/mman.h> #include <sys/mman.h>
#include <sys/resource.h> #include <sys/resource.h>
#include <sys/types.h> #include <sys/types.h>
#include "../include/c.h" #include "../include/c.h"
#include "common.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 unsigned max_leftward = OUTBUF_SIZE-1; /* space for LEFT stuff */
static int wide_signals; /* true if we have room */ static int wide_signals; /* true if we have room */
static time_t seconds_since_1970; 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; 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 **************/ /************ Lots of format functions, starting with the NOP **************/