mirror of
https://github.com/neovim/neovim.git
synced 2024-12-25 21:55:17 -07:00
vim-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)
d28cc3f55d
This commit is contained in:
parent
bb519fb261
commit
dc15dcffad
@ -252,7 +252,7 @@ open_buffer (
|
|||||||
msg_silent = old_msg_silent;
|
msg_silent = old_msg_silent;
|
||||||
|
|
||||||
// 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) {
|
||||||
@ -4930,6 +4930,12 @@ chk_modeline (
|
|||||||
return retval;
|
return retval;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Return true if "buf" is a help buffer.
|
||||||
|
bool bt_help(const buf_T *const buf)
|
||||||
|
{
|
||||||
|
return buf != NULL && buf->b_help;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Return special buffer name.
|
* Return special buffer name.
|
||||||
* Returns NULL when the buffer has a normal file name.
|
* Returns NULL when the buffer has a normal file name.
|
||||||
|
@ -4514,7 +4514,7 @@ void 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)
|
||||||
|| cmdmod.tab != 0
|
|| cmdmod.tab != 0
|
||||||
) {
|
) {
|
||||||
if (cmdmod.tab != 0) {
|
if (cmdmod.tab != 0) {
|
||||||
@ -4522,7 +4522,7 @@ void ex_help(exarg_T *eap)
|
|||||||
} else {
|
} else {
|
||||||
wp = NULL;
|
wp = NULL;
|
||||||
FOR_ALL_WINDOWS_IN_TAB(wp2, curtab) {
|
FOR_ALL_WINDOWS_IN_TAB(wp2, curtab) {
|
||||||
if (wp2->w_buffer != NULL && wp2->w_buffer->b_help) {
|
if (bt_help(wp2->w_buffer)) {
|
||||||
wp = wp2;
|
wp = wp2;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -5509,7 +5509,7 @@ static int next_sign_typenr = 1;
|
|||||||
void ex_helpclose(exarg_T *eap)
|
void ex_helpclose(exarg_T *eap)
|
||||||
{
|
{
|
||||||
FOR_ALL_WINDOWS_IN_TAB(win, curtab) {
|
FOR_ALL_WINDOWS_IN_TAB(win, curtab) {
|
||||||
if (win->w_buffer->b_help) {
|
if (bt_help(win->w_buffer)) {
|
||||||
win_close(win, FALSE);
|
win_close(win, FALSE);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -1839,12 +1839,12 @@ void qf_jump(qf_info_T *qi, int dir, int errornr, int forceit)
|
|||||||
/*
|
/*
|
||||||
* 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 = NULL;
|
win_T *wp = NULL;
|
||||||
|
|
||||||
if (cmdmod.tab == 0) {
|
if (cmdmod.tab == 0) {
|
||||||
FOR_ALL_WINDOWS_IN_TAB(wp2, curtab) {
|
FOR_ALL_WINDOWS_IN_TAB(wp2, curtab) {
|
||||||
if (wp2->w_buffer != NULL && wp2->w_buffer->b_help) {
|
if (bt_help(wp2->w_buffer)) {
|
||||||
wp = wp2;
|
wp = wp2;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -4721,16 +4721,26 @@ void ex_helpgrep(exarg_T *eap)
|
|||||||
p_cpo = empty_option;
|
p_cpo = empty_option;
|
||||||
|
|
||||||
if (eap->cmdidx == CMD_lhelpgrep) {
|
if (eap->cmdidx == CMD_lhelpgrep) {
|
||||||
qi = NULL;
|
win_T *wp = NULL;
|
||||||
|
|
||||||
/* Find an existing help window */
|
// If the current window is a help window, then use it
|
||||||
FOR_ALL_WINDOWS_IN_TAB(wp, curtab) {
|
if (bt_help(curwin->w_buffer)) {
|
||||||
if (wp->w_buffer != NULL && wp->w_buffer->b_help) {
|
wp = curwin;
|
||||||
qi = wp->w_llist;
|
} else {
|
||||||
|
// Find an existing help window
|
||||||
|
FOR_ALL_WINDOWS_IN_TAB(wp2, curtab) {
|
||||||
|
if (bt_help(wp2->w_buffer)) {
|
||||||
|
wp = wp2;
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Help window not found */
|
if (wp == NULL) { // Help window not found
|
||||||
|
qi = NULL;
|
||||||
|
} else {
|
||||||
|
qi = wp->w_llist;
|
||||||
|
}
|
||||||
if (qi == NULL) {
|
if (qi == NULL) {
|
||||||
/* Allocate a new location list for help text matches */
|
/* Allocate a new location list for help text matches */
|
||||||
qi = ll_new_list();
|
qi = ll_new_list();
|
||||||
@ -4851,7 +4861,7 @@ void ex_helpgrep(exarg_T *eap)
|
|||||||
if (eap->cmdidx == CMD_lhelpgrep) {
|
if (eap->cmdidx == CMD_lhelpgrep) {
|
||||||
/* 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);
|
||||||
} else if (curwin->w_llist == NULL)
|
} else if (curwin->w_llist == NULL)
|
||||||
|
@ -2269,3 +2269,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
|
||||||
|
@ -1902,7 +1902,7 @@ int 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);
|
||||||
@ -1967,8 +1967,8 @@ int win_close(win_T *win, int free_buf)
|
|||||||
if (only_one_window() && win_valid(win) && win->w_buffer == NULL
|
if (only_one_window() && win_valid(win) && win->w_buffer == NULL
|
||||||
&& (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 ShaDa file may fail. */
|
// curwin->w_buffer, otherwise writing ShaDa file may fail.
|
||||||
if (curwin->w_buffer == NULL)
|
if (curwin->w_buffer == NULL)
|
||||||
curwin->w_buffer = curbuf;
|
curwin->w_buffer = curbuf;
|
||||||
getout(0);
|
getout(0);
|
||||||
@ -5341,7 +5341,7 @@ bool only_one_window(void) FUNC_ATTR_PURE FUNC_ATTR_WARN_UNUSED_RESULT
|
|||||||
int count = 0;
|
int count = 0;
|
||||||
FOR_ALL_WINDOWS_IN_TAB(wp, curtab) {
|
FOR_ALL_WINDOWS_IN_TAB(wp, curtab) {
|
||||||
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))
|
||||||
|| wp->w_p_pvw) || wp == curwin) && wp != aucmd_win) {
|
|| wp->w_p_pvw) || wp == curwin) && wp != aucmd_win) {
|
||||||
count++;
|
count++;
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user