Fix soundness issue for replace_range
and range
This commit is contained in:
parent
d98d2f57d9
commit
b96063cf47
3 changed files with 70 additions and 6 deletions
|
@ -25,7 +25,12 @@ where
|
|||
K: Borrow<Q>,
|
||||
R: RangeBounds<Q>,
|
||||
{
|
||||
match (range.start_bound(), range.end_bound()) {
|
||||
// WARNING: Inlining these variables would be unsound (#81138)
|
||||
// We assume the bounds reported by `range` remain the same, but
|
||||
// an adversarial implementation could change between calls
|
||||
let start = range.start_bound();
|
||||
let end = range.end_bound();
|
||||
match (start, end) {
|
||||
(Excluded(s), Excluded(e)) if s == e => {
|
||||
panic!("range start and end are equal and excluded in BTreeMap")
|
||||
}
|
||||
|
@ -41,7 +46,8 @@ where
|
|||
let mut max_found = false;
|
||||
|
||||
loop {
|
||||
let front = match (min_found, range.start_bound()) {
|
||||
// Using `range` again would be unsound (#81138)
|
||||
let front = match (min_found, start) {
|
||||
(false, Included(key)) => match min_node.search_node(key) {
|
||||
SearchResult::Found(kv) => {
|
||||
min_found = true;
|
||||
|
@ -61,7 +67,8 @@ where
|
|||
(_, Unbounded) => min_node.first_edge(),
|
||||
};
|
||||
|
||||
let back = match (max_found, range.end_bound()) {
|
||||
// Using `range` again would be unsound (#81138)
|
||||
let back = match (max_found, end) {
|
||||
(false, Included(key)) => match max_node.search_node(key) {
|
||||
SearchResult::Found(kv) => {
|
||||
max_found = true;
|
||||
|
|
|
@ -1553,18 +1553,25 @@ impl String {
|
|||
// Replace_range does not have the memory safety issues of a vector Splice.
|
||||
// of the vector version. The data is just plain bytes.
|
||||
|
||||
match range.start_bound() {
|
||||
// WARNING: Inlining this variable would be unsound (#81138)
|
||||
let start = range.start_bound();
|
||||
match start {
|
||||
Included(&n) => assert!(self.is_char_boundary(n)),
|
||||
Excluded(&n) => assert!(self.is_char_boundary(n + 1)),
|
||||
Unbounded => {}
|
||||
};
|
||||
match range.end_bound() {
|
||||
// WARNING: Inlining this variable would be unsound (#81138)
|
||||
let end = range.end_bound();
|
||||
match end {
|
||||
Included(&n) => assert!(self.is_char_boundary(n + 1)),
|
||||
Excluded(&n) => assert!(self.is_char_boundary(n)),
|
||||
Unbounded => {}
|
||||
};
|
||||
|
||||
unsafe { self.as_mut_vec() }.splice(range, replace_with.bytes());
|
||||
// Using `range` again would be unsound (#81138)
|
||||
// We assume the bounds reported by `range` remain the same, but
|
||||
// an adversarial implementation could change between calls
|
||||
unsafe { self.as_mut_vec() }.splice((start, end), replace_with.bytes());
|
||||
}
|
||||
|
||||
/// Converts this `String` into a [`Box`]`<`[`str`]`>`.
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue