Skip to content

Commit 6302512

Browse files
committed
Auto merge of #268 - Amanieu:fix_large_alloc, r=Amanieu
Guard against allocations exceeding isize::MAX Fixes #264
2 parents 90b63b4 + 8fe8f9f commit 6302512

File tree

2 files changed

+16
-3
lines changed

2 files changed

+16
-3
lines changed

src/map.rs

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4644,12 +4644,16 @@ mod test_map {
46444644
panic!("usize::MAX should trigger an overflow!");
46454645
}
46464646

4647-
if let Err(AllocError { .. }) = empty_bytes.try_reserve(MAX_USIZE / 8) {
4647+
if let Err(AllocError { .. }) = empty_bytes.try_reserve(MAX_USIZE / 16) {
46484648
} else {
46494649
// This may succeed if there is enough free memory. Attempt to
4650-
// allocate a second hashmap to ensure the allocation will fail.
4650+
// allocate a few more hashmaps to ensure the allocation will fail.
46514651
let mut empty_bytes2: HashMap<u8, u8> = HashMap::new();
4652-
if let Err(AllocError { .. }) = empty_bytes2.try_reserve(MAX_USIZE / 8) {
4652+
let _ = empty_bytes2.try_reserve(MAX_USIZE / 16);
4653+
let mut empty_bytes3: HashMap<u8, u8> = HashMap::new();
4654+
let _ = empty_bytes3.try_reserve(MAX_USIZE / 16);
4655+
let mut empty_bytes4: HashMap<u8, u8> = HashMap::new();
4656+
if let Err(AllocError { .. }) = empty_bytes4.try_reserve(MAX_USIZE / 16) {
46534657
} else {
46544658
panic!("usize::MAX / 8 should trigger an OOM!");
46554659
}

src/raw/mod.rs

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1160,6 +1160,15 @@ impl<A: Allocator + Clone> RawTableInner<A> {
11601160
None => return Err(fallibility.capacity_overflow()),
11611161
};
11621162

1163+
// We need an additional check to ensure that the allocation doesn't
1164+
// exceed `isize::MAX`. We can skip this check on 64-bit systems since
1165+
// such allocations will never succeed anyways.
1166+
//
1167+
// This mirrors what Vec does in the standard library.
1168+
if mem::size_of::<usize>() < 8 && layout.size() > isize::MAX as usize {
1169+
return Err(fallibility.capacity_overflow());
1170+
}
1171+
11631172
let ptr: NonNull<u8> = match do_alloc(&alloc, layout) {
11641173
Ok(block) => block.cast(),
11651174
Err(_) => return Err(fallibility.alloc_err(layout)),

0 commit comments

Comments
 (0)