]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
basic/escape: add helper for quoting command lines
authorZbigniew Jędrzejewski-Szmek <zbyszek@in.waw.pl>
Wed, 7 Jul 2021 14:27:51 +0000 (16:27 +0200)
committerZbigniew Jędrzejewski-Szmek <zbyszek@in.waw.pl>
Fri, 9 Jul 2021 09:18:21 +0000 (11:18 +0200)
src/basic/escape.c
src/basic/escape.h
src/test/test-escape.c

index 2a3a0e31a1ec24291a85bfd8ada22b28fa51af89..fcade5a1b47354d2f897decb5974c98e77c3231b 100644 (file)
@@ -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);
+}
index 907b572bd4ad8d7a21b2cf8a1545b4f13bf7465e..e9d48d227adaa271cd7d243b7c97a860906e6be3 100644 (file)
@@ -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);
index 2ca5fa32e20ce0fadae2924e003d6e784528bb29..413e8cd860e734972a56923710789f369e895cfd 100644 (file)
@@ -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;
 }