Skip to content

Commit d28cc3f

Browse files
committed
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)
1 parent ab6eec3 commit d28cc3f

7 files changed

Lines changed: 44 additions & 14 deletions

File tree

src/buffer.c

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -249,7 +249,7 @@ open_buffer(
249249
netbeansFireChanges = oldFire;
250250
#endif
251251
/* Help buffer is filtered. */
252-
if (curbuf->b_help)
252+
if (bt_help(curbuf))
253253
fix_help_buffer();
254254
}
255255
else if (read_stdin)
@@ -5668,6 +5668,15 @@ bt_terminal(buf_T *buf)
56685668
return buf != NULL && buf->b_p_bt[0] == 't';
56695669
}
56705670

5671+
/*
5672+
* Return TRUE if "buf" is a help buffer.
5673+
*/
5674+
int
5675+
bt_help(buf_T *buf)
5676+
{
5677+
return buf != NULL && buf->b_help;
5678+
}
5679+
56715680
/*
56725681
* Return TRUE if "buf" is a "nofile", "acwrite" or "terminal" buffer.
56735682
* This means the buffer name is not a file name.

src/ex_cmds.c

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6314,7 +6314,7 @@ ex_help(exarg_T *eap)
63146314
* Re-use an existing help window or open a new one.
63156315
* Always open a new one for ":tab help".
63166316
*/
6317-
if (!curwin->w_buffer->b_help
6317+
if (!bt_help(curwin->w_buffer)
63186318
#ifdef FEAT_WINDOWS
63196319
|| cmdmod.tab != 0
63206320
#endif
@@ -6325,7 +6325,7 @@ ex_help(exarg_T *eap)
63256325
wp = NULL;
63266326
else
63276327
FOR_ALL_WINDOWS(wp)
6328-
if (wp->w_buffer != NULL && wp->w_buffer->b_help)
6328+
if (bt_help(wp->w_buffer))
63296329
break;
63306330
if (wp != NULL && wp->w_buffer->b_nwindows > 0)
63316331
win_enter(wp, TRUE);
@@ -6425,7 +6425,7 @@ ex_helpclose(exarg_T *eap UNUSED)
64256425

64266426
FOR_ALL_WINDOWS(win)
64276427
{
6428-
if (win->w_buffer->b_help)
6428+
if (bt_help(win->w_buffer))
64296429
{
64306430
win_close(win, FALSE);
64316431
return;

src/proto/buffer.pro

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,7 @@ int read_viminfo_bufferlist(vir_T *virp, int writing);
5555
void write_viminfo_bufferlist(FILE *fp);
5656
int bt_quickfix(buf_T *buf);
5757
int bt_terminal(buf_T *buf);
58+
int bt_help(buf_T *buf);
5859
int bt_nofile(buf_T *buf);
5960
int bt_dontwrite(buf_T *buf);
6061
int bt_dontwrite_msg(buf_T *buf);

src/quickfix.c

Lines changed: 11 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -2101,15 +2101,15 @@ qf_jump(
21012101
/*
21022102
* For ":helpgrep" find a help window or open one.
21032103
*/
2104-
if (qf_ptr->qf_type == 1 && (!curwin->w_buffer->b_help || cmdmod.tab != 0))
2104+
if (qf_ptr->qf_type == 1 && (!bt_help(curwin->w_buffer) || cmdmod.tab != 0))
21052105
{
21062106
win_T *wp;
21072107

21082108
if (cmdmod.tab != 0)
21092109
wp = NULL;
21102110
else
21112111
FOR_ALL_WINDOWS(wp)
2112-
if (wp->w_buffer != NULL && wp->w_buffer->b_help)
2112+
if (bt_help(wp->w_buffer))
21132113
break;
21142114
if (wp != NULL && wp->w_buffer->b_nwindows > 0)
21152115
win_enter(wp, TRUE);
@@ -5343,10 +5343,14 @@ ex_helpgrep(exarg_T *eap)
53435343

53445344
if (eap->cmdidx == CMD_lhelpgrep)
53455345
{
5346-
/* Find an existing help window */
5347-
FOR_ALL_WINDOWS(wp)
5348-
if (wp->w_buffer != NULL && wp->w_buffer->b_help)
5349-
break;
5346+
/* If the current window is a help window, then use it */
5347+
if (bt_help(curwin->w_buffer))
5348+
wp = curwin;
5349+
else
5350+
/* Find an existing help window */
5351+
FOR_ALL_WINDOWS(wp)
5352+
if (bt_help(wp->w_buffer))
5353+
break;
53505354

53515355
if (wp == NULL) /* Help window not found */
53525356
qi = NULL;
@@ -5515,7 +5519,7 @@ ex_helpgrep(exarg_T *eap)
55155519
{
55165520
/* If the help window is not opened or if it already points to the
55175521
* correct location list, then free the new location list. */
5518-
if (!curwin->w_buffer->b_help || curwin->w_llist == qi)
5522+
if (!bt_help(curwin->w_buffer) || curwin->w_llist == qi)
55195523
{
55205524
if (new_qi)
55215525
ll_free_all(&qi);

src/testdir/test_quickfix.vim

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2287,3 +2287,17 @@ func Test_changedtick()
22872287
call Xchangedtick_tests('c')
22882288
call Xchangedtick_tests('l')
22892289
endfunc
2290+
2291+
" Open multiple help windows using ":lhelpgrep
2292+
" This test used to crash Vim
2293+
func Test_Multi_LL_Help()
2294+
new | only
2295+
lhelpgrep window
2296+
lopen
2297+
e#
2298+
lhelpgrep buffer
2299+
call assert_equal(3, winnr('$'))
2300+
call assert_true(len(getloclist(1)) != 0)
2301+
call assert_true(len(getloclist(2)) != 0)
2302+
new | only
2303+
endfunc

src/version.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -769,6 +769,8 @@ static char *(features[]) =
769769

770770
static int included_patches[] =
771771
{ /* Add new patch number below this line */
772+
/**/
773+
782,
772774
/**/
773775
781,
774776
/**/

src/window.c

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2314,7 +2314,7 @@ win_close(win_T *win, int free_buf)
23142314

23152315
/* When closing the help window, try restoring a snapshot after closing
23162316
* the window. Otherwise clear the snapshot, it's now invalid. */
2317-
if (win->w_buffer != NULL && win->w_buffer->b_help)
2317+
if (bt_help(win->w_buffer))
23182318
help_window = TRUE;
23192319
else
23202320
clear_snapshot(curtab, SNAP_HELP_IDX);
@@ -2397,7 +2397,7 @@ win_close(win_T *win, int free_buf)
23972397
&& (last_window() || curtab != prev_curtab
23982398
|| close_last_window_tabpage(win, free_buf, prev_curtab)))
23992399
{
2400-
/* Autocommands have close all windows, quit now. Restore
2400+
/* Autocommands have closed all windows, quit now. Restore
24012401
* curwin->w_buffer, otherwise writing viminfo may fail. */
24022402
if (curwin->w_buffer == NULL)
24032403
curwin->w_buffer = curbuf;
@@ -6479,7 +6479,7 @@ only_one_window(void)
64796479

64806480
FOR_ALL_WINDOWS(wp)
64816481
if (wp->w_buffer != NULL
6482-
&& (!((wp->w_buffer->b_help && !curbuf->b_help)
6482+
&& (!((bt_help(wp->w_buffer) && !bt_help(curbuf))
64836483
# ifdef FEAT_QUICKFIX
64846484
|| wp->w_p_pvw
64856485
# endif

0 commit comments

Comments
 (0)