1
0
forked from aniani/vim

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 #11441)
This commit is contained in:
Bram Moolenaar 2022-11-13 17:53:46 +00:00
parent 2f7bfe66a1
commit 3b014befa0
3 changed files with 41 additions and 5 deletions

View File

@ -296,9 +296,14 @@ show_autocmd(AutoPat *ap, event_T event)
if (ap->pat == NULL) // pattern has been removed if (ap->pat == NULL) // pattern has been removed
return; 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'); msg_putchar('\n');
if (got_int) if (got_int)
return; goto theend;
if (event != last_event || ap->group != last_group) if (event != last_event || ap->group != last_group)
{ {
if (ap->group != AUGROUP_DEFAULT) if (ap->group != AUGROUP_DEFAULT)
@ -314,8 +319,12 @@ show_autocmd(AutoPat *ap, event_T event)
last_group = ap->group; last_group = ap->group;
msg_putchar('\n'); msg_putchar('\n');
if (got_int) if (got_int)
return; goto theend;
} }
if (ap->pat == NULL)
goto theend; // timer might have cleared the pattern or group
msg_col = 4; msg_col = 4;
msg_outtrans(ap->pat); msg_outtrans(ap->pat);
@ -328,21 +337,24 @@ show_autocmd(AutoPat *ap, event_T event)
msg_putchar('\n'); msg_putchar('\n');
msg_col = 14; msg_col = 14;
if (got_int) if (got_int)
return; goto theend;
msg_outtrans(ac->cmd); msg_outtrans(ac->cmd);
#ifdef FEAT_EVAL #ifdef FEAT_EVAL
if (p_verbose > 0) if (p_verbose > 0)
last_set_msg(ac->script_ctx); last_set_msg(ac->script_ctx);
#endif #endif
if (got_int) if (got_int)
return; goto theend;
if (ac->next != NULL) if (ac->next != NULL)
{ {
msg_putchar('\n'); msg_putchar('\n');
if (got_int) if (got_int)
return; goto theend;
} }
} }
theend:
--autocmd_busy;
} }
/* /*

View File

@ -62,6 +62,7 @@ if has('timers')
set updatetime=20 set updatetime=20
call timer_start(200, 'ExitInsertMode') call timer_start(200, 'ExitInsertMode')
call feedkeys('a', 'x!') call feedkeys('a', 'x!')
sleep 30m
call assert_equal(1, g:triggered) call assert_equal(1, g:triggered)
unlet g:triggered unlet g:triggered
au! CursorHoldI au! CursorHoldI
@ -2159,6 +2160,27 @@ func Test_autocmd_user()
unlet s:res unlet s:res
endfunc 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() function s:Before_test_dirchanged()
augroup test_dirchanged augroup test_dirchanged
autocmd! autocmd!

View File

@ -695,6 +695,8 @@ static char *(features[]) =
static int included_patches[] = static int included_patches[] =
{ /* Add new patch number below this line */ { /* Add new patch number below this line */
/**/
871,
/**/ /**/
870, 870,
/**/ /**/