Skip to content

Commit 4475b62

Browse files
committed
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.
1 parent beb9cb1 commit 4475b62

File tree

3 files changed

+64
-10
lines changed

3 files changed

+64
-10
lines changed

src/edit.c

Lines changed: 19 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -96,6 +96,7 @@ struct compl_S
9696
static compl_T *compl_first_match = NULL;
9797
static compl_T *compl_curr_match = NULL;
9898
static compl_T *compl_shown_match = NULL;
99+
static compl_T *compl_old_match = NULL;
99100

100101
/* After using a cursor key <Enter> selects a match in the popup menu,
101102
* otherwise it inserts a line break. */
@@ -3431,6 +3432,7 @@ ins_compl_free(void)
34313432
} while (compl_curr_match != NULL && compl_curr_match != compl_first_match);
34323433
compl_first_match = compl_curr_match = NULL;
34333434
compl_shown_match = NULL;
3435+
compl_old_match = NULL;
34343436
}
34353437

34363438
static void
@@ -4272,7 +4274,6 @@ ins_compl_get_exp(pos_T *ini)
42724274
char_u *ptr;
42734275
char_u *dict = NULL;
42744276
int dict_f = 0;
4275-
compl_T *old_match;
42764277
int set_match_pos;
42774278

42784279
if (!compl_started)
@@ -4286,7 +4287,7 @@ ins_compl_get_exp(pos_T *ini)
42864287
last_match_pos = first_match_pos = *ini;
42874288
}
42884289

4289-
old_match = compl_curr_match; /* remember the last current match */
4290+
compl_old_match = compl_curr_match; /* remember the last current match */
42904291
pos = (compl_direction == FORWARD) ? &last_match_pos : &first_match_pos;
42914292
/* For ^N/^P loop over all the flags/windows/buffers in 'complete' */
42924293
for (;;)
@@ -4388,6 +4389,11 @@ ins_compl_get_exp(pos_T *ini)
43884389
}
43894390
}
43904391

4392+
/* If complete() was called then compl_pattern has been reset. The
4393+
* following won't work then, bail out. */
4394+
if (compl_pattern == NULL)
4395+
break;
4396+
43914397
switch (type)
43924398
{
43934399
case -1:
@@ -4621,7 +4627,7 @@ ins_compl_get_exp(pos_T *ini)
46214627

46224628
/* check if compl_curr_match has changed, (e.g. other type of
46234629
* expansion added something) */
4624-
if (type != 0 && compl_curr_match != old_match)
4630+
if (type != 0 && compl_curr_match != compl_old_match)
46254631
found_new_match = OK;
46264632

46274633
/* break the loop for specialized modes (use 'complete' just for the
@@ -4660,13 +4666,16 @@ ins_compl_get_exp(pos_T *ini)
46604666
|| (ctrl_x_mode != 0 && !CTRL_X_MODE_LINE_OR_EVAL(ctrl_x_mode)))
46614667
i = ins_compl_make_cyclic();
46624668

4663-
/* If several matches were added (FORWARD) or the search failed and has
4664-
* just been made cyclic then we have to move compl_curr_match to the next
4665-
* or previous entry (if any) -- Acevedo */
4666-
compl_curr_match = compl_direction == FORWARD ? old_match->cp_next
4667-
: old_match->cp_prev;
4668-
if (compl_curr_match == NULL)
4669-
compl_curr_match = old_match;
4669+
if (compl_old_match != NULL)
4670+
{
4671+
/* If several matches were added (FORWARD) or the search failed and has
4672+
* just been made cyclic then we have to move compl_curr_match to the
4673+
* next or previous entry (if any) -- Acevedo */
4674+
compl_curr_match = compl_direction == FORWARD ? compl_old_match->cp_next
4675+
: compl_old_match->cp_prev;
4676+
if (compl_curr_match == NULL)
4677+
compl_curr_match = compl_old_match;
4678+
}
46704679
return i;
46714680
}
46724681

src/testdir/test_popup.vim

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -570,4 +570,47 @@ func Test_completion_comment_formatting()
570570
bwipe!
571571
endfunc
572572

573+
fun MessCompleteMonths()
574+
for m in split("Jan Feb Mar Apr May Jun Jul Aug Sep")
575+
call complete_add(m)
576+
if complete_check()
577+
break
578+
endif
579+
endfor
580+
return []
581+
endfun
582+
583+
fun MessCompleteMore()
584+
call complete(1, split("Oct Nov Dec"))
585+
return []
586+
endfun
587+
588+
fun MessComplete(findstart, base)
589+
if a:findstart
590+
let line = getline('.')
591+
let start = col('.') - 1
592+
while start > 0 && line[start - 1] =~ '\a'
593+
let start -= 1
594+
endwhile
595+
return start
596+
else
597+
call MessCompleteMonths()
598+
call MessCompleteMore()
599+
return []
600+
endif
601+
endf
602+
603+
func Test_complete_func_mess()
604+
" Calling complete() after complete_add() in 'completefunc' is wrong, but it
605+
" should not crash.
606+
set completefunc=MessComplete
607+
new
608+
call setline(1, 'Ju')
609+
call feedkeys("A\<c-x>\<c-u>/\<esc>", 'tx')
610+
call assert_equal('Oct/Oct', getline(1))
611+
bwipe!
612+
set completefunc=
613+
endfunc
614+
615+
573616
" vim: shiftwidth=2 sts=2 expandtab

src/version.c

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

765765
static int included_patches[] =
766766
{ /* Add new patch number below this line */
767+
/**/
768+
596,
767769
/**/
768770
595,
769771
/**/

0 commit comments

Comments
 (0)