changeset 18667:de350001150c v8.1.2325

patch 8.1.2325: crash when using balloon with empty line Commit: https://github.com/vim/vim/commit/9ae862ebba4a8962cb1c6811a2a46656fa672599 Author: Bram Moolenaar <Bram@vim.org> Date: Thu Nov 21 13:27:06 2019 +0100 patch 8.1.2325: crash when using balloon with empty line Problem: Crash when using balloon with empty line. Solution: Handle empty lines. (Markus Braun)
author Bram Moolenaar <Bram@vim.org>
date Thu, 21 Nov 2019 13:30:03 +0100
parents d451a92c772c
children ce55d198b1b5
files src/popupmenu.c src/testdir/test_popup.vim src/version.c
diffstat 3 files changed, 45 insertions(+), 33 deletions(-) [+]
line wrap: on
line diff
--- a/src/popupmenu.c
+++ b/src/popupmenu.c
@@ -1209,42 +1209,46 @@ split_message(char_u *mesg, pumitem_T **
 	int	cells;
 
 	item = ((balpart_T *)ga.ga_data) + item_idx;
-	for (skip = 0; skip < item->bytelen; skip += thislen)
-	{
-	    if (split_long_items && item->cells >= BALLOON_MIN_WIDTH)
-	    {
-		cells = item->indent * 2;
-		for (p = item->start + skip; p < item->start + item->bytelen;
-							    p += mb_ptr2len(p))
-		    if ((cells += ptr2cells(p)) > BALLOON_MIN_WIDTH)
-			break;
-		thislen = p - (item->start + skip);
-	    }
-	    else
-		thislen = item->bytelen;
-
-	    // put indent at the start
-	    p = alloc(thislen + item->indent * 2 + 1);
-	    if (p == NULL)
+	if (item->bytelen == 0)
+	    (*array)[line++].pum_text = vim_strsave((char_u *)"");
+	else
+	    for (skip = 0; skip < item->bytelen; skip += thislen)
 	    {
-		for (line = 0; line <= height - 1; ++line)
-		    vim_free((*array)[line].pum_text);
-		vim_free(*array);
-		goto failed;
-	    }
-	    for (ind = 0; ind < item->indent * 2; ++ind)
-		p[ind] = ' ';
+		if (split_long_items && item->cells >= BALLOON_MIN_WIDTH)
+		{
+		    cells = item->indent * 2;
+		    for (p = item->start + skip;
+			    p < item->start + item->bytelen;
+							    p += mb_ptr2len(p))
+			if ((cells += ptr2cells(p)) > BALLOON_MIN_WIDTH)
+			    break;
+		    thislen = p - (item->start + skip);
+		}
+		else
+		    thislen = item->bytelen;
 
-	    // exclude spaces at the end of the string
-	    for (copylen = thislen; copylen > 0; --copylen)
-		if (item->start[skip + copylen - 1] != ' ')
-		    break;
+		// put indent at the start
+		p = alloc(thislen + item->indent * 2 + 1);
+		if (p == NULL)
+		{
+		    for (line = 0; line <= height - 1; ++line)
+			vim_free((*array)[line].pum_text);
+		    vim_free(*array);
+		    goto failed;
+		}
+		for (ind = 0; ind < item->indent * 2; ++ind)
+		    p[ind] = ' ';
 
-	    vim_strncpy(p + ind, item->start + skip, copylen);
-	    (*array)[line].pum_text = p;
-	    item->indent = 0;  /* wrapped line has no indent */
-	    ++line;
-	}
+		// exclude spaces at the end of the string
+		for (copylen = thislen; copylen > 0; --copylen)
+		    if (item->start[skip + copylen - 1] != ' ')
+			break;
+
+		vim_strncpy(p + ind, item->start + skip, copylen);
+		(*array)[line].pum_text = p;
+		item->indent = 0;  /* wrapped line has no indent */
+		++line;
+	    }
     }
     ga_clear(&ga);
     return height;
--- a/src/testdir/test_popup.vim
+++ b/src/testdir/test_popup.vim
@@ -795,6 +795,12 @@ func Test_balloon_split()
         \ '  next = 123}',
         \ ], balloon_split(
         \ 'struct = 0x234 {long = 2343 "\\"some long string that will be wrapped in two\\"", next = 123}'))
+  call assert_equal([
+        \ 'Some comment',
+        \ '',
+        \ 'typedef this that;',
+        \ ], balloon_split(
+        \ "Some comment\n\ntypedef this that;"))
 endfunc
 
 func Test_popup_position()
--- a/src/version.c
+++ b/src/version.c
@@ -742,6 +742,8 @@ static char *(features[]) =
 static int included_patches[] =
 {   /* Add new patch number below this line */
 /**/
+    2325,
+/**/
     2324,
 /**/
     2323,