| 
1 | 1 | use std::borrow::Cow;  | 
 | 2 | +use std::cell::Cell;  | 
2 | 3 | use std::collections::TryReserveError::*;  | 
 | 4 | +use std::ops::Bound;  | 
3 | 5 | use std::ops::Bound::*;  | 
 | 6 | +use std::ops::RangeBounds;  | 
4 | 7 | use std::panic;  | 
 | 8 | +use std::str;  | 
5 | 9 | 
 
  | 
6 | 10 | pub trait IntoCow<'a, B: ?Sized>  | 
7 | 11 | where  | 
@@ -561,6 +565,52 @@ fn test_replace_range_unbounded() {  | 
561 | 565 |     assert_eq!(s, "");  | 
562 | 566 | }  | 
563 | 567 | 
 
  | 
 | 568 | +#[test]  | 
 | 569 | +fn test_replace_range_evil_start_bound() {  | 
 | 570 | +    struct EvilRange(Cell<bool>);  | 
 | 571 | + | 
 | 572 | +    impl RangeBounds<usize> for EvilRange {  | 
 | 573 | +        fn start_bound(&self) -> Bound<&usize> {  | 
 | 574 | +            Bound::Included(if self.0.get() {  | 
 | 575 | +                &1  | 
 | 576 | +            } else {  | 
 | 577 | +                self.0.set(true);  | 
 | 578 | +                &0  | 
 | 579 | +            })  | 
 | 580 | +        }  | 
 | 581 | +        fn end_bound(&self) -> Bound<&usize> {  | 
 | 582 | +            Bound::Unbounded  | 
 | 583 | +        }  | 
 | 584 | +    }  | 
 | 585 | + | 
 | 586 | +    let mut s = String::from("🦀");  | 
 | 587 | +    s.replace_range(EvilRange(Cell::new(false)), "");  | 
 | 588 | +    assert_eq!(Ok(""), str::from_utf8(s.as_bytes()));  | 
 | 589 | +}  | 
 | 590 | + | 
 | 591 | +#[test]  | 
 | 592 | +fn test_replace_range_evil_end_bound() {  | 
 | 593 | +    struct EvilRange(Cell<bool>);  | 
 | 594 | + | 
 | 595 | +    impl RangeBounds<usize> for EvilRange {  | 
 | 596 | +        fn start_bound(&self) -> Bound<&usize> {  | 
 | 597 | +            Bound::Included(&0)  | 
 | 598 | +        }  | 
 | 599 | +        fn end_bound(&self) -> Bound<&usize> {  | 
 | 600 | +            Bound::Excluded(if self.0.get() {  | 
 | 601 | +                &3  | 
 | 602 | +            } else {  | 
 | 603 | +                self.0.set(true);  | 
 | 604 | +                &4  | 
 | 605 | +            })  | 
 | 606 | +        }  | 
 | 607 | +    }  | 
 | 608 | + | 
 | 609 | +    let mut s = String::from("🦀");  | 
 | 610 | +    s.replace_range(EvilRange(Cell::new(false)), "");  | 
 | 611 | +    assert_eq!(Ok(""), str::from_utf8(s.as_bytes()));  | 
 | 612 | +}  | 
 | 613 | + | 
564 | 614 | #[test]  | 
565 | 615 | fn test_extend_ref() {  | 
566 | 616 |     let mut a = "foo".to_string();  | 
 | 
0 commit comments