Skip to content

Commit

Permalink
Fix binary_search_by() overflow issue in ZST case
Browse files Browse the repository at this point in the history
  • Loading branch information
Folyd committed Feb 27, 2021
1 parent 385ad48 commit 3eb5bee
Show file tree
Hide file tree
Showing 2 changed files with 19 additions and 3 deletions.
9 changes: 6 additions & 3 deletions library/core/src/slice/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2154,11 +2154,12 @@ impl<T> [T] {
where
F: FnMut(&'a T) -> Ordering,
{
let mut size = self.len();
let mut left = 0;
let mut right = self.len();
let mut right = size;
while left < right {
// never overflow because `slice::len()` max is `isize::MAX`.
let mid = (left + right) / 2;
let mid = left + size / 2;

// SAFETY: the call is made safe by the following invariants:
// - `mid >= 0`
// - `mid < size`: `mid` is limited by `[left; right)` bound.
Expand All @@ -2174,6 +2175,8 @@ impl<T> [T] {
} else {
return Ok(mid);
}

size = right - left;
}
Err(left)
}
Expand Down
13 changes: 13 additions & 0 deletions library/core/tests/slice.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
use core::cell::Cell;
use core::cmp::Ordering;
use core::result::Result::{Err, Ok};

#[test]
Expand Down Expand Up @@ -64,6 +65,17 @@ fn test_binary_search() {
assert_eq!(b.binary_search(&6), Err(4));
assert_eq!(b.binary_search(&7), Ok(4));
assert_eq!(b.binary_search(&8), Err(5));

let b = [(); usize::MAX];
assert_eq!(b.binary_search(&()), Ok(usize::MAX / 2));
}

#[test]
fn test_binary_search_by_overflow() {
let b = [(); usize::MAX];
assert_eq!(b.binary_search_by(|_| Ordering::Equal), Ok(usize::MAX / 2));
assert_eq!(b.binary_search_by(|_| Ordering::Greater), Err(0));
assert_eq!(b.binary_search_by(|_| Ordering::Less), Err(usize::MAX));
}

#[test]
Expand Down Expand Up @@ -1982,6 +1994,7 @@ fn test_copy_within_panics_dest_too_long() {
// The length is only 13, so a slice of length 4 starting at index 10 is out of bounds.
bytes.copy_within(0..4, 10);
}

#[test]
#[should_panic(expected = "slice index starts at 2 but ends at 1")]
fn test_copy_within_panics_src_inverted() {
Expand Down

0 comments on commit 3eb5bee

Please sign in to comment.