From 58b510e5805d8350c31bfb81a47bcd38ea9fdd7e Mon Sep 17 00:00:00 2001 From: Karel Zak Date: Thu, 3 Dec 2020 12:14:10 +0100 Subject: [PATCH] libsmartcols: sanitize variable names on export output The shells are very restrictive about variable names, only [:alnum:] chars are allowed (and alphabetic chars as the first char). The library will replace "bad" chars with "_". The char '%' at the end is replaced by _PCT. Addresses: https://github.com/karelzak/util-linux/issues/1201 Signed-off-by: Karel Zak --- include/carefulputc.h | 16 ++++++++++++++++ libsmartcols/src/print.c | 5 ++++- libsmartcols/src/table.c | 4 ++++ misc-utils/findmnt.8 | 4 +++- misc-utils/lsblk.8 | 4 +++- sys-utils/lsipc.1 | 5 ++++- sys-utils/lsmem.1 | 4 ++-- 7 files changed, 36 insertions(+), 6 deletions(-) diff --git a/include/carefulputc.h b/include/carefulputc.h index f1c03566d..81f1ad463 100644 --- a/include/carefulputc.h +++ b/include/carefulputc.h @@ -151,5 +151,21 @@ static inline void fputs_nonblank(const char *data, FILE *out) } } +static inline void fputs_shell_ident(const char *data, FILE *out) +{ + const char *p = data; + + /* convert "1FOO" to "_1FOO" */ + if (p && !isalpha(*p)) + fputc('_', out); + + /* replace all "bad" chars with "_" */ + for (p = data; p && *p; p++) { + if (!isalnum(*p)) + fputc('_', out); + else + fputc(*p, out); + } +} #endif /* _CAREFULPUTC_H */ diff --git a/libsmartcols/src/print.c b/libsmartcols/src/print.c index 9d78c90b3..2293a43fa 100644 --- a/libsmartcols/src/print.c +++ b/libsmartcols/src/print.c @@ -472,7 +472,10 @@ static int print_data(struct libscols_table *tb, return 0; case SCOLS_FMT_EXPORT: - fprintf(tb->out, "%s=", name); + fputs_shell_ident(name, tb->out); + if (endswith(name, "%")) + fputs("PCT", tb->out); + fputc('=', tb->out); fputs_quoted(data, tb->out); if (!is_last) fputs(colsep(tb), tb->out); diff --git a/libsmartcols/src/table.c b/libsmartcols/src/table.c index a3ba21dc6..d5c406bd7 100644 --- a/libsmartcols/src/table.c +++ b/libsmartcols/src/table.c @@ -1076,6 +1076,10 @@ int scols_table_enable_json(struct libscols_table *tb, int enable) * Enable/disable export output format (COLUMNAME="value" ...). * The parsable output formats (export and raw) are mutually exclusive. * + * Note that COLUMNAME maybe be modified on output to contains only chars + * allowed as shell variable identifiers, for example MIN-IO and FSUSE% will be + * MIN_IO and FSUSE_PCT. + * * Returns: 0 on success, negative number in case of an error. */ int scols_table_enable_export(struct libscols_table *tb, int enable) diff --git a/misc-utils/findmnt.8 b/misc-utils/findmnt.8 index e411c3010..86ab6ff93 100644 --- a/misc-utils/findmnt.8 +++ b/misc-utils/findmnt.8 @@ -156,7 +156,9 @@ Output almost all available columns. The columns that require are not included. .TP .BR \-P , " \-\-pairs" -Use key="value" output format. All potentially unsafe characters are hex-escaped (\\x). +Produce output in the form of key="value" pairs. All potentially unsafe value characters are hex-escaped (\\x). +The key (variable name) will be modified to contain only characters allowed for a shell variable +identifiers, for example, FS_OPTIONS and USE_PCT instead of FS-OPTIONS and USE%. .TP .BR \-p , " \-\-poll\fR[\fI=list\fR]" Monitor changes in the /proc/self/mountinfo file. Supported actions are: mount, diff --git a/misc-utils/lsblk.8 b/misc-utils/lsblk.8 index eeefd8282..f59e1d8b6 100644 --- a/misc-utils/lsblk.8 +++ b/misc-utils/lsblk.8 @@ -128,7 +128,9 @@ Output all available columns. .TP .BR \-P , " \-\-pairs" Produce output in the form of key="value" pairs. The output lines are still ordered by -dependencies. All potentially unsafe characters are hex-escaped (\\x). +dependencies. All potentially unsafe value characters are hex-escaped (\\x). +The key (variable name) will be modified to contain only characters allowed for a shell variable +identifiers, for example, MIN_IO and FSUSE_PCT instead of MIN-IO and FSUSE%. .TP .BR \-p , " \-\-paths" Print full device paths. diff --git a/sys-utils/lsipc.1 b/sys-utils/lsipc.1 index b58b4cdf4..34ed5dae6 100644 --- a/sys-utils/lsipc.1 +++ b/sys-utils/lsipc.1 @@ -51,7 +51,10 @@ Write information about active semaphore sets. Show creator and owner. .TP \fB\-e\fR, \fB\-\-export\fR -Output data in the format of NAME=VALUE. +Produce output in the form of key="value" pairs. All potentially unsafe value +characters are hex-escaped (\\x). The key (variable name) will be +modified to contain only characters allowed for a shell variable identifiers, +for example, USE_PCT instead of USE%. .TP \fB\-J\fR, \fB\-\-json\fR Use the JSON output format. diff --git a/sys-utils/lsmem.1 b/sys-utils/lsmem.1 index 2fe78b4c6..e726b72ce 100644 --- a/sys-utils/lsmem.1 +++ b/sys-utils/lsmem.1 @@ -61,8 +61,8 @@ specified in the format \fB+\fIlist\fP (e.g., \fBlsmem \-o +NODE\fP). Output all available columns. .TP .BR \-P , " \-\-pairs" -Produce output in the form of key="value" pairs. -All potentially unsafe characters are hex-escaped (\\x). +Produce output in the form of key="value" pairs. All potentially unsafe value +characters are hex-escaped (\\x). .TP .BR \-r , " \-\-raw" Produce output in raw format. All potentially unsafe characters are hex-escaped