From b5c4bc1a5d0309a78a0f2c8316ed6d8028577817 Mon Sep 17 00:00:00 2001 From: Jacob Pratt Date: Wed, 21 Dec 2022 23:10:03 -0500 Subject: [PATCH] Let user invoke UB if they choose --- tests/util.rs | 4 +--- time/src/sys/local_offset_at/unix.rs | 34 ++++++++-------------------- 2 files changed, 10 insertions(+), 28 deletions(-) diff --git a/tests/util.rs b/tests/util.rs index 0d9b5082c..c9de3b580 100644 --- a/tests/util.rs +++ b/tests/util.rs @@ -82,9 +82,7 @@ fn weeks_in_year() { fn local_offset_soundness() { use time::util::local_offset::*; - // Safety for these calls: Technically they are unsound, as cargo runs tests in parallel. - // However, the odds of a test failing as a result of this is extremely low. It is better to - // test that these methods function as expected than to worry about a rare segfault. + // Safety: cargo does not mutate the environment while tests are running. assert_eq!(get_soundness(), Soundness::Sound); unsafe { set_soundness(Soundness::Unsound) }; diff --git a/time/src/sys/local_offset_at/unix.rs b/time/src/sys/local_offset_at/unix.rs index 421b4a20b..0c2d9818a 100644 --- a/time/src/sys/local_offset_at/unix.rs +++ b/time/src/sys/local_offset_at/unix.rs @@ -121,31 +121,15 @@ pub(super) fn local_offset_at(datetime: OffsetDateTime) -> Option { // If the `num_threads` crate is incapable of determining the number of running threads, then // we conservatively return `None` to avoid a soundness bug. - // In release mode, let the user invoke undefined behavior if they so choose. - #[cfg(not(debug_assertions))] - if local_offset::get_soundness() == Soundness::Sound - && num_threads::is_single_threaded() != Some(true) + if local_offset::get_soundness() == Soundness::Unsound + || num_threads::is_single_threaded() == Some(true) { - return None; - } - // In debug mode, abort the program if the user would have invoked undefined behavior. - #[cfg(debug_assertions)] - if num_threads::is_single_threaded() != Some(true) { - if local_offset::get_soundness() == Soundness::Unsound { - eprintln!( - "WARNING: You are attempting to obtain the local UTC offset in a multi-threaded \ - context. On Unix-like systems, this is undefined behavior. Either you or a \ - dependency explicitly opted into unsound behavior. See the safety documentation \ - for `time::local_offset::set_soundness` for further details." - ); - std::process::abort(); - } - return None; + let unix_timestamp = datetime.unix_timestamp(); + // Safety: We have just confirmed that the process is single-threaded or the user has + // explicitly opted out of soundness. + let tm = unsafe { timestamp_to_tm(unix_timestamp) }?; + tm_to_offset(unix_timestamp, tm) + } else { + None } - - let unix_timestamp = datetime.unix_timestamp(); - // Safety: We have just confirmed that the process is single-threaded or the user has explicitly - // opted out of soundness. - let tm = unsafe { timestamp_to_tm(unix_timestamp) }?; - tm_to_offset(unix_timestamp, tm) }