Skip to content

Commit 8decbdf

Browse files
committed
time: Fix Windows' SystemTime::checked_sub
The Windows implementation of `SystemTime::checked_sub` contains a bug, namely that it does not return `None` on values below 1601. This bug stems from the fact that internally, the time gets converted to an i64, with zero representing the anchor in 1601. Of course, performing checked subtraction on a signed integer generally works fine. However, the resulting value delivers undefined behavior on Windows systems. To mitigate this issue, we try to convert the resulting i64 to an u64 because a negative value should obviously fail there.
1 parent 1b9b4f4 commit 8decbdf

File tree

1 file changed

+7
-2
lines changed
  • library/std/src/sys/pal/windows

1 file changed

+7
-2
lines changed

library/std/src/sys/pal/windows/time.rs

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -111,8 +111,13 @@ impl SystemTime {
111111
}
112112

113113
pub fn checked_sub_duration(&self, other: &Duration) -> Option<SystemTime> {
114-
let intervals = self.intervals().checked_sub(checked_dur2intervals(other)?)?;
115-
Some(SystemTime::from_intervals(intervals))
114+
// Windows does not support times before 1601, hence why we don't
115+
// support negatives. In order to tackle this, we try to convert the
116+
// resulting value into an u64, which should obviously fail in the case
117+
// that the value is below zero.
118+
let intervals: u64 =
119+
self.intervals().checked_sub(checked_dur2intervals(other)?)?.try_into()?;
120+
Some(SystemTime::from_intervals(intervals as i64))
116121
}
117122
}
118123

0 commit comments

Comments
 (0)