From 8149bc3fa6e93cb083b165a21baa5ec07dd473dc 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). --- input.c | 13 +++++++++---- screen.c | 3 ++- tmux.h | 1 + utf8.c | 25 +++++++++++++++++++++++++ window.c | 3 ++- 5 files changed, 39 insertions(+), 6 deletions(-) diff --git a/input.c b/input.c index 5ba2ec5f..27c0a31a 100644 --- a/input.c +++ b/input.c @@ -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/screen.c b/screen.c index 087611ae..ebd117a0 100644 --- a/screen.c +++ b/screen.c @@ -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/tmux.h b/tmux.h index 77d5372a..99c42aa4 100644 --- a/tmux.h +++ b/tmux.h @@ -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/utf8.c b/utf8.c index 3a315749..099541fe 100644 --- a/utf8.c +++ b/utf8.c @@ -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/window.c b/window.c index 5fe7c8b8..4b59f205 100644 --- a/window.c +++ b/window.c @@ -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); }