diff options
| author | dylni <46035563+dylni@users.noreply.github.com> | 2021-01-18 22:14:38 -0500 |
|---|---|---|
| committer | dylni <46035563+dylni@users.noreply.github.com> | 2021-01-18 22:14:38 -0500 |
| commit | b96063cf4757eb698611b57e9032da2b74c8c789 (patch) | |
| tree | 7461d147a687279685cd5fa870577887b25955c6 /library/alloc/tests | |
| parent | d98d2f57d9b98325ff075c343d2c7695b66dfa7d (diff) | |
Fix soundness issue for `replace_range` and `range`
Diffstat (limited to 'library/alloc/tests')
| -rw-r--r-- | library/alloc/tests/string.rs | 50 |
1 files changed, 50 insertions, 0 deletions
diff --git a/library/alloc/tests/string.rs b/library/alloc/tests/string.rs index b28694186b6..f3d74e0514d 100644 --- a/library/alloc/tests/string.rs +++ b/library/alloc/tests/string.rs @@ -1,7 +1,11 @@ use std::borrow::Cow; +use std::cell::Cell; use std::collections::TryReserveError::*; +use std::ops::Bound; use std::ops::Bound::*; +use std::ops::RangeBounds; use std::panic; +use std::str; pub trait IntoCow<'a, B: ?Sized> where @@ -562,6 +566,52 @@ fn test_replace_range_unbounded() { } #[test] +fn test_replace_range_evil_start_bound() { + struct EvilRange(Cell<bool>); + + impl RangeBounds<usize> for EvilRange { + fn start_bound(&self) -> Bound<&usize> { + Bound::Included(if self.0.get() { + &1 + } else { + self.0.set(true); + &0 + }) + } + fn end_bound(&self) -> Bound<&usize> { + Bound::Unbounded + } + } + + let mut s = String::from("🦀"); + s.replace_range(EvilRange(Cell::new(false)), ""); + assert_eq!(Ok(""), str::from_utf8(s.as_bytes())); +} + +#[test] +fn test_replace_range_evil_end_bound() { + struct EvilRange(Cell<bool>); + + impl RangeBounds<usize> for EvilRange { + fn start_bound(&self) -> Bound<&usize> { + Bound::Included(&0) + } + fn end_bound(&self) -> Bound<&usize> { + Bound::Excluded(if self.0.get() { + &3 + } else { + self.0.set(true); + &4 + }) + } + } + + let mut s = String::from("🦀"); + s.replace_range(EvilRange(Cell::new(false)), ""); + assert_eq!(Ok(""), str::from_utf8(s.as_bytes())); +} + +#[test] fn test_extend_ref() { let mut a = "foo".to_string(); a.extend(&['b', 'a', 'r']); |
