Fix "invalid path" error for UNC paths on Windows
resolve_path() only handled Prefix::Disk and Prefix::VerbatimDisk when initializing the path root on Windows, so any UNC path (\server\share, or its \?\UNC\server\share verbatim form) fell through to the catch-all branch and errored with "invalid path", even though the path itself was perfectly valid. This broke zoxide entirely for anyone whose directories live on a network share. Add a Prefix::UNC / Prefix::VerbatimUNC arm that builds the \server\share root the same way the Disk arms build their drive root, and add resolve_path unit tests covering UNC, verbatim UNC, and a disk-path regression check. Fixes #331
This commit is contained in:
parent
6d6066dd25
commit
55bc9f0f2f
45
src/util.rs
45
src/util.rs
|
|
@ -332,6 +332,18 @@ pub fn resolve_path(path: impl AsRef<Path>) -> Result<PathBuf> {
|
|||
base_path = get_drive_path(drive_letter);
|
||||
stack.extend(base_path.components());
|
||||
}
|
||||
Prefix::UNC(server, share) | Prefix::VerbatimUNC(server, share) => {
|
||||
let server = server.to_string_lossy();
|
||||
let share = share.to_string_lossy();
|
||||
|
||||
components.next();
|
||||
if components.peek() == Some(&Component::RootDir) {
|
||||
components.next();
|
||||
}
|
||||
|
||||
base_path = format!(r"\\{server}\{share}").into();
|
||||
stack.extend(base_path.components());
|
||||
}
|
||||
_ => bail!("invalid path: {}", path.display()),
|
||||
},
|
||||
Some(Component::RootDir) => {
|
||||
|
|
@ -378,3 +390,36 @@ pub fn to_lowercase(s: impl AsRef<str>) -> String {
|
|||
let s = s.as_ref();
|
||||
if s.is_ascii() { s.to_ascii_lowercase() } else { s.to_lowercase() }
|
||||
}
|
||||
|
||||
#[cfg(all(test, windows))]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn resolve_path_unc() {
|
||||
let resolved = resolve_path(r"\\a.network-drive\a-folder").unwrap();
|
||||
assert_eq!(resolved, PathBuf::from(r"\\a.network-drive\a-folder"));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn resolve_path_unc_with_subdirs() {
|
||||
let resolved = resolve_path(r"\\a.network-drive\a-folder\subdir\nested").unwrap();
|
||||
assert_eq!(resolved, PathBuf::from(r"\\a.network-drive\a-folder\subdir\nested"));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn resolve_path_verbatim_unc() {
|
||||
// `\\?\UNC\server\share\...` is the verbatim form Windows APIs produce
|
||||
// for UNC paths (e.g. via `dunce`/`canonicalize` on paths that were
|
||||
// already long-path-prefixed). It should resolve to the same
|
||||
// non-verbatim form as a plain UNC path.
|
||||
let resolved = resolve_path(r"\\?\UNC\a.network-drive\a-folder\subdir").unwrap();
|
||||
assert_eq!(resolved, PathBuf::from(r"\\a.network-drive\a-folder\subdir"));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn resolve_path_disk() {
|
||||
let resolved = resolve_path(r"C:\Users\test").unwrap();
|
||||
assert_eq!(resolved, PathBuf::from(r"C:\Users\test"));
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue