To: vim-dev@vim.org Subject: patch 5.4p.5 Fcc: outbox From: Bram Moolenaar ------------ Another nasty autocommand problem. It appears more people are using autocommands these days. It requires a radical change to how autocommands are executed. But not right now. Patch 5.4p.5 Problem: When changing buffers in a BufDelete autocommand, there could be ml_line errors and/or a crash. (Schandl) Was caused by deleting the current buffer. Solution: When the buffer to be deleted unexpectedly becomes the current buffer, don't delete it. Also added a check for this in test13. Files: src/buffer.c, src/testdir/test13.in, src/testdir/test13.ok *** ../vim-5.4p/src/buffer.c Mon Jul 19 11:08:56 1999 --- src/buffer.c Tue Jul 20 13:17:13 1999 *************** *** 185,190 **** --- 185,194 ---- int free_buf; int del_buf; { + #ifdef AUTOCMD + int is_curbuf; + #endif + if (buf->b_nwindows > 0) --buf->b_nwindows; if (buf->b_nwindows == 0 && win != NULL) *************** *** 218,226 **** * Free all things allocated for this buffer. * Also calls the "BufDelete" autocommands when del_buf is TRUE. */ buf_freeall(buf, del_buf); ! if (!buf_valid(buf)) /* autocommands may delete the buffer */ return; /* * Remove the buffer from the list. --- 222,242 ---- * Free all things allocated for this buffer. * Also calls the "BufDelete" autocommands when del_buf is TRUE. */ + #ifdef AUTOCMD + is_curbuf = (buf == curbuf); + #endif buf_freeall(buf, del_buf); ! #ifdef AUTOCMD ! /* ! * Autocommands may have deleted the buffer. ! * It's possible that autocommands change curbuf to the one being deleted. ! * This might cause curbuf to be deleted unexpectedly. But in some cases ! * it's OK to delete the curbuf, because a new one is obtained anyway. ! * Therefore only return if curbuf changed to the deleted buffer. ! */ ! if (!buf_valid(buf) || (buf == curbuf && !is_curbuf)) return; + #endif /* * Remove the buffer from the list. *************** *** 267,276 **** /*ARGSUSED*/ void buf_freeall(buf, del_buf) ! BUF *buf; ! int del_buf; /* buffer is going to be deleted */ { #ifdef AUTOCMD apply_autocmds(EVENT_BUFUNLOAD, buf->b_fname, buf->b_fname, FALSE, buf); if (!buf_valid(buf)) /* autocommands may delete the buffer */ return; --- 283,294 ---- /*ARGSUSED*/ void buf_freeall(buf, del_buf) ! BUF *buf; ! int del_buf; /* buffer is going to be deleted */ { #ifdef AUTOCMD + int is_curbuf = (buf == curbuf); + apply_autocmds(EVENT_BUFUNLOAD, buf->b_fname, buf->b_fname, FALSE, buf); if (!buf_valid(buf)) /* autocommands may delete the buffer */ return; *************** *** 280,285 **** --- 298,311 ---- if (!buf_valid(buf)) /* autocommands may delete the buffer */ return; } + /* + * It's possible that autocommands change curbuf to the one being deleted. + * This might cause curbuf to be deleted unexpectedly. But in some cases + * it's OK to delete the curbuf, because a new one is obtained anyway. + * Therefore only return if curbuf changed to the deleted buffer. + */ + if (buf == curbuf && !is_curbuf) + return; #endif #ifdef HAVE_TCL tcl_buffer_free(buf); *** ../vim-5.4p/src/testdir/test13.in Mon Jul 19 11:08:50 1999 --- src/testdir/test13.in Tue Jul 20 13:31:27 1999 *************** *** 7,12 **** --- 7,15 ---- Also test deleting the buffer on a Unload event. If this goes wrong there will be the ATTENTION prompt. + Also test changing buffers in a BufDel autocommand. If this goes wrong there + are ml_line errors and/or a Crash. + STARTTEST :/^start of testfile/,/^end of testfile/w! Xtestje1 :/^start of testfile/,/^end of testfile/w! Xtestje2 *************** *** 36,41 **** --- 39,51 ---- :e Xtestje2 :sp Xtestje1 :e + :w >>test.out + :au! + :only + :e Xtestje1 + :bdel Xtestje2 Xtestje3 test.out test13.in + :au BufDelete Xtestje1 buf Xtestje1 + :bd :w >>test.out :!rm -rf Xtestje* :qa! *** ../vim-5.4p/src/testdir/test13.ok Mon Jul 19 11:08:50 1999 --- src/testdir/test13.ok Tue Jul 20 13:35:40 1999 *************** *** 22,24 **** --- 22,30 ---- contents contents end of testfile + start of testfile + testje1 + contents + contents + contents + end of testfile -- hundred-and-one symptoms of being an internet addict: 174. You know what a listserv is. --/-/---- Bram Moolenaar ---- Bram@moolenaar.net ---- Bram@vim.org ---\-\-- \ \ www.vim.org/iccf www.moolenaar.net www.vim.org / /