diff options
author | Bram Moolenaar <Bram@vim.org> | 2017-03-31 22:27:12 +0200 |
---|---|---|
committer | Bram Moolenaar <Bram@vim.org> | 2017-03-31 22:27:12 +0200 |
commit | 658a3a2caf5852d071b6b1be92d9d6614a6208dc (patch) | |
tree | c78aa94abed7966b0b6c69fe2b56d720e6d91666 | |
parent | 13489b9c41922b9ecb16fa47564ec76641515c08 (diff) | |
download | vim-658a3a2caf5852d071b6b1be92d9d6614a6208dc.zip |
patch 8.0.0530: buffer overflow when 'columns' is very big
Problem: Buffer overflow when 'columns' is very big. (Nikolai Pavlov)
Solution: Correctly compute where to truncate. Fix translation.
(closes #1600)
-rw-r--r-- | src/edit.c | 34 | ||||
-rw-r--r-- | src/testdir/test_edit.vim | 21 | ||||
-rw-r--r-- | src/version.c | 2 |
3 files changed, 47 insertions, 10 deletions
diff --git a/src/edit.c b/src/edit.c index cdde11e40..8aa15af83 100644 --- a/src/edit.c +++ b/src/edit.c @@ -4756,7 +4756,6 @@ ins_compl_next( int in_compl_func) /* called from complete_check() */ { int num_matches = -1; - int i; int todo = count; compl_T *found_compl = NULL; int found_end = FALSE; @@ -4948,15 +4947,30 @@ ins_compl_next( */ if (compl_shown_match->cp_fname != NULL) { - STRCPY(IObuff, "match in file "); - i = (vim_strsize(compl_shown_match->cp_fname) + 16) - sc_col; - if (i <= 0) - i = 0; - else - STRCAT(IObuff, "<"); - STRCAT(IObuff, compl_shown_match->cp_fname + i); - msg(IObuff); - redraw_cmdline = FALSE; /* don't overwrite! */ + char *lead = _("match in file"); + int space = sc_col - vim_strsize((char_u *)lead) - 2; + char_u *s; + char_u *e; + + if (space > 0) + { + /* We need the tail that fits. With double-byte encoding going + * back from the end is very slow, thus go from the start and keep + * the text that fits in "space" between "s" and "e". */ + for (s = e = compl_shown_match->cp_fname; *e != NUL; MB_PTR_ADV(e)) + { + space -= ptr2cells(e); + while (space < 0) + { + space += ptr2cells(s); + MB_PTR_ADV(s); + } + } + vim_snprintf((char *)IObuff, IOSIZE, "%s %s%s", lead, + s > compl_shown_match->cp_fname ? "<" : "", s); + msg(IObuff); + redraw_cmdline = FALSE; /* don't overwrite! */ + } } return num_matches; diff --git a/src/testdir/test_edit.vim b/src/testdir/test_edit.vim index 344c12664..b43f84ba2 100644 --- a/src/testdir/test_edit.vim +++ b/src/testdir/test_edit.vim @@ -1322,3 +1322,24 @@ func! Test_edit_rightleft() set norightleft bw! endfunc + +func Test_edit_complete_very_long_name() + let save_columns = &columns + set columns=5000 + call assert_equal(5000, &columns) + set noswapfile + let dirname = getcwd() . "/Xdir" + let longdirname = dirname . repeat('/' . repeat('d', 255), 4) + let longfilename = longdirname . '/' . repeat('a', 255) + call mkdir(longdirname, 'p') + call writefile(['Totum', 'Table'], longfilename) + new + exe "next Xfile " . longfilename + exe "normal iT\<C-N>" + + bwipe! + exe 'bwipe! ' . longfilename + call delete(dirname, 'rf') + let &columns = save_columns + set swapfile& +endfunc diff --git a/src/version.c b/src/version.c index 82510cdfe..16ebc8784 100644 --- a/src/version.c +++ b/src/version.c @@ -765,6 +765,8 @@ static char *(features[]) = static int included_patches[] = { /* Add new patch number below this line */ /**/ + 530, +/**/ 529, /**/ 528, |