Skip to content

Commit aeab810

Browse files
authored
Avoid unsafe where safety depends on non-local values (#1791)
1 parent 1896d7c commit aeab810

3 files changed

Lines changed: 8 additions & 16 deletions

File tree

CHANGELOG.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,8 +12,10 @@ You may also find the [Upgrade Guide](https://rust-random.github.io/book/update.
1212

1313
### Changes
1414
- Document required output order of fn `partial_shuffle` and apply `#[must_use]` ([#1769])
15+
- Avoid usage of `unsafe` in contexts where non-local memory corruption could invalidate contract ([#1791])
1516

1617
[#1769]: https://github.com/rust-random/rand/pull/1769
18+
[#1791]: https://github.com/rust-random/rand/pull/1791
1719

1820
## [0.10.1] — 2026-02-11
1921
This release includes a fix for a soundness bug; see [#1763].

src/distr/slice.rs

Lines changed: 3 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -86,18 +86,9 @@ impl<'a, T> Choose<'a, T> {
8686
impl<'a, T> Distribution<&'a T> for Choose<'a, T> {
8787
fn sample<R: Rng + ?Sized>(&self, rng: &mut R) -> &'a T {
8888
let idx = self.range.sample(rng);
89-
90-
debug_assert!(
91-
idx < self.slice.len(),
92-
"Uniform::new(0, {}) somehow returned {}",
93-
self.slice.len(),
94-
idx
95-
);
96-
97-
// Safety: at construction time, it was ensured that the slice was
98-
// non-empty, and that the `Uniform` range produces values in range
99-
// for the slice
100-
unsafe { self.slice.get_unchecked(idx) }
89+
self.slice
90+
.get(idx)
91+
.expect("rand::distr::slice::Choose: index out-of-range (likely memory corruption)")
10192
}
10293
}
10394

src/distr/uniform_other.rs

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -83,10 +83,9 @@ impl UniformSampler for UniformChar {
8383
if x >= CHAR_SURROGATE_START {
8484
x += CHAR_SURROGATE_LEN;
8585
}
86-
// SAFETY: x must not be in surrogate range or greater than char::MAX.
87-
// This relies on range constructors which accept char arguments.
88-
// Validity of input char values is assumed.
89-
unsafe { core::char::from_u32_unchecked(x) }
86+
87+
char::from_u32(x)
88+
.expect("rand::distr::uniform::UniformChar: invalid Unicode scalar value (likely memory corruption)")
9089
}
9190
}
9291

0 commit comments

Comments
 (0)