From ac772706cccbcfbd05699368492b51a34d78bcbd Mon Sep 17 00:00:00 2001 From: zeertzjq Date: Wed, 11 Jun 2025 06:38:40 +0800 Subject: [PATCH] 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 --- src/nvim/insexpand.c | 14 ++++++++------ test/old/testdir/test_ins_complete.vim | 25 +++++++++++++++++++++++++ 2 files changed, 33 insertions(+), 6 deletions(-) diff --git a/src/nvim/insexpand.c b/src/nvim/insexpand.c index 19bfd726e4..1f0e3b54d8 100644 --- 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 index aa2f2569d1..14a917376c 100644 --- 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\\\\0", 'tx!') + call assert_equal('ab', getline(1)) + + bwipe! + delfunc Omni_test + unlet g:do_complete +endfunc + " vim: shiftwidth=2 sts=2 expandtab nofoldenable