Mercurial > vim
changeset 31073:df4957f0ccb5 v9.0.0871
patch 9.0.0871: using freed memory when clearing augroup at more prompt
Commit: https://github.com/vim/vim/commit/3b014befa006b7224a84d7d58d9603fc261f34cd
Author: Bram Moolenaar <Bram@vim.org>
Date: Sun Nov 13 17:53:46 2022 +0000
patch 9.0.0871: using freed memory when clearing augroup at more prompt
Problem: Using freed memory when clearing augroup at more prompt.
Solution: Delay clearing augroup until it's safe. (closes https://github.com/vim/vim/issues/11441)
author | Bram Moolenaar <Bram@vim.org> |
---|---|
date | Sun, 13 Nov 2022 19:00:05 +0100 |
parents | f6694a9612d2 |
children | a64ca9f84fd3 |
files | src/autocmd.c src/testdir/test_autocmd.vim src/version.c |
diffstat | 3 files changed, 41 insertions(+), 5 deletions(-) [+] |
line wrap: on
line diff
--- 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; } /*
--- 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!