PathBuf contains this gem:
|
#[inline] |
|
fn as_mut_vec(&mut self) -> &mut Vec<u8> { |
|
unsafe { &mut *(self as *mut PathBuf as *mut Vec<u8>) } |
|
} |
This effectively transmutes an OsString to Vec<u8>. But on Windows, OsString is Wtf8Buf:
|
/// An owned, growable string of well-formed WTF-8 data. |
|
/// |
|
/// Similar to `String`, but can additionally contain surrogate code points |
|
/// if they’re not in a surrogate pair. |
|
#[derive(Eq, PartialEq, Ord, PartialOrd, Clone)] |
|
pub struct Wtf8Buf { |
|
bytes: Vec<u8>, |
|
|
|
/// Do we know that `bytes` holds a valid UTF-8 encoding? We can easily |
|
/// know this if we're constructed from a `String` or `&str`. |
|
/// |
|
/// It is possible for `bytes` to have valid UTF-8 without this being |
|
/// set, such as when we're concatenating `&Wtf8`'s and surrogates become |
|
/// paired, as we don't bother to rescan the entire string. |
|
is_known_utf8: bool, |
|
} |
This is not repr(transparent), so there is no guarantee that we can just transmute this. And I think with layout randomization this can actually fail -- that's probably what happened here.
Is there a reason why this uses transmutes rather than some sort of private accessor that exposes a *mut Vec<u8> through all these layers?
PathBuf contains this gem:
rust/library/std/src/path.rs
Lines 1172 to 1175 in f56afa0
This effectively transmutes an
OsStringtoVec<u8>. But on Windows,OsStringisWtf8Buf:rust/library/std/src/sys_common/wtf8.rs
Lines 131 to 146 in 51a7396
This is not
repr(transparent), so there is no guarantee that we can just transmute this. And I think with layout randomization this can actually fail -- that's probably what happened here.Is there a reason why this uses transmutes rather than some sort of private accessor that exposes a
*mut Vec<u8>through all these layers?