diff options
author | Bram Moolenaar <Bram@vim.org> | 2022-11-13 17:53:46 +0000 |
---|---|---|
committer | Bram Moolenaar <Bram@vim.org> | 2022-11-13 17:53:46 +0000 |
commit | 3b014befa006b7224a84d7d58d9603fc261f34cd (patch) | |
tree | e3fd53778f0a9a46bb46e6d096ece9e0f51ac18f | |
parent | 2f7bfe66a1373051792f2ecaeefb66049825221d (diff) | |
download | vim-git-3b014befa006b7224a84d7d58d9603fc261f34cd.tar.gz |
patch 9.0.0871: using freed memory when clearing augroup at more promptv9.0.0871
Problem: Using freed memory when clearing augroup at more prompt.
Solution: Delay clearing augroup until it's safe. (closes #11441)
-rw-r--r-- | src/autocmd.c | 22 | ||||
-rw-r--r-- | src/testdir/test_autocmd.vim | 22 | ||||
-rw-r--r-- | src/version.c | 2 |
3 files changed, 41 insertions, 5 deletions
diff --git a/src/autocmd.c b/src/autocmd.c index cf0f0946a..8a0992c09 100644 --- a/src/autocmd.c +++ b/src/autocmd.c @@ -296,9 +296,14 @@ show_autocmd(AutoPat *ap, event_T event) if (ap->pat == NULL) // pattern has been removed return; + // Make sure no info referenced by "ap" is cleared, e.g. when a timer + // clears an augroup. Jump to "theend" after this! + // "ap->pat" may be cleared anyway. + ++autocmd_busy; + msg_putchar('\n'); if (got_int) - return; + goto theend; if (event != last_event || ap->group != last_group) { if (ap->group != AUGROUP_DEFAULT) @@ -314,8 +319,12 @@ show_autocmd(AutoPat *ap, event_T event) last_group = ap->group; msg_putchar('\n'); if (got_int) - return; + goto theend; } + + if (ap->pat == NULL) + goto theend; // timer might have cleared the pattern or group + msg_col = 4; msg_outtrans(ap->pat); @@ -328,21 +337,24 @@ show_autocmd(AutoPat *ap, event_T event) msg_putchar('\n'); msg_col = 14; if (got_int) - return; + goto theend; msg_outtrans(ac->cmd); #ifdef FEAT_EVAL if (p_verbose > 0) last_set_msg(ac->script_ctx); #endif if (got_int) - return; + goto theend; if (ac->next != NULL) { msg_putchar('\n'); if (got_int) - return; + goto theend; } } + +theend: + --autocmd_busy; } /* diff --git a/src/testdir/test_autocmd.vim b/src/testdir/test_autocmd.vim index 04f3e1431..f2f3725b3 100644 --- a/src/testdir/test_autocmd.vim +++ b/src/testdir/test_autocmd.vim @@ -62,6 +62,7 @@ if has('timers') set updatetime=20 call timer_start(200, 'ExitInsertMode') call feedkeys('a', 'x!') + sleep 30m call assert_equal(1, g:triggered) unlet g:triggered au! CursorHoldI @@ -2159,6 +2160,27 @@ func Test_autocmd_user() unlet s:res endfunc +func Test_autocmd_user_clear_group() + CheckRunVimInTerminal + + let lines =<< trim END + autocmd! User + for i in range(1, 999) + exe 'autocmd User ' .. 'Foo' .. i .. ' bar' + endfor + au CmdlineLeave : call timer_start(0, {-> execute('autocmd! User')}) + END + call writefile(lines, 'XautoUser', 'D') + let buf = RunVimInTerminal('-S XautoUser', {'rows': 10}) + + " this was using freed memory + call term_sendkeys(buf, ":autocmd User\<CR>") + call TermWait(buf, 50) + call term_sendkeys(buf, "G") + + call StopVimInTerminal(buf) +endfunc + function s:Before_test_dirchanged() augroup test_dirchanged autocmd! diff --git a/src/version.c b/src/version.c index 73c106e1d..b57fffe7d 100644 --- a/src/version.c +++ b/src/version.c @@ -696,6 +696,8 @@ static char *(features[]) = static int included_patches[] = { /* Add new patch number below this line */ /**/ + 871, +/**/ 870, /**/ 869, |