Add q: format prefix to escape sh(1) special characters. Suggested by
authornicm <nicm@openbsd.org>
Sun, 26 Aug 2018 09:28:42 +0000 (09:28 +0000)
committernicm <nicm@openbsd.org>
Sun, 26 Aug 2018 09:28:42 +0000 (09:28 +0000)
someone ages ago and then more recently in GitHub issue 1449.

usr.bin/tmux/format.c
usr.bin/tmux/tmux.1

index d573e87..9154023 100644 (file)
@@ -1,4 +1,4 @@
-/* $OpenBSD: format.c,v 1.160 2018/08/23 15:45:05 nicm Exp $ */
+/* $OpenBSD: format.c,v 1.161 2018/08/26 09:28:42 nicm Exp $ */
 
 /*
  * Copyright (c) 2011 Nicholas Marriott <nicholas.marriott@gmail.com>
@@ -94,6 +94,7 @@ format_job_cmp(struct format_job *fj1, struct format_job *fj2)
 #define FORMAT_BASENAME 0x2
 #define FORMAT_DIRNAME 0x4
 #define FORMAT_SUBSTITUTE 0x8
+#define FORMAT_QUOTE 0x10
 
 /* Entry in format tree. */
 struct format_entry {
@@ -754,6 +755,23 @@ format_add_cb(struct format_tree *ft, const char *key, format_cb cb)
        fe->value = NULL;
 }
 
+/* Quote special characters in string. */
+static char *
+format_quote(const char *s)
+{
+       const char      *cp;
+       char            *out, *at;
+
+       at = out = xmalloc(strlen(s) * 2 + 1);
+       for (cp = s; *cp != '\0'; cp++) {
+               if (strchr("|&;<>()$`\\\"'*?[# =%", *cp) != NULL)
+                       *at++ = '\\';
+               *at++ = *cp;
+       }
+       *at = '\0';
+       return (out);
+}
+
 /* Find a format entry. */
 static char *
 format_find(struct format_tree *ft, const char *key, int modifiers)
@@ -836,6 +854,11 @@ found:
                copy = xstrdup(dirname(saved));
                free(saved);
        }
+       if (modifiers & FORMAT_QUOTE) {
+               saved = copy;
+               copy = xstrdup(format_quote(saved));
+               free(saved);
+       }
        return (copy);
 }
 
@@ -976,6 +999,12 @@ format_replace(struct format_tree *ft, const char *key, size_t keylen,
                modifiers |= FORMAT_TIMESTRING;
                copy += 2;
                break;
+       case 'q':
+               if (copy[1] != ':')
+                       break;
+               modifiers |= FORMAT_QUOTE;
+               copy += 2;
+               break;
        case 's':
                sep = copy[1];
                if (sep == ':' || !ispunct((u_char)sep))
index fb37e3b..eca8e2a 100644 (file)
@@ -1,4 +1,4 @@
-.\" $OpenBSD: tmux.1,v 1.609 2018/08/22 20:06:14 nicm Exp $
+.\" $OpenBSD: tmux.1,v 1.610 2018/08/26 09:28:42 nicm Exp $
 .\"
 .\" Copyright (c) 2007 Nicholas Marriott <nicholas.marriott@gmail.com>
 .\"
@@ -14,7 +14,7 @@
 .\" IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
 .\" OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 .\"
-.Dd $Mdocdate: August 22 2018 $
+.Dd $Mdocdate: August 26 2018 $
 .Dt TMUX 1
 .Os
 .Sh NAME
@@ -3676,6 +3676,10 @@ prefixes are
 and
 .Xr dirname 3
 of the variable respectively.
+.Ql q:
+will escape
+.Xr sh 1
+special characters.
 A prefix of the form
 .Ql s/foo/bar/:
 will substitute