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/src/string.rs | |
| parent | d98d2f57d9b98325ff075c343d2c7695b66dfa7d (diff) | |
| download | rust-b96063cf4757eb698611b57e9032da2b74c8c789.tar.gz rust-b96063cf4757eb698611b57e9032da2b74c8c789.zip | |
Fix soundness issue for `replace_range` and `range`
Diffstat (limited to 'library/alloc/src/string.rs')
| -rw-r--r-- | library/alloc/src/string.rs | 13 |
1 files changed, 10 insertions, 3 deletions
diff --git a/library/alloc/src/string.rs b/library/alloc/src/string.rs index 91988928593..6f2a497598d 100644 --- a/library/alloc/src/string.rs +++ b/library/alloc/src/string.rs @@ -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`]`>`. |
