[PATCH 0/2] lib: fix snprintf() for UTF-16 strings

Up to now printing UTF-16 strings with snprintf() resulted in correct truncation of printed strings. But the returned required buffer length was incorrect.
* fix function string16() * provide a unit test
Heinrich Schuchardt (2): lib: fix snprintf() for UTF-16 strings test: test UTF-16 truncation in sprintf()
lib/vsprintf.c | 14 ++++++++++++-- test/unicode_ut.c | 31 +++++++++++++++++++++++++++++++ 2 files changed, 43 insertions(+), 2 deletions(-)

snprintf() must return the required buffer length.
Signed-off-by: Heinrich Schuchardt heinrich.schuchardt@canonical.com --- lib/vsprintf.c | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-)
diff --git a/lib/vsprintf.c b/lib/vsprintf.c index 2c84649fa8..779efc30bc 100644 --- a/lib/vsprintf.c +++ b/lib/vsprintf.c @@ -285,15 +285,25 @@ static __maybe_unused char *string16(char *buf, char *end, u16 *s, if (!(flags & LEFT)) for (; len < field_width; --field_width) ADDCH(buf, ' '); - for (i = 0; i < len && buf + utf16_utf8_strnlen(str, 1) <= end; ++i) { + if (buf < end) + *buf = 0; + for (i = 0; i < len; ++i) { + int slen = utf16_utf8_strnlen(str, 1); s32 s = utf16_get(&str);
if (s < 0) s = '?'; - utf8_put(s, &buf); + if (buf + slen < end) { + utf8_put(s, &buf); + if (buf < end) + *buf = 0; + } else { + buf += slen; + } } for (; len < field_width; --field_width) ADDCH(buf, ' '); + return buf; }

Check that snprintf() returns the correct required buffer length and prints the correct string for UTF-16 strings.
Signed-off-by: Heinrich Schuchardt heinrich.schuchardt@canonical.com --- test/unicode_ut.c | 31 +++++++++++++++++++++++++++++++ 1 file changed, 31 insertions(+)
diff --git a/test/unicode_ut.c b/test/unicode_ut.c index a16dd09579..9b3b9d4f08 100644 --- a/test/unicode_ut.c +++ b/test/unicode_ut.c @@ -97,6 +97,7 @@ UNICODE_TEST(unicode_test_u16_strcpy); static int unicode_test_string16(struct unit_test_state *uts) { char buf[20]; + int ret;
/* Test length and precision */ memset(buf, 0xff, sizeof(buf)); @@ -130,6 +131,36 @@ static int unicode_test_string16(struct unit_test_state *uts) sprintf(buf, "%ls", i3); ut_asserteq_str("i3?", buf);
+ memset(buf, 0xff, sizeof(buf)); + ret = snprintf(buf, 4, "%ls", c1); + ut_asserteq(6, ret); + ut_asserteq_str("U-B", buf); + + memset(buf, 0xff, sizeof(buf)); + ret = snprintf(buf, 6, "%ls", c2); + ut_asserteq_str("kafb", buf); + ut_asserteq(9, ret); + + memset(buf, 0xff, sizeof(buf)); + ret = snprintf(buf, 7, "%ls", c2); + ut_asserteq_str("kafb\xC3\xA1", buf); + ut_asserteq(9, ret); + + memset(buf, 0xff, sizeof(buf)); + ret = snprintf(buf, 8, "%ls", c3); + ut_asserteq_str("\xE6\xBD\x9C\xE6\xB0\xB4", buf); + ut_asserteq(9, ret); + + memset(buf, 0xff, sizeof(buf)); + ret = snprintf(buf, 11, "%ls", c4); + ut_asserteq_str("\xF0\x90\x92\x8D\xF0\x90\x92\x96", buf); + ut_asserteq(12, ret); + + memset(buf, 0xff, sizeof(buf)); + ret = snprintf(buf, 4, "%ls", c4); + ut_asserteq_str("", buf); + ut_asserteq(12, ret); + return 0; } UNICODE_TEST(unicode_test_string16);

On Sat, 29 Jan 2022 at 10:40, Heinrich Schuchardt heinrich.schuchardt@canonical.com wrote:
Check that snprintf() returns the correct required buffer length and prints the correct string for UTF-16 strings.
Signed-off-by: Heinrich Schuchardt heinrich.schuchardt@canonical.com
test/unicode_ut.c | 31 +++++++++++++++++++++++++++++++ 1 file changed, 31 insertions(+)
Reviewed-by: Simon Glass sjg@chromium.org

Hi Heinrich,
On Sat, 29 Jan 2022 at 10:40, Heinrich Schuchardt heinrich.schuchardt@canonical.com wrote:
Up to now printing UTF-16 strings with snprintf() resulted in correct truncation of printed strings. But the returned required buffer length was incorrect.
- fix function string16()
- provide a unit test
Heinrich Schuchardt (2): lib: fix snprintf() for UTF-16 strings test: test UTF-16 truncation in sprintf()
lib/vsprintf.c | 14 ++++++++++++-- test/unicode_ut.c | 31 +++++++++++++++++++++++++++++++ 2 files changed, 43 insertions(+), 2 deletions(-)
-- 2.33.1
Would you mind reviewing this one, please?
https://patchwork.ozlabs.org/project/uboot/list/?series=282385
I am worried there might be conflicts and it has been outstanding for a long time.
Regards, Simon
participants (2)
-
Heinrich Schuchardt
-
Simon Glass