From bf12add007a14a7639105477ffcfdc71b34b3b7d Mon Sep 17 00:00:00 2001 From: David Wiesen Date: Mon, 22 Jun 2026 11:37:24 -0700 Subject: [PATCH] path-uri: accept WSL mount URIs on Windows --- codex-rs/utils/path-uri/src/lib.rs | 35 ++++++++++++++++++++++++++++ codex-rs/utils/path-uri/src/tests.rs | 13 +++++++++++ 2 files changed, 48 insertions(+) diff --git a/codex-rs/utils/path-uri/src/lib.rs b/codex-rs/utils/path-uri/src/lib.rs index 5ef1df2fa2..faaa308eeb 100644 --- a/codex-rs/utils/path-uri/src/lib.rs +++ b/codex-rs/utils/path-uri/src/lib.rs @@ -342,6 +342,18 @@ impl PathUri { /// URIs created by [`Self::from_abs_path`]. Foreign conventions are rejected rather than being /// projected onto a syntactically valid but unrelated host path. pub fn to_abs_path(&self) -> io::Result { + #[cfg(windows)] + if let Some(path) = wsl_mount_uri_to_windows_path(&self.0) { + return AbsolutePathBuf::from_absolute_path_checked(path).map_err(|_| { + io::Error::new( + io::ErrorKind::InvalidInput, + PathUriParseError::InvalidFileUriPath { + path: self.to_string(), + }, + ) + }); + } + if self.infer_path_convention() != Some(PathConvention::native()) { return Err(io::Error::new( io::ErrorKind::InvalidInput, @@ -408,6 +420,29 @@ impl PathUri { } } +#[cfg(windows)] +fn wsl_mount_uri_to_windows_path(url: &Url) -> Option { + if url.host_str().is_some() { + return None; + } + + let mut segments = url.path_segments()?; + if segments.next()? != "mnt" { + return None; + } + + let drive = segments.next()?; + if drive.len() != 1 || !drive.as_bytes()[0].is_ascii_alphabetic() { + return None; + } + + let mut path = PathBuf::from(format!("{}:\\", drive.to_ascii_uppercase())); + for segment in segments { + path.push(decode_uri_path(segment)); + } + Some(path) +} + impl TryFrom for PathUri { type Error = PathUriParseError; diff --git a/codex-rs/utils/path-uri/src/tests.rs b/codex-rs/utils/path-uri/src/tests.rs index 075d343d01..61147f48cf 100644 --- a/codex-rs/utils/path-uri/src/tests.rs +++ b/codex-rs/utils/path-uri/src/tests.rs @@ -206,6 +206,19 @@ fn file_uri_fallback_round_trips_non_unicode_windows_paths() { ); } +#[cfg(windows)] +#[test] +fn wsl_mount_file_uri_maps_to_windows_path() { + let uri = + PathUri::parse("file:///mnt/c/Users/Alice%20Smith/src/main.rs").expect("valid WSL URI"); + + assert_eq!( + uri.to_abs_path().expect("WSL mount URI should convert"), + AbsolutePathBuf::from_absolute_path_checked(r"C:\Users\Alice Smith\src\main.rs") + .expect("absolute Windows path") + ); +} + #[cfg(unix)] #[test] fn file_uri_falls_back_for_posix_paths_with_null_bytes() {