about summary refs log tree commit diff
diff options
context:
space:
mode:
authorDylan DPC <dylan.dpc@gmail.com>2020-09-16 01:30:30 +0200
committerGitHub <noreply@github.com>2020-09-16 01:30:30 +0200
commitfb9bb2b5ca517d85e1041ea9f80d06f48054624c (patch)
treef4f791d8da5b4ebe8ca370fb274eaeac7d0c03bf
parent4f0c245429a0a42ea652b85a5390203bd6a12bbc (diff)
parentf8cfb2f5ad847b871399dfef9b8b8ff4e84a75cb (diff)
downloadrust-fb9bb2b5ca517d85e1041ea9f80d06f48054624c.tar.gz
rust-fb9bb2b5ca517d85e1041ea9f80d06f48054624c.zip
Rollup merge of #75146 - tmiasko:range-overflow, r=Mark-Simulacrum
Detect overflow in proc_macro_server subspan

* Detect overflow in proc_macro_server subspan
* Add tests for overflow in Vec::drain
* Add tests for overflow in String / VecDeque operations using ranges
-rw-r--r--compiler/rustc_expand/src/proc_macro_server.rs4
-rw-r--r--library/alloc/tests/lib.rs1
-rw-r--r--library/alloc/tests/string.rs29
-rw-r--r--library/alloc/tests/vec.rs25
-rw-r--r--library/alloc/tests/vec_deque.rs15
5 files changed, 72 insertions, 2 deletions
diff --git a/compiler/rustc_expand/src/proc_macro_server.rs b/compiler/rustc_expand/src/proc_macro_server.rs
index ec41fd7a3ee..4cfb188783b 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 590639d9834..03737e1ef1f 100644
--- a/library/alloc/tests/lib.rs
+++ b/library/alloc/tests/lib.rs
@@ -15,6 +15,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 f7f78046d08..7ba1c2c6116 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
@@ -468,6 +469,20 @@ fn test_drain() {
 }
 
 #[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();
     s.replace_range(7..12, "世界");
@@ -505,6 +520,20 @@ fn test_replace_range_inclusive_out_of_bounds() {
 }
 
 #[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");
     s.replace_range(1..2, "");
diff --git a/library/alloc/tests/vec.rs b/library/alloc/tests/vec.rs
index 608a3c9bdf7..563dd7ab645 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};
@@ -647,12 +648,36 @@ fn test_drain_max_vec_size() {
 
 #[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() {
     let mut v = vec![1, 2, 3, 4, 5];
     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 762dc4be44d..46d8a3c4cb4 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),