mirror of
https://github.com/tmux/tmux.git
synced 2026-07-03 10:32:31 +00:00
Do not double free or leak pane on failure, from Uzair Aftab in GitHub
issue 5316.
This commit is contained in:
@@ -82,7 +82,7 @@ cmd_split_window_exec(struct cmd *self, struct cmdq_item *item)
|
|||||||
struct session *s = target->s;
|
struct session *s = target->s;
|
||||||
struct winlink *wl = target->wl;
|
struct winlink *wl = target->wl;
|
||||||
struct window *w = wl->window;
|
struct window *w = wl->window;
|
||||||
struct window_pane *wp = target->wp, *new_wp;
|
struct window_pane *wp = target->wp, *new_wp = NULL;
|
||||||
struct layout_cell *lc = NULL;
|
struct layout_cell *lc = NULL;
|
||||||
struct cmd_find_state fs;
|
struct cmd_find_state fs;
|
||||||
int input, empty, is_floating, flags = 0;
|
int input, empty, is_floating, flags = 0;
|
||||||
@@ -168,6 +168,11 @@ cmd_split_window_exec(struct cmd *self, struct cmdq_item *item)
|
|||||||
if ((new_wp = spawn_pane(&sc, &cause)) == NULL) {
|
if ((new_wp = spawn_pane(&sc, &cause)) == NULL) {
|
||||||
cmdq_error(item, "create pane failed: %s", cause);
|
cmdq_error(item, "create pane failed: %s", cause);
|
||||||
free(cause);
|
free(cause);
|
||||||
|
/*
|
||||||
|
* spawn_pane has already torn the half-built pane down (its
|
||||||
|
* fork-failure path removes the pane and destroys the layout
|
||||||
|
* cell), so new_wp is NULL and there is nothing for fail to do.
|
||||||
|
*/
|
||||||
goto fail;
|
goto fail;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -220,10 +225,6 @@ cmd_split_window_exec(struct cmd *self, struct cmdq_item *item)
|
|||||||
if (input) {
|
if (input) {
|
||||||
switch (window_pane_start_input(new_wp, item, &cause)) {
|
switch (window_pane_start_input(new_wp, item, &cause)) {
|
||||||
case -1:
|
case -1:
|
||||||
server_client_remove_pane(new_wp);
|
|
||||||
if (!is_floating)
|
|
||||||
layout_close_pane(new_wp);
|
|
||||||
window_remove_pane(wp->window, new_wp);
|
|
||||||
cmdq_error(item, "%s", cause);
|
cmdq_error(item, "%s", cause);
|
||||||
free(cause);
|
free(cause);
|
||||||
goto fail;
|
goto fail;
|
||||||
@@ -270,10 +271,20 @@ cmd_split_window_exec(struct cmd *self, struct cmdq_item *item)
|
|||||||
return (CMD_RETURN_NORMAL);
|
return (CMD_RETURN_NORMAL);
|
||||||
|
|
||||||
fail:
|
fail:
|
||||||
|
/*
|
||||||
|
* If the pane was spawned before we failed, tear it down here; this
|
||||||
|
* also destroys its layout cell. spawn_pane's own failure path has
|
||||||
|
* already done this, so new_wp is NULL in that case.
|
||||||
|
*/
|
||||||
|
if (new_wp != NULL) {
|
||||||
|
server_client_remove_pane(new_wp);
|
||||||
|
if (!is_floating)
|
||||||
|
layout_close_pane(new_wp);
|
||||||
|
window_remove_pane(wp->window, new_wp);
|
||||||
|
}
|
||||||
if (sc.argv != NULL)
|
if (sc.argv != NULL)
|
||||||
cmd_free_argv(sc.argc, sc.argv);
|
cmd_free_argv(sc.argc, sc.argv);
|
||||||
environ_free(sc.environ);
|
environ_free(sc.environ);
|
||||||
layout_destroy_cell(w, lc, &w->layout_root);
|
|
||||||
|
|
||||||
return (CMD_RETURN_ERROR);
|
return (CMD_RETURN_ERROR);
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user