diff options
| author | Randy Palamar <palamar@ualberta.ca> | 2023-04-25 14:39:02 -0600 |
|---|---|---|
| committer | Randy Palamar <palamar@ualberta.ca> | 2023-05-28 08:51:57 -0600 |
| commit | 3909d70f554a140bd4fa6eea04e1e24ae8ccc663 (patch) | |
| tree | 4e200c019d0adc0f15b225de5c5e2fccfbd9d733 /sam.c | |
| parent | 814cda01ba7805d7c7e29871e979b609b9fa9312 (diff) | |
| download | vis-3909d70f554a140bd4fa6eea04e1e24ae8ccc663.tar.gz vis-3909d70f554a140bd4fa6eea04e1e24ae8ccc663.tar.xz | |
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
Diffstat (limited to 'sam.c')
| -rw-r--r-- | sam.c | 10 |
1 files changed, 6 insertions, 4 deletions
@@ -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; |
