diff options
author | Zbigniew Jędrzejewski-Szmek <zbyszek@in.waw.pl> | 2017-06-11 15:24:07 -0400 |
---|---|---|
committer | Sven Eden <yamakuzure@gmx.net> | 2017-07-25 09:46:52 +0200 |
commit | 94678e2009c5eb2fa259d4f74f7b055ddda38d9e (patch) | |
tree | 6183ea3df70c5cbb3b4708a848c4c2159fd162c0 /src/test/test-escape.c | |
parent | 12a1aa92a493b2e156a3dfb6563e68211f2c2bf1 (diff) |
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/test/test-escape.c')
-rw-r--r-- | src/test/test-escape.c | 51 |
1 files changed, 39 insertions, 12 deletions
diff --git a/src/test/test-escape.c b/src/test/test-escape.c index 2c2270b13..20b54c6ab 100644 --- a/src/test/test-escape.c +++ b/src/test/test-escape.c @@ -87,26 +87,53 @@ static void test_shell_escape(void) { test_shell_escape_one("foo:bar,baz", ",:", "foo\\:bar\\,baz"); } -static void test_shell_maybe_quote_one(const char *s, const char *expected) { - _cleanup_free_ char *r; - - assert_se(r = shell_maybe_quote(s)); - assert_se(streq(r, expected)); +static void test_shell_maybe_quote_one(const char *s, + EscapeStyle style, + const char *expected) { + _cleanup_free_ char *ret = NULL; + + assert_se(ret = shell_maybe_quote(s, style)); + log_debug("[%s] → [%s] (%s)", s, ret, expected); + assert_se(streq(ret, expected)); } static void test_shell_maybe_quote(void) { - test_shell_maybe_quote_one("", ""); - test_shell_maybe_quote_one("\\", "\"\\\\\""); - test_shell_maybe_quote_one("\"", "\"\\\"\""); - test_shell_maybe_quote_one("foobar", "foobar"); - test_shell_maybe_quote_one("foo bar", "\"foo bar\""); - test_shell_maybe_quote_one("foo \"bar\" waldo", "\"foo \\\"bar\\\" waldo\""); - test_shell_maybe_quote_one("foo$bar", "\"foo\\$bar\""); + test_shell_maybe_quote_one("", ESCAPE_BACKSLASH, ""); + test_shell_maybe_quote_one("", ESCAPE_POSIX, ""); + test_shell_maybe_quote_one("\\", ESCAPE_BACKSLASH, "\"\\\\\""); + test_shell_maybe_quote_one("\\", ESCAPE_POSIX, "$'\\\\'"); + test_shell_maybe_quote_one("\"", ESCAPE_BACKSLASH, "\"\\\"\""); + test_shell_maybe_quote_one("\"", ESCAPE_POSIX, "$'\"'"); + test_shell_maybe_quote_one("foobar", ESCAPE_BACKSLASH, "foobar"); + test_shell_maybe_quote_one("foobar", ESCAPE_POSIX, "foobar"); + test_shell_maybe_quote_one("foo bar", ESCAPE_BACKSLASH, "\"foo bar\""); + test_shell_maybe_quote_one("foo bar", ESCAPE_POSIX, "$'foo bar'"); + test_shell_maybe_quote_one("foo\tbar", ESCAPE_BACKSLASH, "\"foo\tbar\""); + test_shell_maybe_quote_one("foo\tbar", ESCAPE_POSIX, "$'foo\\tbar'"); + test_shell_maybe_quote_one("foo\nbar", ESCAPE_BACKSLASH, "\"foo\nbar\""); + test_shell_maybe_quote_one("foo\nbar", ESCAPE_POSIX, "$'foo\\nbar'"); + test_shell_maybe_quote_one("foo \"bar\" waldo", ESCAPE_BACKSLASH, "\"foo \\\"bar\\\" waldo\""); + test_shell_maybe_quote_one("foo \"bar\" waldo", ESCAPE_POSIX, "$'foo \"bar\" waldo'"); + test_shell_maybe_quote_one("foo$bar", ESCAPE_BACKSLASH, "\"foo\\$bar\""); + test_shell_maybe_quote_one("foo$bar", ESCAPE_POSIX, "$'foo$bar'"); + + /* Note that current users disallow control characters, so this "test" + * is here merely to establish current behaviour. If control characters + * were allowed, they should be quoted, i.e. \001 should become \\001. */ + test_shell_maybe_quote_one("a\nb\001", ESCAPE_BACKSLASH, "\"a\nb\001\""); + test_shell_maybe_quote_one("a\nb\001", ESCAPE_POSIX, "$'a\\nb\001'"); + + test_shell_maybe_quote_one("foo!bar", ESCAPE_BACKSLASH, "\"foo!bar\""); + test_shell_maybe_quote_one("foo!bar", ESCAPE_POSIX, "$'foo!bar'"); } #endif // 0 int main(int argc, char *argv[]) { + log_set_max_level(LOG_DEBUG); + log_parse_environment(); + log_open(); + test_cescape(); test_cunescape(); #if 0 /// UNNEEDED by elogind |