Validate extension in PathBuf::add_extension

The extension is validated in `PathBuf::set_extension`, but not
`add_extension`. Fix that. Check for both / and \ path separators on
Windows, even when the path is verbatim, since this is logically like
`PathBuf::push` which normalizes separators (i.e., keeping the current
behavior).
This commit is contained in:
Thalia Archibald
2025-04-22 05:10:45 -07:00
parent 8bf5a8d12f
commit 006b7e3a2b

View File

@@ -353,6 +353,15 @@ fn split_file_at_dot(file: &OsStr) -> (&OsStr, Option<&OsStr>) {
}
}
/// Checks whether the string is valid as a file extension, or panics otherwise.
fn validate_extension(extension: &OsStr) {
for &b in extension.as_encoded_bytes() {
if is_sep_byte(b) {
panic!("extension cannot contain path separators: {extension:?}");
}
}
}
////////////////////////////////////////////////////////////////////////////////
// The core iterators
////////////////////////////////////////////////////////////////////////////////
@@ -1507,13 +1516,7 @@ impl PathBuf {
}
fn _set_extension(&mut self, extension: &OsStr) -> bool {
for &b in extension.as_encoded_bytes() {
if b < 128 {
if is_separator(b as char) {
panic!("extension cannot contain path separators: {:?}", extension);
}
}
}
validate_extension(extension);
let file_stem = match self.file_stem() {
None => return false,
@@ -1541,6 +1544,11 @@ impl PathBuf {
/// Returns `false` and does nothing if [`self.file_name`] is [`None`],
/// returns `true` and updates the extension otherwise.
///
/// # Panics
///
/// Panics if the passed extension contains a path separator (see
/// [`is_separator`]).
///
/// # Caveats
///
/// The appended `extension` may contain dots and will be used in its entirety,
@@ -1582,6 +1590,8 @@ impl PathBuf {
}
fn _add_extension(&mut self, extension: &OsStr) -> bool {
validate_extension(extension);
let file_name = match self.file_name() {
None => return false,
Some(f) => f.as_encoded_bytes(),