Skip to content

Commit 29a05c0

Browse files
VirtualTimkripken
authored andcommitted
Update vswprintf to musl 1.1.23 (#9387)
Copy-pasted updated source from http://git.musl-libc.org/cgit/musl/tree/src/stdio/vswprintf.c. Also added a test case for this. Fixes #9305.
1 parent 6a4ad2a commit 29a05c0

File tree

4 files changed

+49
-15
lines changed

4 files changed

+49
-15
lines changed

system/lib/libc/README.md

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
1-
This folder contains the musl version of libc at `/musl`. The upstream version can be found at http://www.musl-libc.org/
1+
This folder contains the musl version of libc at `/musl`. The upstream version can be found at http://www.musl-libc.org/.
2+
Most of the source comes from musl 1.1.15, with some exceptions listed below.
23

34
Some changes have been made to the version that was taken from upstream, including:
45

@@ -8,3 +9,4 @@ Some changes have been made to the version that was taken from upstream, includi
89
* 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.
910
* Setting `_POSIX_REALTIME_SIGNALS` and `_POSIX_SPAWN` macros to -1, to exclude unsupported functions.
1011

12+
Backported src/stdio/vswprintf.c from 1.1.23 to fix #9305.

system/lib/libc/musl/src/stdio/vswprintf.c

Lines changed: 17 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
#include "stdio_impl.h"
22
#include <limits.h>
3-
#include <string.h>
43
#include <errno.h>
54
#include <stdint.h>
5+
#include <stdlib.h>
66
#include <wchar.h>
77

88
struct cookie {
@@ -24,23 +24,30 @@ static size_t sw_write(FILE *f, const unsigned char *s, size_t l)
2424
c->ws++;
2525
}
2626
*c->ws = 0;
27-
return i<0 ? i : l0;
27+
if (i < 0) {
28+
f->wpos = f->wbase = f->wend = 0;
29+
f->flags |= F_ERR;
30+
return i;
31+
}
32+
f->wend = f->buf + f->buf_size;
33+
f->wpos = f->wbase = f->buf;
34+
return l0;
2835
}
2936

3037
int vswprintf(wchar_t *restrict s, size_t n, const wchar_t *restrict fmt, va_list ap)
3138
{
3239
int r;
33-
FILE f;
3440
unsigned char buf[256];
3541
struct cookie c = { s, n-1 };
42+
FILE f = {
43+
.lbf = EOF,
44+
.write = sw_write,
45+
.lock = -1,
46+
.buf = buf,
47+
.buf_size = sizeof buf,
48+
.cookie = &c,
49+
};
3650

37-
memset(&f, 0, sizeof(FILE));
38-
f.lbf = EOF;
39-
f.write = sw_write;
40-
f.buf_size = sizeof buf;
41-
f.buf = buf;
42-
f.lock = -1;
43-
f.cookie = &c;
4451
if (!n) {
4552
return -1;
4653
} else if (n > INT_MAX) {

tests/core/test_wprintf.cpp

Lines changed: 26 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -8,16 +8,19 @@
88
#include <stdarg.h>
99
#include <wchar.h>
1010

11+
#define MAX_CHARS_SMALL 256
12+
#define MAX_CHARS_BIG 8096
13+
1114
void PrintWide ( const wchar_t * format, ... )
1215
{
13-
wchar_t buffer[256];
14-
memset(buffer, 0, 256);
16+
wchar_t buffer[MAX_CHARS_SMALL];
17+
memset(buffer, 0, MAX_CHARS_SMALL);
1518
va_list args;
1619
va_start ( args, format );
1720
wprintf(L"format starts with 0x%x\n", *(int*)format);
1821
wprintf(L"fmt continues with 0x%x\n", *(((int*)format) + 1));
1922
wprintf(L"fmt continues with 0x%x\n", *(((int*)format) + 2));
20-
int r = vswprintf ( buffer, 256, format, args );
23+
int r = vswprintf ( buffer, MAX_CHARS_SMALL-1, format, args );
2124
wprintf(L"vswprintf told us %d\n", r);
2225
wprintf(L"vswoutput st-rts with 0x%x\n", *(int*)buffer);
2326
wprintf(L"vsw continues with 0x%x\n", *(((int*)buffer) + 1));
@@ -26,6 +29,17 @@ void PrintWide ( const wchar_t * format, ... )
2629
va_end ( args );
2730
}
2831

32+
void PrintBigWide ( const wchar_t * format, ... )
33+
{
34+
wchar_t buffer[MAX_CHARS_BIG] = { 0 };
35+
va_list args;
36+
va_start ( args, format );
37+
int ret = vswprintf ( buffer, MAX_CHARS_BIG-1, format, args );
38+
va_end ( args );
39+
wprintf(L"PrintBigWide wrote %d wchars:\n", ret);
40+
wprintf(buffer);
41+
}
42+
2943
int main ()
3044
{
3145
FILE *f = fopen("test.dat", "wb");
@@ -45,7 +59,15 @@ int main ()
4559
PrintWide ( str, wcslen(str) );
4660
PrintWide ( str, wcslen(str) );
4761
PrintWide ( str, wcslen(str) );
48-
62+
63+
64+
wchar_t long_str[] = L"test string has %d wide characters.\n"
65+
"Internally the variadic print functions use a 256 char buffer, so this is a string that's longer than 256 chars, "
66+
"so in case this breaks we have a test case. As discovered in #9305 vswprintf had been broken for some time, "
67+
"but was never picked up as the test strings were all shorter then 256 chars. So hopefully this long rambly string "
68+
"will help guard against that bug being re-introduced.\n";
69+
PrintBigWide ( long_str, wcslen(long_str) );
70+
4971
wprintf (L"Characters: %lc %lc \n", L'a', 65);
5072
wprintf (L"Decimals: %d %ld\n", 1977, 650000L);
5173
wprintf (L"Preceding with blanks: %10d \n", 1977);

tests/core/test_wprintf.out

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,9 @@ vswoutput st-rts with 0x74
2727
vsw continues with 0x65
2828
vsw continues with 0x73
2929
test string has 36 wide characters.
30+
PrintBigWide wrote 426 wchars:
31+
test string has 425 wide characters.
32+
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.
3033
Characters: a A
3134
Decimals: 1977 650000
3235
Preceding with blanks: 1977

0 commit comments

Comments
 (0)