procps/proc/escape.c

242 lines
6.4 KiB
C
Raw Normal View History

2002-02-02 04:17:29 +05:30
/*
* escape.c - printing handling
* Copyright 1998-2002 by Albert Cahalan
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
2002-02-02 04:17:29 +05:30
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#include <limits.h>
2004-11-05 02:20:59 +05:30
#include <stdio.h>
2002-02-02 04:17:29 +05:30
#include <sys/types.h>
2002-12-21 16:04:50 +05:30
#include <string.h>
#include <proc/procps.h>
2002-12-21 16:04:50 +05:30
#include "escape.h"
#include "readproc.h"
2002-02-02 04:17:29 +05:30
#if (__GNU_LIBRARY__ >= 6) && (!defined(__UCLIBC__) || defined(__UCLIBC_HAS_WCHAR__))
2004-11-05 02:20:59 +05:30
# include <wchar.h>
# include <wctype.h>
# include <stdlib.h> /* MB_CUR_MAX */
# include <ctype.h>
# include <langinfo.h>
#endif
2002-12-21 16:04:50 +05:30
#define SECURE_ESCAPE_ARGS(dst, bytes, cells) do { \
if ((bytes) <= 0) return 0; \
*(dst) = '\0'; \
if ((bytes) >= INT_MAX) return 0; \
if ((cells) >= INT_MAX) return 0; \
if ((cells) <= 0) return 0; \
} while (0)
#if (__GNU_LIBRARY__ >= 6) && (!defined(__UCLIBC__) || defined(__UCLIBC_HAS_WCHAR__))
2004-11-05 02:20:59 +05:30
static int escape_str_utf8(char *restrict dst, const char *restrict src, int bufsize, int *maxcells){
int my_cells = 0;
int my_bytes = 0;
mbstate_t s;
SECURE_ESCAPE_ARGS(dst, bufsize, *maxcells);
2004-11-05 02:20:59 +05:30
memset(&s, 0, sizeof (s));
2004-11-05 02:20:59 +05:30
for(;;) {
wchar_t wc;
int len = 0;
if(my_cells >= *maxcells || my_bytes+1 >= bufsize)
2002-02-02 04:17:29 +05:30
break;
2004-11-05 02:20:59 +05:30
if (!(len = mbrtowc (&wc, src, MB_CUR_MAX, &s)))
/* 'str' contains \0 */
2002-02-02 04:17:29 +05:30
break;
2004-11-05 02:20:59 +05:30
if (len < 0) {
/* invalid multibyte sequence -- zeroize state */
memset (&s, 0, sizeof (s));
*(dst++) = '?';
src++;
my_cells++;
2004-11-05 02:20:59 +05:30
my_bytes++;
} else if (len==1) {
/* non-multibyte */
*(dst++) = isprint(*src) ? *src : '?';
src++;
my_cells++;
my_bytes++;
2004-11-05 02:20:59 +05:30
} else if (!iswprint(wc)) {
/* multibyte - no printable */
*(dst++) = '?';
src+=len;
my_cells++;
my_bytes++;
2004-11-05 02:20:59 +05:30
} else {
/* multibyte - printable */
2004-11-05 02:20:59 +05:30
int wlen = wcwidth(wc);
if (wlen<=0) {
// invisible multibyte -- we don't ignore it, because some terminal
2004-11-05 02:20:59 +05:30
// interpret it wrong and more safe is replace it with '?'
*(dst++) = '?';
src+=len;
my_cells++;
my_bytes++;
} else {
// multibyte - printable
// Got space?
if (wlen > *maxcells-my_cells || len >= bufsize-(my_bytes+1)) break;
2004-11-05 02:20:59 +05:30
// 0x9b is control byte for some terminals
if (memchr(src, 0x9B, len)) {
// unsafe multibyte
*(dst++) = '?';
src+=len;
my_cells++;
my_bytes++;
} else {
// safe multibyte
memcpy(dst, src, len);
my_cells += wlen;
dst += len;
my_bytes += len;
src += len;
}
}
2002-02-02 04:17:29 +05:30
}
2004-11-05 02:20:59 +05:30
//fprintf(stdout, "cells: %d\n", my_cells);
2002-02-02 04:17:29 +05:30
}
enhanced libproc cgroup/cmdline support, exploited by top Library Changes . added PROC_EDITCMDLCVT flag . added an internal (static) fill_cmdline_cvt function: - reads and "escapes" /proc/#/cmdline - returns result as a single string in a single vector - callers are guaranteed a cmdline (no more NULL) . added vectorize_this_str function, exploited by fill_cgroup_cvt, fill_cmdline_cvt . generalized read_cmdline function as read_unvectored, now exploited by fill_cgroup_cvt, fill_cmdline_cvt, read_cmdline ( cgroup and cmdline no longer need be converted to string ) ( vectors before being transformed to final representation ) . fixed bug regarding skipped group numbers (when enabled) . escape_str made responsible for all single byte translation with distinction between control chars + other unprintable . added escaped_copy function for already escaped strings . reorganized parts of proc_t to restore formatting standards ( displacement changes shouldn't matter with new version # ) . former ZAP_SUSEONLY #define now OOMEM_ENABLE . added to library.map: escaped_copy; read_cmdline Top Program Changes . exploited the new PROC_EDITCMDLCVT provision . eliminated now obsolete #include "proc/escape.h" . changed the P_WCH display format if no kernel symbol table . fixed very old bug in lflgs for out-of-view sort fields . former ZAP_SUSEONLY #define now OOMEM_ENABLE Ps Program Changes . exploited the new PROC_EDITCMDLCVT provision . exploited the new escaped_copy function . consolidated pr_args and pr_comm into pr_argcom Signed-off-by: Jan Görig <jgorig@redhat.com>
2011-05-18 14:03:44 +05:30
*dst = '\0';
2004-11-05 02:20:59 +05:30
// fprintf(stderr, "maxcells: %d, my_cells; %d\n", *maxcells, my_cells);
2004-11-05 02:20:59 +05:30
*maxcells -= my_cells;
return my_bytes; // bytes of text, excluding the NUL
2002-02-02 04:17:29 +05:30
}
2004-11-05 02:20:59 +05:30
#endif /* __GNU_LIBRARY__ */
2002-02-02 04:17:29 +05:30
/* sanitize a string via one-way mangle */
2004-11-05 02:20:59 +05:30
int escape_str(char *restrict dst, const char *restrict src, int bufsize, int *maxcells){
2002-02-02 04:17:29 +05:30
unsigned char c;
2004-11-05 02:20:59 +05:30
int my_cells = 0;
2002-12-21 18:37:53 +05:30
int my_bytes = 0;
2002-11-27 05:54:01 +05:30
const char codes[] =
enhanced libproc cgroup/cmdline support, exploited by top Library Changes . added PROC_EDITCMDLCVT flag . added an internal (static) fill_cmdline_cvt function: - reads and "escapes" /proc/#/cmdline - returns result as a single string in a single vector - callers are guaranteed a cmdline (no more NULL) . added vectorize_this_str function, exploited by fill_cgroup_cvt, fill_cmdline_cvt . generalized read_cmdline function as read_unvectored, now exploited by fill_cgroup_cvt, fill_cmdline_cvt, read_cmdline ( cgroup and cmdline no longer need be converted to string ) ( vectors before being transformed to final representation ) . fixed bug regarding skipped group numbers (when enabled) . escape_str made responsible for all single byte translation with distinction between control chars + other unprintable . added escaped_copy function for already escaped strings . reorganized parts of proc_t to restore formatting standards ( displacement changes shouldn't matter with new version # ) . former ZAP_SUSEONLY #define now OOMEM_ENABLE . added to library.map: escaped_copy; read_cmdline Top Program Changes . exploited the new PROC_EDITCMDLCVT provision . eliminated now obsolete #include "proc/escape.h" . changed the P_WCH display format if no kernel symbol table . fixed very old bug in lflgs for out-of-view sort fields . former ZAP_SUSEONLY #define now OOMEM_ENABLE Ps Program Changes . exploited the new PROC_EDITCMDLCVT provision . exploited the new escaped_copy function . consolidated pr_args and pr_comm into pr_argcom Signed-off-by: Jan Görig <jgorig@redhat.com>
2011-05-18 14:03:44 +05:30
"Z..............................."
"||||||||||||||||||||||||||||||||"
"||||||||||||||||||||||||||||||||"
"|||||||||||||||||||||||||||||||."
"????????????????????????????????"
"????????????????????????????????"
"????????????????????????????????"
"????????????????????????????????";
#if (__GNU_LIBRARY__ >= 6) && (!defined(__UCLIBC__) || defined(__UCLIBC_HAS_WCHAR__))
2004-11-05 02:20:59 +05:30
static int utf_init=0;
2004-11-05 02:20:59 +05:30
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;
}
enhanced libproc cgroup/cmdline support, exploited by top Library Changes . added PROC_EDITCMDLCVT flag . added an internal (static) fill_cmdline_cvt function: - reads and "escapes" /proc/#/cmdline - returns result as a single string in a single vector - callers are guaranteed a cmdline (no more NULL) . added vectorize_this_str function, exploited by fill_cgroup_cvt, fill_cmdline_cvt . generalized read_cmdline function as read_unvectored, now exploited by fill_cgroup_cvt, fill_cmdline_cvt, read_cmdline ( cgroup and cmdline no longer need be converted to string ) ( vectors before being transformed to final representation ) . fixed bug regarding skipped group numbers (when enabled) . escape_str made responsible for all single byte translation with distinction between control chars + other unprintable . added escaped_copy function for already escaped strings . reorganized parts of proc_t to restore formatting standards ( displacement changes shouldn't matter with new version # ) . former ZAP_SUSEONLY #define now OOMEM_ENABLE . added to library.map: escaped_copy; read_cmdline Top Program Changes . exploited the new PROC_EDITCMDLCVT provision . eliminated now obsolete #include "proc/escape.h" . changed the P_WCH display format if no kernel symbol table . fixed very old bug in lflgs for out-of-view sort fields . former ZAP_SUSEONLY #define now OOMEM_ENABLE Ps Program Changes . exploited the new PROC_EDITCMDLCVT provision . exploited the new escaped_copy function . consolidated pr_args and pr_comm into pr_argcom Signed-off-by: Jan Görig <jgorig@redhat.com>
2011-05-18 14:03:44 +05:30
if (utf_init==1 && MB_CUR_MAX>1) {
2004-11-05 02:20:59 +05:30
/* UTF8 locales */
return escape_str_utf8(dst, src, bufsize, maxcells);
enhanced libproc cgroup/cmdline support, exploited by top Library Changes . added PROC_EDITCMDLCVT flag . added an internal (static) fill_cmdline_cvt function: - reads and "escapes" /proc/#/cmdline - returns result as a single string in a single vector - callers are guaranteed a cmdline (no more NULL) . added vectorize_this_str function, exploited by fill_cgroup_cvt, fill_cmdline_cvt . generalized read_cmdline function as read_unvectored, now exploited by fill_cgroup_cvt, fill_cmdline_cvt, read_cmdline ( cgroup and cmdline no longer need be converted to string ) ( vectors before being transformed to final representation ) . fixed bug regarding skipped group numbers (when enabled) . escape_str made responsible for all single byte translation with distinction between control chars + other unprintable . added escaped_copy function for already escaped strings . reorganized parts of proc_t to restore formatting standards ( displacement changes shouldn't matter with new version # ) . former ZAP_SUSEONLY #define now OOMEM_ENABLE . added to library.map: escaped_copy; read_cmdline Top Program Changes . exploited the new PROC_EDITCMDLCVT provision . eliminated now obsolete #include "proc/escape.h" . changed the P_WCH display format if no kernel symbol table . fixed very old bug in lflgs for out-of-view sort fields . former ZAP_SUSEONLY #define now OOMEM_ENABLE Ps Program Changes . exploited the new PROC_EDITCMDLCVT provision . exploited the new escaped_copy function . consolidated pr_args and pr_comm into pr_argcom Signed-off-by: Jan Görig <jgorig@redhat.com>
2011-05-18 14:03:44 +05:30
}
2004-11-05 02:20:59 +05:30
#endif
SECURE_ESCAPE_ARGS(dst, bufsize, *maxcells);
2004-11-05 02:20:59 +05:30
if(bufsize > *maxcells+1) bufsize=*maxcells+1; // FIXME: assumes 8-bit locale
2002-12-21 18:37:53 +05:30
for(;;){
if(my_cells >= *maxcells || my_bytes+1 >= bufsize)
2004-11-05 02:20:59 +05:30
break;
2002-02-02 04:17:29 +05:30
c = (unsigned char) *(src++);
2002-12-21 18:37:53 +05:30
if(!c) break;
enhanced libproc cgroup/cmdline support, exploited by top Library Changes . added PROC_EDITCMDLCVT flag . added an internal (static) fill_cmdline_cvt function: - reads and "escapes" /proc/#/cmdline - returns result as a single string in a single vector - callers are guaranteed a cmdline (no more NULL) . added vectorize_this_str function, exploited by fill_cgroup_cvt, fill_cmdline_cvt . generalized read_cmdline function as read_unvectored, now exploited by fill_cgroup_cvt, fill_cmdline_cvt, read_cmdline ( cgroup and cmdline no longer need be converted to string ) ( vectors before being transformed to final representation ) . fixed bug regarding skipped group numbers (when enabled) . escape_str made responsible for all single byte translation with distinction between control chars + other unprintable . added escaped_copy function for already escaped strings . reorganized parts of proc_t to restore formatting standards ( displacement changes shouldn't matter with new version # ) . former ZAP_SUSEONLY #define now OOMEM_ENABLE . added to library.map: escaped_copy; read_cmdline Top Program Changes . exploited the new PROC_EDITCMDLCVT provision . eliminated now obsolete #include "proc/escape.h" . changed the P_WCH display format if no kernel symbol table . fixed very old bug in lflgs for out-of-view sort fields . former ZAP_SUSEONLY #define now OOMEM_ENABLE Ps Program Changes . exploited the new PROC_EDITCMDLCVT provision . exploited the new escaped_copy function . consolidated pr_args and pr_comm into pr_argcom Signed-off-by: Jan Görig <jgorig@redhat.com>
2011-05-18 14:03:44 +05:30
if(codes[c]!='|') c=codes[c];
2004-11-05 02:20:59 +05:30
my_cells++;
2002-12-21 18:37:53 +05:30
my_bytes++;
*(dst++) = c;
2002-02-02 04:17:29 +05:30
}
enhanced libproc cgroup/cmdline support, exploited by top Library Changes . added PROC_EDITCMDLCVT flag . added an internal (static) fill_cmdline_cvt function: - reads and "escapes" /proc/#/cmdline - returns result as a single string in a single vector - callers are guaranteed a cmdline (no more NULL) . added vectorize_this_str function, exploited by fill_cgroup_cvt, fill_cmdline_cvt . generalized read_cmdline function as read_unvectored, now exploited by fill_cgroup_cvt, fill_cmdline_cvt, read_cmdline ( cgroup and cmdline no longer need be converted to string ) ( vectors before being transformed to final representation ) . fixed bug regarding skipped group numbers (when enabled) . escape_str made responsible for all single byte translation with distinction between control chars + other unprintable . added escaped_copy function for already escaped strings . reorganized parts of proc_t to restore formatting standards ( displacement changes shouldn't matter with new version # ) . former ZAP_SUSEONLY #define now OOMEM_ENABLE . added to library.map: escaped_copy; read_cmdline Top Program Changes . exploited the new PROC_EDITCMDLCVT provision . eliminated now obsolete #include "proc/escape.h" . changed the P_WCH display format if no kernel symbol table . fixed very old bug in lflgs for out-of-view sort fields . former ZAP_SUSEONLY #define now OOMEM_ENABLE Ps Program Changes . exploited the new PROC_EDITCMDLCVT provision . exploited the new escaped_copy function . consolidated pr_args and pr_comm into pr_argcom Signed-off-by: Jan Görig <jgorig@redhat.com>
2011-05-18 14:03:44 +05:30
*dst = '\0';
2004-11-05 02:20:59 +05:30
*maxcells -= my_cells;
2002-12-21 18:37:53 +05:30
return my_bytes; // bytes of text, excluding the NUL
2002-02-02 04:17:29 +05:30
}
2002-12-21 16:04:50 +05:30
/////////////////////////////////////////////////
2002-02-02 04:17:29 +05:30
2002-12-21 16:04:50 +05:30
// 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){
2002-02-02 04:17:29 +05:30
size_t i = 0;
2002-12-21 16:04:50 +05:30
for(;;){
2004-11-05 02:20:59 +05:30
i += escape_str(dst+i, *src, bytes-i, cells);
2002-12-21 16:04:50 +05:30
if(bytes-i < 3) break; // need room for space, a character, and the NUL
2002-02-02 04:17:29 +05:30
src++;
2002-12-21 16:04:50 +05:30
if(!*src) break; // need something to print
2004-11-05 02:20:59 +05:30
if (*cells<=1) break; // need room for printed size of text
2002-12-21 16:04:50 +05:30
dst[i++] = ' ';
2004-11-05 02:20:59 +05:30
--*cells;
2002-02-02 04:17:29 +05:30
}
2004-11-05 02:20:59 +05:30
return i; // bytes, excluding the NUL
2002-12-21 16:04:50 +05:30
}
///////////////////////////////////////////////////
2004-11-05 02:20:59 +05:30
int escape_command(char *restrict const outbuf, const proc_t *restrict const pp, int bytes, int *cells, unsigned flags){
2004-07-15 06:47:15 +05:30
int overhead = 0;
2002-12-21 16:04:50 +05:30
int end = 0;
if(flags & ESC_ARGS){
char **lc = (char**)pp->cmdline;
2004-11-05 02:20:59 +05:30
if(lc && *lc) return escape_strlist(outbuf, lc, bytes, cells);
2002-12-21 16:04:50 +05:30
}
if(flags & ESC_BRACKETS){
overhead += 2;
}
if(flags & ESC_DEFUNCT){
if(pp->state=='Z') overhead += 10; // chars in " <defunct>"
else flags &= ~ESC_DEFUNCT;
}
if(overhead + 1 >= *cells || // if no room for even one byte of the command name
overhead + 1 >= bytes){
outbuf[0] = '\0';
return 0;
2002-12-21 16:04:50 +05:30
}
if(flags & ESC_BRACKETS){
outbuf[end++] = '[';
}
2004-11-05 02:20:59 +05:30
*cells -= overhead;
end += escape_str(outbuf+end, pp->cmd, bytes-overhead, cells);
2002-12-21 16:04:50 +05:30
// Hmmm, do we want "[foo] <defunct>" or "[foo <defunct>]"?
if(flags & ESC_BRACKETS){
outbuf[end++] = ']';
}
if(flags & ESC_DEFUNCT){
memcpy(outbuf+end, " <defunct>", 10);
end += 10;
}
outbuf[end] = '\0';
2004-11-05 02:20:59 +05:30
return end; // bytes, not including the NUL
2002-02-02 04:17:29 +05:30
}
enhanced libproc cgroup/cmdline support, exploited by top Library Changes . added PROC_EDITCMDLCVT flag . added an internal (static) fill_cmdline_cvt function: - reads and "escapes" /proc/#/cmdline - returns result as a single string in a single vector - callers are guaranteed a cmdline (no more NULL) . added vectorize_this_str function, exploited by fill_cgroup_cvt, fill_cmdline_cvt . generalized read_cmdline function as read_unvectored, now exploited by fill_cgroup_cvt, fill_cmdline_cvt, read_cmdline ( cgroup and cmdline no longer need be converted to string ) ( vectors before being transformed to final representation ) . fixed bug regarding skipped group numbers (when enabled) . escape_str made responsible for all single byte translation with distinction between control chars + other unprintable . added escaped_copy function for already escaped strings . reorganized parts of proc_t to restore formatting standards ( displacement changes shouldn't matter with new version # ) . former ZAP_SUSEONLY #define now OOMEM_ENABLE . added to library.map: escaped_copy; read_cmdline Top Program Changes . exploited the new PROC_EDITCMDLCVT provision . eliminated now obsolete #include "proc/escape.h" . changed the P_WCH display format if no kernel symbol table . fixed very old bug in lflgs for out-of-view sort fields . former ZAP_SUSEONLY #define now OOMEM_ENABLE Ps Program Changes . exploited the new PROC_EDITCMDLCVT provision . exploited the new escaped_copy function . consolidated pr_args and pr_comm into pr_argcom Signed-off-by: Jan Görig <jgorig@redhat.com>
2011-05-18 14:03:44 +05:30