1 /* SPDX-License-Identifier: LGPL-2.1+ */
3 This file is part of systemd.
5 Copyright 2010 Lennart Poettering
7 systemd is free software; you can redistribute it and/or modify it
8 under the terms of the GNU Lesser General Public License as published by
9 the Free Software Foundation; either version 2.1 of the License, or
10 (at your option) any later version.
12 systemd is distributed in the hope that it will be useful, but
13 WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 Lesser General Public License for more details.
17 You should have received a copy of the GNU Lesser General Public License
18 along with systemd; If not, see <http://www.gnu.org/licenses/>.
21 #include "alloc-util.h"
25 static void test_cescape(void) {
26 _cleanup_free_ char *escaped;
28 assert_se(escaped = cescape("abc\\\"\b\f\n\r\t\v\a\003\177\234\313"));
29 assert_se(streq(escaped, "abc\\\\\\\"\\b\\f\\n\\r\\t\\v\\a\\003\\177\\234\\313"));
32 static void test_cunescape(void) {
33 _cleanup_free_ char *unescaped;
35 assert_se(cunescape("abc\\\\\\\"\\b\\f\\a\\n\\r\\t\\v\\003\\177\\234\\313\\000\\x00", 0, &unescaped) < 0);
36 assert_se(cunescape("abc\\\\\\\"\\b\\f\\a\\n\\r\\t\\v\\003\\177\\234\\313\\000\\x00", UNESCAPE_RELAX, &unescaped) >= 0);
37 assert_se(streq_ptr(unescaped, "abc\\\"\b\f\a\n\r\t\v\003\177\234\313\\000\\x00"));
38 unescaped = mfree(unescaped);
40 /* incomplete sequences */
41 assert_se(cunescape("\\x0", 0, &unescaped) < 0);
42 assert_se(cunescape("\\x0", UNESCAPE_RELAX, &unescaped) >= 0);
43 assert_se(streq_ptr(unescaped, "\\x0"));
44 unescaped = mfree(unescaped);
46 assert_se(cunescape("\\x", 0, &unescaped) < 0);
47 assert_se(cunescape("\\x", UNESCAPE_RELAX, &unescaped) >= 0);
48 assert_se(streq_ptr(unescaped, "\\x"));
49 unescaped = mfree(unescaped);
51 assert_se(cunescape("\\", 0, &unescaped) < 0);
52 assert_se(cunescape("\\", UNESCAPE_RELAX, &unescaped) >= 0);
53 assert_se(streq_ptr(unescaped, "\\"));
54 unescaped = mfree(unescaped);
56 assert_se(cunescape("\\11", 0, &unescaped) < 0);
57 assert_se(cunescape("\\11", UNESCAPE_RELAX, &unescaped) >= 0);
58 assert_se(streq_ptr(unescaped, "\\11"));
59 unescaped = mfree(unescaped);
61 assert_se(cunescape("\\1", 0, &unescaped) < 0);
62 assert_se(cunescape("\\1", UNESCAPE_RELAX, &unescaped) >= 0);
63 assert_se(streq_ptr(unescaped, "\\1"));
64 unescaped = mfree(unescaped);
66 assert_se(cunescape("\\u0000", 0, &unescaped) < 0);
67 assert_se(cunescape("\\u00DF\\U000000df\\u03a0\\U00000041", UNESCAPE_RELAX, &unescaped) >= 0);
68 assert_se(streq_ptr(unescaped, "ßßΠA"));
69 unescaped = mfree(unescaped);
71 assert_se(cunescape("\\073", 0, &unescaped) >= 0);
72 assert_se(streq_ptr(unescaped, ";"));
73 unescaped = mfree(unescaped);
75 assert_se(cunescape("A=A\\\\x0aB", 0, &unescaped) >= 0);
76 assert_se(streq_ptr(unescaped, "A=A\\x0aB"));
77 unescaped = mfree(unescaped);
79 assert_se(cunescape("A=A\\\\x0aB", UNESCAPE_RELAX, &unescaped) >= 0);
80 assert_se(streq_ptr(unescaped, "A=A\\x0aB"));
83 #if 0 /// UNNEEDED by elogind
84 static void test_shell_escape_one(const char *s, const char *bad, const char *expected) {
85 _cleanup_free_ char *r;
87 assert_se(r = shell_escape(s, bad));
88 assert_se(streq_ptr(r, expected));
91 static void test_shell_escape(void) {
92 test_shell_escape_one("", "", "");
93 test_shell_escape_one("\\", "", "\\\\");
94 test_shell_escape_one("foobar", "", "foobar");
95 test_shell_escape_one("foobar", "o", "f\\o\\obar");
96 test_shell_escape_one("foo:bar,baz", ",:", "foo\\:bar\\,baz");
99 static void test_shell_maybe_quote_one(const char *s,
101 const char *expected) {
102 _cleanup_free_ char *ret = NULL;
104 assert_se(ret = shell_maybe_quote(s, style));
105 log_debug("[%s] → [%s] (%s)", s, ret, expected);
106 assert_se(streq(ret, expected));
109 static void test_shell_maybe_quote(void) {
111 test_shell_maybe_quote_one("", ESCAPE_BACKSLASH, "");
112 test_shell_maybe_quote_one("", ESCAPE_POSIX, "");
113 test_shell_maybe_quote_one("\\", ESCAPE_BACKSLASH, "\"\\\\\"");
114 test_shell_maybe_quote_one("\\", ESCAPE_POSIX, "$'\\\\'");
115 test_shell_maybe_quote_one("\"", ESCAPE_BACKSLASH, "\"\\\"\"");
116 test_shell_maybe_quote_one("\"", ESCAPE_POSIX, "$'\"'");
117 test_shell_maybe_quote_one("foobar", ESCAPE_BACKSLASH, "foobar");
118 test_shell_maybe_quote_one("foobar", ESCAPE_POSIX, "foobar");
119 test_shell_maybe_quote_one("foo bar", ESCAPE_BACKSLASH, "\"foo bar\"");
120 test_shell_maybe_quote_one("foo bar", ESCAPE_POSIX, "$'foo bar'");
121 test_shell_maybe_quote_one("foo\tbar", ESCAPE_BACKSLASH, "\"foo\tbar\"");
122 test_shell_maybe_quote_one("foo\tbar", ESCAPE_POSIX, "$'foo\\tbar'");
123 test_shell_maybe_quote_one("foo\nbar", ESCAPE_BACKSLASH, "\"foo\nbar\"");
124 test_shell_maybe_quote_one("foo\nbar", ESCAPE_POSIX, "$'foo\\nbar'");
125 test_shell_maybe_quote_one("foo \"bar\" waldo", ESCAPE_BACKSLASH, "\"foo \\\"bar\\\" waldo\"");
126 test_shell_maybe_quote_one("foo \"bar\" waldo", ESCAPE_POSIX, "$'foo \"bar\" waldo'");
127 test_shell_maybe_quote_one("foo$bar", ESCAPE_BACKSLASH, "\"foo\\$bar\"");
128 test_shell_maybe_quote_one("foo$bar", ESCAPE_POSIX, "$'foo$bar'");
130 /* Note that current users disallow control characters, so this "test"
131 * is here merely to establish current behaviour. If control characters
132 * were allowed, they should be quoted, i.e. \001 should become \\001. */
133 test_shell_maybe_quote_one("a\nb\001", ESCAPE_BACKSLASH, "\"a\nb\001\"");
134 test_shell_maybe_quote_one("a\nb\001", ESCAPE_POSIX, "$'a\\nb\001'");
136 test_shell_maybe_quote_one("foo!bar", ESCAPE_BACKSLASH, "\"foo!bar\"");
137 test_shell_maybe_quote_one("foo!bar", ESCAPE_POSIX, "$'foo!bar'");
141 int main(int argc, char *argv[]) {
142 log_set_max_level(LOG_DEBUG);
143 log_parse_environment();
148 #if 0 /// UNNEEDED by elogind
150 test_shell_maybe_quote();