From c5dda82c51f3caf94d5a611b06a3be6dca90643b Mon Sep 17 00:00:00 2001 From: nicm Date: Sun, 26 Aug 2018 09:28:42 +0000 Subject: [PATCH] Add q: format prefix to escape sh(1) special characters. Suggested by someone ages ago and then more recently in GitHub issue 1449. --- usr.bin/tmux/format.c | 31 ++++++++++++++++++++++++++++++- usr.bin/tmux/tmux.1 | 8 ++++++-- 2 files changed, 36 insertions(+), 3 deletions(-) diff --git a/usr.bin/tmux/format.c b/usr.bin/tmux/format.c index d573e878148..91540238436 100644 --- a/usr.bin/tmux/format.c +++ b/usr.bin/tmux/format.c @@ -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 @@ -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)) diff --git a/usr.bin/tmux/tmux.1 b/usr.bin/tmux/tmux.1 index fb37e3b85bb..eca8e2afeec 100644 --- a/usr.bin/tmux/tmux.1 +++ b/usr.bin/tmux/tmux.1 @@ -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 .\" @@ -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 -- 2.20.1