Fix binary_search_by() overflow issue in ZST case

This commit is contained in:
Folyd 2021-02-27 17:27:45 +08:00
parent 385ad48b35
commit 3eb5bee242
2 changed files with 19 additions and 3 deletions

View File

@ -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.
@ -2174,6 +2175,8 @@ impl<T> [T] {
} else {
return Ok(mid);
}
size = right - left;
}
Err(left)
}

View File

@ -1,4 +1,5 @@
use core::cell::Cell;
use core::cmp::Ordering;
use core::result::Result::{Err, Ok};
#[test]
@ -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]
@ -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() {