0
0
mirror of https://github.com/vim/vim.git synced 2025-09-25 03:54:15 -04:00

patch 8.0.0782: using freed memory in quickfix code

Problem:    Using freed memory in quickfix code. (Dominique Pelle)
Solution:   Handle a help window differently. (Yegappan Lakshmanan)
This commit is contained in:
Bram Moolenaar
2017-07-27 22:03:50 +02:00
parent ab6eec3887
commit d28cc3f55d
7 changed files with 44 additions and 14 deletions

View File

@@ -249,7 +249,7 @@ open_buffer(
netbeansFireChanges = oldFire; netbeansFireChanges = oldFire;
#endif #endif
/* Help buffer is filtered. */ /* Help buffer is filtered. */
if (curbuf->b_help) if (bt_help(curbuf))
fix_help_buffer(); fix_help_buffer();
} }
else if (read_stdin) else if (read_stdin)
@@ -5668,6 +5668,15 @@ bt_terminal(buf_T *buf)
return buf != NULL && buf->b_p_bt[0] == 't'; 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. * Return TRUE if "buf" is a "nofile", "acwrite" or "terminal" buffer.
* This means the buffer name is not a file name. * This means the buffer name is not a file name.

View File

@@ -6314,7 +6314,7 @@ ex_help(exarg_T *eap)
* Re-use an existing help window or open a new one. * Re-use an existing help window or open a new one.
* Always open a new one for ":tab help". * Always open a new one for ":tab help".
*/ */
if (!curwin->w_buffer->b_help if (!bt_help(curwin->w_buffer)
#ifdef FEAT_WINDOWS #ifdef FEAT_WINDOWS
|| cmdmod.tab != 0 || cmdmod.tab != 0
#endif #endif
@@ -6325,7 +6325,7 @@ ex_help(exarg_T *eap)
wp = NULL; wp = NULL;
else else
FOR_ALL_WINDOWS(wp) FOR_ALL_WINDOWS(wp)
if (wp->w_buffer != NULL && wp->w_buffer->b_help) if (bt_help(wp->w_buffer))
break; break;
if (wp != NULL && wp->w_buffer->b_nwindows > 0) if (wp != NULL && wp->w_buffer->b_nwindows > 0)
win_enter(wp, TRUE); win_enter(wp, TRUE);
@@ -6425,7 +6425,7 @@ ex_helpclose(exarg_T *eap UNUSED)
FOR_ALL_WINDOWS(win) FOR_ALL_WINDOWS(win)
{ {
if (win->w_buffer->b_help) if (bt_help(win->w_buffer))
{ {
win_close(win, FALSE); win_close(win, FALSE);
return; return;

View File

@@ -55,6 +55,7 @@ int read_viminfo_bufferlist(vir_T *virp, int writing);
void write_viminfo_bufferlist(FILE *fp); void write_viminfo_bufferlist(FILE *fp);
int bt_quickfix(buf_T *buf); int bt_quickfix(buf_T *buf);
int bt_terminal(buf_T *buf); int bt_terminal(buf_T *buf);
int bt_help(buf_T *buf);
int bt_nofile(buf_T *buf); int bt_nofile(buf_T *buf);
int bt_dontwrite(buf_T *buf); int bt_dontwrite(buf_T *buf);
int bt_dontwrite_msg(buf_T *buf); int bt_dontwrite_msg(buf_T *buf);

View File

@@ -2101,7 +2101,7 @@ qf_jump(
/* /*
* For ":helpgrep" find a help window or open one. * 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; win_T *wp;
@@ -2109,7 +2109,7 @@ qf_jump(
wp = NULL; wp = NULL;
else else
FOR_ALL_WINDOWS(wp) FOR_ALL_WINDOWS(wp)
if (wp->w_buffer != NULL && wp->w_buffer->b_help) if (bt_help(wp->w_buffer))
break; break;
if (wp != NULL && wp->w_buffer->b_nwindows > 0) if (wp != NULL && wp->w_buffer->b_nwindows > 0)
win_enter(wp, TRUE); win_enter(wp, TRUE);
@@ -5343,10 +5343,14 @@ ex_helpgrep(exarg_T *eap)
if (eap->cmdidx == CMD_lhelpgrep) if (eap->cmdidx == CMD_lhelpgrep)
{ {
/* Find an existing help window */ /* If the current window is a help window, then use it */
FOR_ALL_WINDOWS(wp) if (bt_help(curwin->w_buffer))
if (wp->w_buffer != NULL && wp->w_buffer->b_help) wp = curwin;
break; else
/* Find an existing help window */
FOR_ALL_WINDOWS(wp)
if (bt_help(wp->w_buffer))
break;
if (wp == NULL) /* Help window not found */ if (wp == NULL) /* Help window not found */
qi = NULL; 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 /* If the help window is not opened or if it already points to the
* correct location list, then free the new location list. */ * 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) if (new_qi)
ll_free_all(&qi); ll_free_all(&qi);

View File

@@ -2287,3 +2287,17 @@ func Test_changedtick()
call Xchangedtick_tests('c') call Xchangedtick_tests('c')
call Xchangedtick_tests('l') call Xchangedtick_tests('l')
endfunc 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

View File

@@ -769,6 +769,8 @@ static char *(features[]) =
static int included_patches[] = static int included_patches[] =
{ /* Add new patch number below this line */ { /* Add new patch number below this line */
/**/
782,
/**/ /**/
781, 781,
/**/ /**/

View File

@@ -2314,7 +2314,7 @@ win_close(win_T *win, int free_buf)
/* When closing the help window, try restoring a snapshot after closing /* When closing the help window, try restoring a snapshot after closing
* the window. Otherwise clear the snapshot, it's now invalid. */ * 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; help_window = TRUE;
else else
clear_snapshot(curtab, SNAP_HELP_IDX); clear_snapshot(curtab, SNAP_HELP_IDX);
@@ -2397,7 +2397,7 @@ win_close(win_T *win, int free_buf)
&& (last_window() || curtab != prev_curtab && (last_window() || curtab != prev_curtab
|| close_last_window_tabpage(win, free_buf, 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. */ * curwin->w_buffer, otherwise writing viminfo may fail. */
if (curwin->w_buffer == NULL) if (curwin->w_buffer == NULL)
curwin->w_buffer = curbuf; curwin->w_buffer = curbuf;
@@ -6479,7 +6479,7 @@ only_one_window(void)
FOR_ALL_WINDOWS(wp) FOR_ALL_WINDOWS(wp)
if (wp->w_buffer != NULL if (wp->w_buffer != NULL
&& (!((wp->w_buffer->b_help && !curbuf->b_help) && (!((bt_help(wp->w_buffer) && !bt_help(curbuf))
# ifdef FEAT_QUICKFIX # ifdef FEAT_QUICKFIX
|| wp->w_p_pvw || wp->w_p_pvw
# endif # endif