Skip to content

Commit

Permalink
deny(unsafe_op_in_unsafe_fn) in libstd/path.rs
Browse files Browse the repository at this point in the history
  • Loading branch information
hellow554 committed Jul 2, 2020
1 parent 9491f18 commit 6e75a50
Showing 1 changed file with 19 additions and 20 deletions.
39 changes: 19 additions & 20 deletions src/libstd/path.rs
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,7 @@
//! [`OsStr`]: ../../std/ffi/struct.OsStr.html

#![stable(feature = "rust1", since = "1.0.0")]
#![deny(unsafe_op_in_unsafe_fn)]

use crate::borrow::{Borrow, Cow};
use crate::cmp;
Expand Down Expand Up @@ -301,7 +302,8 @@ fn os_str_as_u8_slice(s: &OsStr) -> &[u8] {
unsafe { &*(s as *const OsStr as *const [u8]) }
}
unsafe fn u8_slice_as_os_str(s: &[u8]) -> &OsStr {
&*(s as *const [u8] as *const OsStr)
// SAFETY: see the comment of `os_str_as_u8_slice`
unsafe { &*(s as *const [u8] as *const OsStr) }
}

// Detect scheme on Redox
Expand All @@ -321,24 +323,21 @@ fn has_physical_root(s: &[u8], prefix: Option<Prefix<'_>>) -> bool {

// basic workhorse for splitting stem and extension
fn split_file_at_dot(file: &OsStr) -> (Option<&OsStr>, Option<&OsStr>) {
unsafe {
if os_str_as_u8_slice(file) == b".." {
return (Some(file), None);
}

// The unsafety here stems from converting between &OsStr and &[u8]
// and back. This is safe to do because (1) we only look at ASCII
// contents of the encoding and (2) new &OsStr values are produced
// only from ASCII-bounded slices of existing &OsStr values.

let mut iter = os_str_as_u8_slice(file).rsplitn(2, |b| *b == b'.');
let after = iter.next();
let before = iter.next();
if before == Some(b"") {
(Some(file), None)
} else {
(before.map(|s| u8_slice_as_os_str(s)), after.map(|s| u8_slice_as_os_str(s)))
}
if os_str_as_u8_slice(file) == b".." {
return (Some(file), None);
}

// The unsafety here stems from converting between &OsStr and &[u8]
// and back. This is safe to do because (1) we only look at ASCII
// contents of the encoding and (2) new &OsStr values are produced
// only from ASCII-bounded slices of existing &OsStr values.
let mut iter = os_str_as_u8_slice(file).rsplitn(2, |b| *b == b'.');
let after = iter.next();
let before = iter.next();
if before == Some(b"") {
(Some(file), None)
} else {
unsafe { (before.map(|s| u8_slice_as_os_str(s)), after.map(|s| u8_slice_as_os_str(s))) }
}
}

Expand Down Expand Up @@ -1755,7 +1754,7 @@ impl Path {
// The following (private!) function allows construction of a path from a u8
// slice, which is only safe when it is known to follow the OsStr encoding.
unsafe fn from_u8_slice(s: &[u8]) -> &Path {
Path::new(u8_slice_as_os_str(s))
unsafe { Path::new(u8_slice_as_os_str(s)) }
}
// The following (private!) function reveals the byte encoding used for OsStr.
fn as_u8_slice(&self) -> &[u8] {
Expand Down

0 comments on commit 6e75a50

Please sign in to comment.