From 187a34d59bd9631ada57b7b42cc599df30bbf709 Mon Sep 17 00:00:00 2001 From: zeertzjq Date: Tue, 21 Apr 2026 09:18:30 +0800 Subject: [PATCH] vim-patch:9.2.0380: completion: a few issues in completion code (#39264) Problem: ins_compl_stop() sets compl_best_matches = 0, but that's a pointer, should reset compl_num_bests instead, find_common_prefix() reads cpt_sources_array[cur_source] without checking cur_source != -1 which causes an OOB for -1, find_next_completion_match(): second `if` in the pending loop should be `else if`. Forward paging only moves one step per call. Solution: Reset compl_num_bests instead, add a check for cur_source not equal -1, change if to else if (glepnir) closes: vim/vim#20000 https://github.com/vim/vim/commit/b328686d6a1eae1c519a0cdc0420c0d87b6d1fd1 Co-authored-by: glepnir (cherry picked from commit 3f9500e75d816490fb670c92074bcc92fd84e5f3) --- src/nvim/insexpand.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/nvim/insexpand.c b/src/nvim/insexpand.c index dfaedea41d..93577450c7 100644 --- a/src/nvim/insexpand.c +++ b/src/nvim/insexpand.c @@ -2701,7 +2701,7 @@ static bool ins_compl_stop(const int c, const int prev_mode, bool retval) } compl_autocomplete = false; compl_from_nonkeyword = false; - compl_best_matches = 0; + compl_num_bests = 0; compl_ins_end_col = 0; if (c == Ctrl_C && cmdwin_type != 0) { @@ -5053,7 +5053,8 @@ static char *find_common_prefix(size_t *prefix_len, bool curbuf_only) } if (!match_limit_exceeded - && (!curbuf_only || cpt_sources_array[cur_source].cs_flag == '.')) { + && (!curbuf_only || (cur_source != -1 + && cpt_sources_array[cur_source].cs_flag == '.'))) { if (first == NULL && strncmp(ins_compl_leader(), compl->cp_str.data, ins_compl_leader_len()) == 0) { first = compl->cp_str.data; @@ -5286,8 +5287,7 @@ static int find_next_completion_match(bool allow_get_expansion, int todo, bool a if (compl_pending > 0 && compl_shown_match->cp_next != NULL) { compl_shown_match = compl_shown_match->cp_next; compl_pending--; - } - if (compl_pending < 0 && compl_shown_match->cp_prev != NULL) { + } else if (compl_pending < 0 && compl_shown_match->cp_prev != NULL) { compl_shown_match = compl_shown_match->cp_prev; compl_pending++; } else {