From 3909d70f554a140bd4fa6eea04e1e24ae8ccc663 Mon Sep 17 00:00:00 2001 From: Randy Palamar Date: Tue, 25 Apr 2023 14:39:02 -0600 Subject: fix use after free in cmd_files() When the cmd closes the window the window pointer gets freed along the way. We can't use win->next to update the loop variable if sam_execute() has been called. Instead we can store win->next early and use that variable to continue the loop. fixes #1090 --- sam.c | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/sam.c b/sam.c index 29e9c58..181f229 100644 --- a/sam.c +++ b/sam.c @@ -1564,14 +1564,16 @@ static bool cmd_print(Vis *vis, Win *win, Command *cmd, const char *argv[], Sele static bool cmd_files(Vis *vis, Win *win, Command *cmd, const char *argv[], Selection *sel, Filerange *range) { bool ret = true; - for (Win *win = vis->windows; win; win = win->next) { - if (win->file->internal) + for (Win *wn, *w = vis->windows; w; w = wn) { + /* w can get freed by sam_execute() so store w->next early */ + wn = w->next; + if (w->file->internal) continue; bool match = !cmd->regex || - (win->file->name && text_regex_match(cmd->regex, win->file->name, 0) == 0); + (w->file->name && text_regex_match(cmd->regex, w->file->name, 0) == 0); if (match ^ (argv[0][0] == 'Y')) { Filerange def = text_range_new(0, 0); - ret &= sam_execute(vis, win, cmd->cmd, NULL, &def); + ret &= sam_execute(vis, w, cmd->cmd, NULL, &def); } } return ret; -- cgit v1.2.3