changeset 11289:e0309111d976 v8.0.0530

patch 8.0.0530: buffer overflow when 'columns' is very big commit https://github.com/vim/vim/commit/658a3a2caf5852d071b6b1be92d9d6614a6208dc Author: Bram Moolenaar <Bram@vim.org> Date: Fri Mar 31 22:27:12 2017 +0200 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)
author Christian Brabandt <cb@256bit.org>
date Fri, 31 Mar 2017 22:30:04 +0200
parents b0cf68080f6a
children e6881d996169
files src/edit.c src/testdir/test_edit.vim src/version.c
diffstat 3 files changed, 47 insertions(+), 10 deletions(-) [+]
line wrap: on
line diff
--- 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;
--- 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
--- 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,