diff options
author | Nicholas Marriott <nicm@cvs.openbsd.org> | 2019-05-23 14:03:45 +0000 |
---|---|---|
committer | Nicholas Marriott <nicm@cvs.openbsd.org> | 2019-05-23 14:03:45 +0000 |
commit | 4cefe275754a7dd624b1e7c3aab51a4b4b92c6b7 (patch) | |
tree | 064a04a3b5e60e5be349de562cfb824bff054c40 /usr.bin/tmux | |
parent | a06ea0786589f7b036e0ce81c2590041542bda85 (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.c | 63 | ||||
-rw-r--r-- | usr.bin/tmux/cmd-list-keys.c | 15 | ||||
-rw-r--r-- | usr.bin/tmux/cmd-list.c | 14 | ||||
-rw-r--r-- | usr.bin/tmux/cmd-parse.y | 4 | ||||
-rw-r--r-- | usr.bin/tmux/options.c | 4 | ||||
-rw-r--r-- | usr.bin/tmux/tmux.h | 5 | ||||
-rw-r--r-- | usr.bin/tmux/utf8.c | 9 |
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'); |