diff --git a/compiler/rustc_expand/src/proc_macro_server.rs b/compiler/rustc_expand/src/proc_macro_server.rs index 39c82f97e0a39..5a728bbda96c5 100644 --- a/compiler/rustc_expand/src/proc_macro_server.rs +++ b/compiler/rustc_expand/src/proc_macro_server.rs @@ -584,12 +584,12 @@ impl server::Literal for Rustc<'_> { let start = match start { Bound::Included(lo) => lo, - Bound::Excluded(lo) => lo + 1, + Bound::Excluded(lo) => lo.checked_add(1)?, Bound::Unbounded => 0, }; let end = match end { - Bound::Included(hi) => hi + 1, + Bound::Included(hi) => hi.checked_add(1)?, Bound::Excluded(hi) => hi, Bound::Unbounded => length, }; diff --git a/library/alloc/tests/lib.rs b/library/alloc/tests/lib.rs index b1513d1b05655..a6912d3f5bcc3 100644 --- a/library/alloc/tests/lib.rs +++ b/library/alloc/tests/lib.rs @@ -14,6 +14,7 @@ #![feature(slice_ptr_get)] #![feature(split_inclusive)] #![feature(binary_heap_retain)] +#![feature(deque_range)] #![feature(inplace_iteration)] #![feature(iter_map_while)] diff --git a/library/alloc/tests/string.rs b/library/alloc/tests/string.rs index d38655af78cb7..e2eb042f79172 100644 --- a/library/alloc/tests/string.rs +++ b/library/alloc/tests/string.rs @@ -1,6 +1,7 @@ use std::borrow::Cow; use std::collections::TryReserveError::*; use std::mem::size_of; +use std::ops::Bound::*; pub trait IntoCow<'a, B: ?Sized> where @@ -463,6 +464,20 @@ fn test_drain() { assert_eq!(t, ""); } +#[test] +#[should_panic] +fn test_drain_start_overflow() { + let mut s = String::from("abc"); + s.drain((Excluded(usize::MAX), Included(0))); +} + +#[test] +#[should_panic] +fn test_drain_end_overflow() { + let mut s = String::from("abc"); + s.drain((Included(0), Included(usize::MAX))); +} + #[test] fn test_replace_range() { let mut s = "Hello, world!".to_owned(); @@ -500,6 +515,20 @@ fn test_replace_range_inclusive_out_of_bounds() { s.replace_range(5..=5, "789"); } +#[test] +#[should_panic] +fn test_replace_range_start_overflow() { + let mut s = String::from("123"); + s.replace_range((Excluded(usize::MAX), Included(0)), ""); +} + +#[test] +#[should_panic] +fn test_replace_range_end_overflow() { + let mut s = String::from("456"); + s.replace_range((Included(0), Included(usize::MAX)), ""); +} + #[test] fn test_replace_range_empty() { let mut s = String::from("12345"); diff --git a/library/alloc/tests/vec.rs b/library/alloc/tests/vec.rs index 8e66c8a22cec5..8abebd940d20f 100644 --- a/library/alloc/tests/vec.rs +++ b/library/alloc/tests/vec.rs @@ -3,6 +3,7 @@ use std::collections::TryReserveError::*; use std::fmt::Debug; use std::iter::InPlaceIterable; use std::mem::size_of; +use std::ops::Bound::*; use std::panic::{catch_unwind, AssertUnwindSafe}; use std::rc::Rc; use std::vec::{Drain, IntoIter}; @@ -566,6 +567,16 @@ fn test_drain_max_vec_size() { assert_eq!(v.len(), usize::MAX - 1); } +#[test] +#[should_panic] +fn test_drain_index_overflow() { + let mut v = Vec::<()>::with_capacity(usize::MAX); + unsafe { + v.set_len(usize::MAX); + } + v.drain(0..=usize::MAX); +} + #[test] #[should_panic] fn test_drain_inclusive_out_of_bounds() { @@ -573,6 +584,20 @@ fn test_drain_inclusive_out_of_bounds() { v.drain(5..=5); } +#[test] +#[should_panic] +fn test_drain_start_overflow() { + let mut v = vec![1, 2, 3]; + v.drain((Excluded(usize::MAX), Included(0))); +} + +#[test] +#[should_panic] +fn test_drain_end_overflow() { + let mut v = vec![1, 2, 3]; + v.drain((Included(0), Included(usize::MAX))); +} + #[test] fn test_drain_leak() { static mut DROPS: i32 = 0; diff --git a/library/alloc/tests/vec_deque.rs b/library/alloc/tests/vec_deque.rs index 762dc4be44d62..46d8a3c4cb493 100644 --- a/library/alloc/tests/vec_deque.rs +++ b/library/alloc/tests/vec_deque.rs @@ -2,6 +2,7 @@ use std::collections::TryReserveError::*; use std::collections::{vec_deque::Drain, VecDeque}; use std::fmt::Debug; use std::mem::size_of; +use std::ops::Bound::*; use std::panic::{catch_unwind, AssertUnwindSafe}; use crate::hash; @@ -115,6 +116,20 @@ fn test_index_out_of_bounds() { deq[3]; } +#[test] +#[should_panic] +fn test_range_start_overflow() { + let deq = VecDeque::from(vec![1, 2, 3]); + deq.range((Included(0), Included(usize::MAX))); +} + +#[test] +#[should_panic] +fn test_range_end_overflow() { + let deq = VecDeque::from(vec![1, 2, 3]); + deq.range((Excluded(usize::MAX), Included(0))); +} + #[derive(Clone, PartialEq, Debug)] enum Taggy { One(i32),