diff options
author | Luca Boccassi <bluca@debian.org> | 2023-03-02 17:33:16 +0000 |
---|---|---|
committer | GitHub <noreply@github.com> | 2023-03-02 17:33:16 +0000 |
commit | a41ac8ac407a1a58612059a45229f0d440f58e28 (patch) | |
tree | fc50476544799c51f34068077f2cc57c32cd465e /src | |
parent | edd84b8e4b9db4dc57345ff97dfc7c22d8a6f241 (diff) | |
parent | 0b82a6fa5d2ba94bbc1c3db4a04dfd052e1cd446 (diff) | |
download | systemd-a41ac8ac407a1a58612059a45229f0d440f58e28.tar.gz |
Merge pull request #26628 from msizanoen1/utf8-quote-valid
escape: Ensure that output is always valid UTF-8
Diffstat (limited to 'src')
-rw-r--r-- | src/basic/escape.c | 27 | ||||
-rw-r--r-- | src/test/test-escape.c | 4 |
2 files changed, 24 insertions, 7 deletions
diff --git a/src/basic/escape.c b/src/basic/escape.c index e04b435d5b..d2cb1c7320 100644 --- a/src/basic/escape.c +++ b/src/basic/escape.c @@ -473,15 +473,23 @@ char* octescape(const char *s, size_t len) { static char* strcpy_backslash_escaped(char *t, const char *s, const char *bad) { assert(bad); + assert(t); + assert(s); + + while (*s) { + int l = utf8_encoded_valid_unichar(s, SIZE_MAX); - for (; *s; s++) - if (char_is_cc(*s)) - t += cescape_char(*s, t); - else { + if (char_is_cc(*s) || l < 0) + t += cescape_char(*(s++), t); + else if (l == 1) { if (*s == '\\' || strchr(bad, *s)) *(t++) = '\\'; - *(t++) = *s; + *(t++) = *(s++); + } else { + t = mempcpy(t, s, l); + s += l; } + } return t; } @@ -510,11 +518,16 @@ char* shell_maybe_quote(const char *s, ShellEscapeFlags flags) { if (FLAGS_SET(flags, SHELL_ESCAPE_EMPTY) && isempty(s)) return strdup("\"\""); /* We don't use $'' here in the POSIX mode. "" is fine too. */ - for (p = s; *p; p++) - if (char_is_cc(*p) || + for (p = s; *p; ) { + int l = utf8_encoded_valid_unichar(p, SIZE_MAX); + + if (char_is_cc(*p) || l < 0 || strchr(WHITESPACE SHELL_NEED_QUOTES, *p)) break; + p += l; + } + if (!*p) return strdup(s); diff --git a/src/test/test-escape.c b/src/test/test-escape.c index b1ab5bab18..f3dd579e56 100644 --- a/src/test/test-escape.c +++ b/src/test/test-escape.c @@ -196,6 +196,10 @@ TEST(shell_maybe_quote) { test_shell_maybe_quote_one("głąb\002\003rząd", 0, "\"głąb\\002\\003rząd\""); test_shell_maybe_quote_one("głąb\002\003rząd", SHELL_ESCAPE_POSIX, "$'głąb\\002\\003rząd'"); + + /* Bogus UTF-8 strings */ + test_shell_maybe_quote_one("\250\350", 0, "\"\\250\\350\""); + test_shell_maybe_quote_one("\250\350", SHELL_ESCAPE_POSIX, "$'\\250\\350'"); } static void test_quote_command_line_one(char **argv, const char *expected) { |