This commit is contained in:
Daniel Edrisian
2025-08-21 17:40:52 -07:00
parent 38cb33339d
commit 0b8bdfd2ab

View File

@@ -1,6 +1,7 @@
use std::path::PathBuf;
pub fn normalize_pasted_path(pasted: &str) -> Option<PathBuf> {
let pasted = pasted.trim();
// file:// URL → filesystem path
if let Ok(url) = url::Url::parse(pasted) {
if url.scheme() == "file" {
@@ -8,6 +9,20 @@ pub fn normalize_pasted_path(pasted: &str) -> Option<PathBuf> {
}
}
// Windows paths (unquoted) → bypass POSIX shlex to preserve backslashes
// - Drive letter paths like C:\Users\Alice\img.png
// - UNC paths like \\server\share\img.png
let looks_like_windows_drive_path = pasted.len() >= 3
&& pasted.as_bytes()[1] == b':'
&& (pasted.as_bytes()[2] == b'/' || pasted.as_bytes()[2] == b'\\')
&& pasted.as_bytes()[0].is_ascii_alphabetic();
let looks_like_unc = pasted.starts_with("\\\\");
let is_quoted = (pasted.starts_with('"') && pasted.ends_with('"'))
|| (pasted.starts_with('\'') && pasted.ends_with('\''));
if (looks_like_windows_drive_path || looks_like_unc) && !is_quoted {
return Some(PathBuf::from(pasted));
}
// shell-escaped single path → unescaped
let parts: Vec<String> = shlex::Shlex::new(pasted).collect();
if parts.len() == 1 {
@@ -96,4 +111,11 @@ mod tests {
);
assert_eq!(get_img_format_label(PathBuf::from(r"C:\a\b\noext")), "IMG");
}
#[test]
fn normalize_unquoted_windows_path() {
let input = r"C:\Users\Alice\img.png";
let result = normalize_pasted_path(input).expect("should accept unquoted windows path");
assert_eq!(result, PathBuf::from(r"C:\Users\Alice\img.png"));
}
}