0
0
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:
Bram Moolenaar
2017-05-01 20:46:52 +02:00
parent beb9cb19c6
commit 4475b62396
3 changed files with 64 additions and 10 deletions

View File

@@ -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;
} }

View File

@@ -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

View File

@@ -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,
/**/ /**/