Skip to content

Commit fb9bb2b

Browse files
authored
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
2 parents 4f0c245 + f8cfb2f commit fb9bb2b

File tree

5 files changed

+72
-2
lines changed

5 files changed

+72
-2
lines changed

Diff for: compiler/rustc_expand/src/proc_macro_server.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -584,12 +584,12 @@ impl server::Literal for Rustc<'_> {
584584

585585
let start = match start {
586586
Bound::Included(lo) => lo,
587-
Bound::Excluded(lo) => lo + 1,
587+
Bound::Excluded(lo) => lo.checked_add(1)?,
588588
Bound::Unbounded => 0,
589589
};
590590

591591
let end = match end {
592-
Bound::Included(hi) => hi + 1,
592+
Bound::Included(hi) => hi.checked_add(1)?,
593593
Bound::Excluded(hi) => hi,
594594
Bound::Unbounded => length,
595595
};

Diff for: library/alloc/tests/lib.rs

+1
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
#![feature(slice_ptr_get)]
1616
#![feature(split_inclusive)]
1717
#![feature(binary_heap_retain)]
18+
#![feature(deque_range)]
1819
#![feature(inplace_iteration)]
1920
#![feature(iter_map_while)]
2021

Diff for: library/alloc/tests/string.rs

+29
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
use std::borrow::Cow;
22
use std::collections::TryReserveError::*;
33
use std::mem::size_of;
4+
use std::ops::Bound::*;
45

56
pub trait IntoCow<'a, B: ?Sized>
67
where
@@ -467,6 +468,20 @@ fn test_drain() {
467468
assert_eq!(t, "");
468469
}
469470

471+
#[test]
472+
#[should_panic]
473+
fn test_drain_start_overflow() {
474+
let mut s = String::from("abc");
475+
s.drain((Excluded(usize::MAX), Included(0)));
476+
}
477+
478+
#[test]
479+
#[should_panic]
480+
fn test_drain_end_overflow() {
481+
let mut s = String::from("abc");
482+
s.drain((Included(0), Included(usize::MAX)));
483+
}
484+
470485
#[test]
471486
fn test_replace_range() {
472487
let mut s = "Hello, world!".to_owned();
@@ -504,6 +519,20 @@ fn test_replace_range_inclusive_out_of_bounds() {
504519
s.replace_range(5..=5, "789");
505520
}
506521

522+
#[test]
523+
#[should_panic]
524+
fn test_replace_range_start_overflow() {
525+
let mut s = String::from("123");
526+
s.replace_range((Excluded(usize::MAX), Included(0)), "");
527+
}
528+
529+
#[test]
530+
#[should_panic]
531+
fn test_replace_range_end_overflow() {
532+
let mut s = String::from("456");
533+
s.replace_range((Included(0), Included(usize::MAX)), "");
534+
}
535+
507536
#[test]
508537
fn test_replace_range_empty() {
509538
let mut s = String::from("12345");

Diff for: library/alloc/tests/vec.rs

+25
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ use std::collections::TryReserveError::*;
33
use std::fmt::Debug;
44
use std::iter::InPlaceIterable;
55
use std::mem::size_of;
6+
use std::ops::Bound::*;
67
use std::panic::{catch_unwind, AssertUnwindSafe};
78
use std::rc::Rc;
89
use std::vec::{Drain, IntoIter};
@@ -645,13 +646,37 @@ fn test_drain_max_vec_size() {
645646
assert_eq!(v.len(), usize::MAX - 1);
646647
}
647648

649+
#[test]
650+
#[should_panic]
651+
fn test_drain_index_overflow() {
652+
let mut v = Vec::<()>::with_capacity(usize::MAX);
653+
unsafe {
654+
v.set_len(usize::MAX);
655+
}
656+
v.drain(0..=usize::MAX);
657+
}
658+
648659
#[test]
649660
#[should_panic]
650661
fn test_drain_inclusive_out_of_bounds() {
651662
let mut v = vec![1, 2, 3, 4, 5];
652663
v.drain(5..=5);
653664
}
654665

666+
#[test]
667+
#[should_panic]
668+
fn test_drain_start_overflow() {
669+
let mut v = vec![1, 2, 3];
670+
v.drain((Excluded(usize::MAX), Included(0)));
671+
}
672+
673+
#[test]
674+
#[should_panic]
675+
fn test_drain_end_overflow() {
676+
let mut v = vec![1, 2, 3];
677+
v.drain((Included(0), Included(usize::MAX)));
678+
}
679+
655680
#[test]
656681
fn test_drain_leak() {
657682
static mut DROPS: i32 = 0;

Diff for: library/alloc/tests/vec_deque.rs

+15
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ use std::collections::TryReserveError::*;
22
use std::collections::{vec_deque::Drain, VecDeque};
33
use std::fmt::Debug;
44
use std::mem::size_of;
5+
use std::ops::Bound::*;
56
use std::panic::{catch_unwind, AssertUnwindSafe};
67

78
use crate::hash;
@@ -115,6 +116,20 @@ fn test_index_out_of_bounds() {
115116
deq[3];
116117
}
117118

119+
#[test]
120+
#[should_panic]
121+
fn test_range_start_overflow() {
122+
let deq = VecDeque::from(vec![1, 2, 3]);
123+
deq.range((Included(0), Included(usize::MAX)));
124+
}
125+
126+
#[test]
127+
#[should_panic]
128+
fn test_range_end_overflow() {
129+
let deq = VecDeque::from(vec![1, 2, 3]);
130+
deq.range((Excluded(usize::MAX), Included(0)));
131+
}
132+
118133
#[derive(Clone, PartialEq, Debug)]
119134
enum Taggy {
120135
One(i32),

0 commit comments

Comments
 (0)