From 323fe80df1f0a78fb2c8d1dfca7a635fd5e0a3c3 Mon Sep 17 00:00:00 2001 From: justanotheranonymoususer Date: Fri, 9 Oct 2026 21:24:24 +0300 Subject: [PATCH] fix(single-instance): forward non-Unicode arguments and cwd (#3644) * Update windows.rs * Create single-instance-non-unicode-args.md * fix on linux and windows too --------- Co-authored-by: Lucas Nogueira --- .changes/single-instance-non-unicode-args.md | 5 +++++ plugins/single-instance/src/lib.rs | 5 +++-- plugins/single-instance/src/platform_impl/linux.rs | 8 +++++--- plugins/single-instance/src/platform_impl/macos.rs | 10 ++++++---- plugins/single-instance/src/platform_impl/windows.rs | 7 +++++-- 5 files changed, 24 insertions(+), 11 deletions(-) create mode 100644 .changes/single-instance-non-unicode-args.md diff --git a/.changes/single-instance-non-unicode-args.md b/.changes/single-instance-non-unicode-args.md new file mode 100644 index 000000000..9c6147b7a --- /dev/null +++ b/.changes/single-instance-non-unicode-args.md @@ -0,0 +1,5 @@ +--- +"single-instance": patch +--- + +A second instance no longer panics when a command-line argument is not valid Unicode: such an argument is forwarded with its invalid parts replaced by U+FFFD. A working directory that is not valid Unicode is now forwarded the same way instead of as an empty string. diff --git a/plugins/single-instance/src/lib.rs b/plugins/single-instance/src/lib.rs index eaf358486..a5c35c582 100644 --- a/plugins/single-instance/src/lib.rs +++ b/plugins/single-instance/src/lib.rs @@ -39,8 +39,9 @@ pub(crate) type SingleInstanceCallback = /// [`Builder::build`]. Use [`Builder`] directly if you need to set a custom [`Builder::dbus_id`]. /// /// `f` is called with the app handle, the second instance's command line arguments -/// (as collected by [`std::env::args`], so the first element is the executable path) and its -/// current working directory. If the `deep-link` feature is enabled, the arguments are first +/// (as collected by [`std::env::args_os`], so the first element is the executable path) and its +/// current working directory. Arguments and the working directory that are not valid Unicode +/// have their invalid parts replaced by U+FFFD. If the `deep-link` feature is enabled, the arguments are first /// forwarded to [`tauri-plugin-deep-link`](https://crates.io/crates/tauri-plugin-deep-link) /// before `f` runs. /// diff --git a/plugins/single-instance/src/platform_impl/linux.rs b/plugins/single-instance/src/platform_impl/linux.rs index 107f3e743..9ddadafbc 100644 --- a/plugins/single-instance/src/platform_impl/linux.rs +++ b/plugins/single-instance/src/platform_impl/linux.rs @@ -74,11 +74,13 @@ pub fn init( Some("org.SingleInstance.DBus"), "ExecuteCallback", &( - std::env::args().collect::>(), + std::env::args_os() + .map(|arg| arg.to_string_lossy().into_owned()) + .collect::>(), std::env::current_dir() .unwrap_or_default() - .to_str() - .unwrap_or_default(), + .to_string_lossy() + .as_ref(), ), ); } diff --git a/plugins/single-instance/src/platform_impl/macos.rs b/plugins/single-instance/src/platform_impl/macos.rs index ccd66f360..c038ff251 100644 --- a/plugins/single-instance/src/platform_impl/macos.rs +++ b/plugins/single-instance/src/platform_impl/macos.rs @@ -80,12 +80,14 @@ fn notify_singleton(socket: &PathBuf) -> Result<(), Error> { let mut bf = BufWriter::new(&stream); let cwd = std::env::current_dir() .unwrap_or_default() - .to_str() - .unwrap_or_default() - .to_string(); + .to_string_lossy() + .into_owned(); bf.write_all(cwd.as_bytes())?; bf.write_all(b"\0\0")?; - let args_joined = std::env::args().collect::>().join("\0"); + let args_joined = std::env::args_os() + .map(|arg| arg.to_string_lossy().into_owned()) + .collect::>() + .join("\0"); bf.write_all(args_joined.as_bytes())?; bf.flush()?; drop(bf); diff --git a/plugins/single-instance/src/platform_impl/windows.rs b/plugins/single-instance/src/platform_impl/windows.rs index b19feb584..256c3f181 100644 --- a/plugins/single-instance/src/platform_impl/windows.rs +++ b/plugins/single-instance/src/platform_impl/windows.rs @@ -86,9 +86,12 @@ pub fn init(callback: Box>) -> TauriPlugin } let cwd = std::env::current_dir().unwrap_or_default(); - let cwd = cwd.to_str().unwrap_or_default(); + let cwd = cwd.to_string_lossy(); - let args = std::env::args().collect::>().join("|"); + let args = std::env::args_os() + .map(|arg| arg.to_string_lossy().into_owned()) + .collect::>() + .join("|"); let data = format!("{cwd}|{args}\0",);