]> granicus.if.org Git - vim/commitdiff
updated for version 7.4.320 v7.4.320
authorBram Moolenaar <Bram@vim.org>
Thu, 12 Jun 2014 12:01:31 +0000 (14:01 +0200)
committerBram Moolenaar <Bram@vim.org>
Thu, 12 Jun 2014 12:01:31 +0000 (14:01 +0200)
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)

src/buffer.c
src/fileio.c
src/globals.h
src/version.c
src/window.c

index 3c298590c6db856a0ae8d2f79d63fff59fcd032f..7a6dbc5917e396dd8122b857e404a09143bddf5f 100644 (file)
@@ -371,7 +371,11 @@ close_buffer(win, buf, action, abort_if_last)
        unload_buf = TRUE;
 #endif
 
-    if (win != NULL)
+    if (win != NULL
+#ifdef FEAT_WINDOWS
+       && win_valid(win)       /* in case autocommands closed the window */
+#endif
+           )
     {
        /* Set b_last_cursor when closing the last window for the buffer.
         * Remember the last cursor position and window options of the buffer.
index a45ec2cfd76311e68da51fbad929f1f1bce5823f..38dc2597da66b47db0abbb9f21caafd68670abb1 100644 (file)
@@ -9549,7 +9549,8 @@ apply_autocmds_group(event, fname, fname_io, force, group, buf, eap)
 
     /*
      * 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)
     {
@@ -9562,6 +9563,12 @@ apply_autocmds_group(event, fname, fname_io, force, group, buf, eap)
            vim_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;
+           vim_free(au_pending_free_win);
+           au_pending_free_win = w;
+       }
     }
 
     /*
index d831db9f82d7d77f8d55b8e4678f5954394ccd78..b3310b368064a8de3ae316562d145eabd2ef94b5 100644 (file)
@@ -387,10 +387,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);
 #endif
 
 #ifdef FEAT_MOUSE
index 335f9dea418a103767dfb4aba23076db168c02e9..0df080ea3511bcaf6b477f564cd1ec3947ea98b8 100644 (file)
@@ -734,6 +734,8 @@ static char *(features[]) =
 
 static int included_patches[] =
 {   /* Add new patch number below this line */
+/**/
+    320,
 /**/
     319,
 /**/
index fe6f335cca0e1baa9bea041ab2600ea7164cbd98..f4dea1da1a4254fb678a75801cfbbebe857bf127 100644 (file)
@@ -4597,7 +4597,13 @@ win_free(wp, tp)
     if (wp != aucmd_win)
 #endif
        win_remove(wp, tp);
-    vim_free(wp);
+    if (autocmd_busy)
+    {
+       wp->w_next = au_pending_free_win;
+       au_pending_free_win = wp;
+    }
+    else
+       vim_free(wp);
 
 #ifdef FEAT_AUTOCMD
     unblock_autocmds();