home *** CD-ROM | disk | FTP | other *** search
/ vim.ftp.fu-berlin.de / 2015-02-03.vim.ftp.fu-berlin.de.tar / vim.ftp.fu-berlin.de / patches / 6.1.462 < prev    next >
Encoding:
Internet Message Format  |  2003-04-12  |  10.0 KB

  1. To: vim-dev@vim.org
  2. Subject: Patch 6.1.462
  3. Fcc: outbox
  4. From: Bram Moolenaar <Bram@moolenaar.net>
  5. Mime-Version: 1.0
  6. Content-Type: text/plain; charset=ISO-8859-1
  7. Content-Transfer-Encoding: 8bit
  8. ------------
  9.  
  10. Patch 6.1.462
  11. Problem:    When autocommands wipe out a buffer, a crash may happen. (Hari
  12.         Krishna Dara)
  13. Solution:   Don't decrement the window count of a buffer before calling the
  14.         autocommands for it.  When re-using the current buffer, watch out
  15.         for autocommands changing the current buffer.
  16. Files:        src/buffer.c, src/ex_cmds.c, src/proto/buffer.pro
  17.  
  18.  
  19. *** ../vim61.461/src/buffer.c    Sun Apr  6 15:22:34 2003
  20. --- src/buffer.c    Thu Apr 10 21:48:43 2003
  21. ***************
  22. *** 308,324 ****
  23.       unload_buf = TRUE;
  24.   #endif
  25.   
  26. -     /* decrease the link count from windows (unless not in any window) */
  27. -     if (buf->b_nwindows > 0)
  28. -     --buf->b_nwindows;
  29.       if (win != NULL)
  30.       {
  31.       /* Set b_last_cursor when closing the last window for the buffer.
  32.        * Remember the last cursor position and window options of the buffer.
  33.        * This used to be only for the current window, but then options like
  34.        * 'foldmethod' may be lost with a ":only" command. */
  35. !     if (buf->b_nwindows == 0)
  36.           set_last_cursor(win);
  37.       buflist_setfpos(buf, win,
  38.               win->w_cursor.lnum == 1 ? 0 : win->w_cursor.lnum,
  39. --- 308,320 ----
  40.       unload_buf = TRUE;
  41.   #endif
  42.   
  43.       if (win != NULL)
  44.       {
  45.       /* Set b_last_cursor when closing the last window for the buffer.
  46.        * Remember the last cursor position and window options of the buffer.
  47.        * This used to be only for the current window, but then options like
  48.        * 'foldmethod' may be lost with a ":only" command. */
  49. !     if (buf->b_nwindows == 1)
  50.           set_last_cursor(win);
  51.       buflist_setfpos(buf, win,
  52.               win->w_cursor.lnum == 1 ? 0 : win->w_cursor.lnum,
  53. ***************
  54. *** 327,333 ****
  55.   
  56.   #ifdef FEAT_AUTOCMD
  57.       /* When the buffer is no longer in a window, trigger BufWinLeave */
  58. !     if (buf->b_nwindows == 0 && nwindows > 0)
  59.       {
  60.       apply_autocmds(EVENT_BUFWINLEAVE, buf->b_fname, buf->b_fname,
  61.                                     FALSE, buf);
  62. --- 323,329 ----
  63.   
  64.   #ifdef FEAT_AUTOCMD
  65.       /* When the buffer is no longer in a window, trigger BufWinLeave */
  66. !     if (buf->b_nwindows == 1)
  67.       {
  68.       apply_autocmds(EVENT_BUFWINLEAVE, buf->b_fname, buf->b_fname,
  69.                                     FALSE, buf);
  70. ***************
  71. *** 344,351 ****
  72. --- 340,352 ----
  73.           return;
  74.       }
  75.       }
  76. +     nwindows = buf->b_nwindows;
  77.   #endif
  78.   
  79. +     /* decrease the link count from windows (unless not in any window) */
  80. +     if (buf->b_nwindows > 0)
  81. +     --buf->b_nwindows;
  82.       /* Return when a window is displaying the buffer or when it's not
  83.        * unloaded. */
  84.       if (buf->b_nwindows > 0 || !unload_buf)
  85. ***************
  86. *** 364,385 ****
  87.        * Also calls the "BufDelete" autocommands when del_buf is TRUE.
  88.        */
  89.   #ifdef FEAT_AUTOCMD
  90.       is_curbuf = (buf == curbuf);
  91.   #endif
  92. !     buf_freeall(buf, del_buf);
  93.   #ifdef FEAT_AUTOCMD
  94. !     if (wipe_buf && buf_valid(buf))
  95. !     apply_autocmds(EVENT_BUFWIPEOUT, buf->b_fname, buf->b_fname,
  96. !                                   FALSE, buf);
  97.       /*
  98. -      * Autocommands may have deleted the buffer.
  99.        * It's possible that autocommands change curbuf to the one being deleted.
  100.        * This might cause the previous curbuf to be deleted unexpectedly.  But
  101.        * in some cases it's OK to delete the curbuf, because a new one is
  102.        * obtained anyway.  Therefore only return if curbuf changed to the
  103.        * deleted buffer.
  104.        */
  105. !     if (!buf_valid(buf) || (buf == curbuf && !is_curbuf))
  106.       return;
  107.   #endif
  108.   
  109. --- 365,396 ----
  110.        * Also calls the "BufDelete" autocommands when del_buf is TRUE.
  111.        */
  112.   #ifdef FEAT_AUTOCMD
  113. +     /* Remember if we are closing the current buffer.  Restore the number of
  114. +      * windows, so that autocommands in buf_freeall() don't get confused. */
  115.       is_curbuf = (buf == curbuf);
  116. +     buf->b_nwindows = nwindows;
  117.   #endif
  118. !     buf_freeall(buf, del_buf, wipe_buf);
  119.   #ifdef FEAT_AUTOCMD
  120. !     /* Autocommands may have deleted the buffer. */
  121. !     if (!buf_valid(buf))
  122. !     return;
  123. !     /* Autocommands may have opened or closed windows for this buffer.
  124. !      * Decrement the count for the close we do here. */
  125. !     if (buf->b_nwindows > 0)
  126. !     --buf->b_nwindows;
  127.       /*
  128.        * It's possible that autocommands change curbuf to the one being deleted.
  129.        * This might cause the previous curbuf to be deleted unexpectedly.  But
  130.        * in some cases it's OK to delete the curbuf, because a new one is
  131.        * obtained anyway.  Therefore only return if curbuf changed to the
  132.        * deleted buffer.
  133.        */
  134. !     if (buf == curbuf && !is_curbuf)
  135.       return;
  136.   #endif
  137.   
  138. ***************
  139. *** 467,475 ****
  140.    */
  141.   /*ARGSUSED*/
  142.       void
  143. ! buf_freeall(buf, del_buf)
  144.       buf_T    *buf;
  145.       int        del_buf;    /* buffer is going to be deleted */
  146.   {
  147.   #ifdef FEAT_AUTOCMD
  148.       int        is_curbuf = (buf == curbuf);
  149. --- 478,487 ----
  150.    */
  151.   /*ARGSUSED*/
  152.       void
  153. ! buf_freeall(buf, del_buf, wipe_buf)
  154.       buf_T    *buf;
  155.       int        del_buf;    /* buffer is going to be deleted */
  156. +     int        wipe_buf;    /* buffer is going to be wiped out */
  157.   {
  158.   #ifdef FEAT_AUTOCMD
  159.       int        is_curbuf = (buf == curbuf);
  160. ***************
  161. *** 483,488 ****
  162. --- 495,508 ----
  163.       if (!buf_valid(buf))        /* autocommands may delete the buffer */
  164.           return;
  165.       }
  166. +     if (wipe_buf)
  167. +     {
  168. +     apply_autocmds(EVENT_BUFWIPEOUT, buf->b_fname, buf->b_fname,
  169. +                                   FALSE, buf);
  170. +     if (!buf_valid(buf))        /* autocommands may delete the buffer */
  171. +         return;
  172. +     }
  173.       /*
  174.        * It's possible that autocommands change curbuf to the one being deleted.
  175.        * This might cause curbuf to be deleted unexpectedly.  But in some cases
  176. ***************
  177. *** 1320,1325 ****
  178. --- 1340,1346 ----
  179.        *
  180.        * This is the ONLY place where a new buffer structure is allocated!
  181.        */
  182. +     buf = NULL;
  183.       if ((flags & BLN_CURBUF)
  184.           && curbuf != NULL
  185.           && curbuf->b_ffname == NULL
  186. ***************
  187. *** 1328,1345 ****
  188.       {
  189.       buf = curbuf;
  190.   #ifdef FEAT_AUTOCMD
  191. !     /* It's like this buffer is deleted. */
  192.       if (curbuf->b_p_bl)
  193.           apply_autocmds(EVENT_BUFDELETE, NULL, NULL, FALSE, curbuf);
  194. !     apply_autocmds(EVENT_BUFWIPEOUT, NULL, NULL, FALSE, curbuf);
  195.   #endif
  196.   #ifdef FEAT_QUICKFIX
  197. !     /* Make sure 'bufhidden' and 'buftype' are empty */
  198. !     clear_string_option(&buf->b_p_bh);
  199. !     clear_string_option(&buf->b_p_bt);
  200.   #endif
  201.       }
  202. !     else
  203.       {
  204.       buf = (buf_T *)alloc_clear((unsigned)sizeof(buf_T));
  205.       if (buf == NULL)
  206. --- 1349,1373 ----
  207.       {
  208.       buf = curbuf;
  209.   #ifdef FEAT_AUTOCMD
  210. !     /* It's like this buffer is deleted.  Watch out for autocommands that
  211. !      * change curbuf!  If that happens, allocate a new buffer anyway. */
  212.       if (curbuf->b_p_bl)
  213.           apply_autocmds(EVENT_BUFDELETE, NULL, NULL, FALSE, curbuf);
  214. !     if (buf == curbuf)
  215. !         apply_autocmds(EVENT_BUFWIPEOUT, NULL, NULL, FALSE, curbuf);
  216.   #endif
  217.   #ifdef FEAT_QUICKFIX
  218. ! # ifdef FEAT_AUTOCMD
  219. !     if (buf == curbuf)
  220. ! # endif
  221. !     {
  222. !         /* Make sure 'bufhidden' and 'buftype' are empty */
  223. !         clear_string_option(&buf->b_p_bh);
  224. !         clear_string_option(&buf->b_p_bt);
  225. !     }
  226.   #endif
  227.       }
  228. !     if (buf != curbuf || curbuf == NULL)
  229.       {
  230.       buf = (buf_T *)alloc_clear((unsigned)sizeof(buf_T));
  231.       if (buf == NULL)
  232. ***************
  233. *** 1372,1378 ****
  234.   
  235.       if (buf == curbuf)
  236.       {
  237. !     buf_freeall(buf, FALSE); /* free all things allocated for this buffer */
  238.       if (buf != curbuf)     /* autocommands deleted the buffer! */
  239.           return NULL;
  240.       /* buf->b_nwindows = 0; why was this here? */
  241. --- 1400,1407 ----
  242.   
  243.       if (buf == curbuf)
  244.       {
  245. !     /* free all things allocated for this buffer */
  246. !     buf_freeall(buf, FALSE, FALSE);
  247.       if (buf != curbuf)     /* autocommands deleted the buffer! */
  248.           return NULL;
  249.       /* buf->b_nwindows = 0; why was this here? */
  250. *** ../vim61.461/src/ex_cmds.c    Sun Apr 13 20:05:37 2003
  251. --- src/ex_cmds.c    Fri Apr 11 10:50:00 2003
  252. ***************
  253. *** 2833,2839 ****
  254.       else
  255.           new_name = NULL;
  256.   #endif
  257. !     buf_freeall(curbuf, FALSE);    /* free all things for buffer */
  258.   #ifdef FEAT_AUTOCMD
  259.       /* If autocommands deleted the buffer we were going to re-edit, give
  260.        * up and jump to the end. */
  261. --- 2833,2839 ----
  262.       else
  263.           new_name = NULL;
  264.   #endif
  265. !     buf_freeall(curbuf, FALSE, FALSE);   /* free all things for buffer */
  266.   #ifdef FEAT_AUTOCMD
  267.       /* If autocommands deleted the buffer we were going to re-edit, give
  268.        * up and jump to the end. */
  269. *** ../vim61.461/src/proto/buffer.pro    Sun Mar  9 17:49:38 2003
  270. --- src/proto/buffer.pro    Thu Apr 10 21:19:22 2003
  271. ***************
  272. *** 3,9 ****
  273.   int buf_valid __ARGS((buf_T *buf));
  274.   void close_buffer __ARGS((win_T *win, buf_T *buf, int action));
  275.   void buf_clear_file __ARGS((buf_T *buf));
  276. ! void buf_freeall __ARGS((buf_T *buf, int del_buf));
  277.   void goto_buffer __ARGS((exarg_T *eap, int start, int dir, int count));
  278.   void handle_swap_exists __ARGS((buf_T *old_curbuf));
  279.   char_u *do_bufdel __ARGS((int command, char_u *arg, int addr_count, int start_bnr, int end_bnr, int forceit));
  280. --- 3,9 ----
  281.   int buf_valid __ARGS((buf_T *buf));
  282.   void close_buffer __ARGS((win_T *win, buf_T *buf, int action));
  283.   void buf_clear_file __ARGS((buf_T *buf));
  284. ! void buf_freeall __ARGS((buf_T *buf, int del_buf, int wipe_buf));
  285.   void goto_buffer __ARGS((exarg_T *eap, int start, int dir, int count));
  286.   void handle_swap_exists __ARGS((buf_T *old_curbuf));
  287.   char_u *do_bufdel __ARGS((int command, char_u *arg, int addr_count, int start_bnr, int end_bnr, int forceit));
  288. *** ../vim61.461/src/version.c    Sun Apr 13 20:37:44 2003
  289. --- src/version.c    Sun Apr 13 20:39:40 2003
  290. ***************
  291. *** 613,614 ****
  292. --- 613,616 ----
  293.   {   /* Add new patch number below this line */
  294. + /**/
  295. +     462,
  296.   /**/
  297.  
  298. -- 
  299. OLD WOMAN: King of the WHO?
  300. ARTHUR:    The Britons.
  301. OLD WOMAN: Who are the Britons?
  302.                  "Monty Python and the Holy Grail" PYTHON (MONTY) PICTURES LTD
  303.  
  304.  /// Bram Moolenaar -- Bram@Moolenaar.net -- http://www.Moolenaar.net   \\\
  305. ///          Creator of Vim - Vi IMproved -- http://www.Vim.org          \\\
  306. \\\              Project leader for A-A-P -- http://www.A-A-P.org        ///
  307.  \\\     Help AIDS victims, buy at Amazon -- http://ICCF.nl/click1.html ///
  308.