diff options
| author | Mazdak Farrokhzad <twingoow@gmail.com> | 2019-05-28 11:48:58 +0200 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2019-05-28 11:48:58 +0200 |
| commit | 460e626a9cf5c2bec4dba8752de18aebae4c0c93 (patch) | |
| tree | 63e66d375893b3bfde1e68ab0ae591d6d0773401 /src/liballoc | |
| parent | c48835ba190f04bee41ca7c901adc9a23077e787 (diff) | |
| parent | fe31ad38cb5c6fba5be871ab63082d7cdf430374 (diff) | |
| download | rust-460e626a9cf5c2bec4dba8752de18aebae4c0c93.tar.gz rust-460e626a9cf5c2bec4dba8752de18aebae4c0c93.zip | |
Rollup merge of #61230 - matklad:ub-comment, r=RalfJung
avoid creating Boxes of uninitalized values in RawVec `RawVec<bool>::into_box` is definitely instant UB, if not all values are initialized. See https://gankro.github.io/blah/initialize-me-maybe/
Diffstat (limited to 'src/liballoc')
| -rw-r--r-- | src/liballoc/boxed.rs | 16 | ||||
| -rw-r--r-- | src/liballoc/raw_vec.rs | 10 |
2 files changed, 15 insertions, 11 deletions
diff --git a/src/liballoc/boxed.rs b/src/liballoc/boxed.rs index bf8f5b8b91a..76b660fba68 100644 --- a/src/liballoc/boxed.rs +++ b/src/liballoc/boxed.rs @@ -395,11 +395,10 @@ impl<T: Clone> Clone for Box<T> { #[stable(feature = "box_slice_clone", since = "1.3.0")] impl Clone for Box<str> { fn clone(&self) -> Self { - let len = self.len(); - let buf = RawVec::with_capacity(len); + // this makes a copy of the data + let buf: Box<[u8]> = self.as_bytes().into(); unsafe { - ptr::copy_nonoverlapping(self.as_ptr(), buf.ptr(), len); - from_boxed_utf8_unchecked(buf.into_box()) + from_boxed_utf8_unchecked(buf) } } } @@ -546,9 +545,12 @@ impl<T: Copy> From<&[T]> for Box<[T]> { /// println!("{:?}", boxed_slice); /// ``` fn from(slice: &[T]) -> Box<[T]> { - let mut boxed = unsafe { RawVec::with_capacity(slice.len()).into_box() }; - boxed.copy_from_slice(slice); - boxed + let len = slice.len(); + let buf = RawVec::with_capacity(len); + unsafe { + ptr::copy_nonoverlapping(slice.as_ptr(), buf.ptr(), len); + buf.into_box() + } } } diff --git a/src/liballoc/raw_vec.rs b/src/liballoc/raw_vec.rs index d1fc5ac3b30..0454a564435 100644 --- a/src/liballoc/raw_vec.rs +++ b/src/liballoc/raw_vec.rs @@ -685,12 +685,14 @@ impl<T, A: Alloc> RawVec<T, A> { impl<T> RawVec<T, Global> { /// Converts the entire buffer into `Box<[T]>`. /// - /// While it is not *strictly* Undefined Behavior to call - /// this procedure while some of the RawVec is uninitialized, - /// it certainly makes it trivial to trigger it. - /// /// Note that this will correctly reconstitute any `cap` changes /// that may have been performed. (see description of type for details) + /// + /// # Undefined Behavior + /// + /// All elements of `RawVec<T, Global>` must be initialized. Notice that + /// the rules around uninitialized boxed values are not finalized yet, + /// but until they are, it is advisable to avoid them. pub unsafe fn into_box(self) -> Box<[T]> { // NOTE: not calling `cap()` here, actually using the real `cap` field! let slice = slice::from_raw_parts_mut(self.ptr(), self.cap); |
