]> granicus.if.org Git - vim/commitdiff
patch 8.0.0782: using freed memory in quickfix code v8.0.0782
authorBram Moolenaar <Bram@vim.org>
Thu, 27 Jul 2017 20:03:50 +0000 (22:03 +0200)
committerBram Moolenaar <Bram@vim.org>
Thu, 27 Jul 2017 20:03:50 +0000 (22:03 +0200)
Problem:    Using freed memory in quickfix code. (Dominique Pelle)
Solution:   Handle a help window differently. (Yegappan Lakshmanan)

src/buffer.c
src/ex_cmds.c
src/proto/buffer.pro
src/quickfix.c
src/testdir/test_quickfix.vim
src/version.c
src/window.c

index 4dbb9e91b51b35bc7eb171aed2170944fc5b7e86..45100788b01fa471e550673353e10695a9909b13 100644 (file)
@@ -249,7 +249,7 @@ open_buffer(
        netbeansFireChanges = oldFire;
 #endif
        /* Help buffer is filtered. */
-       if (curbuf->b_help)
+       if (bt_help(curbuf))
            fix_help_buffer();
     }
     else if (read_stdin)
@@ -5668,6 +5668,15 @@ bt_terminal(buf_T *buf)
     return buf != NULL && buf->b_p_bt[0] == 't';
 }
 
+/*
+ * Return TRUE if "buf" is a help buffer.
+ */
+    int
+bt_help(buf_T *buf)
+{
+    return buf != NULL && buf->b_help;
+}
+
 /*
  * Return TRUE if "buf" is a "nofile", "acwrite" or "terminal" buffer.
  * This means the buffer name is not a file name.
index 9c84e24b15da627f654810ad72b82cd550f3cbd4..6ec3ded90b0816e730ad86e15d0160ba512cc7b6 100644 (file)
@@ -6314,7 +6314,7 @@ ex_help(exarg_T *eap)
      * Re-use an existing help window or open a new one.
      * Always open a new one for ":tab help".
      */
-    if (!curwin->w_buffer->b_help
+    if (!bt_help(curwin->w_buffer)
 #ifdef FEAT_WINDOWS
            || cmdmod.tab != 0
 #endif
@@ -6325,7 +6325,7 @@ ex_help(exarg_T *eap)
            wp = NULL;
        else
            FOR_ALL_WINDOWS(wp)
-               if (wp->w_buffer != NULL && wp->w_buffer->b_help)
+               if (bt_help(wp->w_buffer))
                    break;
        if (wp != NULL && wp->w_buffer->b_nwindows > 0)
            win_enter(wp, TRUE);
@@ -6425,7 +6425,7 @@ ex_helpclose(exarg_T *eap UNUSED)
 
     FOR_ALL_WINDOWS(win)
     {
-       if (win->w_buffer->b_help)
+       if (bt_help(win->w_buffer))
        {
            win_close(win, FALSE);
            return;
index e9a37dec86ccc58433600297a91a7dfb419efc97..a671075363d5596417e288173a39079240e8433e 100644 (file)
@@ -55,6 +55,7 @@ int read_viminfo_bufferlist(vir_T *virp, int writing);
 void write_viminfo_bufferlist(FILE *fp);
 int bt_quickfix(buf_T *buf);
 int bt_terminal(buf_T *buf);
+int bt_help(buf_T *buf);
 int bt_nofile(buf_T *buf);
 int bt_dontwrite(buf_T *buf);
 int bt_dontwrite_msg(buf_T *buf);
index c34e34d1ce4dfce871d38da124039ffd16d825c5..79cb4168d678b8ec665a0f9d03dfe18a107b2b1e 100644 (file)
@@ -2101,7 +2101,7 @@ qf_jump(
     /*
      * For ":helpgrep" find a help window or open one.
      */
-    if (qf_ptr->qf_type == 1 && (!curwin->w_buffer->b_help || cmdmod.tab != 0))
+    if (qf_ptr->qf_type == 1 && (!bt_help(curwin->w_buffer) || cmdmod.tab != 0))
     {
        win_T   *wp;
 
@@ -2109,7 +2109,7 @@ qf_jump(
            wp = NULL;
        else
            FOR_ALL_WINDOWS(wp)
-               if (wp->w_buffer != NULL && wp->w_buffer->b_help)
+               if (bt_help(wp->w_buffer))
                    break;
        if (wp != NULL && wp->w_buffer->b_nwindows > 0)
            win_enter(wp, TRUE);
@@ -5343,10 +5343,14 @@ ex_helpgrep(exarg_T *eap)
 
     if (eap->cmdidx == CMD_lhelpgrep)
     {
-       /* Find an existing help window */
-       FOR_ALL_WINDOWS(wp)
-           if (wp->w_buffer != NULL && wp->w_buffer->b_help)
-               break;
+       /* If the current window is a help window, then use it */
+       if (bt_help(curwin->w_buffer))
+           wp = curwin;
+       else
+           /* Find an existing help window */
+           FOR_ALL_WINDOWS(wp)
+               if (bt_help(wp->w_buffer))
+                   break;
 
        if (wp == NULL)     /* Help window not found */
            qi = NULL;
@@ -5515,7 +5519,7 @@ ex_helpgrep(exarg_T *eap)
     {
        /* If the help window is not opened or if it already points to the
         * correct location list, then free the new location list. */
-       if (!curwin->w_buffer->b_help || curwin->w_llist == qi)
+       if (!bt_help(curwin->w_buffer) || curwin->w_llist == qi)
        {
            if (new_qi)
                ll_free_all(&qi);
index 7b344eaad74460816637be7cd3b6f343b0a28450..41e5021548ca22c14ea26411af07f66eea132e63 100644 (file)
@@ -2287,3 +2287,17 @@ func Test_changedtick()
     call Xchangedtick_tests('c')
     call Xchangedtick_tests('l')
 endfunc
+
+" Open multiple help windows using ":lhelpgrep
+" This test used to crash Vim
+func Test_Multi_LL_Help()
+    new | only
+    lhelpgrep window
+    lopen
+    e#
+    lhelpgrep buffer
+    call assert_equal(3, winnr('$'))
+    call assert_true(len(getloclist(1)) != 0)
+    call assert_true(len(getloclist(2)) != 0)
+    new | only
+endfunc
index f62d3f05b9a6fe57f923576c7b8f92f70757c136..da00188ce0bbb95cbfe186a14d77b3580a17d090 100644 (file)
@@ -769,6 +769,8 @@ static char *(features[]) =
 
 static int included_patches[] =
 {   /* Add new patch number below this line */
+/**/
+    782,
 /**/
     781,
 /**/
index 192721708a10fa73fd39601ee4903f435cc798a8..948303c093a5c1a4f48b63adb8a2f46e554689ac 100644 (file)
@@ -2314,7 +2314,7 @@ win_close(win_T *win, int free_buf)
 
     /* When closing the help window, try restoring a snapshot after closing
      * the window.  Otherwise clear the snapshot, it's now invalid. */
-    if (win->w_buffer != NULL && win->w_buffer->b_help)
+    if (bt_help(win->w_buffer))
        help_window = TRUE;
     else
        clear_snapshot(curtab, SNAP_HELP_IDX);
@@ -2397,7 +2397,7 @@ win_close(win_T *win, int free_buf)
            && (last_window() || curtab != prev_curtab
                || close_last_window_tabpage(win, free_buf, prev_curtab)))
     {
-       /* Autocommands have close all windows, quit now.  Restore
+       /* Autocommands have closed all windows, quit now.  Restore
         * curwin->w_buffer, otherwise writing viminfo may fail. */
        if (curwin->w_buffer == NULL)
            curwin->w_buffer = curbuf;
@@ -6479,7 +6479,7 @@ only_one_window(void)
 
     FOR_ALL_WINDOWS(wp)
        if (wp->w_buffer != NULL
-               && (!((wp->w_buffer->b_help && !curbuf->b_help)
+               && (!((bt_help(wp->w_buffer) && !bt_help(curbuf))
 # ifdef FEAT_QUICKFIX
                    || wp->w_p_pvw
 # endif