summary refs log tree commit diff
path: root/library/alloc/src
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2022-02-22 20:50:38 +0000
committerbors <bors@rust-lang.org>2022-02-22 20:50:38 +0000
commit5bd1ec3283874b97b27da4539b2950fbd01c4b0e (patch)
tree5642d3a3c816dfd39caf9fdd11d3274a8bbe4ba8 /library/alloc/src
parent68369a041cea809a87e5bd80701da90e0e0a4799 (diff)
parent5376317c7f39c41250f354d6c35858bd383d1970 (diff)
downloadrust-5bd1ec3283874b97b27da4539b2950fbd01c4b0e.tar.gz
rust-5bd1ec3283874b97b27da4539b2950fbd01c4b0e.zip
Auto merge of #83706 - a1phyr:fix_vec_layout_calculation, r=JohnTitor
Fix a layout possible miscalculation in `alloc::RawVec`

A layout miscalculation could happen in `RawVec` when used with a type whose size isn't a multiple of its alignment. I don't know if such type can exist in Rust, but the Layout API provides ways to manipulate such types. Anyway, it is better to calculate memory size in a consistent way.
Diffstat (limited to 'library/alloc/src')
-rw-r--r--library/alloc/src/raw_vec.rs9
1 files changed, 4 insertions, 5 deletions
diff --git a/library/alloc/src/raw_vec.rs b/library/alloc/src/raw_vec.rs
index 8fa0242ca9a..0ce2beb63d6 100644
--- a/library/alloc/src/raw_vec.rs
+++ b/library/alloc/src/raw_vec.rs
@@ -244,9 +244,7 @@ impl<T, A: Allocator> RawVec<T, A> {
             // We have an allocated chunk of memory, so we can bypass runtime
             // checks to get our current layout.
             unsafe {
-                let align = mem::align_of::<T>();
-                let size = mem::size_of::<T>() * self.cap;
-                let layout = Layout::from_size_align_unchecked(size, align);
+                let layout = Layout::array::<T>(self.cap).unwrap_unchecked();
                 Some((self.ptr.cast().into(), layout))
             }
         }
@@ -427,10 +425,11 @@ impl<T, A: Allocator> RawVec<T, A> {
         assert!(cap <= self.capacity(), "Tried to shrink to a larger capacity");
 
         let (ptr, layout) = if let Some(mem) = self.current_memory() { mem } else { return Ok(()) };
-        let new_size = cap * mem::size_of::<T>();
 
         let ptr = unsafe {
-            let new_layout = Layout::from_size_align_unchecked(new_size, layout.align());
+            // `Layout::array` cannot overflow here because it would have
+            // overflowed earlier when capacity was larger.
+            let new_layout = Layout::array::<T>(cap).unwrap_unchecked();
             self.alloc
                 .shrink(ptr, layout, new_layout)
                 .map_err(|_| AllocError { layout: new_layout, non_exhaustive: () })?