aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndré Twupack <atwupack@mailbox.org>2014-09-21 00:29:45 +0200
committerAndré Twupack <atwupack@mailbox.org>2014-09-21 10:42:27 +0200
commit2b937fe00d8b0b308cce87aee9f70699f8474c1e (patch)
tree7b3c7cf3597222905f907fe99233120df79ef504
parent0ed9f3ec8338783466b0a6ab2661d9a061a436fa (diff)
downloadrneovim-2b937fe00d8b0b308cce87aee9f70699f8474c1e.tar.gz
rneovim-2b937fe00d8b0b308cce87aee9f70699f8474c1e.tar.bz2
rneovim-2b937fe00d8b0b308cce87aee9f70699f8474c1e.zip
vim-patch:7.4.320
Problem: Possible crash when an BufLeave autocommand deletes the buffer. Solution: Check for the window pointer being valid. Postpone freeing the window until autocommands are done. (Yasuhiro Matsumoto) https://code.google.com/p/vim/source/detail?r=v7-4-320
-rw-r--r--src/nvim/buffer.c2
-rw-r--r--src/nvim/fileio.c8
-rw-r--r--src/nvim/globals.h8
-rw-r--r--src/nvim/version.c2
-rw-r--r--src/nvim/window.c7
5 files changed, 20 insertions, 7 deletions
diff --git a/src/nvim/buffer.c b/src/nvim/buffer.c
index 11171617ef..31fa54295a 100644
--- a/src/nvim/buffer.c
+++ b/src/nvim/buffer.c
@@ -318,7 +318,7 @@ close_buffer (
} else if (buf->b_p_bh[0] == 'u') /* 'bufhidden' == "unload" */
unload_buf = true;
- if (win != NULL) {
+ if (win_valid(win)) {
/* Set b_last_cursor when closing the last window for the buffer.
* Remember the last cursor position and window options of the buffer.
* This used to be only for the current window, but then options like
diff --git a/src/nvim/fileio.c b/src/nvim/fileio.c
index 97daa035f8..72dd7170ce 100644
--- a/src/nvim/fileio.c
+++ b/src/nvim/fileio.c
@@ -6754,7 +6754,8 @@ apply_autocmds_group (
--nesting; /* see matching increment above */
// When stopping to execute autocommands, restore the search patterns and
- // the redo buffer. Free buffers in the au_pending_free_buf list.
+ // the redo buffer. Free any buffers in the au_pending_free_buf list and
+ // free any windows in the au_pending_free_win list.
if (!autocmd_busy) {
restore_search_patterns();
restoreRedobuff();
@@ -6764,6 +6765,11 @@ apply_autocmds_group (
free(au_pending_free_buf);
au_pending_free_buf = b;
}
+ while (au_pending_free_win != NULL) {
+ win_T *w = au_pending_free_win->w_next;
+ free(au_pending_free_win);
+ au_pending_free_win = w;
+ }
}
/*
diff --git a/src/nvim/globals.h b/src/nvim/globals.h
index 851022cd62..efad3c3af1 100644
--- a/src/nvim/globals.h
+++ b/src/nvim/globals.h
@@ -468,10 +468,12 @@ EXTERN int keep_filetype INIT(= FALSE); /* value for did_filetype when
* which one is preferred, au_new_curbuf is set to it */
EXTERN buf_T *au_new_curbuf INIT(= NULL);
-// When deleting the buffer and autocmd_busy is TRUE, do not free the buffer
-// but link it in the list starting with au_pending_free_buf, using b_next.
-// Free the buffer when autocmd_busy is set to FALSE.
+// When deleting a buffer/window and autocmd_busy is TRUE, do not free the
+// buffer/window. but link it in the list starting with
+// au_pending_free_buf/ap_pending_free_win, using b_next/w_next.
+// Free the buffer/window when autocmd_busy is being set to FALSE.
EXTERN buf_T *au_pending_free_buf INIT(= NULL);
+EXTERN win_T *au_pending_free_win INIT(= NULL);
/*
* Mouse coordinates, set by check_termcode()
diff --git a/src/nvim/version.c b/src/nvim/version.c
index 5a0b01df28..200d34e2fb 100644
--- a/src/nvim/version.c
+++ b/src/nvim/version.c
@@ -308,7 +308,7 @@ static int included_patches[] = {
323,
//322 NA
//321 NA
- //320,
+ 320,
//319 NA
318,
317,
diff --git a/src/nvim/window.c b/src/nvim/window.c
index f5d8edc751..f41a5d8872 100644
--- a/src/nvim/window.c
+++ b/src/nvim/window.c
@@ -3679,7 +3679,12 @@ win_free (
if (wp != aucmd_win)
win_remove(wp, tp);
- free(wp);
+ if (autocmd_busy) {
+ wp->w_next = au_pending_free_win;
+ au_pending_free_win = wp;
+ } else {
+ free(wp);
+ }
unblock_autocmds();
}