From 43292ce49d9f0af28fc38eb93ff162b8cd4cc269 Mon Sep 17 00:00:00 2001 From: Tim Lander Date: Thu, 5 Sep 2019 14:20:05 +0800 Subject: [PATCH 1/9] Update vswprintf to mussl 1.1.23 --- system/lib/libc/musl/src/stdio/vswprintf.c | 27 ++++++++++++++-------- 1 file changed, 17 insertions(+), 10 deletions(-) diff --git a/system/lib/libc/musl/src/stdio/vswprintf.c b/system/lib/libc/musl/src/stdio/vswprintf.c index 7d237bae72e94..7f98c5c9690e4 100644 --- a/system/lib/libc/musl/src/stdio/vswprintf.c +++ b/system/lib/libc/musl/src/stdio/vswprintf.c @@ -1,8 +1,8 @@ #include "stdio_impl.h" #include -#include #include #include +#include #include struct cookie { @@ -24,23 +24,30 @@ static size_t sw_write(FILE *f, const unsigned char *s, size_t l) c->ws++; } *c->ws = 0; - return i<0 ? i : l0; + if (i < 0) { + f->wpos = f->wbase = f->wend = 0; + f->flags |= F_ERR; + return i; + } + f->wend = f->buf + f->buf_size; + f->wpos = f->wbase = f->buf; + return l0; } int vswprintf(wchar_t *restrict s, size_t n, const wchar_t *restrict fmt, va_list ap) { int r; - FILE f; unsigned char buf[256]; struct cookie c = { s, n-1 }; + FILE f = { + .lbf = EOF, + .write = sw_write, + .lock = -1, + .buf = buf, + .buf_size = sizeof buf, + .cookie = &c, + }; - memset(&f, 0, sizeof(FILE)); - f.lbf = EOF; - f.write = sw_write; - f.buf_size = sizeof buf; - f.buf = buf; - f.lock = -1; - f.cookie = &c; if (!n) { return -1; } else if (n > INT_MAX) { From 99a0a96e6eb53d6362f7f1a8cc2ddfa581e03cb0 Mon Sep 17 00:00:00 2001 From: Tim Lander Date: Thu, 5 Sep 2019 14:41:51 +0800 Subject: [PATCH 2/9] Add a vswprintf test for long (>256) strings --- tests/core/test_wprintf.cpp | 34 ++++++++++++++++++++++++++++++---- 1 file changed, 30 insertions(+), 4 deletions(-) diff --git a/tests/core/test_wprintf.cpp b/tests/core/test_wprintf.cpp index 5e9185241918d..0df5e3697db8a 100644 --- a/tests/core/test_wprintf.cpp +++ b/tests/core/test_wprintf.cpp @@ -10,14 +10,15 @@ void PrintWide ( const wchar_t * format, ... ) { - wchar_t buffer[256]; - memset(buffer, 0, 256); + int max_chars = 256; + wchar_t buffer[max_chars]; + memset(buffer, 0, max_chars); va_list args; va_start ( args, format ); wprintf(L"format starts with 0x%x\n", *(int*)format); wprintf(L"fmt continues with 0x%x\n", *(((int*)format) + 1)); wprintf(L"fmt continues with 0x%x\n", *(((int*)format) + 2)); - int r = vswprintf ( buffer, 256, format, args ); + int r = vswprintf ( buffer, max_chars-1, format, args ); wprintf(L"vswprintf told us %d\n", r); wprintf(L"vswoutput st-rts with 0x%x\n", *(int*)buffer); wprintf(L"vsw continues with 0x%x\n", *(((int*)buffer) + 1)); @@ -26,6 +27,23 @@ void PrintWide ( const wchar_t * format, ... ) va_end ( args ); } +void PrintBigWide ( const wchar_t * format, ... ) +{ + int max_chars = 8096; + wchar_t buffer[max_chars] = { 0 }; + va_list args; + va_start ( args, format ); + int ret = vswprintf ( buffer, max_chars-1, format, args ); + if (ret >= max_chars) { + ret = max_chars - 1; + } + if (ret > 0) { + wprintf(L"PrintBigWide wrote %d wchars:\n", ret); + } + wprintf(buffer); + va_end ( args ); +} + int main () { FILE *f = fopen("test.dat", "wb"); @@ -45,7 +63,15 @@ int main () PrintWide ( str, wcslen(str) ); PrintWide ( str, wcslen(str) ); PrintWide ( str, wcslen(str) ); - + + + wchar_t long_str[] = L"test string has %d wide characters.\n" + "Internally the variadic print functions use a 256 char buffer, so this is a string that's longer than 256 chars, " + "so in case this breaks we have a test case. As discovered in #9305 vswprintf had been broken for some time, " + "but was never picked up as the test strings were all shorter then 256 chars. So hopefully this long rambly string " + "will help guard against that bug being re-introduced.\n"; + PrintWide ( str, wcslen(str) ); + wprintf (L"Characters: %lc %lc \n", L'a', 65); wprintf (L"Decimals: %d %ld\n", 1977, 650000L); wprintf (L"Preceding with blanks: %10d \n", 1977); From 06e69bb755f124f9808669cfb50b7de2b457482f Mon Sep 17 00:00:00 2001 From: Tim Lander Date: Thu, 5 Sep 2019 15:18:11 +0800 Subject: [PATCH 3/9] Fix indentation, change function call to correct function --- tests/core/test_wprintf.cpp | 31 ++++++++++++++++--------------- 1 file changed, 16 insertions(+), 15 deletions(-) diff --git a/tests/core/test_wprintf.cpp b/tests/core/test_wprintf.cpp index 0df5e3697db8a..cf68ed4a6973d 100644 --- a/tests/core/test_wprintf.cpp +++ b/tests/core/test_wprintf.cpp @@ -8,17 +8,19 @@ #include #include +#define MAX_CHARS_SMALL 256 +#define MAX_CHARS_BIG 8096 + void PrintWide ( const wchar_t * format, ... ) { - int max_chars = 256; - wchar_t buffer[max_chars]; - memset(buffer, 0, max_chars); + wchar_t buffer[MAX_CHARS_SMALL]; + memset(buffer, 0, MAX_CHARS_SMALL); va_list args; va_start ( args, format ); wprintf(L"format starts with 0x%x\n", *(int*)format); wprintf(L"fmt continues with 0x%x\n", *(((int*)format) + 1)); wprintf(L"fmt continues with 0x%x\n", *(((int*)format) + 2)); - int r = vswprintf ( buffer, max_chars-1, format, args ); + int r = vswprintf ( buffer, MAX_CHARS_SMALL-1, format, args ); wprintf(L"vswprintf told us %d\n", r); wprintf(L"vswoutput st-rts with 0x%x\n", *(int*)buffer); wprintf(L"vsw continues with 0x%x\n", *(((int*)buffer) + 1)); @@ -29,19 +31,18 @@ void PrintWide ( const wchar_t * format, ... ) void PrintBigWide ( const wchar_t * format, ... ) { - int max_chars = 8096; - wchar_t buffer[max_chars] = { 0 }; + wchar_t buffer[MAX_CHARS_BIG] = { 0 }; va_list args; va_start ( args, format ); - int ret = vswprintf ( buffer, max_chars-1, format, args ); - if (ret >= max_chars) { - ret = max_chars - 1; - } - if (ret > 0) { - wprintf(L"PrintBigWide wrote %d wchars:\n", ret); - } - wprintf(buffer); + int ret = vswprintf ( buffer, MAX_CHARS_BIG-1, format, args ); va_end ( args ); + if (ret >= MAX_CHARS_BIG) { + ret = MAX_CHARS_BIG - 1; + } + if (ret > 0) { + wprintf(L"PrintBigWide wrote %d wchars:\n", ret); + } + wprintf(buffer); } int main () @@ -70,7 +71,7 @@ int main () "so in case this breaks we have a test case. As discovered in #9305 vswprintf had been broken for some time, " "but was never picked up as the test strings were all shorter then 256 chars. So hopefully this long rambly string " "will help guard against that bug being re-introduced.\n"; - PrintWide ( str, wcslen(str) ); + PrintBigWide ( long_str, wcslen(long_str) ); wprintf (L"Characters: %lc %lc \n", L'a', 65); wprintf (L"Decimals: %d %ld\n", 1977, 650000L); From 3537883df3e1cf85a3efd2d3b3618b5fddc9bca8 Mon Sep 17 00:00:00 2001 From: Tim Lander Date: Thu, 5 Sep 2019 15:18:20 +0800 Subject: [PATCH 4/9] Update expected test output --- tests/core/test_wprintf.out | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/tests/core/test_wprintf.out b/tests/core/test_wprintf.out index 8dfed67acfeb6..6298fea7ed818 100644 --- a/tests/core/test_wprintf.out +++ b/tests/core/test_wprintf.out @@ -26,7 +26,9 @@ vswprintf told us 36 vswoutput st-rts with 0x74 vsw continues with 0x65 vsw continues with 0x73 -test string has 36 wide characters. +test string has 36 wide characters.PrintBigWide wrote 426 wchars: +test string has 425 wide characters. +Internally the variadic print functions use a 256 char buffer, so this is a string that's longer than 256 chars, so in case this breaks we have a test case. As discovered in #9305 vswprintf had been broken for some time, but was never picked up as the test strings were all shorter then 256 chars. So hopefully this long rambly string will help guard against that bug being re-introduced. Characters: a A Decimals: 1977 650000 Preceding with blanks: 1977 From faea2fec22b318391403e985b6965cd6dfadffcf Mon Sep 17 00:00:00 2001 From: Tim Lander Date: Thu, 5 Sep 2019 15:20:11 +0800 Subject: [PATCH 5/9] Missed new line --- tests/core/test_wprintf.out | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/tests/core/test_wprintf.out b/tests/core/test_wprintf.out index 6298fea7ed818..44fee7f77c69d 100644 --- a/tests/core/test_wprintf.out +++ b/tests/core/test_wprintf.out @@ -26,7 +26,8 @@ vswprintf told us 36 vswoutput st-rts with 0x74 vsw continues with 0x65 vsw continues with 0x73 -test string has 36 wide characters.PrintBigWide wrote 426 wchars: +test string has 36 wide characters. +PrintBigWide wrote 426 wchars: test string has 425 wide characters. Internally the variadic print functions use a 256 char buffer, so this is a string that's longer than 256 chars, so in case this breaks we have a test case. As discovered in #9305 vswprintf had been broken for some time, but was never picked up as the test strings were all shorter then 256 chars. So hopefully this long rambly string will help guard against that bug being re-introduced. Characters: a A From 81a65230136ac04d8c5cb0918ddb5e32e36004d1 Mon Sep 17 00:00:00 2001 From: Tim Lander Date: Fri, 6 Sep 2019 09:51:47 +0800 Subject: [PATCH 6/9] Update the musl readme. --- system/lib/libc/README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/system/lib/libc/README.md b/system/lib/libc/README.md index 6df1a919ecc38..d5ec874f408f1 100644 --- a/system/lib/libc/README.md +++ b/system/lib/libc/README.md @@ -5,3 +5,4 @@ Some changes have been made to the version that was taken from upstream, includi * Emscripten-specific changes (from before this readme existed). These should be marked with `XXX EMSCRIPTEN` in the source. They are mostly in pthreads code and hopefully temporary. * Backporting an operator-precedence warning fix from 6e76e1540fc58a418494bf5eb832b556f9c5763e in the upstream version +Most of the source comes from musl 1.1.15. Some is from older versions, but I'm assuming that this is because these files haven't changed between versions. src/stdio/vswprintf.c is from version 1.1.23 because that resolves #9305. From a29e8db589f51259ff3dd924a91fcd8c9b533d7e Mon Sep 17 00:00:00 2001 From: Tim Lander Date: Thu, 12 Sep 2019 15:21:11 +0800 Subject: [PATCH 7/9] Removed unnecessary branching --- tests/core/test_wprintf.cpp | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/tests/core/test_wprintf.cpp b/tests/core/test_wprintf.cpp index cf68ed4a6973d..8b40a47b1f7a3 100644 --- a/tests/core/test_wprintf.cpp +++ b/tests/core/test_wprintf.cpp @@ -36,12 +36,7 @@ void PrintBigWide ( const wchar_t * format, ... ) va_start ( args, format ); int ret = vswprintf ( buffer, MAX_CHARS_BIG-1, format, args ); va_end ( args ); - if (ret >= MAX_CHARS_BIG) { - ret = MAX_CHARS_BIG - 1; - } - if (ret > 0) { - wprintf(L"PrintBigWide wrote %d wchars:\n", ret); - } + wprintf(L"PrintBigWide wrote %d wchars:\n", ret); wprintf(buffer); } From 60e5715cbe29b4bbf099ae2823f6d258962c48a9 Mon Sep 17 00:00:00 2001 From: Tim Lander Date: Thu, 12 Sep 2019 15:30:52 +0800 Subject: [PATCH 8/9] Change readme as per code review --- system/lib/libc/README.md | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/system/lib/libc/README.md b/system/lib/libc/README.md index 4e951b832aa2e..ece30c19b12b8 100644 --- a/system/lib/libc/README.md +++ b/system/lib/libc/README.md @@ -1,4 +1,5 @@ -This folder contains the musl version of libc at `/musl`. The upstream version can be found at http://www.musl-libc.org/ +This folder contains the musl version of libc at `/musl`. The upstream version can be found at http://www.musl-libc.org/. +Most of the source comes from musl 1.1.15. Some is from older versions, but I'm assuming that this is because these files haven't changed between versions. Some changes have been made to the version that was taken from upstream, including: @@ -7,4 +8,4 @@ Some changes have been made to the version that was taken from upstream, includi * Switch to using the wasi `fd_write` syscall instead of `writev`. * Simplify stdout stream handling: do not support seeking, terminal handling, etc., as it just increases code size and Emscripten doesn't have those features anyhow. -Most of the source comes from musl 1.1.15. Some is from older versions, but I'm assuming that this is because these files haven't changed between versions. src/stdio/vswprintf.c is from version 1.1.23 because that resolves #9305. +Backported src/stdio/vswprintf.c from 1.1.23 to fix #9305. From 0d9e5c720f38c1f0ed447e8cf8a23d953505655c Mon Sep 17 00:00:00 2001 From: Tim Lander Date: Tue, 24 Sep 2019 09:43:13 +0800 Subject: [PATCH 9/9] Improve readme change --- system/lib/libc/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/system/lib/libc/README.md b/system/lib/libc/README.md index ece30c19b12b8..5ef15dbe2f371 100644 --- a/system/lib/libc/README.md +++ b/system/lib/libc/README.md @@ -1,5 +1,5 @@ This folder contains the musl version of libc at `/musl`. The upstream version can be found at http://www.musl-libc.org/. -Most of the source comes from musl 1.1.15. Some is from older versions, but I'm assuming that this is because these files haven't changed between versions. +Most of the source comes from musl 1.1.15, with some exceptions listed below. Some changes have been made to the version that was taken from upstream, including: