mirror of
https://github.com/neovim/neovim.git
synced 2026-03-31 04:42:03 +00:00
vim-patch:9.2.0182: autocmds may leave windows with w_locked set #38332
Problem: autocmds that switch windows may cause them to remain with
w_locked set, preventing them from being closed longer than
intended.
Solution: Unset w_locked in the window where it was set (Sean Dewar).
closes: vim/vim#19716
bae31c35bb
Also move alist_add_list's ga_grow inside the if block, so it's only called when
check_arglist_locked is OK, like Vim.
I also notice a redundant return at the end of the block; could be useful if
more code is added later, so I'm leaving it.
This commit is contained in:
@@ -205,6 +205,8 @@ void alist_set(alist_T *al, int count, char **files, int use_curbuf, int *fnum_l
|
||||
/// @param set_fnum 1: set buffer number; 2: re-use curbuf
|
||||
void alist_add(alist_T *al, char *fname, int set_fnum)
|
||||
{
|
||||
win_T *wp = curwin;
|
||||
|
||||
if (fname == NULL) { // don't add NULL file names
|
||||
return;
|
||||
}
|
||||
@@ -212,7 +214,7 @@ void alist_add(alist_T *al, char *fname, int set_fnum)
|
||||
return;
|
||||
}
|
||||
arglist_locked = true;
|
||||
curwin->w_locked = true;
|
||||
wp->w_locked = true;
|
||||
|
||||
#ifdef BACKSLASH_IN_FILENAME
|
||||
slash_adjust(fname);
|
||||
@@ -225,7 +227,7 @@ void alist_add(alist_T *al, char *fname, int set_fnum)
|
||||
al->al_ga.ga_len++;
|
||||
|
||||
arglist_locked = false;
|
||||
curwin->w_locked = false;
|
||||
wp->w_locked = false;
|
||||
}
|
||||
|
||||
#if defined(BACKSLASH_IN_FILENAME)
|
||||
@@ -345,25 +347,28 @@ static void alist_add_list(int count, char **files, int after, bool will_edit)
|
||||
FUNC_ATTR_NONNULL_ALL
|
||||
{
|
||||
int old_argcount = ARGCOUNT;
|
||||
ga_grow(&ALIST(curwin)->al_ga, count);
|
||||
|
||||
if (check_arglist_locked() != FAIL) {
|
||||
win_T *wp = curwin;
|
||||
|
||||
ga_grow(&ALIST(wp)->al_ga, count);
|
||||
after = MIN(MAX(after, 0), ARGCOUNT);
|
||||
if (after < ARGCOUNT) {
|
||||
memmove(&(ARGLIST[after + count]), &(ARGLIST[after]),
|
||||
(size_t)(ARGCOUNT - after) * sizeof(aentry_T));
|
||||
}
|
||||
arglist_locked = true;
|
||||
curwin->w_locked = true;
|
||||
wp->w_locked = true;
|
||||
for (int i = 0; i < count; i++) {
|
||||
const int flags = BLN_LISTED | (will_edit ? BLN_CURBUF : 0);
|
||||
ARGLIST[after + i].ae_fname = files[i];
|
||||
ARGLIST[after + i].ae_fnum = buflist_add(files[i], flags);
|
||||
}
|
||||
arglist_locked = false;
|
||||
curwin->w_locked = false;
|
||||
ALIST(curwin)->al_ga.ga_len += count;
|
||||
if (old_argcount > 0 && curwin->w_arg_idx >= after) {
|
||||
curwin->w_arg_idx += count;
|
||||
wp->w_locked = false;
|
||||
ALIST(wp)->al_ga.ga_len += count;
|
||||
if (old_argcount > 0 && wp->w_arg_idx >= after) {
|
||||
wp->w_arg_idx += count;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -802,4 +802,24 @@ func Test_crash_arglist_uaf2()
|
||||
au! BufAdd
|
||||
endfunc
|
||||
|
||||
func Test_arglist_w_locked_unlock()
|
||||
au BufAdd * split
|
||||
|
||||
args a
|
||||
call assert_equal(2, winnr('$'))
|
||||
wincmd p
|
||||
quit
|
||||
call assert_equal(1, winnr('$'))
|
||||
|
||||
argedit b
|
||||
call assert_equal(2, winnr('$'))
|
||||
wincmd p
|
||||
quit
|
||||
call assert_equal(1, winnr('$'))
|
||||
|
||||
%argd
|
||||
%bw!
|
||||
au! BufAdd
|
||||
endfunc
|
||||
|
||||
" vim: shiftwidth=2 sts=2 expandtab
|
||||
|
||||
Reference in New Issue
Block a user