diff options
| author | Sebastian Geisler <sebastian@blockstream.io> | 2018-10-30 22:24:33 -0700 |
|---|---|---|
| committer | Sebastian Geisler <sebastian@blockstream.io> | 2018-11-15 22:55:24 -0800 |
| commit | 6d40b7232eaa00ab5c060582011f350725703a1e (patch) | |
| tree | f2e1c25c92d32bb635a8df1792e96c32cec199bb /src/libstd/sys/cloudabi | |
| parent | e8aef7cae14bc7a56859408c90253e9bcc07fcff (diff) | |
Implement checked_add_duration for SystemTime
Since SystemTime is opaque there is no way to check if the result of an addition will be in bounds. That makes the Add<Duration> trait completely unusable with untrusted data. This is a big problem because adding a Duration to UNIX_EPOCH is the standard way of constructing a SystemTime from a unix timestamp. This commit implements checked_add_duration(&self, &Duration) -> Option<SystemTime> for std::time::SystemTime and as a prerequisite also for all platform specific time structs. This also led to the refactoring of many add_duration(&self, &Duration) -> SystemTime functions to avoid redundancy (they now unwrap the result of checked_add_duration). Some basic unit tests for the newly introduced function were added too.
Diffstat (limited to 'src/libstd/sys/cloudabi')
| -rw-r--r-- | src/libstd/sys/cloudabi/time.rs | 19 |
1 files changed, 13 insertions, 6 deletions
diff --git a/src/libstd/sys/cloudabi/time.rs b/src/libstd/sys/cloudabi/time.rs index ee12731619a..191324e26a4 100644 --- a/src/libstd/sys/cloudabi/time.rs +++ b/src/libstd/sys/cloudabi/time.rs @@ -19,10 +19,14 @@ pub struct Instant { t: abi::timestamp, } -pub fn dur2intervals(dur: &Duration) -> abi::timestamp { +fn checked_dur2intervals(dur: &Duration) -> Option<abi::timestamp> { dur.as_secs() .checked_mul(NSEC_PER_SEC) .and_then(|nanos| nanos.checked_add(dur.subsec_nanos() as abi::timestamp)) +} + +pub fn dur2intervals(dur: &Duration) -> abi::timestamp { + checked_dur2intervals(dur) .expect("overflow converting duration to nanoseconds") } @@ -92,11 +96,14 @@ impl SystemTime { } pub fn add_duration(&self, other: &Duration) -> SystemTime { - SystemTime { - t: self.t - .checked_add(dur2intervals(other)) - .expect("overflow when adding duration to instant"), - } + self.checked_add_duration(other) + .expect("overflow when adding duration to instant") + } + + pub fn checked_add_duration(&self, other: &Duration) -> Option<SystemTime> { + checked_dur2intervals(other) + .and_then(|d| self.t.checked_add(d)) + .map(|t| SystemTime {t}) } pub fn sub_duration(&self, other: &Duration) -> SystemTime { |
