From 9d9ffcabe9781ac214d1f80a2085ec8045640b70 Mon Sep 17 00:00:00 2001 From: nicm Date: Sun, 4 Jun 2017 09:02:36 +0000 Subject: [PATCH] Be more strict about escape sequences that rename windows or set titles: ignore any that not valid UTF-8 outright, and for good measure pass the result through our UTF-8-aware vis(3). --- usr.bin/tmux/input.c | 15 ++++++++++----- usr.bin/tmux/screen.c | 5 +++-- usr.bin/tmux/tmux.h | 3 ++- usr.bin/tmux/utf8.c | 27 ++++++++++++++++++++++++++- usr.bin/tmux/window.c | 5 +++-- 5 files changed, 44 insertions(+), 11 deletions(-) diff --git a/usr.bin/tmux/input.c b/usr.bin/tmux/input.c index 7eb4b20f7a8..e6ea4c95feb 100644 --- a/usr.bin/tmux/input.c +++ b/usr.bin/tmux/input.c @@ -1,4 +1,4 @@ -/* $OpenBSD: input.c,v 1.123 2017/06/03 17:43:01 nicm Exp $ */ +/* $OpenBSD: input.c,v 1.124 2017/06/04 09:02:36 nicm Exp $ */ /* * Copyright (c) 2007 Nicholas Marriott @@ -1896,8 +1896,10 @@ input_exit_osc(struct input_ctx *ictx) switch (option) { case 0: case 2: - screen_set_title(ictx->ctx.s, p); - server_status_window(ictx->wp->window); + if (utf8_isvalid(p)) { + screen_set_title(ictx->ctx.s, p); + server_status_window(ictx->wp->window); + } break; case 4: input_osc_4(ictx->wp, p); @@ -1909,7 +1911,7 @@ input_exit_osc(struct input_ctx *ictx) input_osc_11(ictx->wp, p); break; case 12: - if (*p != '?') /* ? is colour request */ + if (utf8_isvalid(p) && *p != '?') /* ? is colour request */ screen_set_cursor_colour(ictx->ctx.s, p); break; case 52: @@ -1945,6 +1947,8 @@ input_exit_apc(struct input_ctx *ictx) return; log_debug("%s: \"%s\"", __func__, ictx->input_buf); + if (!utf8_isvalid(ictx->input_buf)) + return; screen_set_title(ictx->ctx.s, ictx->input_buf); server_status_window(ictx->wp->window); } @@ -1968,9 +1972,10 @@ input_exit_rename(struct input_ctx *ictx) return; log_debug("%s: \"%s\"", __func__, ictx->input_buf); + if (!utf8_isvalid(ictx->input_buf)) + return; window_set_name(ictx->wp->window, ictx->input_buf); options_set_number(ictx->wp->window->options, "automatic-rename", 0); - server_status_window(ictx->wp->window); } diff --git a/usr.bin/tmux/screen.c b/usr.bin/tmux/screen.c index 3e305ef7c93..262929a2105 100644 --- a/usr.bin/tmux/screen.c +++ b/usr.bin/tmux/screen.c @@ -1,4 +1,4 @@ -/* $OpenBSD: screen.c,v 1.46 2017/02/08 16:45:18 nicm Exp $ */ +/* $OpenBSD: screen.c,v 1.47 2017/06/04 09:02:36 nicm Exp $ */ /* * Copyright (c) 2007 Nicholas Marriott @@ -21,6 +21,7 @@ #include #include #include +#include #include "tmux.h" @@ -107,7 +108,7 @@ void screen_set_title(struct screen *s, const char *title) { free(s->title); - s->title = xstrdup(title); + utf8_stravis(&s->title, title, VIS_OCTAL|VIS_CSTYLE|VIS_TAB|VIS_NL); } /* Resize screen. */ diff --git a/usr.bin/tmux/tmux.h b/usr.bin/tmux/tmux.h index 9faa25c56be..b80ee654350 100644 --- a/usr.bin/tmux/tmux.h +++ b/usr.bin/tmux/tmux.h @@ -1,4 +1,4 @@ -/* $OpenBSD: tmux.h,v 1.780 2017/06/04 08:25:57 nicm Exp $ */ +/* $OpenBSD: tmux.h,v 1.781 2017/06/04 09:02:36 nicm Exp $ */ /* * Copyright (c) 2007 Nicholas Marriott @@ -2318,6 +2318,7 @@ enum utf8_state utf8_open(struct utf8_data *, u_char); enum utf8_state utf8_append(struct utf8_data *, u_char); enum utf8_state utf8_combine(const struct utf8_data *, wchar_t *); enum utf8_state utf8_split(wchar_t, struct utf8_data *); +int utf8_isvalid(const char *); int utf8_strvis(char *, const char *, size_t, int); int utf8_stravis(char **, const char *, int); char *utf8_sanitize(const char *); diff --git a/usr.bin/tmux/utf8.c b/usr.bin/tmux/utf8.c index 7e07c64c4b8..53627d28eb4 100644 --- a/usr.bin/tmux/utf8.c +++ b/usr.bin/tmux/utf8.c @@ -1,4 +1,4 @@ -/* $OpenBSD: utf8.c,v 1.37 2017/05/31 17:56:48 nicm Exp $ */ +/* $OpenBSD: utf8.c,v 1.38 2017/06/04 09:02:36 nicm Exp $ */ /* * Copyright (c) 2008 Nicholas Marriott @@ -207,6 +207,31 @@ utf8_stravis(char **dst, const char *src, int flag) return (len); } +/* Does this string contain anything that isn't valid UTF-8? */ +int +utf8_isvalid(const char *s) +{ + struct utf8_data ud; + const char *end; + enum utf8_state more; + size_t i; + + end = s + strlen(s); + while (s < end) { + if ((more = utf8_open(&ud, *s)) == UTF8_MORE) { + while (++s < end && more == UTF8_MORE) + more = utf8_append(&ud, *s); + if (more == UTF8_DONE) + continue; + return (0); + } + if (*s < 0x20 || *s > 0x7e) + return (0); + s++; + } + return (1); +} + /* * Sanitize a string, changing any UTF-8 characters to '_'. Caller should free * the returned string. Anything not valid printable ASCII or UTF-8 is diff --git a/usr.bin/tmux/window.c b/usr.bin/tmux/window.c index 66b11660288..a890801a498 100644 --- a/usr.bin/tmux/window.c +++ b/usr.bin/tmux/window.c @@ -1,4 +1,4 @@ -/* $OpenBSD: window.c,v 1.197 2017/05/31 10:15:51 nicm Exp $ */ +/* $OpenBSD: window.c,v 1.198 2017/06/04 09:02:36 nicm Exp $ */ /* * Copyright (c) 2007 Nicholas Marriott @@ -29,6 +29,7 @@ #include #include #include +#include #include "tmux.h" @@ -408,7 +409,7 @@ void window_set_name(struct window *w, const char *new_name) { free(w->name); - w->name = xstrdup(new_name); + utf8_stravis(&w->name, new_name, VIS_OCTAL|VIS_CSTYLE|VIS_TAB|VIS_NL); notify_window("window-renamed", w); } -- 2.20.1