mirror of
				https://github.com/tmux/tmux.git
				synced 2025-11-04 00:56:10 +00:00 
			
		
		
		
	Treat plausible but invalid keys (like C-BSpace) as literal like any
other unrecognised string passed to send-keys. Reported by Anthony Sottile in GitHub issue 2049.
This commit is contained in:
		@@ -60,6 +60,9 @@ static struct cmdq_item *
 | 
				
			|||||||
cmd_send_keys_inject_key(struct client *c, struct cmd_find_state *fs,
 | 
					cmd_send_keys_inject_key(struct client *c, struct cmd_find_state *fs,
 | 
				
			||||||
    struct cmdq_item *item, key_code key)
 | 
					    struct cmdq_item *item, key_code key)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
 | 
						struct session			*s = fs->s;
 | 
				
			||||||
 | 
						struct winlink			*wl = fs->wl;
 | 
				
			||||||
 | 
						struct window_pane		*wp = fs->wp;
 | 
				
			||||||
	struct window_mode_entry	*wme;
 | 
						struct window_mode_entry	*wme;
 | 
				
			||||||
	struct key_table		*table;
 | 
						struct key_table		*table;
 | 
				
			||||||
	struct key_binding		*bd;
 | 
						struct key_binding		*bd;
 | 
				
			||||||
