Mercurial > vim
changeset 26197:2093cc976da8 v8.2.3630
patch 8.2.3630: printf() with %S does not handle multi-byte correctly
Commit: https://github.com/vim/vim/commit/d85fccdfed58108c4e0958d0b17c64690b5f073f
Author: presuku <presuku@users.noreply.github.com>
Date: Sat Nov 20 19:38:31 2021 +0000
patch 8.2.3630: printf() with %S does not handle multi-byte correctly
Problem: Printf() with %S does not handle multi-byte correctly.
Solution: Count cells instead of bytes. (closes https://github.com/vim/vim/issues/9169, closes https://github.com/vim/vim/issues/7486)
author | Bram Moolenaar <Bram@vim.org> |
---|---|
date | Sat, 20 Nov 2021 20:45:02 +0100 |
parents | 75bc457099c4 |
children | 6dc2643388d2 |
files | src/strings.c src/testdir/test_expr.vim src/version.c |
diffstat | 3 files changed, 16 insertions(+), 4 deletions(-) [+] |
line wrap: on
line diff
--- a/src/strings.c +++ b/src/strings.c @@ -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;
--- a/src/testdir/test_expr.vim +++ b/src/testdir/test_expr.vim @@ -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