mirror of
https://github.com/astral-sh/uv.git
synced 2025-10-18 14:29:57 +00:00
fix: replace std::fs::canonicalize with Simplified::simple_canonicaliz… (#6776)
## Summary This PR addresses an issue on Windows where `std::fs::canonicalize` can fail or panic when resolving paths on mapped network drives. By replacing it with `Simplified::simple_canonicalize`, we aim to improve the robustness and cross-platform compatibility of path resolution. ### Changes * Updated `CANONICAL_CWD` in `path.rs` to use `Simplified::simple_canonicalize` instead of `std::fs::canonicalize`. ### Why * `std::fs::canonicalize` has known issues with resolving paths on mapped network drives on Windows, which can lead to panics or incorrect path resolution. * `Simplified::simple_canonicalize` internally uses `dunce::canonicalize`, which handles these cases more gracefully, ensuring better stability and reliability. ## Test Plan Since `simple_canonicalize` has already been tested in a prior PR, this change is expected to work without introducing any new issues. No additional tests are necessary beyond ensuring existing tests pass, which will confirm the correctness of the change.
This commit is contained in:
parent
736ccb950a
commit
ae3f35cfe2
1 changed files with 19 additions and 3 deletions
|
@ -1,5 +1,5 @@
|
|||
use std::borrow::Cow;
|
||||
use std::path::{Component, Path, PathBuf};
|
||||
use std::path::{absolute, Component, Path, PathBuf};
|
||||
use std::sync::LazyLock;
|
||||
|
||||
use either::Either;
|
||||
|
@ -13,7 +13,7 @@ pub static CWD: LazyLock<PathBuf> =
|
|||
pub static CANONICAL_CWD: LazyLock<PathBuf> = LazyLock::new(|| {
|
||||
std::env::current_dir()
|
||||
.expect("The current directory must exist")
|
||||
.canonicalize()
|
||||
.simple_canonicalize()
|
||||
.expect("The current directory must be canonicalized")
|
||||
});
|
||||
|
||||
|
@ -30,6 +30,8 @@ pub trait Simplified {
|
|||
fn simplified_display(&self) -> impl std::fmt::Display;
|
||||
|
||||
/// Canonicalize a path without a `\\?\` prefix on Windows.
|
||||
/// For a path that can't be canonicalized (e.g. on network drive or RAM drive on Windows),
|
||||
/// this will return the absolute path if it exists.
|
||||
fn simple_canonicalize(&self) -> std::io::Result<PathBuf>;
|
||||
|
||||
/// Render a [`Path`] for user-facing display.
|
||||
|
@ -59,7 +61,21 @@ impl<T: AsRef<Path>> Simplified for T {
|
|||
}
|
||||
|
||||
fn simple_canonicalize(&self) -> std::io::Result<PathBuf> {
|
||||
dunce::canonicalize(self.as_ref())
|
||||
match dunce::canonicalize(self.as_ref()) {
|
||||
Ok(path) => Ok(path),
|
||||
// On Windows, `dunce::canonicalize` can't canonicalize paths on network drives or RAM
|
||||
// drives. In that case, fall back on `std::path::absolute`, but also verify that the
|
||||
// path exists.
|
||||
Err(e) if std::env::consts::OS != "windows" => Err(e),
|
||||
_ => match absolute(self.as_ref()) {
|
||||
Ok(path) if path.exists() => Ok(path),
|
||||
Ok(_) => Err(std::io::Error::new(
|
||||
std::io::ErrorKind::NotFound,
|
||||
format!("Path does not exist: {}", self.simplified_display()),
|
||||
)),
|
||||
Err(e) => Err(e),
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
fn user_display(&self) -> impl std::fmt::Display {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue