Mercurial > vim
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()