]> granicus.if.org Git - vim/commitdiff
updated for version 7.4.251 v7.4.251
authorBram Moolenaar <Bram@vim.org>
Sun, 6 Apr 2014 18:45:43 +0000 (20:45 +0200)
committerBram Moolenaar <Bram@vim.org>
Sun, 6 Apr 2014 18:45:43 +0000 (20:45 +0200)
Problem:    Crash when BufAdd autocommand wipes out the buffer.
Solution:   Check for buffer to still be valid. Postpone freeing the buffer
            structure. (Hirohito Higashi)

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

index c703465e3f89ae5347e0ff452ee227c6e1744f19..3506dbb9a5ed73982ea364e5474c5dca1e05ee33 100644 (file)
@@ -676,8 +676,16 @@ free_buffer(buf)
 #endif
 #ifdef FEAT_AUTOCMD
     aubuflocal_remove(buf);
+    if (autocmd_busy)
+    {
+       /* Do not free the buffer structure while autocommands are executing,
+        * it's still needed. Free it when autocmd_busy is reset. */
+       buf->b_next = au_pending_free_buf;
+       au_pending_free_buf = buf;
+    }
+    else
 #endif
-    vim_free(buf);
+       vim_free(buf);
 }
 
 /*
@@ -1681,7 +1689,11 @@ buflist_new(ffname, sfname, lnum, flags)
            buf->b_p_bl = TRUE;
 #ifdef FEAT_AUTOCMD
            if (!(flags & BLN_DUMMY))
+           {
                apply_autocmds(EVENT_BUFADD, NULL, NULL, FALSE, buf);
+               if (!buf_valid(buf))
+                   return NULL;
+           }
 #endif
        }
        return buf;
@@ -1857,8 +1869,14 @@ buflist_new(ffname, sfname, lnum, flags)
     if (!(flags & BLN_DUMMY))
     {
        apply_autocmds(EVENT_BUFNEW, NULL, NULL, FALSE, buf);
+       if (!buf_valid(buf))
+           return NULL;
        if (flags & BLN_LISTED)
+       {
            apply_autocmds(EVENT_BUFADD, NULL, NULL, FALSE, buf);
+           if (!buf_valid(buf))
+               return NULL;
+       }
 # ifdef FEAT_EVAL
        if (aborting())         /* autocmds may abort script processing */
            return NULL;
index 7ae4917a8bd333498316485b020860b8cc8f5d47..ac30f2c01774057a2fcd05a0093fa5e9aa5f939b 100644 (file)
@@ -3343,6 +3343,12 @@ do_ecmd(fnum, ffname, sfname, eap, newlnum, flags, oldwin)
 #endif
            buf = buflist_new(ffname, sfname, 0L,
                    BLN_CURBUF | ((flags & ECMD_SET_HELP) ? 0 : BLN_LISTED));
+#ifdef FEAT_AUTOCMD
+           /* autocommands may change curwin and curbuf */
+           if (oldwin != NULL)
+               oldwin = curwin;
+           old_curbuf = curbuf;
+#endif
        }
        if (buf == NULL)
            goto theend;
index 17f36e7b06a92083f57701c009235e6d9bddbd65..f8b384b9e9e18c0b458d34d7dcd738f3d90352dc 100644 (file)
@@ -9548,13 +9548,19 @@ apply_autocmds_group(event, fname, fname_io, force, group, buf, eap)
 
     /*
      * When stopping to execute autocommands, restore the search patterns and
-     * the redo buffer.
+     * the redo buffer.  Free buffers in the au_pending_free_buf list.
      */
     if (!autocmd_busy)
     {
        restore_search_patterns();
        restoreRedobuff();
        did_filetype = FALSE;
+       while (au_pending_free_buf != NULL)
+       {
+           buf_T *b = au_pending_free_buf->b_next;
+           vim_free(au_pending_free_buf);
+           au_pending_free_buf = b;
+       }
     }
 
     /*
index 0281103360ccb8bfeccb16fc2bf8a526b5bcaee6..a17430d0652f65a7a0ee4da44d867703a57fce60 100644 (file)
@@ -386,6 +386,11 @@ EXTERN int keep_filetype INIT(= FALSE);    /* value for did_filetype when
 /* When deleting the current buffer, another one must be loaded.  If we know
  * 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. */
+EXTERN buf_T   *au_pending_free_buf INIT(= NULL);
 #endif
 
 #ifdef FEAT_MOUSE
index ad38a7d0cf53560d57ef106a00baf5c6bac56884..b74ea983c7d0cab50c0a83ea5d7c2275c333715a 100644 (file)
@@ -734,6 +734,8 @@ static char *(features[]) =
 
 static int included_patches[] =
 {   /* Add new patch number below this line */
+/**/
+    251,
 /**/
     250,
 /**/