about summary refs log tree commit diff
path: root/src/libstd/sys/cloudabi
diff options
context:
space:
mode:
authorSebastian Geisler <sebastian@blockstream.io>2018-10-30 22:24:33 -0700
committerSebastian Geisler <sebastian@blockstream.io>2018-11-15 22:55:24 -0800
commit6d40b7232eaa00ab5c060582011f350725703a1e (patch)
treef2e1c25c92d32bb635a8df1792e96c32cec199bb /src/libstd/sys/cloudabi
parente8aef7cae14bc7a56859408c90253e9bcc07fcff (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.rs19
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 {