diff --git a/.cargo/config b/.cargo/config index 0a8fd3d00..26008597f 100644 --- a/.cargo/config +++ b/.cargo/config @@ -9,3 +9,12 @@ rustflags = [ "-Wclippy::single_char_pattern", "-Wclippy::explicit_iter_loop", ] + +[build] +# See https://github.com/time-rs/time/issues/293#issuecomment-1005002386. The +# unsoundness here is not in the `time` library, but in the Rust stdlib, and as +# such it needs to be fixed there. +rustflags = "--cfg unsound_local_offset" + +[target.'cfg(target_os = "linux")'] +rustflags = ["--cfg", "unsound_local_offset"] diff --git a/.github/workflows/CICD.yml b/.github/workflows/CICD.yml index fbe04a1db..04acd4c18 100644 --- a/.github/workflows/CICD.yml +++ b/.github/workflows/CICD.yml @@ -386,7 +386,7 @@ jobs: command: test args: -v ${{ steps.vars.outputs.CARGO_FEATURES_OPTION }} -p uucore -p coreutils env: - RUSTFLAGS: "-Awarnings" + RUSTFLAGS: "-Awarnings --cfg unsound_local_offset" deps: name: Dependencies diff --git a/Cargo.lock b/Cargo.lock index 497d7ab42..69a83941b 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -871,7 +871,7 @@ checksum = "418d37c8b1d42553c93648be529cb70f920d3baf8ef469b74b9638df426e0b4c" dependencies = [ "cfg-if 1.0.0", "libc", - "wasi 0.10.2+wasi-snapshot-preview1", + "wasi 0.10.0+wasi-snapshot-preview1", ] [[package]] @@ -985,6 +985,12 @@ dependencies = [ "either", ] +[[package]] +name = "itoa" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1aab8fc367588b89dcee83ab0fd66b72b50b72fa1904d7095045ace2b0c81c35" + [[package]] name = "keccak" version = "0.1.0" @@ -1958,12 +1964,30 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6db9e6914ab8b1ae1c260a4ae7a49b6c5611b40328a735b21862567685e73255" dependencies = [ "libc", - "wasi", + "wasi 0.10.0+wasi-snapshot-preview1", "winapi 0.3.9", ] [[package]] -< time::OffsetDateTime { - let ts_nanos: i128 = (self.inner.ut_tv.tv_sec as i64 * 1_000_000_000 as i64 - + self.inner.ut_tv.tv_usec as i64 * 1_000 as i64) + let ts_nanos: i128 = (self.inner.ut_tv.tv_sec as i64 * 1_000_000_000_i64 + + self.inner.ut_tv.tv_usec as i64 * 1_000_i64) .into(); let local_offset = time::OffsetDateTime::now_local().unwrap().offset(); time::OffsetDateTime::from_unix_timestamp_nanos(ts_nanos) diff --git a/tests/by-util/test_cp.rs b/tests/by-util/test_cp.rs index 079e966be..90e85b76a 100644 --- a/tests/by-util/test_cp.rs +++ b/tests/by-util/test_cp.rs @@ -1032,8 +1032,8 @@ fn test_cp_no_deref_folder_to_folder() { #[cfg(target_os = "linux")] fn test_cp_archive() { let (at, mut ucmd) = at_and_ucmd!(); - let ts = time::now().to_timespec(); - let previous = FileTime::from_unix_time(ts.sec as i64 - 3600, ts.nsec as u32); + let ts = time::OffsetDateTime::now_local().unwrap(); + let previous = FileTime::from_unix_time(ts.unix_timestamp() - 3600, ts.nanosecond() as u32); // set the file creation/modification an hour ago filetime::set_file_times( at.plus_as_string(TEST_HELLO_WORLD_SOURCE), @@ -1135,8 +1135,8 @@ fn test_cp_archive_recursive() { #[cfg(any(target_os = "linux", target_os = "android"))] fn test_cp_preserve_timestamps() { let (at, mut ucmd) = at_and_ucmd!(); - let ts = time::now().to_timespec(); - let previous = FileTime::from_unix_time(ts.sec as i64 - 3600, ts.nsec as u32); + let ts = time::OffsetDateTime::now_local().unwrap(); + let previous = FileTime::from_unix_time(ts.unix_timestamp() - 3600, ts.nanosecond()); // set the file creation/modification an hour ago filetime::set_file_times( at.plus_as_string(TEST_HELLO_WORLD_SOURCE), @@ -1168,8 +1168,8 @@ fn test_cp_preserve_timestamps() { #[cfg(any(target_os = "linux", target_os = "android"))] fn test_cp_no_preserve_timestamps() { let (at, mut ucmd) = at_and_ucmd!(); - let ts = time::now().to_timespec(); - let previous = FileTime::from_unix_time(ts.sec as i64 - 3600, ts.nsec as u32); + let ts = time::OffsetDateTime::now_local().unwrap(); + let previous = FileTime::from_unix_time(ts.unix_timestamp() - 3600, ts.nanosecond()); // set the file creation/modification an hour ago filetime::set_file_times( at.plus_as_string(TEST_HELLO_WORLD_SOURCE), diff --git a/tests/by-util/test_touch.rs b/tests/by-util/test_touch.rs index 6de635831..2c538d8b4 100644 --- a/tests/by-util/test_touch.rs +++ b/tests/by-util/test_touch.rs @@ -1,4 +1,10 @@ -// spell-checker:ignore (formats) cymdhm cymdhms mdhm mdhms ymdhm ymdhms +// spell-checker:ignore (formats) cymdhm cymdhms mdhm mdhms ymdhm ymdhms datetime mktime + +// This test relies on +// --cfg unsound_local_offset +// https://github.com/time-rs/time/blob/deb8161b84f355b31e39ce09e40c4d6ce3fea837/src/sys/local_offset_at/unix.rs#L112-L120= +// See https://github.com/time-rs/time/issues/293#issuecomment-946382614= +// Defined in .cargo/config extern crate touch; use self::touch::filetime::{self, FileTime}; @@ -42,8 +48,14 @@ fn str_to_filetime(format: &str, s: &str) -> FileTime { "%Y%m%d%H%M.%S" => format_description!("[year][month][day][hour][minute].[second]"), _ => panic!("unexpected dt format"), }; - let tm = time::PrimitiveDateTime::parse(&s, &format_description).unwrap(); - let offset_dt = tm.assume_offset(time::OffsetDateTime::now_local().unwrap().offset()); + let tm = time::PrimitiveDateTime::parse(s, &format_description).unwrap(); + let d = match time::OffsetDateTime::now_local() { + Ok(now) => now, + Err(e) => { + panic!("Error {} retrieving the OffsetDateTime::now_local", e); + } + }; + let offset_dt = tm.assume_offset(d.offset()); FileTime::from_unix_time(offset_dt.unix_timestamp(), tm.nanosecond()) } @@ -461,7 +473,13 @@ fn test_touch_mtime_dst_succeeds() { // In other locales it will be a different date/time, and in some locales // it doesn't exist at all, in which case this function will return None. fn get_dst_switch_hour() -> Option { - let now = time::OffsetDateTime::now_local().unwrap(); + //let now = time::OffsetDateTime::now_local().unwrap(); + let now = match time::OffsetDateTime::now_local() { + Ok(now) => now, + Err(e) => { + panic!("Error {} retrieving the OffsetDateTime::now_local", e); + } + }; // Start from January 1, 2020, 00:00. let tm = datetime!(2020-01-01 00:00 UTC);