From 090391d94fbd17da51cef116cf261ab494ae1d60 Mon Sep 17 00:00:00 2001 From: Josh Megnauth Date: Tue, 1 Apr 2025 23:35:29 -0400 Subject: [PATCH] fix(strptime): Don't clobber struct tm Our strptime implementation uses subformatting to handle specifiers that expand to other specifiers. For example, '%T' expands to "%H:%M%:%S". Relibc calls strptime again to handle '%T' by expanding it. However, our strptime zeroes out struct tm which clobbers old values. If strptime is called with a format string like "%D%t%T", the set values for '%D' are clobbered. Zeroing out the struct is extra, unneeded work as well. The user may want to preserve old values. We don't read from struct tm so we don't have to worry about invalid values. Finally, `musl` and `glibc` don't clear the values either so we can default to their behavior. --- src/header/time/strptime.rs | 6 ------ tests/time/strptime.c | 31 +++++++++++++++---------------- 2 files changed, 15 insertions(+), 22 deletions(-) diff --git a/src/header/time/strptime.rs b/src/header/time/strptime.rs index 365c7f97e9..a3c4979dc7 100644 --- a/src/header/time/strptime.rs +++ b/src/header/time/strptime.rs @@ -89,12 +89,6 @@ pub unsafe extern "C" fn strptime( } }; - // Zero-initialize the output `tm` structure - // (equivalent to: tm_sec=0, tm_min=0, tm_hour=0...) - unsafe { - ptr::write_bytes(tm, 0, 1); - } - // We parse the format specifiers in a loop let mut fmt_chars = fmt_str.chars().peekable(); let mut index_in_input = 0; diff --git a/tests/time/strptime.c b/tests/time/strptime.c index e0084f923c..9d1b3211c5 100644 --- a/tests/time/strptime.c +++ b/tests/time/strptime.c @@ -99,22 +99,21 @@ int main(void) { ); // TODO: Locale offset - // Also, this test is broken on Redox - /* const char redox[] = "Mon Oct 31 11:19:57 2016"; */ - /* struct tm redox_expect = { */ - /* .tm_year = 116, */ - /* .tm_mon = 9, */ - /* .tm_mday = 31, */ - /* .tm_hour = 11, */ - /* .tm_min = 19, */ - /* .tm_sec = 57, */ - /* .tm_yday = 304, */ - /* .tm_wday = 1, */ - /* }; */ - /* strptime_test(redox, */ - /* "%a%t%b%t%d%t%T%t%Y", */ - /* redox_expect, */ - /* ""); */ + const char redox[] = "Mon Oct 31 11:19:57 2016"; + struct tm redox_expect = { + .tm_year = 116, + .tm_mon = 9, + .tm_mday = 31, + .tm_hour = 11, + .tm_min = 19, + .tm_sec = 57, + /* .tm_yday = 304, */ + .tm_wday = 1, + }; + strptime_test(redox, + "%a%t%b%t%d%t%T%t%Y", + redox_expect, + ""); // Roundtrip const char roundtrip[] = "2012-01-19 13:37:00";