@@ -68,7 +71,8 @@ cmd_send_keys_inject_key(struct client *c, struct cmd_find_state *fs,
 | 
				
			|||||||
	if (wme == NULL || wme->mode->key_table == NULL) {
 | 
						if (wme == NULL || wme->mode->key_table == NULL) {
 | 
				
			||||||
		if (options_get_number(fs->wp->window->options, "xterm-keys"))
 | 
							if (options_get_number(fs->wp->window->options, "xterm-keys"))
 | 
				
			||||||
			key |= KEYC_XTERM;
 | 
								key |= KEYC_XTERM;
 | 
				
			||||||
		window_pane_key(fs->wp, item->client, fs->s, fs->wl, key, NULL);
 | 
							if (window_pane_key(wp, item->client, s, wl, key, NULL) != 0)
 | 
				
			||||||
 | 
								return (NULL);
 | 
				
			||||||
		return (item);
 | 
							return (item);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	table = key_bindings_get_table(wme->mode->key_table(wme), 1);
 | 
						table = key_bindings_get_table(wme->mode->key_table(wme), 1);
 | 
				
			||||||
@@ -87,6 +91,7 @@ cmd_send_keys_inject_string(struct client *c, struct cmd_find_state *fs,
 | 
				
			|||||||
    struct cmdq_item *item, struct args *args, int i)
 | 
					    struct cmdq_item *item, struct args *args, int i)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	const char		*s = args->argv[i];
 | 
						const char		*s = args->argv[i];
 | 
				
			||||||
 | 
						struct cmdq_item	*new_item;
 | 
				
			||||||
	struct utf8_data	*ud, *uc;
 | 
						struct utf8_data	*ud, *uc;
 | 
				
			||||||
	wchar_t			 wc;
 | 
						wchar_t			 wc;
 | 
				
			||||||
	key_code		 key;
 | 
						key_code		 key;
 | 
				
			||||||
@@ -104,8 +109,11 @@ cmd_send_keys_inject_string(struct client *c, struct cmd_find_state *fs,
 | 
				
			|||||||
	literal = args_has(args, 'l');
 | 
						literal = args_has(args, 'l');
 | 
				
			||||||
	if (!literal) {
 | 
						if (!literal) {
 | 
				
			||||||
		key = key_string_lookup_string(s);
 | 
							key = key_string_lookup_string(s);
 | 
				
			||||||
		if (key != KEYC_NONE && key != KEYC_UNKNOWN)
 | 
							if (key != KEYC_NONE && key != KEYC_UNKNOWN) {
 | 
				
			||||||
			return (cmd_send_keys_inject_key(c, fs, item, key));
 | 
								new_item = cmd_send_keys_inject_key(c, fs, item, key);
 | 
				
			||||||
 | 
								if (new_item != NULL)
 | 
				
			||||||
 | 
									return (new_item);
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
		literal = 1;
 | 
							literal = 1;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	if (literal) {
 | 
						if (literal) {
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										17
									
								
								input-keys.c
									
									
									
									
									
								
							
							
						
						
									
										17
									
								
								input-keys.c
									
									
									
									
									
								
							@@ -150,7 +150,7 @@ input_split2(u_int c, u_char *dst)
 | 
				
			|||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* Translate a key code into an output key sequence. */
 | 
					/* Translate a key code into an output key sequence. */
 | 
				
			||||||
void
 | 
					int
 | 
				
			||||||
input_key(struct window_pane *wp, key_code key, struct mouse_event *m)
 | 
					input_key(struct window_pane *wp, key_code key, struct mouse_event *m)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	const struct input_key_ent	*ike;
 | 
						const struct input_key_ent	*ike;
 | 
				
			||||||
@@ -167,14 +167,14 @@ input_key(struct window_pane *wp, key_code key, struct mouse_event *m)
 | 
				
			|||||||
	if (KEYC_IS_MOUSE(key)) {
 | 
						if (KEYC_IS_MOUSE(key)) {
 | 
				
			||||||
		if (m != NULL && m->wp != -1 && (u_int)m->wp == wp->id)
 | 
							if (m != NULL && m->wp != -1 && (u_int)m->wp == wp->id)
 | 
				
			||||||
			input_key_mouse(wp, m);
 | 
								input_key_mouse(wp, m);
 | 
				
			||||||
		return;
 | 
							return (0);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/* Literal keys go as themselves (can't be more than eight bits). */
 | 
						/* Literal keys go as themselves (can't be more than eight bits). */
 | 
				
			||||||
	if (key & KEYC_LITERAL) {
 | 
						if (key & KEYC_LITERAL) {
 | 
				
			||||||
		ud.data[0] = (u_char)key;
 | 
							ud.data[0] = (u_char)key;
 | 
				
			||||||
		bufferevent_write(wp->event, &ud.data[0], 1);
 | 
							bufferevent_write(wp->event, &ud.data[0], 1);
 | 
				
			||||||
		return;
 | 
							return (0);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/* Is this backspace? */
 | 
						/* Is this backspace? */
 | 
				
			||||||
@@ -195,15 +195,15 @@ input_key(struct window_pane *wp, key_code key, struct mouse_event *m)
 | 
				
			|||||||
			bufferevent_write(wp->event, "\033", 1);
 | 
								bufferevent_write(wp->event, "\033", 1);
 | 
				
			||||||
		ud.data[0] = justkey;
 | 
							ud.data[0] = justkey;
 | 
				
			||||||
		bufferevent_write(wp->event, &ud.data[0], 1);
 | 
							bufferevent_write(wp->event, &ud.data[0], 1);
 | 
				
			||||||
		return;
 | 
							return (0);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	if (justkey > 0x7f && justkey < KEYC_BASE) {
 | 
						if (justkey > 0x7f && justkey < KEYC_BASE) {
 | 
				
			||||||
		if (utf8_split(justkey, &ud) != UTF8_DONE)
 | 
							if (utf8_split(justkey, &ud) != UTF8_DONE)
 | 
				
			||||||
			return;
 | 
								return (-1);
 | 
				
			||||||
		if (key & KEYC_ESCAPE)
 | 
							if (key & KEYC_ESCAPE)
 | 
				
			||||||
			bufferevent_write(wp->event, "\033", 1);
 | 
								bufferevent_write(wp->event, "\033", 1);
 | 
				
			||||||
		bufferevent_write(wp->event, ud.data, ud.size);
 | 
							bufferevent_write(wp->event, ud.data, ud.size);
 | 
				
			||||||
		return;
 | 
							return (0);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/*
 | 
						/*
 | 
				
			||||||
@@ -214,7 +214,7 @@ input_key(struct window_pane *wp, key_code key, struct mouse_event *m)
 | 
				
			|||||||
		if ((out = xterm_keys_lookup(key)) != NULL) {
 | 
							if ((out = xterm_keys_lookup(key)) != NULL) {
 | 
				
			||||||
			bufferevent_write(wp->event, out, strlen(out));
 | 
								bufferevent_write(wp->event, out, strlen(out));
 | 
				
			||||||
			free(out);
 | 
								free(out);
 | 
				
			||||||
			return;
 | 
								return (0);
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	key &= ~KEYC_XTERM;
 | 
						key &= ~KEYC_XTERM;
 | 
				
			||||||
@@ -237,7 +237,7 @@ input_key(struct window_pane *wp, key_code key, struct mouse_event *m)
 | 
				
			|||||||
	}
 | 
						}
 | 
				
			||||||
	if (i == nitems(input_keys)) {
 | 
						if (i == nitems(input_keys)) {
 | 
				
			||||||
		log_debug("key 0x%llx missing", key);
 | 
							log_debug("key 0x%llx missing", key);
 | 
				
			||||||
		return;
 | 
							return (-1);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	dlen = strlen(ike->data);
 | 
						dlen = strlen(ike->data);
 | 
				
			||||||
	log_debug("found key 0x%llx: \"%s\"", key, ike->data);
 | 
						log_debug("found key 0x%llx: \"%s\"", key, ike->data);
 | 
				
			||||||
@@ -246,6 +246,7 @@ input_key(struct window_pane *wp, key_code key, struct mouse_event *m)
 | 
				
			|||||||
	if (key & KEYC_ESCAPE)
 | 
						if (key & KEYC_ESCAPE)
 | 
				
			||||||
		bufferevent_write(wp->event, "\033", 1);
 | 
							bufferevent_write(wp->event, "\033", 1);
 | 
				
			||||||
	bufferevent_write(wp->event, ike->data, dlen);
 | 
						bufferevent_write(wp->event, ike->data, dlen);
 | 
				
			||||||
 | 
						return (0);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* Translate mouse and output. */
 | 
					/* Translate mouse and output. */
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										4
									
								
								tmux.h
									
									
									
									
									
								
							
							
						
						
									
										4
									
								
								tmux.h
									
									
									
									
									
								
							@@ -2275,7 +2275,7 @@ void	 input_parse(struct window_pane *);
 | 
				
			|||||||
void	 input_parse_buffer(struct window_pane *, u_char *, size_t);
 | 
					void	 input_parse_buffer(struct window_pane *, u_char *, size_t);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* input-key.c */
 | 
					/* input-key.c */
 | 
				
			||||||
void	 input_key(struct window_pane *, key_code, struct mouse_event *);
 | 
					int	 input_key(struct window_pane *, key_code, struct mouse_event *);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* xterm-keys.c */
 | 
					/* xterm-keys.c */
 | 
				
			||||||
char	*xterm_keys_lookup(key_code);
 | 
					char	*xterm_keys_lookup(key_code);
 | 
				
			||||||
@@ -2498,7 +2498,7 @@ int		 window_pane_set_mode(struct window_pane *,
 | 
				
			|||||||
		     struct args *);
 | 
							     struct args *);
 | 
				
			||||||
void		 window_pane_reset_mode(struct window_pane *);
 | 
					void		 window_pane_reset_mode(struct window_pane *);
 | 
				
			||||||
void		 window_pane_reset_mode_all(struct window_pane *);
 | 
					void		 window_pane_reset_mode_all(struct window_pane *);
 | 
				
			||||||
void		 window_pane_key(struct window_pane *, struct client *,
 | 
					int		 window_pane_key(struct window_pane *, struct client *,
 | 
				
			||||||
		     struct session *, struct winlink *, key_code,
 | 
							     struct session *, struct winlink *, key_code,
 | 
				
			||||||
		     struct mouse_event *);
 | 
							     struct mouse_event *);
 | 
				
			||||||
int		 window_pane_visible(struct window_pane *);
 | 
					int		 window_pane_visible(struct window_pane *);
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										14
									
								
								window.c
									
									
									
									
									
								
							
							
						
						
									
										14
									
								
								window.c
									
									
									
									
									
								
							@@ -1229,7 +1229,7 @@ window_pane_reset_mode_all(struct window_pane *wp)
 | 
				
			|||||||
		window_pane_reset_mode(wp);
 | 
							window_pane_reset_mode(wp);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void
 | 
					int
 | 
				
			||||||
window_pane_key(struct window_pane *wp, struct client *c, struct session *s,
 | 
					window_pane_key(struct window_pane *wp, struct client *c, struct session *s,
 | 
				
			||||||
    struct winlink *wl, key_code key, struct mouse_event *m)
 | 
					    struct winlink *wl, key_code key, struct mouse_event *m)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
@@ -1237,23 +1237,24 @@ window_pane_key(struct window_pane *wp, struct client *c, struct session *s,
 | 
				
			|||||||
	struct window_pane		*wp2;
 | 
						struct window_pane		*wp2;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (KEYC_IS_MOUSE(key) && m == NULL)
 | 
						if (KEYC_IS_MOUSE(key) && m == NULL)
 | 
				
			||||||
		return;
 | 
							return (-1);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	wme = TAILQ_FIRST(&wp->modes);
 | 
						wme = TAILQ_FIRST(&wp->modes);
 | 
				
			||||||
	if (wme != NULL) {
 | 
						if (wme != NULL) {
 | 
				
			||||||
		wp->modelast = time(NULL);
 | 
							wp->modelast = time(NULL);
 | 
				
			||||||
		if (wme->mode->key != NULL)
 | 
							if (wme->mode->key != NULL)
 | 
				
			||||||
			wme->mode->key(wme, c, s, wl, (key & ~KEYC_XTERM), m);
 | 
								wme->mode->key(wme, c, s, wl, (key & ~KEYC_XTERM), m);
 | 
				
			||||||
		return;
 | 
							return (0);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (wp->fd == -1 || wp->flags & PANE_INPUTOFF)
 | 
						if (wp->fd == -1 || wp->flags & PANE_INPUTOFF)
 | 
				
			||||||
		return;
 | 
							return (0);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	input_key(wp, key, m);
 | 
						if (input_key(wp, key, m) != 0)
 | 
				
			||||||
 | 
							return (-1);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (KEYC_IS_MOUSE(key))
 | 
						if (KEYC_IS_MOUSE(key))
 | 
				
			||||||
		return;
 | 
							return (0);
 | 
				
			||||||
	if (options_get_number(wp->window->options, "synchronize-panes")) {
 | 
						if (options_get_number(wp->window->options, "synchronize-panes")) {
 | 
				
			||||||
		TAILQ_FOREACH(wp2, &wp->window->panes, entry) {
 | 
							TAILQ_FOREACH(wp2, &wp->window->panes, entry) {
 | 
				
			||||||
			if (wp2 != wp &&
 | 
								if (wp2 != wp &&
 | 
				
			||||||
@@ -1264,6 +1265,7 @@ window_pane_key(struct window_pane *wp, struct client *c, struct session *s,
 | 
				
			|||||||
				input_key(wp2, key, NULL);
 | 
									input_key(wp2, key, NULL);
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
						return (0);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
int
 | 
					int
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user