commit 5f23aaba00dcc83a5eb3e1b0bb011cd0d1531bfe
parent b1e35cbd7b32d4163131bdd1d828db9ecb19fd62
Author: zeertzjq <zeertzjq@outlook.com>
Date: Sat, 9 Aug 2025 10:43:49 +0800
vim-patch:9.1.1609: complete: Heap-buffer overflow with complete function
Problem: complete: Heap-buffer overflow with complete function
(zeertzjq)
Solution: Do not let startcol become negative (Girish Palya).
fixes: vim/vim#17907
closes: vim/vim#17934
https://github.com/vim/vim/commit/761ea77670c4fdb96d6c6fb7d4db6dc77eb8095f
Co-authored-by: Girish Palya <girishji@gmail.com>
Co-authored-by: Hirohito Higashi <h.east.727@gmail.com>
Diffstat:
2 files changed, 33 insertions(+), 4 deletions(-)
diff --git a/src/nvim/insexpand.c b/src/nvim/insexpand.c
@@ -333,7 +333,6 @@ typedef struct cpt_source_T {
uint64_t compl_start_tv; ///< Timestamp when match collection starts
} cpt_source_T;
-#define STARTCOL_NONE -9
/// Pointer to the array of completion sources
static cpt_source_T *cpt_sources_array;
/// Total number of completion sources specified in the 'cpt' option
@@ -4620,10 +4619,12 @@ static void prepare_cpt_compl_funcs(void)
} else {
startcol = -2;
}
+ } else if (startcol < 0 || startcol > curwin->w_cursor.col) {
+ startcol = curwin->w_cursor.col;
}
cpt_sources_array[idx].cs_startcol = startcol;
} else {
- cpt_sources_array[idx].cs_startcol = STARTCOL_NONE;
+ cpt_sources_array[idx].cs_startcol = -3;
}
(void)copy_option_part(&p, IObuff, IOSIZE, ","); // Advance p
@@ -6379,14 +6380,14 @@ static void cpt_compl_refresh(void)
} else {
startcol = -2;
}
+ } else if (startcol < 0 || startcol > curwin->w_cursor.col) {
+ startcol = curwin->w_cursor.col;
}
cpt_sources_array[cpt_sources_index].cs_startcol = startcol;
if (ret == OK) {
compl_source_start_timer(cpt_sources_index);
get_cpt_func_completion_matches(cb);
}
- } else {
- cpt_sources_array[cpt_sources_index].cs_startcol = STARTCOL_NONE;
}
}
diff --git a/test/old/testdir/test_ins_complete.vim b/test/old/testdir/test_ins_complete.vim
@@ -5524,4 +5524,32 @@ func Test_scriplocal_autoload_func()
let &rtp = save_rtp
endfunc
+" Issue #17907
+func Test_omni_start_invalid_col()
+ func OmniFunc(startcol, findstart, base)
+ if a:findstart
+ return a:startcol
+ else
+ return ['foo', 'foobar']
+ endif
+ endfunc
+
+ new
+ redraw " need this to prevent NULL dereference in Nvim
+ set complete=o
+ set omnifunc=funcref('OmniFunc',\ [-1])
+ call setline(1, ['baz '])
+ call feedkeys("A\<C-N>\<Esc>0", 'tx!')
+ call assert_equal('baz foo', getline(1))
+
+ set omnifunc=funcref('OmniFunc',\ [1000])
+ call setline(1, ['bar '])
+ call feedkeys("A\<C-N>\<Esc>0", 'tx!')
+ call assert_equal('bar foo', getline(1))
+ bw!
+
+ delfunc OmniFunc
+ set omnifunc& complete&
+endfunc
+
" vim: shiftwidth=2 sts=2 expandtab nofoldenable