From: Bram Moolenaar Date: Fri, 6 Nov 2020 16:58:35 +0000 (+0100) Subject: patch 8.2.1963: crash when using a popup window with "latin1" encoding X-Git-Tag: v8.2.1963 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=927495b1fef835a8f83c089bb3aa3608b617e972;p=vim patch 8.2.1963: crash when using a popup window with "latin1" encoding Problem: Crash when using a popup window with "latin1" encoding. Solution: Don't use ScreenLinesUC when enc_utf8 is false. (closes #7241) --- diff --git a/src/screen.c b/src/screen.c index 6e907cdf4..b204de9bf 100644 --- a/src/screen.c +++ b/src/screen.c @@ -464,7 +464,8 @@ screen_line( // First char of a popup window may go on top of the right half of a // double-wide character. Clear the left half to avoid it getting the popup // window background color. - if (coloff > 0 && ScreenLines[off_to] == 0 + if (coloff > 0 && enc_utf8 + && ScreenLines[off_to] == 0 && ScreenLinesUC[off_to - 1] != 0 && (*mb_char2cells)(ScreenLinesUC[off_to - 1]) > 1) { diff --git a/src/terminal.c b/src/terminal.c index ff3e3bd6a..e81754cca 100644 --- a/src/terminal.c +++ b/src/terminal.c @@ -1830,6 +1830,10 @@ update_snapshot(term_T *term) width = cell.width; cell2cellattr(&cell, &p[pos.col]); + if (width == 2) + // second cell of double-width character has the + // same attributes. + p[pos.col + 1] = p[pos.col]; // Each character can be up to 6 bytes. if (ga_grow(&ga, VTERM_MAX_CHARS_PER_CELL * 6) == OK) @@ -3639,6 +3643,7 @@ term_line2screenline( } #endif else + // This will only store the lower byte of "c". ScreenLines[off] = c; } ScreenAttrs[off] = cell2attr(term, wp, cell.attrs, cell.fg, cell.bg); @@ -3647,13 +3652,20 @@ term_line2screenline( ++off; if (cell.width == 2) { - if (enc_utf8) - ScreenLinesUC[off] = NUL; - // don't set the second byte to NUL for a DBCS encoding, it // has been set above - if (enc_utf8 || !has_mbyte) + if (enc_utf8) + { + ScreenLinesUC[off] = NUL; ScreenLines[off] = NUL; + } + else if (!has_mbyte) + { + // Can't show a double-width character with a single-byte + // 'encoding', just use a space. + ScreenLines[off] = ' '; + ScreenAttrs[off] = ScreenAttrs[off - 1]; + } ++pos->col; ++off; diff --git a/src/testdir/test_popupwin.vim b/src/testdir/test_popupwin.vim index 435873ec6..43dbeb5a1 100644 --- a/src/testdir/test_popupwin.vim +++ b/src/testdir/test_popupwin.vim @@ -3685,6 +3685,28 @@ func Test_popupwin_filter_close_three_errors() call delete('XtestPopupThreeErrors') endfunc +func Test_popupwin_latin1_encoding() + CheckScreendump + CheckUnix + + " When 'encoding' is a single-byte encoding a terminal window will mess up + " the display. Check that showing a popup on top of that doesn't crash. + let lines =<< trim END + set encoding=latin1 + terminal cat Xmultibyte + call popup_create(['one', 'two', 'three', 'four'], #{line: 1, col: 10}) + END + call writefile(lines, 'XtestPopupLatin') + call writefile([repeat("\u3042 ", 120)], 'Xmultibyte') + + let buf = RunVimInTerminal('-S XtestPopupLatin', #{rows: 10}) + + call term_sendkeys(buf, ":q\") + call StopVimInTerminal(buf) + call delete('XtestPopupLatin') + call delete('Xmultibyte') +endfunc + func Test_popupwin_atcursor_far_right() new diff --git a/src/version.c b/src/version.c index 6baaf593e..3ff458676 100644 --- a/src/version.c +++ b/src/version.c @@ -750,6 +750,8 @@ static char *(features[]) = static int included_patches[] = { /* Add new patch number below this line */ +/**/ + 1963, /**/ 1962, /**/