mirror of
https://github.com/vim/vim.git
synced 2025-09-25 03:54:15 -04:00
patch 8.0.0596: crash when complete() called after complete_add()
Problem: Crash when complete() is called after complete_add() in 'completefunc'. (Lifepillar) Solution: Bail out if compl_pattern is NULL. (closes #1668) Also avoid using freed memory.
This commit is contained in:
29
src/edit.c
29
src/edit.c
@@ -96,6 +96,7 @@ struct compl_S
|
|||||||
static compl_T *compl_first_match = NULL;
|
static compl_T *compl_first_match = NULL;
|
||||||
static compl_T *compl_curr_match = NULL;
|
static compl_T *compl_curr_match = NULL;
|
||||||
static compl_T *compl_shown_match = NULL;
|
static compl_T *compl_shown_match = NULL;
|
||||||
|
static compl_T *compl_old_match = NULL;
|
||||||
|
|
||||||
/* After using a cursor key <Enter> selects a match in the popup menu,
|
/* After using a cursor key <Enter> selects a match in the popup menu,
|
||||||
* otherwise it inserts a line break. */
|
* otherwise it inserts a line break. */
|
||||||
@@ -3431,6 +3432,7 @@ ins_compl_free(void)
|
|||||||
} while (compl_curr_match != NULL && compl_curr_match != compl_first_match);
|
} while (compl_curr_match != NULL && compl_curr_match != compl_first_match);
|
||||||
compl_first_match = compl_curr_match = NULL;
|
compl_first_match = compl_curr_match = NULL;
|
||||||
compl_shown_match = NULL;
|
compl_shown_match = NULL;
|
||||||
|
compl_old_match = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@@ -4272,7 +4274,6 @@ ins_compl_get_exp(pos_T *ini)
|
|||||||
char_u *ptr;
|
char_u *ptr;
|
||||||
char_u *dict = NULL;
|
char_u *dict = NULL;
|
||||||
int dict_f = 0;
|
int dict_f = 0;
|
||||||
compl_T *old_match;
|
|
||||||
int set_match_pos;
|
int set_match_pos;
|
||||||
|
|
||||||
if (!compl_started)
|
if (!compl_started)
|
||||||
@@ -4286,7 +4287,7 @@ ins_compl_get_exp(pos_T *ini)
|
|||||||
last_match_pos = first_match_pos = *ini;
|
last_match_pos = first_match_pos = *ini;
|
||||||
}
|
}
|
||||||
|
|
||||||
old_match = compl_curr_match; /* remember the last current match */
|
compl_old_match = compl_curr_match; /* remember the last current match */
|
||||||
pos = (compl_direction == FORWARD) ? &last_match_pos : &first_match_pos;
|
pos = (compl_direction == FORWARD) ? &last_match_pos : &first_match_pos;
|
||||||
/* For ^N/^P loop over all the flags/windows/buffers in 'complete' */
|
/* For ^N/^P loop over all the flags/windows/buffers in 'complete' */
|
||||||
for (;;)
|
for (;;)
|
||||||
@@ -4388,6 +4389,11 @@ ins_compl_get_exp(pos_T *ini)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* If complete() was called then compl_pattern has been reset. The
|
||||||
|
* following won't work then, bail out. */
|
||||||
|
if (compl_pattern == NULL)
|
||||||
|
break;
|
||||||
|
|
||||||
switch (type)
|
switch (type)
|
||||||
{
|
{
|
||||||
case -1:
|
case -1:
|
||||||
@@ -4621,7 +4627,7 @@ ins_compl_get_exp(pos_T *ini)
|
|||||||
|
|
||||||
/* check if compl_curr_match has changed, (e.g. other type of
|
/* check if compl_curr_match has changed, (e.g. other type of
|
||||||
* expansion added something) */
|
* expansion added something) */
|
||||||
if (type != 0 && compl_curr_match != old_match)
|
if (type != 0 && compl_curr_match != compl_old_match)
|
||||||
found_new_match = OK;
|
found_new_match = OK;
|
||||||
|
|
||||||
/* break the loop for specialized modes (use 'complete' just for the
|
/* break the loop for specialized modes (use 'complete' just for the
|
||||||
@@ -4660,13 +4666,16 @@ ins_compl_get_exp(pos_T *ini)
|
|||||||
|| (ctrl_x_mode != 0 && !CTRL_X_MODE_LINE_OR_EVAL(ctrl_x_mode)))
|
|| (ctrl_x_mode != 0 && !CTRL_X_MODE_LINE_OR_EVAL(ctrl_x_mode)))
|
||||||
i = ins_compl_make_cyclic();
|
i = ins_compl_make_cyclic();
|
||||||
|
|
||||||
/* If several matches were added (FORWARD) or the search failed and has
|
if (compl_old_match != NULL)
|
||||||
* just been made cyclic then we have to move compl_curr_match to the next
|
{
|
||||||
* or previous entry (if any) -- Acevedo */
|
/* If several matches were added (FORWARD) or the search failed and has
|
||||||
compl_curr_match = compl_direction == FORWARD ? old_match->cp_next
|
* just been made cyclic then we have to move compl_curr_match to the
|
||||||
: old_match->cp_prev;
|
* next or previous entry (if any) -- Acevedo */
|
||||||
if (compl_curr_match == NULL)
|
compl_curr_match = compl_direction == FORWARD ? compl_old_match->cp_next
|
||||||
compl_curr_match = old_match;
|
: compl_old_match->cp_prev;
|
||||||
|
if (compl_curr_match == NULL)
|
||||||
|
compl_curr_match = compl_old_match;
|
||||||
|
}
|
||||||
return i;
|
return i;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -570,4 +570,47 @@ func Test_completion_comment_formatting()
|
|||||||
bwipe!
|
bwipe!
|
||||||
endfunc
|
endfunc
|
||||||
|
|
||||||
|
fun MessCompleteMonths()
|
||||||
|
for m in split("Jan Feb Mar Apr May Jun Jul Aug Sep")
|
||||||
|
call complete_add(m)
|
||||||
|
if complete_check()
|
||||||
|
break
|
||||||
|
endif
|
||||||
|
endfor
|
||||||
|
return []
|
||||||
|
endfun
|
||||||
|
|
||||||
|
fun MessCompleteMore()
|
||||||
|
call complete(1, split("Oct Nov Dec"))
|
||||||
|
return []
|
||||||
|
endfun
|
||||||
|
|
||||||
|
fun MessComplete(findstart, base)
|
||||||
|
if a:findstart
|
||||||
|
let line = getline('.')
|
||||||
|
let start = col('.') - 1
|
||||||
|
while start > 0 && line[start - 1] =~ '\a'
|
||||||
|
let start -= 1
|
||||||
|
endwhile
|
||||||
|
return start
|
||||||
|
else
|
||||||
|
call MessCompleteMonths()
|
||||||
|
call MessCompleteMore()
|
||||||
|
return []
|
||||||
|
endif
|
||||||
|
endf
|
||||||
|
|
||||||
|
func Test_complete_func_mess()
|
||||||
|
" Calling complete() after complete_add() in 'completefunc' is wrong, but it
|
||||||
|
" should not crash.
|
||||||
|
set completefunc=MessComplete
|
||||||
|
new
|
||||||
|
call setline(1, 'Ju')
|
||||||
|
call feedkeys("A\<c-x>\<c-u>/\<esc>", 'tx')
|
||||||
|
call assert_equal('Oct/Oct', getline(1))
|
||||||
|
bwipe!
|
||||||
|
set completefunc=
|
||||||
|
endfunc
|
||||||
|
|
||||||
|
|
||||||
" vim: shiftwidth=2 sts=2 expandtab
|
" vim: shiftwidth=2 sts=2 expandtab
|
||||||
|
@@ -764,6 +764,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 */
|
||||||
|
/**/
|
||||||
|
596,
|
||||||
/**/
|
/**/
|
||||||
595,
|
595,
|
||||||
/**/
|
/**/
|
||||||
|
Reference in New Issue
Block a user