patch 9.1.1083: setreg() doesn't correctly handle mbyte chars in blockwise mode
Commit:
https://github.com/vim/vim/commit/a17f8bfb282805ee8ded014089d3094ef6dbf913
Author: Yee Cheng Chin <
ychi...@gmail.com>
Date: Sat Feb 8 18:19:15 2025 +0100
patch 9.1.1083: setreg() doesn't correctly handle mbyte chars in blockwise mode
Problem: setreg() doesn't correctly handle mbyte chars in blockwise
mode
Solution: use mb_ptr2len_len function pointer (Yee Cheng Chin)
setreg() will automatically calculate the width when a blockwise mode is
specified, but it does not properly calculate the line widths of mbyte
characters when value is passed as newline-terminated string. It does
work when value is passed as a list of lines though.
Fix this by properly using the mbyte function pointer to increment the
loop counter.
closes: #16596
Signed-off-by: Yee Cheng Chin <
ychi...@gmail.com>
Signed-off-by: Christian Brabandt <
c...@256bit.org>
diff --git a/src/register.c b/src/register.c
index 3ca425b45..0df05054c 100644
--- a/src/register.c
+++ b/src/register.c
@@ -3019,12 +3019,17 @@ str_to_reg(
{
int charlen = 0;
- for (i = start; i < len; ++i) // find the end of the line
+ for (i = start; i < len;) // find the end of the line
{
if (str[i] == '
')
break;
if (type == MBLOCK)
charlen += mb_ptr2cells_len(str + i, len - i);
+
+ if (str[i] == NUL)
+ i++; // registers can have NUL chars
+ else
+ i += mb_ptr2len_len(str + i, len - i);
}
i -= start; // i is now length of line
if (charlen > maxlen)
diff --git a/src/testdir/test_registers.vim b/src/testdir/test_registers.vim
index 36fc3046c..1177c2395 100644
--- a/src/testdir/test_registers.vim
+++ b/src/testdir/test_registers.vim
@@ -431,6 +431,23 @@ func Test_set_register()
enew!
endfunc
+" Test for blockwise register width calculations
+func Test_set_register_blockwise_width()
+ " Test for regular calculations and overriding the width
+ call setreg('a', "12
1234
123", 'b')
+ call assert_equal("\<c-v>4", getreginfo('a').regtype)
+ call setreg('a', "12
1234
123", 'b1')
+ call assert_equal("\<c-v>1", getreginfo('a').regtype)
+ call setreg('a', "12
1234
123", 'b6')
+ call assert_equal("\<c-v>6", getreginfo('a').regtype)
+
+ " Test for Unicode parsing
+ call setreg('a', "z😅😅z
12345", 'b')
+ call assert_equal("\<c-v>6", getreginfo('a').regtype)
+ call setreg('a', ["z😅😅z", "12345"], 'b')
+ call assert_equal("\<c-v>6", getreginfo('a').regtype)
+endfunc
+
" Test for clipboard registers (* and +)
func Test_clipboard_regs()
CheckNotGui
diff --git a/src/version.c b/src/version.c
index 35deca863..4651be27e 100644
--- a/src/version.c
+++ b/src/version.c
@@ -704,6 +704,8 @@ static char *(features[]) =
static int included_patches[] =
{ /* Add new patch number below this line */
+/**/
+ 1083,
/**/
1082,
/**/