diff options
author | Konst Mayer <cdlscpmv@gmail.com> | 2023-11-18 23:05:01 +0700 |
---|---|---|
committer | Rafael Marçalo <raroma09@gmail.com> | 2023-12-05 15:40:16 +0000 |
commit | ccc4484add602d36e847b4eace5f475ff24a5f12 (patch) | |
tree | 39f973ceca36bb41aec6056442574bbf18907083 /src | |
parent | 1a1a232e4a78d5ab3eb55978606db9a6dc4e78b8 (diff) |
Prevent use-after-free
Diffstat (limited to 'src')
-rw-r--r-- | src/autocmd.c | 19 |
1 files changed, 16 insertions, 3 deletions
diff --git a/src/autocmd.c b/src/autocmd.c index f3a1875..8e6af79 100644 --- a/src/autocmd.c +++ b/src/autocmd.c @@ -249,9 +249,9 @@ gboolean autocmd_add(Client *c, char *name, gboolean delete) */ gboolean autocmd_run(Client *c, AuEvent event, const char *uri, const char *group) { - GSList *lg, *lc; + GSList *lg, *lc, *lcc; AuGroup *grp; - AutoCmd *cmd; + AutoCmd *cmd, *new; guint bits = events[event].bits; /* if there is no autocmd for this event - skip here */ @@ -266,9 +266,20 @@ gboolean autocmd_run(Client *c, AuEvent event, const char *uri, const char *grou if (group && strcmp(group, grp->name)) { continue; } - /* test each command in group */ + + /* make a deep copy of grp->cmds since it can be modified by ex_run_string() below */ + lcc = NULL; for (lc = grp->cmds; lc; lc = lc->next) { cmd = lc->data; + new = new_autocmd(cmd->excmd, cmd->pattern); + new->bits = cmd->bits; + lcc = g_slist_prepend(lcc, new); // use prepend+reverse instead of append for efficiency + } + lcc = g_slist_reverse(lcc); + + /* test each command in group */ + for (lc = lcc; lc; lc = lc->next, free_autocmd(cmd)) { + cmd = lc->data; /* skip if this dos not match the event bits */ if (!(bits & cmd->bits)) { continue; @@ -279,6 +290,8 @@ gboolean autocmd_run(Client *c, AuEvent event, const char *uri, const char *grou continue; } } + + g_slist_free(lcc); } return true; |