Skip to content

Commit c0247fa

Browse files
committed
Auto merge of #362 - JustForFun88:check_layout_size, r=Amanieu
Check that layout size fits in isize in Layout Since [rust-lang/rust#95295](rust-lang/rust#95295) we need check that Layout `size`, when rounded up to the nearest multiple of `align`, must not overflow isize (i.e., the rounded value must be less than or equal to `isize::MAX`)
2 parents 2a7c322 + ec164bf commit c0247fa

File tree

2 files changed

+18
-16
lines changed

2 files changed

+18
-16
lines changed

src/map.rs

Lines changed: 12 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -8044,27 +8044,32 @@ mod test_map {
80448044
fn test_try_reserve() {
80458045
use crate::TryReserveError::{AllocError, CapacityOverflow};
80468046

8047-
const MAX_USIZE: usize = usize::MAX;
8047+
const MAX_ISIZE: usize = isize::MAX as usize;
80488048

80498049
let mut empty_bytes: HashMap<u8, u8> = HashMap::new();
80508050

8051-
if let Err(CapacityOverflow) = empty_bytes.try_reserve(MAX_USIZE) {
8051+
if let Err(CapacityOverflow) = empty_bytes.try_reserve(usize::MAX) {
80528052
} else {
80538053
panic!("usize::MAX should trigger an overflow!");
80548054
}
80558055

8056-
if let Err(AllocError { .. }) = empty_bytes.try_reserve(MAX_USIZE / 16) {
8056+
if let Err(CapacityOverflow) = empty_bytes.try_reserve(MAX_ISIZE) {
8057+
} else {
8058+
panic!("isize::MAX should trigger an overflow!");
8059+
}
8060+
8061+
if let Err(AllocError { .. }) = empty_bytes.try_reserve(MAX_ISIZE / 5) {
80578062
} else {
80588063
// This may succeed if there is enough free memory. Attempt to
80598064
// allocate a few more hashmaps to ensure the allocation will fail.
80608065
let mut empty_bytes2: HashMap<u8, u8> = HashMap::new();
8061-
let _ = empty_bytes2.try_reserve(MAX_USIZE / 16);
8066+
let _ = empty_bytes2.try_reserve(MAX_ISIZE / 5);
80628067
let mut empty_bytes3: HashMap<u8, u8> = HashMap::new();
8063-
let _ = empty_bytes3.try_reserve(MAX_USIZE / 16);
8068+
let _ = empty_bytes3.try_reserve(MAX_ISIZE / 5);
80648069
let mut empty_bytes4: HashMap<u8, u8> = HashMap::new();
8065-
if let Err(AllocError { .. }) = empty_bytes4.try_reserve(MAX_USIZE / 16) {
8070+
if let Err(AllocError { .. }) = empty_bytes4.try_reserve(MAX_ISIZE / 5) {
80668071
} else {
8067-
panic!("usize::MAX / 8 should trigger an OOM!");
8072+
panic!("isize::MAX / 5 should trigger an OOM!");
80688073
}
80698074
}
80708075
}

src/raw/mod.rs

Lines changed: 6 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -248,6 +248,12 @@ impl TableLayout {
248248
size.checked_mul(buckets)?.checked_add(ctrl_align - 1)? & !(ctrl_align - 1);
249249
let len = ctrl_offset.checked_add(buckets + Group::WIDTH)?;
250250

251+
// We need an additional check to ensure that the allocation doesn't
252+
// exceed `isize::MAX` (https://github.com/rust-lang/rust/pull/95295).
253+
if len > isize::MAX as usize - (ctrl_align - 1) {
254+
return None;
255+
}
256+
251257
Some((
252258
unsafe { Layout::from_size_align_unchecked(len, ctrl_align) },
253259
ctrl_offset,
@@ -1078,15 +1084,6 @@ impl<A: Allocator + Clone> RawTableInner<A> {
10781084
None => return Err(fallibility.capacity_overflow()),
10791085
};
10801086

1081-
// We need an additional check to ensure that the allocation doesn't
1082-
// exceed `isize::MAX`. We can skip this check on 64-bit systems since
1083-
// such allocations will never succeed anyways.
1084-
//
1085-
// This mirrors what Vec does in the standard library.
1086-
if mem::size_of::<usize>() < 8 && layout.size() > isize::MAX as usize {
1087-
return Err(fallibility.capacity_overflow());
1088-
}
1089-
10901087
let ptr: NonNull<u8> = match do_alloc(&alloc, layout) {
10911088
Ok(block) => block.cast(),
10921089
Err(_) => return Err(fallibility.alloc_err(layout)),

0 commit comments

Comments
 (0)