]> granicus.if.org Git - vim/commitdiff
patch 8.2.3630: printf() with %S does not handle multi-byte correctly v8.2.3630
authorpresuku <presuku@users.noreply.github.com>
Sat, 20 Nov 2021 19:38:31 +0000 (19:38 +0000)
committerBram Moolenaar <Bram@vim.org>
Sat, 20 Nov 2021 19:38:31 +0000 (19:38 +0000)
Problem:    Printf() with %S does not handle multi-byte correctly.
Solution:   Count cells instead of bytes. (closes #9169, closes #7486)

src/strings.c
src/testdir/test_expr.vim
src/version.c

index d2d37d80f6f3eb0f4c91c7cdd707ae2650c041ca..bc88ce5f6ed5fb4b9c8881982540b9b023cbc857 100644 (file)
@@ -2137,14 +2137,15 @@ vim_vsnprintf_typval(
                        char *q = memchr(str_arg, '\0',
                                  precision <= (size_t)0x7fffffffL ? precision
                                                       : (size_t)0x7fffffffL);
+
                        str_arg_l = (q == NULL) ? precision
                                                      : (size_t)(q - str_arg);
                    }
                    if (fmt_spec == 'S')
                    {
-                       if (min_field_width != 0)
-                           min_field_width += STRLEN(str_arg)
-                                    - mb_string2cells((char_u *)str_arg, -1);
+                       size_t base_width = min_field_width;
+                       size_t pad_cell = 0;
+
                        if (precision)
                        {
                            char_u  *p1;
@@ -2157,8 +2158,12 @@ vim_vsnprintf_typval(
                                if (i > precision)
                                    break;
                            }
-                           str_arg_l = precision = p1 - (char_u *)str_arg;
+                           pad_cell = min_field_width - precision;
+                           base_width = str_arg_l = precision =
+                                                       p1 - (char_u *)str_arg;
                        }
+                       if (min_field_width != 0)
+                           min_field_width = base_width + pad_cell;
                    }
                    break;
 
index 080eee7e10a773778361c77e7d0271d84bd617ca..97009742785240459ed4e3424194cccfc8d75058 100644 (file)
@@ -297,6 +297,11 @@ function Test_printf_misc()
   call assert_equal('🐍', printf('%.2S', '🐍🐍'))
   call assert_equal('', printf('%.1S', '🐍🐍'))
 
+  call assert_equal('[    あいう]', printf('[%10.6S]', 'あいうえお'))
+  call assert_equal('[  あいうえ]', printf('[%10.8S]', 'あいうえお'))
+  call assert_equal('[あいうえお]', printf('[%10.10S]', 'あいうえお'))
+  call assert_equal('[あいうえお]', printf('[%10.12S]', 'あいうえお'))
+
   call assert_equal('1%', printf('%d%%', 1))
 endfunc
 
index b30979a0b7e2c2fbde818e4bcd02e3dce1c38fa3..4fb0e9eb77b4c33fa2b2682bec860cc908bec2c8 100644 (file)
@@ -757,6 +757,8 @@ static char *(features[]) =
 
 static int included_patches[] =
 {   /* Add new patch number below this line */
+/**/
+    3630,
 /**/
     3629,
 /**/