summaryrefslogtreecommitdiffstats
path: root/src/basic/escape.h
diff options
context:
space:
mode:
authorZbigniew Jędrzejewski-Szmek <zbyszek@in.waw.pl>2017-06-11 21:24:07 +0200
committerZbigniew Jędrzejewski-Szmek <zbyszek@in.waw.pl>2017-06-20 01:39:43 +0200
commit804ee07c1370d49aa9a555c91c26fe3ed22f9957 (patch)
treee313b1c284d4efe675d2ff08d3ece19ccc963a8e /src/basic/escape.h
parentman: systemd-timesyncd.service(8) (#6109) (diff)
downloadsystemd-804ee07c1370d49aa9a555c91c26fe3ed22f9957.tar.xz
systemd-804ee07c1370d49aa9a555c91c26fe3ed22f9957.zip
Use "dollar-single-quotes" to escape shell-sensitive strings
Also called "ANSI-C Quoting" in info:(bash) ANSI-C Quoting. The escaping rules are a POSIX proposal, and are described in http://austingroupbugs.net/view.php?id=249. There's a lot of back-and-forth on the details of escaping of control characters, but we'll be only using a small subset of the syntax that is common to all proposals and is widely supported. Unfortunately dash and fish and maybe some other shells do not support it (see the man page patch for a list). This allows environment variables to be safely exported using show-environment and imported into the shell. Shells which do not support this syntax will have to do something like export $(systemctl show-environment|grep -v '=\$') or whatever is appropriate in their case. I think csh and fish do not support the A=B syntax anyway, so the change is moot for them. Fixes #5536. v2: - also escape newlines (which currently disallowed in shell values, so this doesn't really matter), and tabs (as $'\t'), and ! (as $'!'). This way quoted output can be included directly in both interactive and noninteractive bash.
Diffstat (limited to 'src/basic/escape.h')
-rw-r--r--src/basic/escape.h23
1 files changed, 20 insertions, 3 deletions
diff --git a/src/basic/escape.h b/src/basic/escape.h
index deaa4def28..6f5cc60bc8 100644
--- a/src/basic/escape.h
+++ b/src/basic/escape.h
@@ -31,13 +31,30 @@
/* What characters are special in the shell? */
/* must be escaped outside and inside double-quotes */
#define SHELL_NEED_ESCAPE "\"\\`$"
-/* can be escaped or double-quoted */
-#define SHELL_NEED_QUOTES SHELL_NEED_ESCAPE GLOB_CHARS "'()<>|&;"
+
+/* Those that can be escaped or double-quoted.
+ *
+ * Stricly speaking, ! does not need to be escaped, except in interactive
+ * mode, but let's be extra nice to the user and quote ! in case this
+ * output is ever used in interactive mode. */
+#define SHELL_NEED_QUOTES SHELL_NEED_ESCAPE GLOB_CHARS "'()<>|&;!"
+
+/* Note that we assume control characters would need to be escaped too in
+ * addition to the "special" characters listed here, if they appear in the
+ * string. Current users disallow control characters. Also '"' shall not
+ * be escaped.
+ */
+#define SHELL_NEED_ESCAPE_POSIX "\\\'"
typedef enum UnescapeFlags {
UNESCAPE_RELAX = 1,
} UnescapeFlags;
+typedef enum EscapeStyle {
+ ESCAPE_BACKSLASH = 1,
+ ESCAPE_POSIX = 2,
+} EscapeStyle;
+
char *cescape(const char *s);
char *cescape_length(const char *s, size_t n);
size_t cescape_char(char c, char *buf);
@@ -51,4 +68,4 @@ char *xescape(const char *s, const char *bad);
char *octescape(const char *s, size_t len);
char *shell_escape(const char *s, const char *bad);
-char *shell_maybe_quote(const char *s);
+char* shell_maybe_quote(const char *s, EscapeStyle style);