From: Zbigniew Jędrzejewski-Szmek Date: Wed, 7 Jul 2021 14:27:51 +0000 (+0200) Subject: basic/escape: add helper for quoting command lines X-Git-Tag: v250-rc1~969^2~4 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=eeb91d29b0279d6bf8a3f1c4da54c9e9c0881a19;p=thirdparty%2Fsystemd.git basic/escape: add helper for quoting command lines --- diff --git a/src/basic/escape.c b/src/basic/escape.c index 2a3a0e31a1e..fcade5a1b47 100644 --- a/src/basic/escape.c +++ b/src/basic/escape.c @@ -8,6 +8,7 @@ #include "escape.h" #include "hexdecoct.h" #include "macro.h" +#include "strv.h" #include "utf8.h" int cescape_char(char c, char *buf) { @@ -542,3 +543,23 @@ char* shell_maybe_quote(const char *s, ShellEscapeFlags flags) { return str_realloc(buf); } + +char* quote_command_line(char **argv) { + _cleanup_free_ char *result = NULL; + + assert(argv); + + char **a; + STRV_FOREACH(a, argv) { + _cleanup_free_ char *t = NULL; + + t = shell_maybe_quote(*a, SHELL_ESCAPE_EMPTY); + if (!t) + return NULL; + + if (!strextend_with_separator(&result, " ", t)) + return NULL; + } + + return TAKE_PTR(result); +} diff --git a/src/basic/escape.h b/src/basic/escape.h index 907b572bd4a..e9d48d227ad 100644 --- a/src/basic/escape.h +++ b/src/basic/escape.h @@ -68,3 +68,4 @@ char* escape_non_printable_full(const char *str, size_t console_width, XEscapeFl char* shell_escape(const char *s, const char *bad); char* shell_maybe_quote(const char *s, ShellEscapeFlags flags); +char* quote_command_line(char **argv); diff --git a/src/test/test-escape.c b/src/test/test-escape.c index 2ca5fa32e20..413e8cd860e 100644 --- a/src/test/test-escape.c +++ b/src/test/test-escape.c @@ -203,6 +203,29 @@ static void test_shell_maybe_quote(void) { test_shell_maybe_quote_one("głąb\002\003rząd", SHELL_ESCAPE_POSIX, "$'głąb\\002\\003rząd'"); } +static void test_quote_command_line_one(char **argv, const char *expected) { + _cleanup_free_ char *s; + + assert_se(s = quote_command_line(argv)); + log_info("%s", s); + assert_se(streq(s, expected)); +} + +static void test_quote_command_line(void) { + log_info("/* %s */", __func__); + + test_quote_command_line_one(STRV_MAKE("true", "true"), + "true true"); + test_quote_command_line_one(STRV_MAKE("true", "with a space"), + "true \"with a space\""); + test_quote_command_line_one(STRV_MAKE("true", "with a 'quote'"), + "true \"with a 'quote'\""); + test_quote_command_line_one(STRV_MAKE("true", "with a \"quote\""), + "true \"with a \\\"quote\\\"\""); + test_quote_command_line_one(STRV_MAKE("true", "$dollar"), + "true \"\\$dollar\""); +} + int main(int argc, char *argv[]) { test_setup_logging(LOG_DEBUG); @@ -213,6 +236,7 @@ int main(int argc, char *argv[]) { test_cunescape(); test_shell_escape(); test_shell_maybe_quote(); + test_quote_command_line(); return 0; }