diff options
author | Ben Bridle <bridle.benjamin@gmail.com> | 2024-10-31 09:41:40 +1300 |
---|---|---|
committer | Ben Bridle <bridle.benjamin@gmail.com> | 2024-10-31 09:46:06 +1300 |
commit | 31b697819cdee2c28fb1839589a389e39156e414 (patch) | |
tree | d1e0834e6c707cf4ad96f69f9a6fbf59f00d89b5 | |
parent | 02deef3511e8613a5d737d5586f1efd9fd01637c (diff) | |
download | bedrock-pc-31b697819cdee2c28fb1839589a389e39156e414.zip |
Fix issue with clock device returning UTC time instead of local time
The project previously used the `time` crate for getting the current
time in the local timezone. It was discovered that the time crate would
fail to return the local time when the program used multiple threads,
because of concerns that the other threads could modify timezone-related
environment variables while the timezone was being read from the system
and create a soundness issue. A second program thread was introduced
recently by commit 1a830a3 to provide non-blocking reads of standard
input for the local stream device, and so the time returned by the
clock device was falling back to UTC.
To fix this, the `time` crate has been replaced by the `chrono` crate
which does not suffer from this restriction, and in any case seems to
be the more popular of the two anyway.
-rw-r--r-- | Cargo.lock | 118 | ||||
-rw-r--r-- | Cargo.toml | 2 | ||||
-rw-r--r-- | src/devices/clock_device.rs | 25 |
3 files changed, 80 insertions, 65 deletions
@@ -43,6 +43,21 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "fc7eb209b1518d6bb87b283c20095f5228ecda460da70b44f0802523dea6da04" [[package]] +name = "android-tzdata" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e999941b234f3131b00bc13c22d06e8c5ff726d1b6318ac7eb276997bbb4fef0" + +[[package]] +name = "android_system_properties" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "819e7219dbd41043ac279b19830f2efc897156490d7fd6ea916720117ee66311" +dependencies = [ + "libc", +] + +[[package]] name = "as-raw-xcb-connection" version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -80,9 +95,9 @@ version = "1.0.0-alpha1" dependencies = [ "bedrock-asm", "bedrock-core", + "chrono", "geometry", "phosphor", - "time", "windows", "xflags", ] @@ -204,6 +219,20 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "613afe47fcd5fac7ccf1db93babcb082c5994d996f20b8b159f2ad1658eb5724" [[package]] +name = "chrono" +version = "0.4.38" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a21f936df1771bf62b77f047b726c4625ff2e8aa607c01ec06e5a05bd8463401" +dependencies = [ + "android-tzdata", + "iana-time-zone", + "js-sys", + "num-traits", + "wasm-bindgen", + "windows-targets 0.52.6", +] + +[[package]] name = "colour" version = "2.0.0" source = "git+git://benbridle.com/colour?tag=v2.0.0#0ae93bec309d37cda72e137da83127bb48b22d65" @@ -327,15 +356,6 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "96a6ac251f4a2aca6b3f91340350eab87ae57c3f127ffeb585e92bd336717991" [[package]] -name = "deranged" -version = "0.3.10" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8eb30d70a07a3b04884d2677f06bec33509dc67ca60d92949e5535352d3191dc" -dependencies = [ - "powerfmt", -] - -[[package]] name = "dispatch" version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -494,6 +514,29 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "fbf6a919d6cf397374f7dfeeea91d974c7c0a7221d0d0f4f20d859d329e53fcc" [[package]] +name = "iana-time-zone" +version = "0.1.61" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "235e081f3925a06703c2d0117ea8b91f042756fd6e7a6e5d901e8ca1a996b220" +dependencies = [ + "android_system_properties", + "core-foundation-sys", + "iana-time-zone-haiku", + "js-sys", + "wasm-bindgen", + "windows-core 0.52.0", +] + +[[package]] +name = "iana-time-zone-haiku" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f31827a206f56af32e590ba56d5d2d085f558508192593743f16b2306495269f" +dependencies = [ + "cc", +] + +[[package]] name = "indexmap" version = "2.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -634,6 +677,15 @@ dependencies = [ ] [[package]] +name = "num-traits" +version = "0.2.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "071dfc062690e90b734c0b2273ce72ad0ffa95f0c74596bc250dcfd960262841" +dependencies = [ + "autocfg", +] + +[[package]] name = "num_enum" version = "0.7.3" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -655,15 +707,6 @@ dependencies = [ ] [[package]] -name = "num_threads" -version = "0.1.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2819ce041d2ee131036f4fc9d6ae7ae125a3a40e97ba64d04fe799ad9dabbb44" -dependencies = [ - "libc", -] - -[[package]] name = "objc-sys" version = "0.3.5" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -947,12 +990,6 @@ dependencies = [ ] [[package]] -name = "powerfmt" -version = "0.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "439ee305def115ba05938db6eb1644ff94165c5ab5e9420d1c1bcedbba909391" - -[[package]] name = "proc-macro-crate" version = "1.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -1179,26 +1216,6 @@ dependencies = [ ] [[package]] -name = "time" -version = "0.3.31" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f657ba42c3f86e7680e53c8cd3af8abbe56b5491790b46e22e19c0d57463583e" -dependencies = [ - "deranged", - "libc", - "num_threads", - "powerfmt", - "serde", - "time-core", -] - -[[package]] -name = "time-core" -version = "0.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ef927ca75afb808a4d64dd374f00a2adf8d0fcff8e7b184af886c3c87ec4a3f3" - -[[package]] name = "tiny-xlib" version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -1492,7 +1509,16 @@ version = "0.58.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "dd04d41d93c4992d421894c18c8b43496aa748dd4c081bac0dc93eb0489272b6" dependencies = [ - "windows-core", + "windows-core 0.58.0", + "windows-targets 0.52.6", +] + +[[package]] +name = "windows-core" +version = "0.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "33ab640c8d7e35bf8ba19b884ba838ceb4fba93a4e8c65a9059d08afcfc683d9" +dependencies = [ "windows-targets 0.52.6", ] @@ -11,7 +11,7 @@ bedrock-core = { git = "git://benbridle.com/bedrock_core", tag = "v5.0.0" } phosphor = { git = "git://benbridle.com/phosphor", tag = "v3.1.0" } geometry = { git = "git://benbridle.com/geometry", tag = "v1.0.0" } -time = { version = "0.3.30", features = [ "local-offset" ] } +chrono = { version = "0.4.38" } xflags = "0.4.0-pre.1" [target.'cfg(target_os = "windows")'.dependencies] diff --git a/src/devices/clock_device.rs b/src/devices/clock_device.rs index 494e0c7..7cc877e 100644 --- a/src/devices/clock_device.rs +++ b/src/devices/clock_device.rs @@ -1,20 +1,9 @@ use bedrock_core::*; +use chrono::prelude::*; use std::time::{Duration, Instant}; -macro_rules! now { () => { - time::OffsetDateTime::now_local() - .unwrap_or_else(|_| time::OffsetDateTime::now_utc()) -}; } - -fn current_year() -> u8 { now!().year().saturating_sub(2000) as u8 } -fn current_month() -> u8 { now!().month() as u8 - 1 } -fn current_day() -> u8 { now!().day() as u8 - 1 } -fn current_hour() -> u8 { now!().hour() } -fn current_minute() -> u8 { now!().minute() } -fn current_second() -> u8 { now!().second() } - macro_rules! fn_read_timer { ($fn_name:ident($read:ident, $end:ident)) => { pub fn $fn_name(&mut self) { @@ -123,12 +112,12 @@ impl ClockDevice { impl Device for ClockDevice { fn read(&mut self, port: u8) -> u8 { match port { - 0x0 => current_year(), - 0x1 => current_month(), - 0x2 => current_day(), - 0x3 => current_hour(), - 0x4 => current_minute(), - 0x5 => current_second(), + 0x0 => Local::now().year().saturating_sub(2000) as u8, + 0x1 => Local::now().month().saturating_sub(1) as u8, + 0x2 => Local::now().day().saturating_sub(1) as u8, + 0x3 => Local::now().hour() as u8, + 0x4 => Local::now().minute() as u8, + 0x5 => Local::now().second() as u8, 0x6 => { self.read_uptime(); read_h!(self.uptime_read) }, 0x7 => read_l!(self.uptime_read), 0x8 => { self.read_t1(); read_h!(self.t1_read) }, |