about summary refs log tree commit diff
path: root/library/std/src/path.rs
diff options
context:
space:
mode:
authorChris Denton <chris@chrisdenton.dev>2025-04-23 00:43:07 +0000
committerGitHub <noreply@github.com>2025-04-23 00:43:07 +0000
commited4e167c4a127c4d44a2b434cd479ff8702e2a52 (patch)
tree8c846c76e93cfe8b5b6d57e086fb9e00ab2a2cc7 /library/std/src/path.rs
parentb03267fc1164c1e026e55cc960f8ec0a7b805f17 (diff)
parent006b7e3a2bb0ea93287704cb2dbc3bb6d35c5876 (diff)
downloadrust-ed4e167c4a127c4d44a2b434cd479ff8702e2a52.tar.gz
rust-ed4e167c4a127c4d44a2b434cd479ff8702e2a52.zip
Rollup merge of #140163 - thaliaarchi:pathbuf-validate-extension, r=ChrisDenton
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).

`PathBuf::add_extension` is tracked in #127292.

r? `@ChrisDenton`
Diffstat (limited to 'library/std/src/path.rs')
-rw-r--r--library/std/src/path.rs24
1 files changed, 17 insertions, 7 deletions
diff --git a/library/std/src/path.rs b/library/std/src/path.rs
index 50f403ba411..7cd20c48d89 100644
--- a/library/std/src/path.rs
+++ b/library/std/src/path.rs
@@ -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(),