aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJan Edmund Lazo <jan.lazo@mail.utoronto.ca>2020-03-14 13:41:42 -0400
committerJan Edmund Lazo <jan.lazo@mail.utoronto.ca>2020-04-13 12:00:30 -0400
commit7ef2677ca6a57ad464753e02619f2c9a70ce004b (patch)
tree8f7a847afb30d733b0ecf7932baff89ff9f10549
parente892dde3691bd61c809640b55023c44a1423fd92 (diff)
downloadrneovim-7ef2677ca6a57ad464753e02619f2c9a70ce004b.tar.gz
rneovim-7ef2677ca6a57ad464753e02619f2c9a70ce004b.tar.bz2
rneovim-7ef2677ca6a57ad464753e02619f2c9a70ce004b.zip
vim-patch:8.2.0381: using freed memory with :lvimgrep and autocommand
Problem: Using freed memory with :lvimgrep and autocommand. (extracted from POC by Dominique Pelle) Solution: Avoid deleting a dummy buffer used in a window. (closes vim/vim#5777) https://github.com/vim/vim/commit/2573af3519ad062ddad647b97e32090f106f2ac1
-rw-r--r--src/nvim/quickfix.c24
-rw-r--r--src/nvim/testdir/test_quickfix.vim8
2 files changed, 31 insertions, 1 deletions
diff --git a/src/nvim/quickfix.c b/src/nvim/quickfix.c
index c444326533..484168e798 100644
--- a/src/nvim/quickfix.c
+++ b/src/nvim/quickfix.c
@@ -5134,6 +5134,7 @@ theend:
// Restore current working directory to "dirname_start" if they differ, taking
// into account whether it is set locally or globally.
static void restore_start_dir(char_u *dirname_start)
+ FUNC_ATTR_NONNULL_ALL
{
char_u *dirname_now = xmalloc(MAXPATHL);
@@ -5251,8 +5252,29 @@ load_dummy_buffer (
// directory to "dirname_start" prior to returning, if autocmds or the
// 'autochdir' option have changed it.
static void wipe_dummy_buffer(buf_T *buf, char_u *dirname_start)
+ FUNC_ATTR_NONNULL_ALL
{
- if (curbuf != buf) { // safety check
+ // If any autocommand opened a window on the dummy buffer, close that
+ // window. If we can't close them all then give up.
+ while (buf->b_nwindows > 0) {
+ bool did_one = false;
+
+ if (firstwin->w_next != NULL) {
+ for (win_T *wp = firstwin; wp != NULL; wp = wp->w_next) {
+ if (wp->w_buffer == buf) {
+ if (win_close(wp, false) == OK) {
+ did_one = true;
+ }
+ break;
+ }
+ }
+ }
+ if (!did_one) {
+ return;
+ }
+ }
+
+ if (curbuf != buf && buf->b_nwindows == 0) { // safety check
cleanup_T cs;
// Reset the error/interrupt/exception state here so that aborting()
diff --git a/src/nvim/testdir/test_quickfix.vim b/src/nvim/testdir/test_quickfix.vim
index 015f771435..35555ca9d3 100644
--- a/src/nvim/testdir/test_quickfix.vim
+++ b/src/nvim/testdir/test_quickfix.vim
@@ -3318,6 +3318,14 @@ func Test_lvimgrep_crash()
enew | only
endfunc
+func Test_lvimgrep_crash2()
+ au BufNewFile x sfind
+ call assert_fails('lvimgrep x x', 'E480:')
+ call assert_fails('lvimgrep x x x', 'E480:')
+
+ au! BufNewFile
+endfunc
+
" Test for the position of the quickfix and location list window
func Test_qfwin_pos()
" Open two windows