summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBram Moolenaar <Bram@vim.org>2019-11-21 13:27:06 +0100
committerBram Moolenaar <Bram@vim.org>2019-11-21 13:27:06 +0100
commit9ae862ebba4a8962cb1c6811a2a46656fa672599 (patch)
tree8d2ddb6a864414b159fedd0b00b3d10714891408
parent202c3f7e3e5a90135ad37100fbfd6583c84a6c99 (diff)
downloadvim-git-9ae862ebba4a8962cb1c6811a2a46656fa672599.tar.gz
patch 8.1.2325: crash when using balloon with empty linev8.1.2325
Problem: Crash when using balloon with empty line. Solution: Handle empty lines. (Markus Braun)
-rw-r--r--src/popupmenu.c66
-rw-r--r--src/testdir/test_popup.vim6
-rw-r--r--src/version.c2
3 files changed, 43 insertions, 31 deletions
diff --git a/src/popupmenu.c b/src/popupmenu.c
index 10d367a3b..4d1d84565 100644
--- a/src/popupmenu.c
+++ b/src/popupmenu.c
@@ -1209,42 +1209,46 @@ split_message(char_u *mesg, pumitem_T **array)
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)
+ if (item->bytelen == 0)
+ (*array)[line++].pum_text = vim_strsave((char_u *)"");
+ else
+ for (skip = 0; skip < item->bytelen; skip += thislen)
{
- cells = item->indent * 2;
- for (p = item->start + skip; p < item->start + item->bytelen;
+ 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;
+ 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)
- {
- 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] = ' ';
+ // 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] = ' ';
- // exclude spaces at the end of the string
- for (copylen = thislen; copylen > 0; --copylen)
- if (item->start[skip + copylen - 1] != ' ')
- break;
+ // 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;
- }
+ 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;
diff --git a/src/testdir/test_popup.vim b/src/testdir/test_popup.vim
index 5b602cc12..21bd22ade 100644
--- 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()
diff --git a/src/version.c b/src/version.c
index 0d8d597b3..c448e57fd 100644
--- 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,