diff --git a/Cargo.toml b/Cargo.toml index 5d0c825a8..d73f8d2ba 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -39,6 +39,9 @@ members = ["time-benchmarks", "time-macros", "time-macros-impl"] [target.'cfg(windows)'.dependencies] winapi = { version = "0.3.9", features = ["minwinbase", "minwindef", "timezoneapi"], optional = true } +[target.'cfg(unsound_local_offset)'.dependencies] +libc = "0.2.81" + [dev-dependencies] rand = { version = "0.7.3", default-features = false } serde_json = "1.0.59" diff --git a/src/lib.rs b/src/lib.rs index b8ad59ba4..8b13df567 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -53,6 +53,14 @@ //! - `quickcheck` (_implicitly enables `rand`_) //! //! Enables [quickcheck](https://docs.rs/quickcheck) support for all types except [`Instant`]. +//! +//! One pseudo-feature flag that is only available to end users is the `unsound_local_offset` cfg. +//! As the name indicates, using the feature is unsound, and [may cause unexpected segmentation +//! faults](https://github.com/time-rs/time/issues/293). Unlike other flags, this is deliberately +//! only available to end users; this is to ensure that a user doesn't have unsound behavior without +//! knowing it. To enable this behavior, you must use `RUSTFLAGS="--cfg unsound_local_offset" cargo +//! build` or similar. Note: This flag is _not tested anywhere_, including in the regular test of +//! the powerset of all feature flags. Use at your own risk. #![cfg_attr(__time_03_docs, feature(doc_cfg))] #![cfg_attr(__time_03_docs, deny(broken_intra_doc_links))] diff --git a/src/utc_offset.rs b/src/utc_offset.rs index 0029b52cd..906c948e5 100644 --- a/src/utc_offset.rs +++ b/src/utc_offset.rs @@ -224,13 +224,16 @@ impl Display for UtcOffset { #[cfg_attr(__time_03_docs, doc(cfg(feature = "local-offset")))] #[allow(clippy::too_many_lines, clippy::missing_const_for_fn)] fn local_offset_at(datetime: OffsetDateTime) -> Option { - #[cfg(target_family = "unix")] + // See #293 for details. + #[cfg(all(target_family = "unix", not(unsound_local_offset)))] { - // See #293 for details. let _ = datetime; None - - /* + } + // Let a user explicitly opt-in to unsound behavior. As this is not done via feature flags, it + // can only be enabled by the end user. It must be explicitly passed on each compilation. + #[cfg(all(target_family = "unix", unsound_local_offset))] + { use core::{convert::TryInto, mem::MaybeUninit}; /// Convert the given Unix timestamp to a `libc::tm`. Returns `None` on any error. @@ -319,7 +322,6 @@ fn local_offset_at(datetime: OffsetDateTime) -> Option { ) .ok() } - */ } #[cfg(target_family = "windows")] {