summaryrefslogtreecommitdiff
path: root/usr.bin/tmux
diff options
context:
space:
mode:
authorNicholas Marriott <nicm@cvs.openbsd.org>2019-05-23 14:03:45 +0000
committerNicholas Marriott <nicm@cvs.openbsd.org>2019-05-23 14:03:45 +0000
commit4cefe275754a7dd624b1e7c3aab51a4b4b92c6b7 (patch)
tree064a04a3b5e60e5be349de562cfb824bff054c40 /usr.bin/tmux
parenta06ea0786589f7b036e0ce81c2590041542bda85 (diff)
Break the argument escaping code into a separate function and use it to
escape key bindings in list-keys. Also escape ~ and ; and $ properly.
Diffstat (limited to 'usr.bin/tmux')
-rw-r--r--usr.bin/tmux/arguments.c63
-rw-r--r--usr.bin/tmux/cmd-list-keys.c15
-rw-r--r--usr.bin/tmux/cmd-list.c14
-rw-r--r--usr.bin/tmux/cmd-parse.y4
-rw-r--r--usr.bin/tmux/options.c4
-rw-r--r--usr.bin/tmux/tmux.h5
-rw-r--r--usr.bin/tmux/utf8.c9
7 files changed, 72 insertions, 42 deletions
diff --git a/usr.bin/tmux/arguments.c b/usr.bin/tmux/arguments.c
index 051adf26dd9..143089e28b8 100644
--- a/usr.bin/tmux/arguments.c
+++ b/usr.bin/tmux/arguments.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: arguments.c,v 1.21 2019/04/28 20:05:50 nicm Exp $ */
+/* $OpenBSD: arguments.c,v 1.22 2019/05/23 14:03:44 nicm Exp $ */
/*
* Copyright (c) 2010 Nicholas Marriott <nicholas.marriott@gmail.com>
@@ -141,23 +141,15 @@ static void
args_print_add_value(char **buf, size_t *len, struct args_entry *entry,
struct args_value *value)
{
- static const char quoted[] = " #\"';$";
- char *escaped;
- int flags;
+ char *escaped;
if (**buf != '\0')
args_print_add(buf, len, " -%c ", entry->flag);
else
args_print_add(buf, len, "-%c ", entry->flag);
- flags = VIS_OCTAL|VIS_TAB|VIS_NL;
- if (value->value[strcspn(value->value, quoted)] != '\0')
- flags |= VIS_DQ;
- utf8_stravis(&escaped, value->value, flags);
- if (flags & VIS_DQ)
- args_print_add(buf, len, "\"%s\"", escaped);
- else
- args_print_add(buf, len, "%s", escaped);
+ escaped = args_escape(value->value);
+ args_print_add(buf, len, "%s", escaped);
free(escaped);
}
@@ -165,21 +157,13 @@ args_print_add_value(char **buf, size_t *len, struct args_entry *entry,
static void
args_print_add_argument(char **buf, size_t *len, const char *argument)
{
- static const char quoted[] = " #\"';$";
- char *escaped;
- int flags;
+ char *escaped;
if (**buf != '\0')
args_print_add(buf, len, " ");
- flags = VIS_OCTAL|VIS_TAB|VIS_NL;
- if (argument[strcspn(argument, quoted)] != '\0')
- flags |= VIS_DQ;
- utf8_stravis(&escaped, argument, flags);
- if (flags & VIS_DQ)
- args_print_add(buf, len, "\"%s\"", escaped);
- else
- args_print_add(buf, len, "%s", escaped);
+ escaped = args_escape(argument);
+ args_print_add(buf, len, "%s", escaped);
free(escaped);
}
@@ -219,6 +203,39 @@ args_print(struct args *args)
return (buf);
}
+/* Escape an argument. */
+char *
+args_escape(const char *s)
+{
+ static const char quoted[] = " #\"';$";
+ char *escaped, *result;
+ int flags;
+
+ if ((strchr(quoted, s[0]) != NULL || s[0] == '~') && s[1] == '\0') {
+ xasprintf(&escaped, "\\%c", s[0]);
+ return (escaped);
+ }
+
+ flags = VIS_OCTAL|VIS_TAB|VIS_NL;
+ if (s[strcspn(s, quoted)] != '\0')
+ flags |= VIS_DQ;
+ utf8_stravis(&escaped, s, flags);
+
+ if (flags & VIS_DQ) {
+ if (*escaped == '~')
+ xasprintf(&result, "\"\\%s\"", escaped);
+ else
+ xasprintf(&result, "\"%s\"", escaped);
+ } else {
+ if (*escaped == '~')
+ xasprintf(&result, "\\%s", escaped);
+ else
+ result = xstrdup(escaped);
+ }
+ free(escaped);
+ return (result);
+}
+
/* Return if an argument is present. */
int
args_has(struct args *args, u_char ch)
diff --git a/usr.bin/tmux/cmd-list-keys.c b/usr.bin/tmux/cmd-list-keys.c
index 897def1e0c5..b240c17c738 100644
--- a/usr.bin/tmux/cmd-list-keys.c
+++ b/usr.bin/tmux/cmd-list-keys.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: cmd-list-keys.c,v 1.45 2018/08/02 11:44:07 nicm Exp $ */
+/* $OpenBSD: cmd-list-keys.c,v 1.46 2019/05/23 14:03:44 nicm Exp $ */
/*
* Copyright (c) 2007 Nicholas Marriott <nicholas.marriott@gmail.com>
@@ -60,8 +60,8 @@ cmd_list_keys_exec(struct cmd *self, struct cmdq_item *item)
struct args *args = self->args;
struct key_table *table;
struct key_binding *bd;
- const char *key, *tablename, *r;
- char *cp, tmp[BUFSIZ];
+ const char *tablename, *r;
+ char *key, *cp, tmp[BUFSIZ];
int repeat, width, tablewidth, keywidth;
if (self->entry == &cmd_list_commands_entry)
@@ -83,7 +83,7 @@ cmd_list_keys_exec(struct cmd *self, struct cmdq_item *item)
}
bd = key_bindings_first(table);
while (bd != NULL) {
- key = key_string_lookup_key(bd->key);
+ key = args_escape(key_string_lookup_key(bd->key));
if (bd->flags & KEY_BINDING_REPEAT)
repeat = 1;
@@ -95,6 +95,7 @@ cmd_list_keys_exec(struct cmd *self, struct cmdq_item *item)
if (width > keywidth)
keywidth = width;
+ free(key);
bd = key_bindings_next(table, bd);
}
table = key_bindings_next_table(table);
@@ -108,7 +109,7 @@ cmd_list_keys_exec(struct cmd *self, struct cmdq_item *item)
}
bd = key_bindings_first(table);
while (bd != NULL) {
- key = key_string_lookup_key(bd->key);
+ key = args_escape(key_string_lookup_key(bd->key));
if (!repeat)
r = "";
@@ -128,11 +129,13 @@ cmd_list_keys_exec(struct cmd *self, struct cmdq_item *item)
strlcat(tmp, " ", sizeof tmp);
free(cp);
- cp = cmd_list_print(bd->cmdlist);
+ cp = cmd_list_print(bd->cmdlist, 1);
strlcat(tmp, cp, sizeof tmp);
free(cp);
cmdq_print(item, "bind-key %s", tmp);
+
+ free(key);
bd = key_bindings_next(table, bd);
}
table = key_bindings_next_table(table);
diff --git a/usr.bin/tmux/cmd-list.c b/usr.bin/tmux/cmd-list.c
index 6beaacbfcdf..f98c1b2c31d 100644
--- a/usr.bin/tmux/cmd-list.c
+++ b/usr.bin/tmux/cmd-list.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: cmd-list.c,v 1.18 2019/05/23 11:13:30 nicm Exp $ */
+/* $OpenBSD: cmd-list.c,v 1.19 2019/05/23 14:03:44 nicm Exp $ */
/*
* Copyright (c) 2009 Nicholas Marriott <nicholas.marriott@gmail.com>
@@ -129,7 +129,7 @@ cmd_list_free(struct cmd_list *cmdlist)
}
char *
-cmd_list_print(struct cmd_list *cmdlist)
+cmd_list_print(struct cmd_list *cmdlist, int escaped)
{
struct cmd *cmd;
char *buf, *this;
@@ -141,12 +141,16 @@ cmd_list_print(struct cmd_list *cmdlist)
TAILQ_FOREACH(cmd, &cmdlist->list, qentry) {
this = cmd_print(cmd);
- len += strlen(this) + 3;
+ len += strlen(this) + 4;
buf = xrealloc(buf, len);
strlcat(buf, this, len);
- if (TAILQ_NEXT(cmd, qentry) != NULL)
- strlcat(buf, " ; ", len);
+ if (TAILQ_NEXT(cmd, qentry) != NULL) {
+ if (escaped)
+ strlcat(buf, " \\; ", len);
+ else
+ strlcat(buf, " ; ", len);
+ }
free(this);
}
diff --git a/usr.bin/tmux/cmd-parse.y b/usr.bin/tmux/cmd-parse.y
index 6e107bc8d38..65498ba3c5c 100644
--- a/usr.bin/tmux/cmd-parse.y
+++ b/usr.bin/tmux/cmd-parse.y
@@ -1,4 +1,4 @@
-/* $OpenBSD: cmd-parse.y,v 1.1 2019/05/23 11:13:30 nicm Exp $ */
+/* $OpenBSD: cmd-parse.y,v 1.2 2019/05/23 14:03:44 nicm Exp $ */
/*
* Copyright (c) 2019 Nicholas Marriott <nicholas.marriott@gmail.com>
@@ -663,7 +663,7 @@ cmd_parse_from_file(FILE *f, struct cmd_parse_input *pi)
cmd_list_free(cmdlist);
}
- s = cmd_list_print(result);
+ s = cmd_list_print(result, 0);
log_debug("%s: %s", __func__, s);
free(s);
diff --git a/usr.bin/tmux/options.c b/usr.bin/tmux/options.c
index 1b3ef07ac09..c0a4b3ba2d3 100644
--- a/usr.bin/tmux/options.c
+++ b/usr.bin/tmux/options.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: options.c,v 1.45 2019/05/23 11:13:30 nicm Exp $ */
+/* $OpenBSD: options.c,v 1.46 2019/05/23 14:03:44 nicm Exp $ */
/*
* Copyright (c) 2008 Nicholas Marriott <nicholas.marriott@gmail.com>
@@ -122,7 +122,7 @@ options_value_tostring(struct options_entry *o, union options_value *ov,
char *s;
if (OPTIONS_IS_COMMAND(o))
- return (cmd_list_print(ov->cmdlist));
+ return (cmd_list_print(ov->cmdlist, 0));
if (OPTIONS_IS_STYLE(o))
return (xstrdup(style_tostring(&ov->style)));
if (OPTIONS_IS_NUMBER(o)) {
diff --git a/usr.bin/tmux/tmux.h b/usr.bin/tmux/tmux.h
index 7d5b49606e8..1d6ffb225f7 100644
--- a/usr.bin/tmux/tmux.h
+++ b/usr.bin/tmux/tmux.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: tmux.h,v 1.902 2019/05/23 11:13:30 nicm Exp $ */
+/* $OpenBSD: tmux.h,v 1.903 2019/05/23 14:03:44 nicm Exp $ */
/*
* Copyright (c) 2007 Nicholas Marriott <nicholas.marriott@gmail.com>
@@ -1950,6 +1950,7 @@ void args_set(struct args *, u_char, const char *);
struct args *args_parse(const char *, int, char **);
void args_free(struct args *);
char *args_print(struct args *);
+char *args_escape(const char *);
int args_has(struct args *, u_char);
const char *args_get(struct args *, u_char);
const char *args_first_value(struct args *, u_char, struct args_value **);
@@ -2022,7 +2023,7 @@ void cmd_list_append(struct cmd_list *, struct cmd *);
void cmd_list_move(struct cmd_list *, struct cmd_list *);
struct cmd_list *cmd_list_parse(int, char **, const char *, u_int, char **);
void cmd_list_free(struct cmd_list *);
-char *cmd_list_print(struct cmd_list *);
+char *cmd_list_print(struct cmd_list *, int);
/* cmd-queue.c */
struct cmdq_item *cmdq_get_command(struct cmd_list *, struct cmd_find_state *,
diff --git a/usr.bin/tmux/utf8.c b/usr.bin/tmux/utf8.c
index baf2af846e5..ea4f4e30093 100644
--- a/usr.bin/tmux/utf8.c
+++ b/usr.bin/tmux/utf8.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: utf8.c,v 1.40 2019/03/18 20:53:33 nicm Exp $ */
+/* $OpenBSD: utf8.c,v 1.41 2019/05/23 14:03:44 nicm Exp $ */
/*
* Copyright (c) 2008 Nicholas Marriott <nicholas.marriott@gmail.com>
@@ -18,6 +18,7 @@
#include <sys/types.h>
+#include <ctype.h>
#include <errno.h>
#include <stdlib.h>
#include <string.h>
@@ -182,7 +183,11 @@ utf8_strvis(char *dst, const char *src, size_t len, int flag)
/* Not a complete, valid UTF-8 character. */
src -= ud.have;
}
- if (src < end - 1)
+ if (src[0] == '$' && src < end - 1) {
+ if (isalpha((u_char)src[1]) || src[1] == '_')
+ *dst++ = '\\';
+ *dst++ = '$';
+ } else if (src < end - 1)
dst = vis(dst, src[0], flag, src[1]);
else if (src < end)
dst = vis(dst, src[0], flag, '\0');