chiark / gitweb /
util: add shell_maybe_quote() call for preparing a string for shell cmdline inclusion
authorLennart Poettering <lennart@poettering.net>
Thu, 9 Apr 2015 16:32:21 +0000 (18:32 +0200)
committerSven Eden <yamakuzure@gmx.net>
Tue, 14 Mar 2017 06:54:40 +0000 (07:54 +0100)
If necessary the passed string is enclosed in "", and all special
characters escapes.

This also ports over usage in bus-util.c and job.c to use this, instead
of a incorrect local implementation that forgets to properly escape.

src/libelogind/sd-bus/bus-util.c
src/shared/util.c
src/shared/util.h

index 78ef289eb13b727ee7be49a2c22b019ff8dce090..759809ce8d489b38248d782cd082a391d3053a38 100644 (file)
@@ -1739,16 +1739,15 @@ static int check_wait_response(BusWaitForJobs *d, bool quiet) {
                 else if (streq(d->result, "unsupported"))
                         log_error("Operation on or unit type of %s not supported on this system.", strna(d->name));
                 else if (!streq(d->result, "done") && !streq(d->result, "skipped")) {
-                        if (d->name) {
-                                bool quotes;
+                        _cleanup_free_ char *quoted = NULL;
 
-                                quotes = chars_intersect(d->name, SHELL_NEED_QUOTES);
+                        if (d->name)
+                                quoted = shell_maybe_quote(d->name);
 
-                                log_error("Job for %s failed. See \"systemctl status %s%s%s\" and \"journalctl -xe\" for details.",
-                                          d->name,
-                                          quotes ? "'" : "", d->name, quotes ? "'" : "");
-                        } else
-                                log_error("Job failed. See \"journalctl -xe\" for details.");
+                        if (quoted)
+                                log_error("Job for %s failed. See 'systemctl status %s' and 'journalctl -xe' for details.", d->name, quoted);
+                        else
+                                log_error("Job failed. See 'journalctl -xe' for details.");
                 }
         }
 
index ab891fa2c2fc84e893ef4e8fbf1ed7d75819620b..279def715ab18a0a53038ef662bdaf6acf7075c0 100644 (file)
@@ -1353,7 +1353,8 @@ char *cescape(const char *s) {
 
         assert(s);
 
-        /* Does C style string escaping. */
+        /* Does C style string escaping. May be be reversed with
+         * cunescape(). */
 
         r = new(char, strlen(s)*4 + 1);
         if (!r)
@@ -1565,7 +1566,7 @@ char *xescape(const char *s, const char *bad) {
 
         /* Escapes all chars in bad, in addition to \ and all special
          * chars, in \xFF style escaping. May be reversed with
-         * cunescape. */
+         * cunescape(). */
 
         r = new(char, strlen(s) * 4 + 1);
         if (!r)
@@ -7993,3 +7994,43 @@ int rename_noreplace(int olddirfd, const char *oldpath, int newdirfd, const char
 
         return 0;
 }
+
+char *shell_maybe_quote(const char *s) {
+        const char *p;
+        char *r, *t;
+
+        assert(s);
+
+        /* Encloses a string in double quotes if necessary to make it
+         * OK as shell string. */
+
+        for (p = s; *p; p++)
+                if (*p <= ' ' ||
+                    *p >= 127 ||
+                    strchr(SHELL_NEED_QUOTES, *p))
+                        break;
+
+        if (!*p)
+                return strdup(s);
+
+        r = new(char, 1+strlen(s)*2+1+1);
+        if (!r)
+                return NULL;
+
+        t = r;
+        *(t++) = '"';
+        t = mempcpy(t, s, p - s);
+
+        for (; *p; p++) {
+
+                if (strchr(SHELL_NEED_ESCAPE, *p))
+                        *(t++) = '\\';
+
+                *(t++) = *p;
+        }
+
+        *(t++)= '"';
+        *t = 0;
+
+        return r;
+}
index 427b52ef1eb0cc1613fc3b8d8690022f4c74b8c9..1026070f209078fca27cf4dfa78e032b2d2a677e 100644 (file)
@@ -1089,3 +1089,5 @@ int syslog_parse_priority(const char **p, int *priority, bool with_facility);
 void cmsg_close_all(struct msghdr *mh);
 
 int rename_noreplace(int olddirfd, const char *oldpath, int newdirfd, const char *newpath);
+
+char *shell_maybe_quote(const char *s);