Skip to content

Commit 699eb95

Browse files
committed
Auto merge of #50039 - ExpHP:quick-50002, r=alexcrichton
smaller PR just to fix #50002 I pulled this out of #50010 to make it easier to backport to beta if necessary, considering that inclusive range syntax is stabilizing soon (?). It fixes a bug in `<str>::index_mut` with `(..=end)` ranges (#50002), which prior to this fix was not only unusable but also UB in the cases where it "worked" (it gave improperly truncated UTF-8). (not that I can imagine why anybody would *use* `<str>::index_mut`... but I'm not here to judge)
2 parents d2577ca + 90b361b commit 699eb95

File tree

2 files changed

+32
-7
lines changed

2 files changed

+32
-7
lines changed

src/liballoc/tests/str.rs

+30
Original file line numberDiff line numberDiff line change
@@ -401,6 +401,36 @@ fn test_str_get_maxinclusive() {
401401
}
402402
}
403403

404+
#[test]
405+
fn test_str_slice_rangetoinclusive_ok() {
406+
let s = "abcαβγ";
407+
assert_eq!(&s[..=2], "abc");
408+
assert_eq!(&s[..=4], "abcα");
409+
}
410+
411+
#[test]
412+
#[should_panic]
413+
fn test_str_slice_rangetoinclusive_notok() {
414+
let s = "abcαβγ";
415+
&s[..=3];
416+
}
417+
418+
#[test]
419+
fn test_str_slicemut_rangetoinclusive_ok() {
420+
let mut s = "abcαβγ".to_owned();
421+
let s: &mut str = &mut s;
422+
assert_eq!(&mut s[..=2], "abc");
423+
assert_eq!(&mut s[..=4], "abcα");
424+
}
425+
426+
#[test]
427+
#[should_panic]
428+
fn test_str_slicemut_rangetoinclusive_notok() {
429+
let mut s = "abcαβγ".to_owned();
430+
let s: &mut str = &mut s;
431+
&mut s[..=3];
432+
}
433+
404434
#[test]
405435
fn test_is_char_boundary() {
406436
let s = "ศไทย中华Việt Nam β-release 🐱123";

src/libcore/str/mod.rs

+2-7
Original file line numberDiff line numberDiff line change
@@ -2100,18 +2100,13 @@ mod traits {
21002100
fn index(self, slice: &str) -> &Self::Output {
21012101
assert!(self.end != usize::max_value(),
21022102
"attempted to index str up to maximum usize");
2103-
let end = self.end + 1;
2104-
self.get(slice).unwrap_or_else(|| super::slice_error_fail(slice, 0, end))
2103+
(..self.end+1).index(slice)
21052104
}
21062105
#[inline]
21072106
fn index_mut(self, slice: &mut str) -> &mut Self::Output {
21082107
assert!(self.end != usize::max_value(),
21092108
"attempted to index str up to maximum usize");
2110-
if slice.is_char_boundary(self.end) {
2111-
unsafe { self.get_unchecked_mut(slice) }
2112-
} else {
2113-
super::slice_error_fail(slice, 0, self.end + 1)
2114-
}
2109+
(..self.end+1).index_mut(slice)
21152110
}
21162111
}
21172112

0 commit comments

Comments
 (0)