Skip to content

Commit

Permalink
Add overflow checking for str::get with inclusive ranges
Browse files Browse the repository at this point in the history
Fixes #42401
  • Loading branch information
scottmcm committed Jun 4, 2017
1 parent 18612b2 commit 808a08a
Show file tree
Hide file tree
Showing 3 changed files with 55 additions and 4 deletions.
1 change: 1 addition & 0 deletions src/libcollections/tests/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
#![feature(rand)]
#![feature(slice_rotate)]
#![feature(splice)]
#![feature(str_checked_slicing)]
#![feature(str_escape)]
#![feature(test)]
#![feature(unboxed_closures)]
Expand Down
42 changes: 42 additions & 0 deletions src/libcollections/tests/str.rs
Original file line number Diff line number Diff line change
Expand Up @@ -358,6 +358,48 @@ fn test_slice_fail() {
&"中华Việt Nam"[0..2];
}

#[test]
#[should_panic]
fn test_str_slice_rangetoinclusive_max_panics() {
&"hello"[...usize::max_value()];
}

#[test]
#[should_panic]
fn test_str_slice_rangeinclusive_max_panics() {
&"hello"[1...usize::max_value()];
}

#[test]
#[should_panic]
fn test_str_slicemut_rangetoinclusive_max_panics() {
let mut s = "hello".to_owned();
let s: &mut str = &mut s;
&mut s[...usize::max_value()];
}

#[test]
#[should_panic]
fn test_str_slicemut_rangeinclusive_max_panics() {
let mut s = "hello".to_owned();
let s: &mut str = &mut s;
&mut s[1...usize::max_value()];
}

#[test]
fn test_str_get_maxinclusive() {
let mut s = "hello".to_owned();
{
let s: &str = &s;
assert_eq!(s.get(...usize::max_value()), None);
assert_eq!(s.get(1...usize::max_value()), None);
}
{
let s: &mut str = &mut s;
assert_eq!(s.get(...usize::max_value()), None);
assert_eq!(s.get(1...usize::max_value()), None);
}
}

#[test]
fn test_is_char_boundary() {
Expand Down
16 changes: 12 additions & 4 deletions src/libcore/str/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1918,11 +1918,19 @@ mod traits {
type Output = str;
#[inline]
fn get(self, slice: &str) -> Option<&Self::Output> {
(self.start..self.end+1).get(slice)
if let Some(end) = self.end.checked_add(1) {
(self.start..end).get(slice)
} else {
None
}
}
#[inline]
fn get_mut(self, slice: &mut str) -> Option<&mut Self::Output> {
(self.start..self.end+1).get_mut(slice)
if let Some(end) = self.end.checked_add(1) {
(self.start..end).get_mut(slice)
} else {
None
}
}
#[inline]
unsafe fn get_unchecked(self, slice: &str) -> &Self::Output {
Expand Down Expand Up @@ -1953,15 +1961,15 @@ mod traits {
type Output = str;
#[inline]
fn get(self, slice: &str) -> Option<&Self::Output> {
if slice.is_char_boundary(self.end + 1) {
if self.end < usize::max_value() && slice.is_char_boundary(self.end + 1) {
Some(unsafe { self.get_unchecked(slice) })
} else {
None
}
}
#[inline]
fn get_mut(self, slice: &mut str) -> Option<&mut Self::Output> {
if slice.is_char_boundary(self.end + 1) {
if self.end < usize::max_value() && slice.is_char_boundary(self.end + 1) {
Some(unsafe { self.get_unchecked_mut(slice) })
} else {
None
Expand Down

0 comments on commit 808a08a

Please sign in to comment.