Patch 8.0.0486
Problem: Crash and endless loop when closing windows in a SessionLoadPost
autocommand.
Solution: Check for valid tabpage. (partly neovim #6308)
Files: src/testdir/test_autocmd.vim, src/fileio.c, src/proto/window.pro,
src/window.c
*** ../vim-8.0.0485/src/testdir/test_autocmd.vim 2017-03-19
16:09:41.157653918 +0100
--- src/testdir/test_autocmd.vim 2017-03-19 16:12:55.492239467 +0100
***************
*** 345,347 ****
--- 345,410 ----
call delete('Xdir', 'd')
au! BufEnter
endfunc
+
+ " Closing a window might cause an endless loop
+ " E814 for older Vims
+ function Test_autocmd_bufwipe_in_SessLoadPost()
+ tabnew
+ set noswapfile
+ let g:bufnr=bufnr('%')
+ mksession!
+
+ let content=['set nocp noswapfile',
+ \ 'let v:swapchoice="e"',
+ \ 'augroup test_autocmd_sessionload',
+ \ 'autocmd!',
+ \ 'autocmd SessionLoadPost * 4bw!',
+ \ 'augroup END'
+ \ ]
+ call writefile(content, 'Xvimrc')
+ let a=system(v:progpath. ' -u Xvimrc --noplugins -S Session.vim')
+ call assert_match('E814', a)
+
+ unlet! g:bufnr
+ set swapfile
+ for file in ['Session.vim', 'Xvimrc']
+ call delete(file)
+ endfor
+ endfunc
+
+ " SEGV occurs in older versions.
+ function Test_autocmd_bufwipe_in_SessLoadPost2()
+ tabnew
+ set noswapfile
+ let g:bufnr=bufnr('%')
+ mksession!
+
+ let content = ['set nocp noswapfile',
+ \ 'function! DeleteInactiveBufs()',
+ \ ' tabfirst',
+ \ ' let tabblist = []',
+ \ ' for i in range(1, tabpagenr(''$''))',
+ \ ' call extend(tabblist, tabpagebuflist(i))',
+ \ ' endfor',
+ \ ' for b in range(1, bufnr(''$''))',
+ \ ' if bufexists(b) && buflisted(b) && (index(tabblist, b) == -1 ||
bufname(b) =~# ''^$'')',
+ \ ' exec ''bwipeout '' . b',
+ \ ' endif',
+ \ ' endfor',
+ \ 'call append("1", "SessionLoadPost DONE")',
+ \ 'endfunction',
+ \ 'au SessionLoadPost * call DeleteInactiveBufs()']
+ call writefile(content, 'Xvimrc')
+ let a=system(v:progpath. ' -u Xvimrc --noplugins -S Session.vim')
+ " this probably only matches on unix
+ if has("unix")
+ call assert_notmatch('Caught deadly signal SEGV', a)
+ endif
+ call assert_match('SessionLoadPost DONE', a)
+
+ unlet! g:bufnr
+ set swapfile
+ for file in ['Session.vim', 'Xvimrc']
+ call delete(file)
+ endfor
+ endfunc
*** ../vim-8.0.0485/src/fileio.c 2017-03-16 17:23:26.823815869 +0100
--- src/fileio.c 2017-03-19 16:16:23.954716288 +0100
***************
*** 9033,9038 ****
--- 9033,9043 ----
win_remove(curwin, NULL);
aucmd_win_used = FALSE;
last_status(FALSE); /* may need to remove last status line */
+
+ if (!valid_tabpage_win(curtab))
+ /* no valid window in current tabpage */
+ close_tabpage(curtab);
+
restore_snapshot(SNAP_AUCMD_IDX, FALSE);
(void)win_comp_pos(); /* recompute window positions */
unblock_autocmds();
*** ../vim-8.0.0485/src/proto/window.pro 2016-09-12 13:04:23.000000000
+0200
--- src/proto/window.pro 2017-03-19 16:15:41.091029969 +0100
***************
*** 26,31 ****
--- 26,33 ----
int may_open_tabpage(void);
int make_tabpages(int maxcount);
int valid_tabpage(tabpage_T *tpc);
+ int valid_tabpage_win(tabpage_T *tpc);
+ void close_tabpage(tabpage_T *tpc);
tabpage_T *find_tabpage(int n);
int tabpage_index(tabpage_T *ftp);
void goto_tabpage(int n);
*** ../vim-8.0.0485/src/window.c 2017-03-18 23:11:00.287000094 +0100
--- src/window.c 2017-03-19 17:05:27.709065597 +0100
***************
*** 2107,2113 ****
}
/*
! * close all windows for buffer 'buf'
*/
void
close_windows(
--- 2107,2113 ----
}
/*
! * Close all windows for buffer "buf".
*/
void
close_windows(
***************
*** 2131,2137 ****
#endif
)
{
! win_close(wp, FALSE);
/* Start all over, autocommands may change the window layout. */
wp = firstwin;
--- 2131,2140 ----
#endif
)
{
! if (win_close(wp, FALSE) == FAIL)
! /* If closing the window fails give up, to avoid looping
! * forever. */
! break;
/* Start all over, autocommands may change the window layout. */
wp = firstwin;
***************
*** 3759,3764 ****
--- 3762,3819 ----
}
/*
+ * Return TRUE when "tpc" points to a valid tab page and at least one window
is
+ * valid.
+ */
+ int
+ valid_tabpage_win(tabpage_T *tpc)
+ {
+ tabpage_T *tp;
+ win_T *wp;
+
+ FOR_ALL_TABPAGES(tp)
+ {
+ if (tp == tpc)
+ {
+ FOR_ALL_WINDOWS_IN_TAB(tp, wp)
+ {
+ if (win_valid_any_tab(wp))
+ return TRUE;
+ }
+ return FALSE;
+ }
+ }
+ /* shouldn't happen */
+ return FALSE;
+ }
+
+ /*
+ * Close tabpage "tab", assuming it has no windows in it.
+ * There must be another tabpage or this will crash.
+ */
+ void
+ close_tabpage(tabpage_T *tab)
+ {
+ tabpage_T *ptp;
+
+ if (tab == first_tabpage)
+ {
+ first_tabpage = tab->tp_next;
+ ptp = first_tabpage;
+ }
+ else
+ {
+ for (ptp = first_tabpage; ptp != NULL && ptp->tp_next != tab;
+ ptp = ptp->tp_next)
+ ;
+ ptp->tp_next = tab->tp_next;
+ }
+
+ goto_tabpage_tp(ptp, FALSE, FALSE);
+ free_tabpage(tab);
+ }
+
+ /*
* Find tab page "n" (first one is 1). Returns NULL when not found.
*/
tabpage_T *
*** ../vim-8.0.0485/src/version.c 2017-03-19 16:09:41.157653918 +0100
--- src/version.c 2017-03-19 17:08:47.315564870 +0100
***************
*** 766,767 ****
--- 766,769 ----
{ /* Add new patch number below this line */
+ /**/
+ 486,
/**/
--
hundred-and-one symptoms of being an internet addict:
165. You have a web page burned into your glasses
/// Bram Moolenaar -- [email protected] -- http://www.Moolenaar.net \\\
/// sponsor Vim, vote for features -- http://www.Vim.org/sponsor/ \\\
\\\ an exciting new programming language -- http://www.Zimbu.org ///
\\\ help me help AIDS victims -- http://ICCF-Holland.org ///
--
--
You received this message from the "vim_dev" maillist.
Do not top-post! Type your reply below the text you are replying to.
For more information, visit http://www.vim.org/maillist.php
---
You received this message because you are subscribed to the Google Groups
"vim_dev" group.
To unsubscribe from this group and stop receiving emails from it, send an email
to [email protected].
For more options, visit https://groups.google.com/d/optout.