From 48e5e8c8ce21d4f8a47aa0b1225de22dd0876ac2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mirek=20Wr=C3=B3bel?= Date: Thu, 15 Oct 2026 15:11:26 +0200 Subject: [PATCH] Keep command-line paths that are not valid UTF-8 intact --- src-tauri/src/git.rs | 20 ++++++++++++++++++-- src-tauri/src/lib.rs | 2 +- 2 files changed, 19 insertions(+), 3 deletions(-) diff --git a/src-tauri/src/git.rs b/src-tauri/src/git.rs index 1df7b49..3c9f4ea 100644 --- a/src-tauri/src/git.rs +++ b/src-tauri/src/git.rs @@ -194,9 +194,13 @@ pub fn load(loc: &Location) -> Result { /// current folder if it is inside a repository. `None` means gites starts with its /// welcome screen. A path given on the command line is used even if it is not a /// repository, so the window can say what is wrong with it. -pub fn start_dir(arg: Option, cwd: PathBuf) -> Option { +pub fn start_dir(arg: Option, cwd: PathBuf) -> Option { if let Some(arg) = arg { - return Some(crate::location::parse(&arg, &cwd)); + // Text that is not valid UTF-8 cannot be a `host:path`; keep it exactly as given. + return Some(match arg.to_str() { + Some(text) => crate::location::parse(text, &cwd), + None => Location::Local(PathBuf::from(arg)), + }); } let here = Location::Local(cwd); git(&here, &["rev-parse", "--git-dir"]).ok().map(|_| here) @@ -219,6 +223,18 @@ mod tests { assert_eq!(start_dir(Some("/no/such/folder".into()), temp_dir("arg")), Some(Location::Local(given))); } + #[cfg(unix)] + #[test] + fn keeps_a_command_line_path_that_is_not_valid_utf8_intact() { + use std::os::unix::ffi::{OsStrExt, OsStringExt}; + let bytes = b"/tmp/caf\xe9".to_vec(); + let got = start_dir(Some(std::ffi::OsString::from_vec(bytes.clone())), temp_dir("bytes")); + match got { + Some(Location::Local(p)) => assert_eq!(p.as_os_str().as_bytes(), &bytes[..]), + other => panic!("{other:?}"), + } + } + #[test] fn opens_the_current_folder_when_it_is_inside_a_repository() { let dir = temp_dir("repo"); diff --git a/src-tauri/src/lib.rs b/src-tauri/src/lib.rs index cabac9f..45cf545 100644 --- a/src-tauri/src/lib.rs +++ b/src-tauri/src/lib.rs @@ -78,7 +78,7 @@ fn save_settings(value: serde_json::Value) -> Result<(), String> { #[cfg_attr(mobile, tauri::mobile_entry_point)] pub fn run() { - let arg = std::env::args_os().nth(1).map(|a| a.to_string_lossy().into_owned()); + let arg = std::env::args_os().nth(1); let cwd = std::env::current_dir().unwrap_or_else(|_| PathBuf::from(".")); let path = git::start_dir(arg, cwd);