# HG changeset patch # User Bram Moolenaar # Date 1574339403 -3600 # Node ID de350001150c01edfb29eb68fb5a63eebb8a52b5 # Parent d451a92c772c890670ccd9d0ebcb882ac3d5ace5 patch 8.1.2325: crash when using balloon with empty line Commit: https://github.com/vim/vim/commit/9ae862ebba4a8962cb1c6811a2a46656fa672599 Author: Bram Moolenaar 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) diff --git a/src/popupmenu.c b/src/popupmenu.c --- 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; diff --git a/src/testdir/test_popup.vim b/src/testdir/test_popup.vim --- 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 --- 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,