mirror of
https://git.meli.delivery/meli/meli
synced 2024-10-30 21:20:34 +00:00
Spawn user-given command strings with sh -c ".."
If given string contains arguments, Command::new(string) will fail. Reported in #159 https://git.meli.delivery/meli/meli/issues/159
This commit is contained in:
parent
0ef4dde939
commit
dd0baa82e9
@ -2223,13 +2223,13 @@ impl Component for MailView {
|
|||||||
None,
|
None,
|
||||||
true,
|
true,
|
||||||
);
|
);
|
||||||
let (exec_cmd, argument) = desktop_exec_to_command(
|
let exec_cmd = desktop_exec_to_command(
|
||||||
&command,
|
&command,
|
||||||
p.path.display().to_string(),
|
p.path.display().to_string(),
|
||||||
false,
|
false,
|
||||||
);
|
);
|
||||||
match Command::new(&exec_cmd)
|
match Command::new("sh")
|
||||||
.arg(&argument)
|
.args(&["-c", &exec_cmd])
|
||||||
.stdin(Stdio::piped())
|
.stdin(Stdio::piped())
|
||||||
.stdout(Stdio::piped())
|
.stdout(Stdio::piped())
|
||||||
.spawn()
|
.spawn()
|
||||||
@ -2241,8 +2241,8 @@ impl Component for MailView {
|
|||||||
Err(err) => {
|
Err(err) => {
|
||||||
context.replies.push_back(UIEvent::StatusEvent(
|
context.replies.push_back(UIEvent::StatusEvent(
|
||||||
StatusEvent::DisplayMessage(format!(
|
StatusEvent::DisplayMessage(format!(
|
||||||
"Failed to start `{} {}`: {}",
|
"Failed to start `{}`: {}",
|
||||||
&exec_cmd, &argument, err
|
&exec_cmd, err
|
||||||
)),
|
)),
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
@ -2790,49 +2790,66 @@ fn save_attachment(path: &std::path::Path, bytes: &[u8]) -> Result<()> {
|
|||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn desktop_exec_to_command(command: &str, path: String, is_url: bool) -> (String, String) {
|
fn desktop_exec_to_command(command: &str, path: String, is_url: bool) -> String {
|
||||||
/* Purge unused field codes */
|
/* Purge unused field codes */
|
||||||
let command = command
|
let command = command
|
||||||
.replace("%i", "")
|
.replace("%i", "")
|
||||||
.replace("%c", "")
|
.replace("%c", "")
|
||||||
.replace("%k", "");
|
.replace("%k", "");
|
||||||
if let Some(pos) = command.find("%f").or_else(|| command.find("%F")) {
|
if command.contains("%f") {
|
||||||
(command[0..pos].trim().to_string(), path)
|
command.replacen("%f", &path.replace(' ', "\\ "), 1)
|
||||||
} else if let Some(pos) = command.find("%u").or_else(|| command.find("%U")) {
|
} else if command.contains("%F") {
|
||||||
|
command.replacen("%F", &path.replace(' ', "\\ "), 1)
|
||||||
|
} else if command.contains("%u") || command.contains("%U") {
|
||||||
|
let from_pattern = if command.contains("%u") { "%u" } else { "%U" };
|
||||||
if is_url {
|
if is_url {
|
||||||
(command[0..pos].trim().to_string(), path)
|
command.replacen(from_pattern, &path, 1)
|
||||||
} else {
|
} else {
|
||||||
(
|
command.replacen(
|
||||||
command[0..pos].trim().to_string(),
|
from_pattern,
|
||||||
format!("file://{}", path),
|
&format!("file://{}", path).replace(' ', "\\ "),
|
||||||
|
1,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
} else if is_url {
|
||||||
|
format!("{} {}", command, path)
|
||||||
} else {
|
} else {
|
||||||
(command, path)
|
format!("{} {}", command, path.replace(' ', "\\ "))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_desktop_exec() {
|
fn test_desktop_exec() {
|
||||||
for cmd in [
|
assert_eq!(
|
||||||
"ristretto %F",
|
"ristretto /tmp/file".to_string(),
|
||||||
"/usr/lib/firefox-esr/firefox-esr %u",
|
desktop_exec_to_command("ristretto %F", "/tmp/file".to_string(), false)
|
||||||
"/usr/bin/vlc --started-from-file %U",
|
);
|
||||||
"zathura %U",
|
assert_eq!(
|
||||||
]
|
"/usr/lib/firefox-esr/firefox-esr file:///tmp/file".to_string(),
|
||||||
.iter()
|
desktop_exec_to_command(
|
||||||
{
|
"/usr/lib/firefox-esr/firefox-esr %u",
|
||||||
println!(
|
"/tmp/file".to_string(),
|
||||||
"cmd = {} output = {:?}, is_url = false",
|
false
|
||||||
cmd,
|
)
|
||||||
desktop_exec_to_command(cmd, "/tmp/file".to_string(), false)
|
);
|
||||||
);
|
assert_eq!(
|
||||||
println!(
|
"/usr/lib/firefox-esr/firefox-esr www.example.com".to_string(),
|
||||||
"cmd = {} output = {:?}, is_url = true",
|
desktop_exec_to_command(
|
||||||
cmd,
|
"/usr/lib/firefox-esr/firefox-esr %u",
|
||||||
desktop_exec_to_command(cmd, "www.example.com".to_string(), true)
|
"www.example.com".to_string(),
|
||||||
);
|
true
|
||||||
}
|
)
|
||||||
|
);
|
||||||
|
assert_eq!(
|
||||||
|
"/usr/bin/vlc --started-from-file www.example.com".to_string(),
|
||||||
|
desktop_exec_to_command(
|
||||||
|
"/usr/bin/vlc --started-from-file %U",
|
||||||
|
"www.example.com".to_string(),
|
||||||
|
true
|
||||||
|
)
|
||||||
|
);
|
||||||
|
assert_eq!(
|
||||||
|
"zathura --fork file:///tmp/file".to_string(),
|
||||||
|
desktop_exec_to_command("zathura --fork %U", "file:///tmp/file".to_string(), true)
|
||||||
|
);
|
||||||
}
|
}
|
||||||
*/
|
|
||||||
|
@ -403,13 +403,13 @@ impl Component for EnvelopeView {
|
|||||||
None,
|
None,
|
||||||
true,
|
true,
|
||||||
);
|
);
|
||||||
let (exec_cmd, argument) = super::desktop_exec_to_command(
|
let exec_cmd = super::desktop_exec_to_command(
|
||||||
&command,
|
&command,
|
||||||
p.path.display().to_string(),
|
p.path.display().to_string(),
|
||||||
false,
|
false,
|
||||||
);
|
);
|
||||||
match Command::new(&exec_cmd)
|
match Command::new("sh")
|
||||||
.arg(&argument)
|
.args(&["-c", &exec_cmd])
|
||||||
.stdin(Stdio::piped())
|
.stdin(Stdio::piped())
|
||||||
.stdout(Stdio::piped())
|
.stdout(Stdio::piped())
|
||||||
.spawn()
|
.spawn()
|
||||||
@ -421,8 +421,8 @@ impl Component for EnvelopeView {
|
|||||||
Err(err) => {
|
Err(err) => {
|
||||||
context.replies.push_back(UIEvent::StatusEvent(
|
context.replies.push_back(UIEvent::StatusEvent(
|
||||||
StatusEvent::DisplayMessage(format!(
|
StatusEvent::DisplayMessage(format!(
|
||||||
"Failed to start `{} {}`: {}",
|
"Failed to start `{}`: {}",
|
||||||
&exec_cmd, &argument, err
|
&exec_cmd, err
|
||||||
)),
|
)),
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
|
@ -151,10 +151,10 @@ impl Component for HtmlView {
|
|||||||
};
|
};
|
||||||
if let Some(command) = command {
|
if let Some(command) = command {
|
||||||
let p = create_temp_file(&self.bytes, None, None, true);
|
let p = create_temp_file(&self.bytes, None, None, true);
|
||||||
let (exec_cmd, argument) =
|
let exec_cmd =
|
||||||
super::desktop_exec_to_command(&command, p.path.display().to_string(), false);
|
super::desktop_exec_to_command(&command, p.path.display().to_string(), false);
|
||||||
match Command::new(&exec_cmd)
|
match Command::new("sh")
|
||||||
.arg(&argument)
|
.args(&["-c", &exec_cmd])
|
||||||
.stdin(Stdio::piped())
|
.stdin(Stdio::piped())
|
||||||
.stdout(Stdio::piped())
|
.stdout(Stdio::piped())
|
||||||
.spawn()
|
.spawn()
|
||||||
@ -166,8 +166,8 @@ impl Component for HtmlView {
|
|||||||
Err(err) => {
|
Err(err) => {
|
||||||
context.replies.push_back(UIEvent::StatusEvent(
|
context.replies.push_back(UIEvent::StatusEvent(
|
||||||
StatusEvent::DisplayMessage(format!(
|
StatusEvent::DisplayMessage(format!(
|
||||||
"Failed to start `{} {}`: {}",
|
"Failed to start `{}`: {}",
|
||||||
&exec_cmd, &argument, err
|
&exec_cmd, err
|
||||||
)),
|
)),
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
|
@ -214,7 +214,8 @@ impl MailcapEntry {
|
|||||||
std::borrow::Cow::from("less")
|
std::borrow::Cow::from("less")
|
||||||
};
|
};
|
||||||
|
|
||||||
let mut pager = Command::new(pager_cmd.as_ref())
|
let mut pager = Command::new("sh")
|
||||||
|
.args(["-c", pager_cmd.as_ref()])
|
||||||
.stdin(Stdio::piped())
|
.stdin(Stdio::piped())
|
||||||
.stdout(Stdio::inherit())
|
.stdout(Stdio::inherit())
|
||||||
.spawn()?;
|
.spawn()?;
|
||||||
|
13
src/main.rs
13
src/main.rs
@ -233,12 +233,13 @@ fn run_app(opt: Opt) -> Result<()> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
use std::process::{Command, Stdio};
|
use std::process::{Command, Stdio};
|
||||||
let mut handle =
|
let mut handle = Command::new("sh")
|
||||||
Command::new(std::env::var("PAGER").unwrap_or_else(|_| "more".to_string()))
|
.arg("-c")
|
||||||
.stdin(Stdio::piped())
|
.arg(std::env::var("PAGER").unwrap_or_else(|_| "more".to_string()))
|
||||||
.stdout(Stdio::inherit())
|
.stdin(Stdio::piped())
|
||||||
.stderr(Stdio::inherit())
|
.stdout(Stdio::inherit())
|
||||||
.spawn()?;
|
.stderr(Stdio::inherit())
|
||||||
|
.spawn()?;
|
||||||
handle.stdin.take().unwrap().write_all(v.as_bytes())?;
|
handle.stdin.take().unwrap().write_all(v.as_bytes())?;
|
||||||
handle.wait()?;
|
handle.wait()?;
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user