aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRandy Palamar <palamar@ualberta.ca>2023-04-25 14:39:02 -0600
committerRandy Palamar <palamar@ualberta.ca>2023-05-28 08:51:57 -0600
commit3909d70f554a140bd4fa6eea04e1e24ae8ccc663 (patch)
tree4e200c019d0adc0f15b225de5c5e2fccfbd9d733
parent814cda01ba7805d7c7e29871e979b609b9fa9312 (diff)
downloadvis-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
-rw-r--r--sam.c10
1 files 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;