commit ac772706cccbcfbd05699368492b51a34d78bcbd
parent b5aef05b8f653eca3901a9da32b75417f56904b9
Author: zeertzjq <zeertzjq@outlook.com>
Date: Wed, 11 Jun 2025 06:38:40 +0800
vim-patch:9.1.1447: completion: crash when backspacing with fuzzy completion
Problem: completion: crash when backspacing with fuzzy completion
Solution: Don't dereference compl_first_match when it's NULL
(zeertzjq).
related: neovim/neovim#34419
closes: vim/vim#17511
https://github.com/vim/vim/commit/91782b4aeb62043739138903f30cad2fe79238ab
Diffstat:
2 files changed, 33 insertions(+), 6 deletions(-)
diff --git a/src/nvim/insexpand.c b/src/nvim/insexpand.c
@@ -1339,13 +1339,15 @@ static int cp_compare_nearest(const void *a, const void *b)
/// Set fuzzy score.
static void set_fuzzy_score(void)
{
- if (compl_leader.data != NULL && compl_leader.size > 0) {
- compl_T *comp = compl_first_match;
- do {
- comp->cp_score = fuzzy_match_str(comp->cp_str.data, compl_leader.data);
- comp = comp->cp_next;
- } while (comp != NULL && !is_first_match(comp));
+ if (!compl_first_match || compl_leader.data == NULL || compl_leader.size == 0) {
+ return;
}
+
+ compl_T *comp = compl_first_match;
+ do {
+ comp->cp_score = fuzzy_match_str(comp->cp_str.data, compl_leader.data);
+ comp = comp->cp_next;
+ } while (comp != NULL && !is_first_match(comp));
}
/// Sort completion matches, excluding the node that contains the leader.
diff --git a/test/old/testdir/test_ins_complete.vim b/test/old/testdir/test_ins_complete.vim
@@ -4835,4 +4835,29 @@ func Test_complete_unloaded_buf_refresh_always()
delfunc TestComplete
endfunc
+func Test_complete_fuzzy_omnifunc_backspace()
+ let g:do_complete = v:false
+ func Omni_test(findstart, base)
+ if a:findstart
+ let g:do_complete = !g:do_complete
+ endif
+ if g:do_complete
+ return a:findstart ? 0 : [#{word: a:base .. 'def'}, #{word: a:base .. 'ghi'}]
+ endif
+ return a:findstart ? -3 : {}
+ endfunc
+
+ new
+ redraw " need this to prevent NULL dereference in Nvim
+ setlocal omnifunc=Omni_test
+ setlocal completeopt=menuone,fuzzy,noinsert
+ call setline(1, 'abc')
+ call feedkeys("A\<C-X>\<C-O>\<BS>\<Esc>0", 'tx!')
+ call assert_equal('ab', getline(1))
+
+ bwipe!
+ delfunc Omni_test
+ unlet g:do_complete
+endfunc
+
" vim: shiftwidth=2 sts=2 expandtab nofoldenable