summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNicholas Marriott <nicm@cvs.openbsd.org>2012-10-11 08:53:51 +0000
committerNicholas Marriott <nicm@cvs.openbsd.org>2012-10-11 08:53:51 +0000
commit34dbeac19dd66fbe5a8246e8269d7f29f81c9de1 (patch)
tree3bd19bff9dd10ac042dd46ca802e8226f30e4710
parent34cd82d3e76b73678dcb1e9453e917773cdea5c1 (diff)
Fix a use-after-free when collapsing the tree in choose mode, from
Carl Henrik Lunde.
-rw-r--r--usr.bin/tmux/window-choose.c15
1 files changed, 8 insertions, 7 deletions
diff --git a/usr.bin/tmux/window-choose.c b/usr.bin/tmux/window-choose.c
index 86511193d1c..16d447ca995 100644
--- a/usr.bin/tmux/window-choose.c
+++ b/usr.bin/tmux/window-choose.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: window-choose.c,v 1.27 2012/10/02 08:16:28 nicm Exp $ */
+/* $OpenBSD: window-choose.c,v 1.28 2012/10/11 08:53:50 nicm Exp $ */
/*
* Copyright (c) 2009 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -181,8 +181,8 @@ window_choose_free(struct window_pane *wp)
struct window_choose_mode_item *item;
u_int i;
- for (i = 0; i < ARRAY_LENGTH(&data->list); i++) {
- item = &ARRAY_ITEM(&data->list, i);
+ for (i = 0; i < ARRAY_LENGTH(&data->old_list); i++) {
+ item = &ARRAY_ITEM(&data->old_list, i);
if (data->freefn != NULL && item->wcd != NULL)
data->freefn(item->wcd);
free(item->name);
@@ -289,6 +289,7 @@ window_choose_collapse(struct window_pane *wp, struct session *s)
if (!ARRAY_EMPTY(&list_copy)) {
ARRAY_FREE(&data->list);
ARRAY_CONCAT(&data->list, &list_copy);
+ ARRAY_FREE(&list_copy);
}
}
@@ -296,11 +297,11 @@ void
window_choose_collapse_all(struct window_pane *wp)
{
struct window_choose_mode_data *data = wp->modedata;
- struct window_choose_mode_item *item, *chosen;
- struct session *s;
+ struct window_choose_mode_item *item;
+ struct session *s, *chosen;
u_int i;
- chosen = &ARRAY_ITEM(&data->list, data->selected);
+ chosen = ARRAY_ITEM(&data->list, data->selected).wcd->session;
RB_FOREACH(s, sessions, &sessions)
window_choose_collapse(wp, s);
@@ -309,7 +310,7 @@ window_choose_collapse_all(struct window_pane *wp)
for (i = 0; i < ARRAY_LENGTH(&data->list); i++) {
item = &ARRAY_ITEM(&data->list, i);
- if (chosen->wcd->session != item->wcd->tree_session)
+ if (chosen != item->wcd->tree_session)
continue;
if (item->wcd->type & TREE_SESSION)