about summary refs log tree commit diff
path: root/library/alloc/src/string.rs
diff options
context:
space:
mode:
authordylni <46035563+dylni@users.noreply.github.com>2021-01-18 22:14:38 -0500
committerdylni <46035563+dylni@users.noreply.github.com>2021-01-18 22:14:38 -0500
commitb96063cf4757eb698611b57e9032da2b74c8c789 (patch)
tree7461d147a687279685cd5fa870577887b25955c6 /library/alloc/src/string.rs
parentd98d2f57d9b98325ff075c343d2c7695b66dfa7d (diff)
downloadrust-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.rs13
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`]`>`.