home *** CD-ROM | disk | FTP | other *** search
- To: vim-dev@vim.org
- Subject: Patch 6.1.462
- Fcc: outbox
- From: Bram Moolenaar <Bram@moolenaar.net>
- Mime-Version: 1.0
- Content-Type: text/plain; charset=ISO-8859-1
- Content-Transfer-Encoding: 8bit
- ------------
-
- Patch 6.1.462
- Problem: When autocommands wipe out a buffer, a crash may happen. (Hari
- Krishna Dara)
- Solution: Don't decrement the window count of a buffer before calling the
- autocommands for it. When re-using the current buffer, watch out
- for autocommands changing the current buffer.
- Files: src/buffer.c, src/ex_cmds.c, src/proto/buffer.pro
-
-
- *** ../vim61.461/src/buffer.c Sun Apr 6 15:22:34 2003
- --- src/buffer.c Thu Apr 10 21:48:43 2003
- ***************
- *** 308,324 ****
- unload_buf = TRUE;
- #endif
-
- - /* decrease the link count from windows (unless not in any window) */
- - if (buf->b_nwindows > 0)
- - --buf->b_nwindows;
- -
- if (win != NULL)
- {
- /* 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
- * 'foldmethod' may be lost with a ":only" command. */
- ! if (buf->b_nwindows == 0)
- set_last_cursor(win);
- buflist_setfpos(buf, win,
- win->w_cursor.lnum == 1 ? 0 : win->w_cursor.lnum,
- --- 308,320 ----
- unload_buf = TRUE;
- #endif
-
- if (win != NULL)
- {
- /* 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
- * 'foldmethod' may be lost with a ":only" command. */
- ! if (buf->b_nwindows == 1)
- set_last_cursor(win);
- buflist_setfpos(buf, win,
- win->w_cursor.lnum == 1 ? 0 : win->w_cursor.lnum,
- ***************
- *** 327,333 ****
-
- #ifdef FEAT_AUTOCMD
- /* When the buffer is no longer in a window, trigger BufWinLeave */
- ! if (buf->b_nwindows == 0 && nwindows > 0)
- {
- apply_autocmds(EVENT_BUFWINLEAVE, buf->b_fname, buf->b_fname,
- FALSE, buf);
- --- 323,329 ----
-
- #ifdef FEAT_AUTOCMD
- /* When the buffer is no longer in a window, trigger BufWinLeave */
- ! if (buf->b_nwindows == 1)
- {
- apply_autocmds(EVENT_BUFWINLEAVE, buf->b_fname, buf->b_fname,
- FALSE, buf);
- ***************
- *** 344,351 ****
- --- 340,352 ----
- return;
- }
- }
- + nwindows = buf->b_nwindows;
- #endif
-
- + /* decrease the link count from windows (unless not in any window) */
- + if (buf->b_nwindows > 0)
- + --buf->b_nwindows;
- +
- /* Return when a window is displaying the buffer or when it's not
- * unloaded. */
- if (buf->b_nwindows > 0 || !unload_buf)
- ***************
- *** 364,385 ****
- * Also calls the "BufDelete" autocommands when del_buf is TRUE.
- */
- #ifdef FEAT_AUTOCMD
- is_curbuf = (buf == curbuf);
- #endif
- ! buf_freeall(buf, del_buf);
- #ifdef FEAT_AUTOCMD
- ! if (wipe_buf && buf_valid(buf))
- ! apply_autocmds(EVENT_BUFWIPEOUT, buf->b_fname, buf->b_fname,
- ! FALSE, buf);
- /*
- - * Autocommands may have deleted the buffer.
- * It's possible that autocommands change curbuf to the one being deleted.
- * This might cause the previous 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
-
- --- 365,396 ----
- * Also calls the "BufDelete" autocommands when del_buf is TRUE.
- */
- #ifdef FEAT_AUTOCMD
- + /* Remember if we are closing the current buffer. Restore the number of
- + * windows, so that autocommands in buf_freeall() don't get confused. */
- is_curbuf = (buf == curbuf);
- + buf->b_nwindows = nwindows;
- #endif
- !
- ! buf_freeall(buf, del_buf, wipe_buf);
- !
- #ifdef FEAT_AUTOCMD
- ! /* Autocommands may have deleted the buffer. */
- ! if (!buf_valid(buf))
- ! return;
- !
- ! /* Autocommands may have opened or closed windows for this buffer.
- ! * Decrement the count for the close we do here. */
- ! if (buf->b_nwindows > 0)
- ! --buf->b_nwindows;
- !
- /*
- * It's possible that autocommands change curbuf to the one being deleted.
- * This might cause the previous 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
-
- ***************
- *** 467,475 ****
- */
- /*ARGSUSED*/
- void
- ! buf_freeall(buf, del_buf)
- buf_T *buf;
- int del_buf; /* buffer is going to be deleted */
- {
- #ifdef FEAT_AUTOCMD
- int is_curbuf = (buf == curbuf);
- --- 478,487 ----
- */
- /*ARGSUSED*/
- void
- ! buf_freeall(buf, del_buf, wipe_buf)
- buf_T *buf;
- int del_buf; /* buffer is going to be deleted */
- + int wipe_buf; /* buffer is going to be wiped out */
- {
- #ifdef FEAT_AUTOCMD
- int is_curbuf = (buf == curbuf);
- ***************
- *** 483,488 ****
- --- 495,508 ----
- if (!buf_valid(buf)) /* autocommands may delete the buffer */
- return;
- }
- + if (wipe_buf)
- + {
- + apply_autocmds(EVENT_BUFWIPEOUT, buf->b_fname, buf->b_fname,
- + FALSE, buf);
- + 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
- ***************
- *** 1320,1325 ****
- --- 1340,1346 ----
- *
- * This is the ONLY place where a new buffer structure is allocated!
- */
- + buf = NULL;
- if ((flags & BLN_CURBUF)
- && curbuf != NULL
- && curbuf->b_ffname == NULL
- ***************
- *** 1328,1345 ****
- {
- buf = curbuf;
- #ifdef FEAT_AUTOCMD
- ! /* It's like this buffer is deleted. */
- if (curbuf->b_p_bl)
- apply_autocmds(EVENT_BUFDELETE, NULL, NULL, FALSE, curbuf);
- ! apply_autocmds(EVENT_BUFWIPEOUT, NULL, NULL, FALSE, curbuf);
- #endif
- #ifdef FEAT_QUICKFIX
- ! /* Make sure 'bufhidden' and 'buftype' are empty */
- ! clear_string_option(&buf->b_p_bh);
- ! clear_string_option(&buf->b_p_bt);
- #endif
- }
- ! else
- {
- buf = (buf_T *)alloc_clear((unsigned)sizeof(buf_T));
- if (buf == NULL)
- --- 1349,1373 ----
- {
- buf = curbuf;
- #ifdef FEAT_AUTOCMD
- ! /* It's like this buffer is deleted. Watch out for autocommands that
- ! * change curbuf! If that happens, allocate a new buffer anyway. */
- if (curbuf->b_p_bl)
- apply_autocmds(EVENT_BUFDELETE, NULL, NULL, FALSE, curbuf);
- ! if (buf == curbuf)
- ! apply_autocmds(EVENT_BUFWIPEOUT, NULL, NULL, FALSE, curbuf);
- #endif
- #ifdef FEAT_QUICKFIX
- ! # ifdef FEAT_AUTOCMD
- ! if (buf == curbuf)
- ! # endif
- ! {
- ! /* Make sure 'bufhidden' and 'buftype' are empty */
- ! clear_string_option(&buf->b_p_bh);
- ! clear_string_option(&buf->b_p_bt);
- ! }
- #endif
- }
- ! if (buf != curbuf || curbuf == NULL)
- {
- buf = (buf_T *)alloc_clear((unsigned)sizeof(buf_T));
- if (buf == NULL)
- ***************
- *** 1372,1378 ****
-
- if (buf == curbuf)
- {
- ! buf_freeall(buf, FALSE); /* free all things allocated for this buffer */
- if (buf != curbuf) /* autocommands deleted the buffer! */
- return NULL;
- /* buf->b_nwindows = 0; why was this here? */
- --- 1400,1407 ----
-
- if (buf == curbuf)
- {
- ! /* free all things allocated for this buffer */
- ! buf_freeall(buf, FALSE, FALSE);
- if (buf != curbuf) /* autocommands deleted the buffer! */
- return NULL;
- /* buf->b_nwindows = 0; why was this here? */
- *** ../vim61.461/src/ex_cmds.c Sun Apr 13 20:05:37 2003
- --- src/ex_cmds.c Fri Apr 11 10:50:00 2003
- ***************
- *** 2833,2839 ****
- else
- new_name = NULL;
- #endif
- ! buf_freeall(curbuf, FALSE); /* free all things for buffer */
- #ifdef FEAT_AUTOCMD
- /* If autocommands deleted the buffer we were going to re-edit, give
- * up and jump to the end. */
- --- 2833,2839 ----
- else
- new_name = NULL;
- #endif
- ! buf_freeall(curbuf, FALSE, FALSE); /* free all things for buffer */
- #ifdef FEAT_AUTOCMD
- /* If autocommands deleted the buffer we were going to re-edit, give
- * up and jump to the end. */
- *** ../vim61.461/src/proto/buffer.pro Sun Mar 9 17:49:38 2003
- --- src/proto/buffer.pro Thu Apr 10 21:19:22 2003
- ***************
- *** 3,9 ****
- int buf_valid __ARGS((buf_T *buf));
- void close_buffer __ARGS((win_T *win, buf_T *buf, int action));
- void buf_clear_file __ARGS((buf_T *buf));
- ! void buf_freeall __ARGS((buf_T *buf, int del_buf));
- void goto_buffer __ARGS((exarg_T *eap, int start, int dir, int count));
- void handle_swap_exists __ARGS((buf_T *old_curbuf));
- char_u *do_bufdel __ARGS((int command, char_u *arg, int addr_count, int start_bnr, int end_bnr, int forceit));
- --- 3,9 ----
- int buf_valid __ARGS((buf_T *buf));
- void close_buffer __ARGS((win_T *win, buf_T *buf, int action));
- void buf_clear_file __ARGS((buf_T *buf));
- ! void buf_freeall __ARGS((buf_T *buf, int del_buf, int wipe_buf));
- void goto_buffer __ARGS((exarg_T *eap, int start, int dir, int count));
- void handle_swap_exists __ARGS((buf_T *old_curbuf));
- char_u *do_bufdel __ARGS((int command, char_u *arg, int addr_count, int start_bnr, int end_bnr, int forceit));
- *** ../vim61.461/src/version.c Sun Apr 13 20:37:44 2003
- --- src/version.c Sun Apr 13 20:39:40 2003
- ***************
- *** 613,614 ****
- --- 613,616 ----
- { /* Add new patch number below this line */
- + /**/
- + 462,
- /**/
-
- --
- OLD WOMAN: King of the WHO?
- ARTHUR: The Britons.
- OLD WOMAN: Who are the Britons?
- "Monty Python and the Holy Grail" PYTHON (MONTY) PICTURES LTD
-
- /// Bram Moolenaar -- Bram@Moolenaar.net -- http://www.Moolenaar.net \\\
- /// Creator of Vim - Vi IMproved -- http://www.Vim.org \\\
- \\\ Project leader for A-A-P -- http://www.A-A-P.org ///
- \\\ Help AIDS victims, buy at Amazon -- http://ICCF.nl/click1.html ///
-