Skip to content

Commit

Permalink
fix: Windows URL encoding for multiple query params
Browse files Browse the repository at this point in the history
Previously, passing a URL with multiple query parameters on Windows would result in
improper escaping, causing unexpected behavior when using it with "cmd /c".
This commit addresses this issue by properly escaping all query parameters in the URL.
Now, URLs with multiple query parameters are handled correctly on Windows.

See also:
* https://doc.rust-lang.org/std/os/windows/process/trait.CommandExt.html#tymethod.raw_arg
* https://learn.microsoft.com/en-us/windows-server/administration/windows-commands/cmd
* https://learn.microsoft.com/en-us/windows-server/administration/windows-commands/start

Related #67.
  • Loading branch information
Byron committed Mar 10, 2023
2 parents 031c44b + 9a1178a commit 9ceb0a4
Show file tree
Hide file tree
Showing 2 changed files with 22 additions and 3 deletions.
1 change: 1 addition & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ description = "Open a path or URL using the program configured on the system"
repository = "https://github.com/Byron/open-rs"
keywords = ["open", "xdg-open", "start", "launch"]
include = ["src/**/*", "LICENSE.md", "README.md", "changelog.md"]
rust-version = "1.62"

[[bin]]
test = false
Expand Down
24 changes: 21 additions & 3 deletions src/windows.rs
Original file line number Diff line number Diff line change
@@ -1,13 +1,31 @@
use std::{ffi::OsStr, process::Command};
use std::{
ffi::{OsStr, OsString},
process::Command,
};

use std::os::windows::process::CommandExt;

pub fn commands<T: AsRef<OsStr>>(path: T) -> Vec<Command> {
let mut cmd = Command::new("cmd");
cmd.arg("/c").arg("start").arg(path.as_ref());
cmd.arg("/c")
.arg("start")
.raw_arg("\"\"")
.raw_arg(wrap_in_quotes(path));
vec![cmd]
}

pub fn with_command<T: AsRef<OsStr>>(path: T, app: impl Into<String>) -> Command {
let mut cmd = Command::new("cmd");
cmd.arg("/c").arg(app.into()).arg(path.as_ref());
cmd.arg("/c")
.raw_arg(app.into())
.raw_arg(wrap_in_quotes(path));
cmd
}

fn wrap_in_quotes<T: AsRef<OsStr>>(path: T) -> OsString {
let mut result = OsString::from("\"");
result.push(path);
result.push("\"");

result
}

0 comments on commit 9ceb0a4

Please sign in to comment.