From 68d59a16cec91d2c2747c8c2862560e89f8f2d31 Mon Sep 17 00:00:00 2001 From: nicm Date: Mon, 14 Oct 2019 08:38:07 +0000 Subject: [PATCH 1/4] Memory leaks, from Igor Wong in GitHub issue 1934. --- cmd-parse.y | 1 + options.c | 1 + tmux.c | 1 + 3 files changed, 3 insertions(+) diff --git a/cmd-parse.y b/cmd-parse.y index 0cd7c6bf..2c924010 100644 --- a/cmd-parse.y +++ b/cmd-parse.y @@ -696,6 +696,7 @@ cmd_parse_build_commands(struct cmd_parse_commands *cmds, pr.status = CMD_PARSE_ERROR; pr.error = cmd_parse_get_error(pi->file, line, cause); free(cause); + cmd_list_free(cmdlist); goto out; } cmd_list_append(cmdlist, add); diff --git a/options.c b/options.c index 1be9f8cd..f683c566 100644 --- a/options.c +++ b/options.c @@ -296,6 +296,7 @@ options_remove(struct options_entry *o) else options_value_free(o, &o->value); RB_REMOVE(options_tree, &oo->tree, o); + free((void *)o->name); free(o); } diff --git a/tmux.c b/tmux.c index c3fe3ee6..fe2647f5 100644 --- a/tmux.c +++ b/tmux.c @@ -130,6 +130,7 @@ make_label(const char *label, char **cause) free(base); goto fail; } + free(base); if (mkdir(resolved, S_IRWXU) != 0 && errno != EEXIST) goto fail; From bbe8ebf9c26e45fd8c402627b84b3646db445d45 Mon Sep 17 00:00:00 2001 From: nicm Date: Mon, 14 Oct 2019 09:16:48 +0000 Subject: [PATCH 2/4] Some old tmux versions can sometimes generate layout strings which have the incorrect size for the top cell. Previously tmux didn't care but now that panes can be partly hidden, the size matters and is checked more strictly. So add some code to fix up the most common problem and a sanity check to reject layouts with any other size problems. Reported by Aleksandrs Ledovskis in GitHub issue 1930. --- cmd-list-keys.c | 2 +- layout-custom.c | 69 ++++++++++++++++++++++++++++++++++++++++++++++++- 2 files changed, 69 insertions(+), 2 deletions(-) diff --git a/cmd-list-keys.c b/cmd-list-keys.c index 5113999d..8636b70a 100644 --- a/cmd-list-keys.c +++ b/cmd-list-keys.c @@ -125,7 +125,7 @@ cmd_list_keys_exec(struct cmd *self, struct cmdq_item *item) cp = utf8_padcstr(table->name, tablewidth); cplen = strlen(cp) + 1; - while (tmpused + cplen + 1>= tmpsize) { + while (tmpused + cplen + 1 >= tmpsize) { tmpsize *= 2; tmp = xrealloc(tmp, tmpsize); } diff --git a/layout-custom.c b/layout-custom.c index 4ac90a37..b049f482 100644 --- a/layout-custom.c +++ b/layout-custom.c @@ -116,13 +116,49 @@ layout_append(struct layout_cell *lc, char *buf, size_t len) return (0); } +/* Check layout sizes fit. */ +static int +layout_check(struct layout_cell *lc) +{ + struct layout_cell *lcchild; + u_int n = 0; + + switch (lc->type) { + case LAYOUT_WINDOWPANE: + break; + case LAYOUT_LEFTRIGHT: + TAILQ_FOREACH(lcchild, &lc->cells, entry) { + if (lcchild->sy != lc->sy) + return (0); + if (!layout_check(lcchild)) + return (0); + n += lcchild->sx + 1; + } + if (n - 1 != lc->sx) + return (0); + break; + case LAYOUT_TOPBOTTOM: + TAILQ_FOREACH(lcchild, &lc->cells, entry) { + if (lcchild->sx != lc->sx) + return (0); + if (!layout_check(lcchild)) + return (0); + n += lcchild->sy + 1; + } + if (n - 1 != lc->sy) + return (0); + break; + } + return (1); +} + /* Parse a layout string and arrange window as layout. */ int layout_parse(struct window *w, const char *layout) { struct layout_cell *lc, *lcchild; struct window_pane *wp; - u_int npanes, ncells; + u_int npanes, ncells, sx = 0, sy = 0; u_short csum; /* Check validity. */ @@ -153,6 +189,37 @@ layout_parse(struct window *w, const char *layout) layout_destroy_cell(w, lcchild, &lc); } + /* + * It appears older versions of tmux were able to generate layouts with + * an incorrect top cell size - if it is larger than the top child then + * correct that (if this is still wrong the check code will catch it). + */ + switch (lc->type) { + case LAYOUT_WINDOWPANE: + break; + case LAYOUT_LEFTRIGHT: + TAILQ_FOREACH(lcchild, &lc->cells, entry) { + sy = lcchild->sy + 1; + sx += lcchild->sx + 1; + } + break; + case LAYOUT_TOPBOTTOM: + TAILQ_FOREACH(lcchild, &lc->cells, entry) { + sx = lcchild->sx + 1; + sy += lcchild->sy + 1; + } + break; + } + if (lc->sx != sx || lc->sy != sy) { + log_debug("fix layout %u,%u to %u,%u", lc->sx, lc->sy, sx,sy); + layout_print_cell(lc, __func__, 0); + lc->sx = sx - 1; lc->sy = sy - 1; + } + + /* Check the new layout. */ + if (!layout_check(lc)) + return (-1); + /* Resize to the layout size. */ window_resize(w, lc->sx, lc->sy); From f18cd5b19c3c8e3941c714f9d7e51914fb5d81f0 Mon Sep 17 00:00:00 2001 From: nicm Date: Mon, 14 Oct 2019 09:19:40 +0000 Subject: [PATCH 3/4] Turn automatic-rename back on if the rename escape sequence is used with an empty name, GitHub issue 1921. --- input.c | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/input.c b/input.c index d76216f4..fc08f42c 100644 --- a/input.c +++ b/input.c @@ -2279,6 +2279,9 @@ input_enter_rename(struct input_ctx *ictx) static void input_exit_rename(struct input_ctx *ictx) { + struct window_pane *wp = ictx->wp; + struct options_entry *oe; + if (ictx->flags & INPUT_DISCARD) return; if (!options_get_number(ictx->wp->options, "allow-rename")) @@ -2287,6 +2290,13 @@ input_exit_rename(struct input_ctx *ictx) if (!utf8_isvalid(ictx->input_buf)) return; + + if (ictx->input_len == 0) { + oe = options_get(wp->window->options, "automatic-rename"); + if (oe != NULL) + options_remove(oe); + 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); From b598bbcc2e8b26855e4d34dfff9c222c28080cd7 Mon Sep 17 00:00:00 2001 From: nicm Date: Mon, 14 Oct 2019 09:24:06 +0000 Subject: [PATCH 4/4] Do not crash with pane_current_command if the pane is newly created and has no shell set, from Thomas Adam. --- format.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/format.c b/format.c index 581fa582..dd69512f 100644 --- a/format.c +++ b/format.c @@ -574,7 +574,7 @@ format_cb_current_command(struct format_tree *ft, struct format_entry *fe) struct window_pane *wp = ft->wp; char *cmd; - if (wp == NULL) + if (wp == NULL || wp->shell == NULL) return; cmd = get_proc_name(wp->fd, wp->tty);