From 36d663fcfc7a219f034ecdd219f03517e17db62d Mon Sep 17 00:00:00 2001 From: Nikolai Vazquez Date: Wed, 27 Sep 2017 14:56:20 -0400 Subject: [PATCH 1/9] Remove mem::transmute used in Box conversions --- src/liballoc/boxed.rs | 4 +--- src/liballoc/str.rs | 8 +++----- 2 files changed, 4 insertions(+), 8 deletions(-) diff --git a/src/liballoc/boxed.rs b/src/liballoc/boxed.rs index 4341b0b2975be..35c8530b4dd7d 100644 --- a/src/liballoc/boxed.rs +++ b/src/liballoc/boxed.rs @@ -528,9 +528,7 @@ impl<'a> From<&'a str> for Box { #[stable(feature = "boxed_str_conv", since = "1.19.0")] impl From> for Box<[u8]> { fn from(s: Box) -> Self { - unsafe { - mem::transmute(s) - } + unsafe { Box::from_raw(Box::into_raw(s) as *mut [u8]) } } } diff --git a/src/liballoc/str.rs b/src/liballoc/str.rs index 62b5f13675c23..830128f2b9fcb 100644 --- a/src/liballoc/str.rs +++ b/src/liballoc/str.rs @@ -2047,10 +2047,8 @@ impl str { /// ``` #[stable(feature = "box_str", since = "1.4.0")] pub fn into_string(self: Box) -> String { - unsafe { - let slice = mem::transmute::, Box<[u8]>>(self); - String::from_utf8_unchecked(slice.into_vec()) - } + let slice = Box::<[u8]>::from(self); + unsafe { String::from_utf8_unchecked(slice.into_vec()) } } /// Create a [`String`] by repeating a string `n` times. @@ -2087,5 +2085,5 @@ impl str { /// ``` #[stable(feature = "str_box_extras", since = "1.20.0")] pub unsafe fn from_boxed_utf8_unchecked(v: Box<[u8]>) -> Box { - mem::transmute(v) + Box::from_raw(Box::into_raw(v) as *mut str) } From 6d14512fd9adde3c86d592c14b8b04e01696e972 Mon Sep 17 00:00:00 2001 From: Nikolai Vazquez Date: Thu, 28 Sep 2017 00:51:38 -0400 Subject: [PATCH 2/9] Remove mem::transmute used in CStr conversions --- src/libstd/ffi/c_str.rs | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/src/libstd/ffi/c_str.rs b/src/libstd/ffi/c_str.rs index 7992aefcb4203..2f962416ffce6 100644 --- a/src/libstd/ffi/c_str.rs +++ b/src/libstd/ffi/c_str.rs @@ -312,7 +312,7 @@ impl CString { pub unsafe fn from_raw(ptr: *mut c_char) -> CString { let len = libc::strlen(ptr) + 1; // Including the NUL byte let slice = slice::from_raw_parts(ptr, len as usize); - CString { inner: mem::transmute(slice) } + CString { inner: Box::from_raw(slice as *mut [c_char] as *mut [u8]) } } /// Transfers ownership of the string to a C caller. @@ -480,7 +480,7 @@ impl CString { /// ``` #[stable(feature = "into_boxed_c_str", since = "1.20.0")] pub fn into_boxed_c_str(self) -> Box { - unsafe { mem::transmute(self.into_inner()) } + unsafe { Box::from_raw(Box::into_raw(self.into_inner()) as *mut CStr) } } // Bypass "move out of struct which implements [`Drop`] trait" restriction. @@ -569,7 +569,7 @@ impl Borrow for CString { impl<'a> From<&'a CStr> for Box { fn from(s: &'a CStr) -> Box { let boxed: Box<[u8]> = Box::from(s.to_bytes_with_nul()); - unsafe { mem::transmute(boxed) } + unsafe { Box::from_raw(Box::into_raw(boxed) as *mut CStr) } } } @@ -593,7 +593,7 @@ impl From for Box { impl Default for Box { fn default() -> Box { let boxed: Box<[u8]> = Box::from([0]); - unsafe { mem::transmute(boxed) } + unsafe { Box::from_raw(Box::into_raw(boxed) as *mut CStr) } } } @@ -817,7 +817,7 @@ impl CStr { #[inline] #[stable(feature = "cstr_from_bytes", since = "1.10.0")] pub unsafe fn from_bytes_with_nul_unchecked(bytes: &[u8]) -> &CStr { - mem::transmute(bytes) + &*(bytes as *const [u8] as *const CStr) } /// Returns the inner pointer to this C string. @@ -913,7 +913,7 @@ impl CStr { #[inline] #[stable(feature = "rust1", since = "1.0.0")] pub fn to_bytes_with_nul(&self) -> &[u8] { - unsafe { mem::transmute(&self.inner) } + unsafe { &*(&self.inner as *const [c_char] as *const [u8]) } } /// Yields a [`&str`] slice if the `CStr` contains valid UTF-8. @@ -1005,7 +1005,8 @@ impl CStr { /// ``` #[stable(feature = "into_boxed_c_str", since = "1.20.0")] pub fn into_c_string(self: Box) -> CString { - unsafe { mem::transmute(self) } + let raw = Box::into_raw(self) as *mut [u8]; + CString { inner: unsafe { Box::from_raw(raw) } } } } From 755fd29b60484e550b7fd52985b05a42442e8993 Mon Sep 17 00:00:00 2001 From: Nikolai Vazquez Date: Thu, 28 Sep 2017 07:56:35 -0400 Subject: [PATCH 3/9] Fix mutability error in CString::from_raw --- src/libstd/ffi/c_str.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libstd/ffi/c_str.rs b/src/libstd/ffi/c_str.rs index 2f962416ffce6..f9d803364772f 100644 --- a/src/libstd/ffi/c_str.rs +++ b/src/libstd/ffi/c_str.rs @@ -311,7 +311,7 @@ impl CString { #[stable(feature = "cstr_memory", since = "1.4.0")] pub unsafe fn from_raw(ptr: *mut c_char) -> CString { let len = libc::strlen(ptr) + 1; // Including the NUL byte - let slice = slice::from_raw_parts(ptr, len as usize); + let slice = slice::from_raw_parts_mut(ptr, len as usize); CString { inner: Box::from_raw(slice as *mut [c_char] as *mut [u8]) } } From 33eaa94f90932b282cd81ff17ff6de287c34d4c7 Mon Sep 17 00:00:00 2001 From: Nikolai Vazquez Date: Thu, 28 Sep 2017 08:07:49 -0400 Subject: [PATCH 4/9] Remove mem::transmute used in OsStr conversions --- src/libstd/ffi/os_str.rs | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-) diff --git a/src/libstd/ffi/os_str.rs b/src/libstd/ffi/os_str.rs index a40a9329ed9bf..e7558c3c02266 100644 --- a/src/libstd/ffi/os_str.rs +++ b/src/libstd/ffi/os_str.rs @@ -260,7 +260,8 @@ impl OsString { /// ``` #[stable(feature = "into_boxed_os_str", since = "1.20.0")] pub fn into_boxed_os_str(self) -> Box { - unsafe { mem::transmute(self.inner.into_box()) } + let rw = Box::into_raw(self.inner.into_box()) as *mut OsStr; + unsafe { Box::from_raw(rw) } } } @@ -394,7 +395,7 @@ impl OsStr { } fn from_inner(inner: &Slice) -> &OsStr { - unsafe { mem::transmute(inner) } + unsafe { &*(inner as *const Slice as *const OsStr) } } /// Yields a [`&str`] slice if the `OsStr` is valid Unicode. @@ -511,8 +512,8 @@ impl OsStr { /// [`OsString`]: struct.OsString.html #[stable(feature = "into_boxed_os_str", since = "1.20.0")] pub fn into_os_string(self: Box) -> OsString { - let inner: Box = unsafe { mem::transmute(self) }; - OsString { inner: Buf::from_box(inner) } + let boxed = unsafe { Box::from_raw(Box::into_raw(self) as *mut Slice) }; + OsString { inner: Buf::from_box(boxed) } } /// Gets the underlying byte representation. @@ -520,14 +521,15 @@ impl OsStr { /// Note: it is *crucial* that this API is private, to avoid /// revealing the internal, platform-specific encodings. fn bytes(&self) -> &[u8] { - unsafe { mem::transmute(&self.inner) } + &self.inner.inner } } #[stable(feature = "box_from_os_str", since = "1.17.0")] impl<'a> From<&'a OsStr> for Box { fn from(s: &'a OsStr) -> Box { - unsafe { mem::transmute(s.inner.into_box()) } + let rw = Box::into_raw(s.inner.into_box()) as *mut OsStr; + unsafe { Box::from_raw(rw) } } } @@ -548,7 +550,8 @@ impl From for Box { #[stable(feature = "box_default_extra", since = "1.17.0")] impl Default for Box { fn default() -> Box { - unsafe { mem::transmute(Slice::empty_box()) } + let rw = Box::into_raw(Slice::empty_box()) as *mut OsStr; + unsafe { Box::from_raw(rw) } } } From 627998e86fa7198e235e2aa1963dc59f6b3a017a Mon Sep 17 00:00:00 2001 From: Nikolai Vazquez Date: Thu, 28 Sep 2017 08:43:06 -0400 Subject: [PATCH 5/9] Remove unused 'mem' import in 'os_str' module --- src/libstd/ffi/os_str.rs | 1 - 1 file changed, 1 deletion(-) diff --git a/src/libstd/ffi/os_str.rs b/src/libstd/ffi/os_str.rs index e7558c3c02266..cfa9ecca01916 100644 --- a/src/libstd/ffi/os_str.rs +++ b/src/libstd/ffi/os_str.rs @@ -10,7 +10,6 @@ use borrow::{Borrow, Cow}; use fmt; -use mem; use ops; use cmp; use hash::{Hash, Hasher}; From 48c20b6a50a4e4b589764cb4385ded7988abd7a9 Mon Sep 17 00:00:00 2001 From: Nikolai Vazquez Date: Thu, 28 Sep 2017 10:29:58 -0400 Subject: [PATCH 6/9] Remove mem::transmute used in Path conversions --- src/libstd/path.rs | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/src/libstd/path.rs b/src/libstd/path.rs index 830b9dc475d6d..765cdc29a9f8d 100644 --- a/src/libstd/path.rs +++ b/src/libstd/path.rs @@ -317,10 +317,10 @@ fn iter_after(mut iter: I, mut prefix: J) -> Option // See note at the top of this module to understand why these are used: fn os_str_as_u8_slice(s: &OsStr) -> &[u8] { - unsafe { mem::transmute(s) } + unsafe { &*(s as *const OsStr as *const [u8]) } } unsafe fn u8_slice_as_os_str(s: &[u8]) -> &OsStr { - mem::transmute(s) + &*(s as *const [u8] as *const OsStr) } // Detect scheme on Redox @@ -1334,15 +1334,16 @@ impl PathBuf { /// [`Path`]: struct.Path.html #[stable(feature = "into_boxed_path", since = "1.20.0")] pub fn into_boxed_path(self) -> Box { - unsafe { mem::transmute(self.inner.into_boxed_os_str()) } + let rw = Box::into_raw(self.inner.into_boxed_os_str()) as *mut Path; + unsafe { Box::from_raw(rw) } } } #[stable(feature = "box_from_path", since = "1.17.0")] impl<'a> From<&'a Path> for Box { fn from(path: &'a Path) -> Box { - let boxed: Box = path.inner.into(); - unsafe { mem::transmute(boxed) } + let rw = Box::into_raw(Box::from(&path.inner)) as *mut Path; + unsafe { Box::from_raw(rw) } } } @@ -1589,7 +1590,7 @@ impl Path { /// ``` #[stable(feature = "rust1", since = "1.0.0")] pub fn new + ?Sized>(s: &S) -> &Path { - unsafe { mem::transmute(s.as_ref()) } + unsafe { &*(s.as_ref() as *const OsStr as *const Path) } } /// Yields the underlying [`OsStr`] slice. @@ -2312,8 +2313,8 @@ impl Path { /// [`PathBuf`]: struct.PathBuf.html #[stable(feature = "into_boxed_path", since = "1.20.0")] pub fn into_path_buf(self: Box) -> PathBuf { - let inner: Box = unsafe { mem::transmute(self) }; - PathBuf { inner: OsString::from(inner) } + let rw = Box::into_raw(self) as *mut OsStr; + unsafe { Box::from_raw(rw) } } } From c7b4a96909e535cbd61b9357740ed22c9bbb7ea6 Mon Sep 17 00:00:00 2001 From: Nikolai Vazquez Date: Thu, 28 Sep 2017 10:30:41 -0400 Subject: [PATCH 7/9] Remove unused 'mem' import in 'path' module --- src/libstd/path.rs | 1 - 1 file changed, 1 deletion(-) diff --git a/src/libstd/path.rs b/src/libstd/path.rs index 765cdc29a9f8d..9003b368ebe9e 100644 --- a/src/libstd/path.rs +++ b/src/libstd/path.rs @@ -86,7 +86,6 @@ use fs; use hash::{Hash, Hasher}; use io; use iter::{self, FusedIterator}; -use mem; use ops::{self, Deref}; use ffi::{OsStr, OsString}; From cb2a656cdfb6400ac0200c661267f91fabf237e2 Mon Sep 17 00:00:00 2001 From: Nikolai Vazquez Date: Thu, 28 Sep 2017 10:59:12 -0400 Subject: [PATCH 8/9] Fix errors in Box conversions --- src/libstd/path.rs | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/libstd/path.rs b/src/libstd/path.rs index 9003b368ebe9e..294743ed2cc54 100644 --- a/src/libstd/path.rs +++ b/src/libstd/path.rs @@ -1341,7 +1341,8 @@ impl PathBuf { #[stable(feature = "box_from_path", since = "1.17.0")] impl<'a> From<&'a Path> for Box { fn from(path: &'a Path) -> Box { - let rw = Box::into_raw(Box::from(&path.inner)) as *mut Path; + let boxed: Box = path.inner.into(); + let rw = Box::into_raw(boxed) as *mut Path; unsafe { Box::from_raw(rw) } } } @@ -2313,7 +2314,8 @@ impl Path { #[stable(feature = "into_boxed_path", since = "1.20.0")] pub fn into_path_buf(self: Box) -> PathBuf { let rw = Box::into_raw(self) as *mut OsStr; - unsafe { Box::from_raw(rw) } + let inner = unsafe { Box::from_raw(rw) }; + PathBuf { inner: OsString::from(inner) } } } From f1798d3c9ab22be8f3b6f9f60f5e027be1a02085 Mon Sep 17 00:00:00 2001 From: Nikolai Vazquez Date: Sat, 30 Sep 2017 10:01:41 -0400 Subject: [PATCH 9/9] Cast inner type in OsStr::bytes The innermost type is not [u8] on all platforms but is assumed to have the same memory layout as [u8] since this conversion was done via mem::transmute before. --- src/libstd/ffi/os_str.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libstd/ffi/os_str.rs b/src/libstd/ffi/os_str.rs index cfa9ecca01916..88ee5c9a73420 100644 --- a/src/libstd/ffi/os_str.rs +++ b/src/libstd/ffi/os_str.rs @@ -520,7 +520,7 @@ impl OsStr { /// Note: it is *crucial* that this API is private, to avoid /// revealing the internal, platform-specific encodings. fn bytes(&self) -> &[u8] { - &self.inner.inner + unsafe { &*(&self.inner as *const _ as *const [u8]) } } }