Skip to content

OsStrExt3 transmutes from an &[u8] to a OsStr #1524

Closed
@BurntSushi

Description

In this code:

clap/src/osstringext.rs

Lines 23 to 32 in 784524f

#[cfg(any(target_os = "windows", target_arch = "wasm32"))]
impl OsStrExt3 for OsStr {
fn from_bytes(b: &[u8]) -> &Self {
use std::mem;
unsafe { mem::transmute(b) }
}
fn as_bytes(&self) -> &[u8] {
self.to_str().map(|s| s.as_bytes()).expect(INVALID_UTF8)
}
}

the transmute casts the &[u8] to a &OsStr. There are a couple problems with this:

  1. This is not actually a safe thing to do, since &[u8] can be an arbitrary sequence of bytes, where as &OsStr cannot on Windows. On Windows, it internally is WTF-8 and it's not clear what, if anything, goes wrong when it isn't WTF-8. (But if it isn't WTF-8, then it could very well break a perfectly valid internal invariant that leads to UB.) A plausible alternative is to make from_bytes unsafe.
  2. The fact that an &OsStr is internally a &[u8] on Windows that is WTF-8 is an implementation detail, and could actually change, leading to an incorrect transmute.

Is this code still present in clap 3? If so, could someone explain the motivation for this? I'd be happy to try to help brainstorm ways of removing it.

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions