Skip to content

Commit 72b18d0

Browse files
committed
Avoid redundant WTF-8 checks in PathBuf
Eliminate checks for WTF-8 boundaries in `PathBuf::set_extension` and `add_extension`, where joining WTF-8 surrogate halves is impossible. Don't convert the `str` to `OsStr`, because `OsString::push` specializes to skip the joining when given strings.
1 parent 849747b commit 72b18d0

File tree

1 file changed

+12
-10
lines changed

1 file changed

+12
-10
lines changed

library/std/src/path.rs

+12-10
Original file line numberDiff line numberDiff line change
@@ -1508,10 +1508,8 @@ impl PathBuf {
15081508

15091509
fn _set_extension(&mut self, extension: &OsStr) -> bool {
15101510
for &b in extension.as_encoded_bytes() {
1511-
if b < 128 {
1512-
if is_separator(b as char) {
1513-
panic!("extension cannot contain path separators: {:?}", extension);
1514-
}
1511+
if b.is_ascii() && is_separator(b as char) {
1512+
panic!("extension cannot contain path separators: {extension:?}");
15151513
}
15161514
}
15171515

@@ -1526,11 +1524,13 @@ impl PathBuf {
15261524
self.inner.truncate(end_file_stem.wrapping_sub(start));
15271525

15281526
// add the new extension, if any
1529-
let new = extension;
1527+
let new = extension.as_encoded_bytes();
15301528
if !new.is_empty() {
15311529
self.inner.reserve_exact(new.len() + 1);
1532-
self.inner.push(OsStr::new("."));
1533-
self.inner.push(new);
1530+
self.inner.push(".");
1531+
// SAFETY: Since a UTF-8 string was just pushed, it is not possible
1532+
// for the buffer to end with a surrogate half.
1533+
unsafe { self.inner.extend_from_slice_unchecked(new) };
15341534
}
15351535

15361536
true
@@ -1587,7 +1587,7 @@ impl PathBuf {
15871587
Some(f) => f.as_encoded_bytes(),
15881588
};
15891589

1590-
let new = extension;
1590+
let new = extension.as_encoded_bytes();
15911591
if !new.is_empty() {
15921592
// truncate until right after the file name
15931593
// this is necessary for trimming the trailing slash
@@ -1597,8 +1597,10 @@ impl PathBuf {
15971597

15981598
// append the new extension
15991599
self.inner.reserve_exact(new.len() + 1);
1600-
self.inner.push(OsStr::new("."));
1601-
self.inner.push(new);
1600+
self.inner.push(".");
1601+
// SAFETY: Since a UTF-8 string was just pushed, it is not possible
1602+
// for the buffer to end with a surrogate half.
1603+
unsafe { self.inner.extend_from_slice_unchecked(new) };
16021604
}
16031605

16041606
true

0 commit comments

Comments
 (0)