| use super::super::windows_prefix::*; | |
| use super::*; | |
| use crate::path::Prefix; | |
| #[test] | |
| fn test_parse_next_component() { | |
| assert_eq!( | |
| parse_next_component(OsStr::new(r"server\share"), true), | |
| (OsStr::new(r"server"), OsStr::new(r"share")) | |
| ); | |
| assert_eq!( | |
| parse_next_component(OsStr::new(r"server/share"), true), | |
| (OsStr::new(r"server/share"), OsStr::new(r"")) | |
| ); | |
| assert_eq!( | |
| parse_next_component(OsStr::new(r"server/share"), false), | |
| (OsStr::new(r"server"), OsStr::new(r"share")) | |
| ); | |
| assert_eq!( | |
| parse_next_component(OsStr::new(r"server\"), false), | |
| (OsStr::new(r"server"), OsStr::new(r"")) | |
| ); | |
| assert_eq!( | |
| parse_next_component(OsStr::new(r"\server\"), false), | |
| (OsStr::new(r""), OsStr::new(r"server\")) | |
| ); | |
| assert_eq!( | |
| parse_next_component(OsStr::new(r"servershare"), false), | |
| (OsStr::new(r"servershare"), OsStr::new("")) | |
| ); | |
| } | |
| #[test] | |
| fn verbatim() { | |
| use crate::path::Path; | |
| fn check(path: &str, expected: &str) { | |
| let verbatim = maybe_verbatim(Path::new(path)).unwrap(); | |
| let verbatim = String::from_utf16_lossy(verbatim.strip_suffix(&[0]).unwrap()); | |
| assert_eq!(&verbatim, expected, "{}", path); | |
| } | |
| // Ensure long paths are correctly prefixed. | |
| check( | |
| r"C:\Program Files\Rust\aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb\foo.txt", | |
| r"\\?\C:\Program Files\Rust\aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb\foo.txt", | |
| ); | |
| check( | |
| r"\\server\share\aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb\foo.txt", | |
| r"\\?\UNC\server\share\aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb\foo.txt", | |
| ); | |
| check( | |
| r"\\.\PIPE\aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb\foo.txt", | |
| r"\\?\PIPE\aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb\foo.txt", | |
| ); | |
| // `\\?\` prefixed paths are left unchanged... | |
| check( | |
| r"\\?\verbatim.\aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb\foo.txt", | |
| r"\\?\verbatim.\aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb\foo.txt", | |
| ); | |
| // But `//?/` is not a verbatim prefix so it will be normalized. | |
| check( | |
| r"//?/E:/verbatim.\aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb\foo.txt", | |
| r"\\?\E:\verbatim\aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb\foo.txt", | |
| ); | |
| // For performance, short absolute paths are left unchanged. | |
| check(r"C:\Program Files\Rust", r"C:\Program Files\Rust"); | |
| check(r"\\server\share", r"\\server\share"); | |
| check(r"\\.\COM1", r"\\.\COM1"); | |
| // Check that paths of length 247 are converted to verbatim. | |
| // This is necessary for `CreateDirectory`. | |
| check( | |
| r"C:\aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", | |
| r"\\?\C:\aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", | |
| ); | |
| // Make sure opening a drive will work. | |
| check("Z:", "Z:"); | |
| // Verbatim drive paths begin with `LETTER:\`. `/` is just a regular character here | |
| check(r"\\?\C:/path\somewhere", r"\\?\C:/path\somewhere"); | |
| // A path that contains null is not a valid path. | |
| assert!(maybe_verbatim(Path::new("\0")).is_err()); | |
| } | |
| fn parse_prefix(path: &str) -> Option<Prefix<'_>> { | |
| super::parse_prefix(OsStr::new(path)) | |
| } | |
| #[test] | |
| fn test_parse_prefix_verbatim() { | |
| assert_eq!( | |
| parse_prefix(r"\\?\C:\windows\system32\notepad.exe"), | |
| Some(Prefix::VerbatimDisk(b'C')), | |
| ); | |
| } | |
| #[test] | |
| fn test_verbatim_disk_issue_161651() { | |
| use crate::path::Path; | |
| // This is not a `VerbatimDisk` path, because `/` is not a separator in verbatim paths! | |
| assert_eq!( | |
| parse_prefix(r"\\?\C:/windows\system32"), | |
| Some(Prefix::Verbatim(OsStr::new("C:/windows"))), | |
| ); | |
| assert_ne!(Path::new(r"\\?\C:/foo"), Path::new(r"\\?\C:\foo")); | |
| } | |
| #[test] | |
| fn test_parse_prefix_verbatim_device() { | |
| let prefix = Some(Prefix::UNC(OsStr::new("?"), OsStr::new("C:"))); | |
| assert_eq!(prefix, parse_prefix(r"//?/C:/windows/system32/notepad.exe")); | |
| assert_eq!(prefix, parse_prefix(r"//?/C:\windows\system32\notepad.exe")); | |
| assert_eq!(prefix, parse_prefix(r"/\?\C:\windows\system32\notepad.exe")); | |
| assert_eq!(prefix, parse_prefix(r"\\?/C:\windows\system32\notepad.exe")); | |
| } | |
| // See #93586 for more information. | |
| #[test] | |
| fn test_windows_prefix_components() { | |
| use crate::path::Path; | |
| let path = Path::new("C:"); | |
| let mut components = path.components(); | |
| let drive = components.next().expect("drive is expected here"); | |
| assert_eq!(drive.as_os_str(), OsStr::new("C:")); | |
| assert_eq!(components.as_path(), Path::new("")); | |
| } | |
| /// See #101358. | |
| /// | |
| /// Note that the exact behavior here may change in the future. | |
| /// In which case this test will need to adjusted. | |
| #[test] | |
| fn broken_unc_path() { | |
| use crate::path::Component; | |
| let mut components = Path::new(r"\\foo\\bar\\").components(); | |
| assert_eq!(components.next(), Some(Component::RootDir)); | |
| assert_eq!(components.next(), Some(Component::Normal("foo".as_ref()))); | |
| assert_eq!(components.next(), Some(Component::Normal("bar".as_ref()))); | |
| let mut components = Path::new("//foo//bar//").components(); | |
| assert_eq!(components.next(), Some(Component::RootDir)); | |
| assert_eq!(components.next(), Some(Component::Normal("foo".as_ref()))); | |
| assert_eq!(components.next(), Some(Component::Normal("bar".as_ref()))); | |
| } | |
| #[test] | |
| fn test_is_absolute_exact() { | |
| use crate::sys::pal::api::wide_str; | |
| // These paths can be made verbatim by only changing their prefix. | |
| assert!(is_absolute_exact(wide_str!(r"C:\path\to\file"))); | |
| assert!(is_absolute_exact(wide_str!(r"\\server\share\path\to\file"))); | |
| // These paths change more substantially | |
| assert!(!is_absolute_exact(wide_str!(r"C:\path\to\..\file"))); | |
| assert!(!is_absolute_exact(wide_str!(r"\\server\share\path\to\..\file"))); | |
| assert!(!is_absolute_exact(wide_str!(r"C:\path\to\NUL"))); // Converts to \\.\NUL | |
| } |