Merge pull request #508 from fpdotmonkey/vec-layout-array-chk

Use the newest Layout::array size checks for vec-alloc
pull/510/head
Yuki Okushi 3 weeks ago committed by GitHub
commit 28f4ae6967
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194

@ -170,20 +170,17 @@ use std::alloc::{self, Layout};
impl<T> Vec<T> { impl<T> Vec<T> {
fn grow(&mut self) { fn grow(&mut self) {
let (new_cap, new_layout) = if self.cap == 0 { let (new_cap, new_layout) = if self.cap == 0 {
(1, Layout::array::<T>(1).unwrap()) (1, Layout::array::<T>(1))
} else { } else {
// This can't overflow since self.cap <= isize::MAX. // This can't overflow since self.cap <= isize::MAX.
let new_cap = 2 * self.cap; let new_cap = 2 * self.cap;
(new_cap, Layout::array::<T>(new_cap))
// `Layout::array` checks that the number of bytes is <= usize::MAX,
// but this is redundant since old_layout.size() <= isize::MAX,
// so the `unwrap` should never fail.
let new_layout = Layout::array::<T>(new_cap).unwrap();
(new_cap, new_layout)
}; };
// Ensure that the new allocation doesn't exceed `isize::MAX` bytes. // `Layout::array` checks that the number of bytes allocated is
assert!(new_layout.size() <= isize::MAX as usize, "Allocation too large"); // in 1..=isize::MAX and will error otherwise. An allocation of
// 0 bytes isn't possible thanks to the above condition.
let new_layout = new_layout.expect("Allocation too large");
let new_ptr = if self.cap == 0 { let new_ptr = if self.cap == 0 {
unsafe { alloc::alloc(new_layout) } unsafe { alloc::alloc(new_layout) }

@ -33,23 +33,17 @@ impl<T> RawVec<T> {
assert!(mem::size_of::<T>() != 0, "capacity overflow"); assert!(mem::size_of::<T>() != 0, "capacity overflow");
let (new_cap, new_layout) = if self.cap == 0 { let (new_cap, new_layout) = if self.cap == 0 {
(1, Layout::array::<T>(1).unwrap()) (1, Layout::array::<T>(1))
} else { } else {
// This can't overflow because we ensure self.cap <= isize::MAX. // This can't overflow since self.cap <= isize::MAX.
let new_cap = 2 * self.cap; let new_cap = 2 * self.cap;
(new_cap, Layout::array::<T>(new_cap))
// `Layout::array` checks that the number of bytes is <= usize::MAX,
// but this is redundant since old_layout.size() <= isize::MAX,
// so the `unwrap` should never fail.
let new_layout = Layout::array::<T>(new_cap).unwrap();
(new_cap, new_layout)
}; };
// Ensure that the new allocation doesn't exceed `isize::MAX` bytes. // `Layout::array` checks that the number of bytes allocated is
assert!( // in 1..=isize::MAX and will error otherwise. An allocation of
new_layout.size() <= isize::MAX as usize, // 0 bytes isn't possible thanks to the above condition.
"Allocation too large" let new_layout = new_layout.expect("Allocation too large");
);
let new_ptr = if self.cap == 0 { let new_ptr = if self.cap == 0 {
unsafe { alloc::alloc(new_layout) } unsafe { alloc::alloc(new_layout) }

Loading…
Cancel
Save