Commit: patch 9.2.0939: mbyte: wrong cell count for an overlong UTF-8 sequence
Christian Brabandt <[email protected]> Tue, 11 Aug 2026 21:30:05 +0200
| Newsgroups | gmane.editors.vim.devel |
|---|---|
| Message-ID | <[email protected]> |
patch 9.2.0939: mbyte: wrong cell count for an overlong UTF-8 sequence Commit: https://github.com/vim/vim/commit/0cdcd95cc2f6a000aafe084f31299cc69affc139 Author: Hirohito Higashi <[email protected]> Date: Tue Aug 11 19:16:00 2026 +0000 patch 9.2.0939: mbyte: wrong cell count for an overlong UTF-8 sequence Problem: An overlong UTF-8 encoding of an unprintable ASCII character is displayed as <xx> but counted as two screen cells, so that the cursor ends up in the wrong position when editing the line. Solution: Count four cells for an unprintable overlong sequence. fixes: #20988 closes: #21005 Co-Authored-By: Claude Opus 5 (1M context) <[email protected]> Signed-off-by: Hirohito Higashi <[email protected]> Signed-off-by: Christian Brabandt <[email protected]> diff --git a/src/mbyte.c b/src/mbyte.c index 54ee229a1..e196f30ca 100644 --- a/src/mbyte.c +++ b/src/mbyte.c @@ -1645,7 +1645,7 @@ utf_ptr2cells( return 4; // If the char is ASCII it must be an overlong sequence. if (c < 0x80) - return char2cells(c); + return vim_isprintc(c) ? char2cells(c) : 4; return utf_char2cells(c); } return 1; @@ -1689,7 +1689,7 @@ utf_ptr2cells_len(char_u *p, int size) return 4; // If the char is ASCII it must be an overlong sequence. if (c < 0x80) - return char2cells(c); + return vim_isprintc(c) ? char2cells(c) : 4; return utf_char2cells(c); } return 1; diff --git a/src/testdir/test_utf8.vim b/src/testdir/test_utf8.vim index a0cd5bd79..3070d4cc4 100644 --- a/src/testdir/test_utf8.vim +++ b/src/testdir/test_utf8.vim @@ -372,4 +372,20 @@ func Test_print_overlong() bwipe! endfunc +" The cell count of an overlong encoded character must match what is drawn. +func Test_overlong_utf8_cells() + call assert_equal(4, strdisplaywidth("\xc0\x81")) " <01> + call assert_equal(4, strdisplaywidth("\xe0\x80\x81")) " <01>, three bytes + call assert_equal(4, strdisplaywidth("\xc1\xbf")) " <7f> + call assert_equal(4, strdisplaywidth("\xc0\x89")) " <09>, not a Tab + + new + call setline(1, "\xc1\x81\xc0\x81\xc0\x80") + call assert_equal('A<01><00>', ScreenLines(1, 9)[0]) + normal! $ + call assert_equal(5, col('.')) + call assert_equal([6, 9], virtcol('.', v:true)) + bwipe! +endfunc + " vim: shiftwidth=2 sts=2 expandtab diff --git a/src/version.c b/src/version.c index 48a1faf0f..6405f229e 100644 --- a/src/version.c +++ b/src/version.c @@ -763,6 +763,8 @@ static char *(features[]) = static int included_patches[] = { /* Add new patch number below this line */ +/**/ + 939, /**/ 938, /**/ -- -- You received this message from the "vim_dev" maillist. Do not top-post! Type your reply below the text you are replying to. For more information, visit http://www.vim.org/maillist.php --- You received this message because you are subscribed to the Google Groups "vim_dev" group. To unsubscribe from this group and stop receiving emails from it, send an email to [email protected]. To view this discussion visit https://groups.google.com/d/msgid/vim_dev/E1wtsAn-007aIe-Ui%40256bit.org.