about summary refs log tree commit diff
path: root/src/libstd/sys/unix/time.rs
diff options
context:
space:
mode:
authorkennytm <kennytm@gmail.com>2017-09-01 01:16:24 +0800
committerkennytm <kennytm@gmail.com>2017-09-07 17:14:27 +0800
commit8410ca663258423cd16b0741f7a053b320e13da0 (patch)
tree97c6f21fe2697ee48960c6b4d3126914370c1684 /src/libstd/sys/unix/time.rs
parenta6a9d4c5fd214cb8110482dee2017607e23ccc7b (diff)
downloadrust-8410ca663258423cd16b0741f7a053b320e13da0.tar.gz
rust-8410ca663258423cd16b0741f7a053b320e13da0.zip
Properly detect overflow in Instance +/- Duration.
Avoid unchecked cast from `u64` to `i64`. Use `try_into()` for checked
cast. (On Unix, cast to `time_t` instead of `i64`.)
Diffstat (limited to 'src/libstd/sys/unix/time.rs')
-rw-r--r--src/libstd/sys/unix/time.rs22
1 files changed, 15 insertions, 7 deletions
diff --git a/src/libstd/sys/unix/time.rs b/src/libstd/sys/unix/time.rs
index a1ad94872de..c1bea95ce91 100644
--- a/src/libstd/sys/unix/time.rs
+++ b/src/libstd/sys/unix/time.rs
@@ -13,6 +13,7 @@ use libc;
 use time::Duration;
 
 pub use self::inner::{Instant, SystemTime, UNIX_EPOCH};
+use convert::TryInto;
 
 const NSEC_PER_SEC: u64 = 1_000_000_000;
 
@@ -41,8 +42,12 @@ impl Timespec {
     }
 
     fn add_duration(&self, other: &Duration) -> Timespec {
-        let secs = (self.t.tv_sec as i64).checked_add(other.as_secs() as i64);
-        let mut secs = secs.expect("overflow when adding duration to time");
+        let mut secs = other
+            .as_secs()
+            .try_into() // <- target type would be `libc::time_t`
+            .ok()
+            .and_then(|secs| self.t.tv_sec.checked_add(secs))
+            .expect("overflow when adding duration to time");
 
         // Nano calculations can't overflow because nanos are <1B which fit
         // in a u32.
@@ -54,16 +59,19 @@ impl Timespec {
         }
         Timespec {
             t: libc::timespec {
-                tv_sec: secs as libc::time_t,
+                tv_sec: secs,
                 tv_nsec: nsec as libc::c_long,
             },
         }
     }
 
     fn sub_duration(&self, other: &Duration) -> Timespec {
-        let secs = (self.t.tv_sec as i64).checked_sub(other.as_secs() as i64);
-        let mut secs = secs.expect("overflow when subtracting duration \
-                                    from time");
+        let mut secs = other
+            .as_secs()
+            .try_into() // <- target type would be `libc::time_t`
+            .ok()
+            .and_then(|secs| self.t.tv_sec.checked_sub(secs))
+            .expect("overflow when subtracting duration from time");
 
         // Similar to above, nanos can't overflow.
         let mut nsec = self.t.tv_nsec as i32 - other.subsec_nanos() as i32;
@@ -74,7 +82,7 @@ impl Timespec {
         }
         Timespec {
             t: libc::timespec {
-                tv_sec: secs as libc::time_t,
+                tv_sec: secs,
                 tv_nsec: nsec as libc::c_long,
             },
         }