From 54689733a798492849262bcb3312f38ccb795dbc Mon Sep 17 00:00:00 2001 From: Hood Chatham Date: Mon, 2 Dec 2024 15:34:24 +0100 Subject: [PATCH 1/2] Handle trailing % in strftime "In glibc a trailing % in strftime() acts like printf, ie it's a literal %". This is breaking some Python tests. I've applied the patch suggested here: https://www.openwall.com/lists/musl/2022/12/19/2 --- system/lib/libc/musl/src/time/strftime.c | 2 +- test/other/test_strftime.c | 3 +++ 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/system/lib/libc/musl/src/time/strftime.c b/system/lib/libc/musl/src/time/strftime.c index c40246dbb0fa3..7b890388feb1f 100644 --- a/system/lib/libc/musl/src/time/strftime.c +++ b/system/lib/libc/musl/src/time/strftime.c @@ -226,7 +226,7 @@ size_t __strftime_l(char *restrict s, size_t n, const char *restrict f, const st s[l] = 0; return l; } - if (*f != '%') { + if (*f != '%' || !f[1]) { s[l++] = *f; continue; } diff --git a/test/other/test_strftime.c b/test/other/test_strftime.c index 9f14e177c9e9b..26a388ba54b87 100644 --- a/test/other/test_strftime.c +++ b/test/other/test_strftime.c @@ -307,5 +307,8 @@ int main() { size = strftime(s, sizeof(s), "%Ec", &tm); TEST(!cmp(s, "Mon Dec 17 00:00:00 2018"), "strftime test #36a", s); + size = strftime(s, sizeof(s), "trailing %", &tm); + TEST((size == 10), "strftime test #37", s); + TEST(!cmp(s, "trailing %"), "strftime test #37", s); return 0; } From c1c3fc570daa26743b4085345787d568f4fe15c3 Mon Sep 17 00:00:00 2001 From: Hood Chatham Date: Wed, 4 Dec 2024 09:49:41 +0100 Subject: [PATCH 2/2] Add #ifdef, comment, and update libc readme --- system/lib/libc/README.md | 1 + system/lib/libc/musl/src/time/strftime.c | 6 ++++++ 2 files changed, 7 insertions(+) diff --git a/system/lib/libc/README.md b/system/lib/libc/README.md index 895524e6f309c..0094e8a96dfe7 100644 --- a/system/lib/libc/README.md +++ b/system/lib/libc/README.md @@ -12,6 +12,7 @@ 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. * Setting `_POSIX_REALTIME_SIGNALS` and `_POSIX_SPAWN` macros to -1, to exclude unsupported functions. + * Handling trailing % in `strftime` and `wcsftime` format strings. Copy log.c and log2.c from earlier version of musl which result in smaller binary size since they do not rely data tables in log_data.c and log2_data.c. diff --git a/system/lib/libc/musl/src/time/strftime.c b/system/lib/libc/musl/src/time/strftime.c index 7b890388feb1f..59d609ba92245 100644 --- a/system/lib/libc/musl/src/time/strftime.c +++ b/system/lib/libc/musl/src/time/strftime.c @@ -226,7 +226,13 @@ size_t __strftime_l(char *restrict s, size_t n, const char *restrict f, const st s[l] = 0; return l; } +#ifdef __EMSCRIPTEN__ + // Handle trailing % by outputting a % rather than returning 0. Ideally + // this 6 character change could be upstreamed into musl... if (*f != '%' || !f[1]) { +#else + if (*f != '%') { +#endif s[l++] = *f; continue; }