Skip to content

Commit 5c508d3

Browse files
committed
Seed thread_rng with the current time if OsRng fails.
1 parent a8c833e commit 5c508d3

File tree

1 file changed

+16
-6
lines changed

1 file changed

+16
-6
lines changed

src/lib.rs

Lines changed: 16 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -254,6 +254,7 @@ use std::mem;
254254
use std::io;
255255
use std::rc::Rc;
256256
use std::num::Wrapping as w;
257+
use std::time;
257258

258259
pub use os::OsRng;
259260

@@ -906,9 +907,9 @@ struct ThreadRngReseeder;
906907

907908
impl reseeding::Reseeder<StdRng> for ThreadRngReseeder {
908909
fn reseed(&mut self, rng: &mut StdRng) {
909-
*rng = match StdRng::new() {
910-
Ok(r) => r,
911-
Err(e) => panic!("could not reseed thread_rng: {}", e)
910+
match StdRng::new() {
911+
Ok(r) => *rng = r,
912+
Err(_) => rng.reseed(&weak_seed())
912913
}
913914
}
914915
}
@@ -925,8 +926,9 @@ pub struct ThreadRng {
925926
/// generator, seeded by the system. Intended to be used in method
926927
/// chaining style, e.g. `thread_rng().gen::<i32>()`.
927928
///
928-
/// The RNG provided will reseed itself from the operating system
929-
/// after generating a certain amount of randomness.
929+
/// After generating a certain amount of randomness, the RNG will reseed itself
930+
/// from the operating system or, if the operating system RNG returns an error,
931+
/// a seed based on the current system time.
930932
///
931933
/// The internal RNG used is platform and architecture dependent, even
932934
/// if the operating system random number generator is rigged to give
@@ -937,7 +939,7 @@ pub fn thread_rng() -> ThreadRng {
937939
thread_local!(static THREAD_RNG_KEY: Rc<RefCell<ThreadRngInner>> = {
938940
let r = match StdRng::new() {
939941
Ok(r) => r,
940-
Err(e) => panic!("could not initialize thread_rng: {}", e)
942+
Err(_) => StdRng::from_seed(&weak_seed())
941943
};
942944
let rng = reseeding::ReseedingRng::new(r,
943945
THREAD_RNG_RESEED_THRESHOLD,
@@ -948,6 +950,14 @@ pub fn thread_rng() -> ThreadRng {
948950
ThreadRng { rng: THREAD_RNG_KEY.with(|t| t.clone()) }
949951
}
950952

953+
fn weak_seed() -> [usize; 2] {
954+
let now = time::SystemTime::now();
955+
let unix_time = now.duration_since(time::UNIX_EPOCH).unwrap();
956+
let seconds = unix_time.as_secs() as usize;
957+
let nanoseconds = unix_time.subsec_nanos() as usize;
958+
[seconds, nanoseconds]
959+
}
960+
951961
impl Rng for ThreadRng {
952962
fn next_u32(&mut self) -> u32 {
953963
self.rng.borrow_mut().next_u32()

0 commit comments

Comments
 (0)