Skip to content

Commit 2e4ba41

Browse files
committed
impl: make Arbitrary::arbitrary for SystemTime not panic
Arbitrary `SystemTime`s are generated based on arbitrary `Duration`s by adding or subtracting from `UNIX_EPOCH`. If we happen to generate big `Duration`s, this could cause an overflow. This change avoids this problem by resorting to ever smaller durations in case of an overflow.
1 parent 03ab585 commit 2e4ba41

File tree

1 file changed

+11
-6
lines changed

1 file changed

+11
-6
lines changed

src/arbitrary.rs

+11-6
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ use std::collections::{
55
use std::env;
66
use std::ffi::{CString, OsString};
77
use std::hash::{BuildHasher, Hash};
8-
use std::iter::{empty, once};
8+
use std::iter::{empty, once, successors};
99
use std::net::{
1010
IpAddr, Ipv4Addr, Ipv6Addr, SocketAddr, SocketAddrV4, SocketAddrV6,
1111
};
@@ -1186,11 +1186,16 @@ impl Arbitrary for SystemTime {
11861186
fn arbitrary(rng: &mut Gen) -> Self {
11871187
let after_epoch = bool::arbitrary(rng);
11881188
let duration = Duration::arbitrary(rng);
1189-
if after_epoch {
1190-
UNIX_EPOCH + duration
1191-
} else {
1192-
UNIX_EPOCH - duration
1193-
}
1189+
successors(Some(duration), |d| Some(*d / 2))
1190+
.take_while(|d| !d.is_zero())
1191+
.find_map(|d| {
1192+
if after_epoch {
1193+
UNIX_EPOCH.checked_add(d)
1194+
} else {
1195+
UNIX_EPOCH.checked_sub(d)
1196+
}
1197+
})
1198+
.unwrap_or(UNIX_EPOCH)
11941199
}
11951200

11961201
fn shrink(&self) -> Box<dyn Iterator<Item = Self>> {

0 commit comments

Comments
 (0)