aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJesse Luehrs <doy@tozt.net>2021-10-29 01:29:56 -0400
committerJesse Luehrs <doy@tozt.net>2021-10-29 01:29:56 -0400
commit00e90e7e7d3bdc2e35fea0fab2dc704326831bad (patch)
tree552e1a8a5082f58fd11c39e7991504d949203988
parent0a6cb355e1f53be7b53dc656875f2ebf29675086 (diff)
downloadrbw-00e90e7e7d3bdc2e35fea0fab2dc704326831bad.tar.gz
rbw-00e90e7e7d3bdc2e35fea0fab2dc704326831bad.zip
support command line arguments in EDITOR/VISUAL
-rw-r--r--src/edit.rs72
-rw-r--r--src/error.rs4
2 files changed, 50 insertions, 26 deletions
diff --git a/src/edit.rs b/src/edit.rs
index a62dffa..1a831a7 100644
--- a/src/edit.rs
+++ b/src/edit.rs
@@ -8,27 +8,6 @@ pub fn edit(contents: &str, help: &str) -> Result<String> {
var = "EDITOR";
std::env::var_os(var).unwrap_or_else(|| "/usr/bin/vim".into())
});
- let editor = std::path::Path::new(&editor);
-
- let mut args = vec![];
- match editor.file_name() {
- Some(editor) => match editor.to_str() {
- Some("vim" | "nvim") => {
- // disable swap files and viminfo for password entry
- args.push(std::ffi::OsStr::new("-ni"));
- args.push(std::ffi::OsStr::new("NONE"));
- }
- _ => {
- // other editor support welcomed
- }
- },
- None => {
- return Err(Error::InvalidEditor {
- var: var.to_string(),
- editor: editor.as_os_str().to_os_string(),
- })
- }
- }
let dir = tempfile::tempdir().unwrap();
let file = dir.path().join("rbw");
@@ -37,20 +16,56 @@ pub fn edit(contents: &str, help: &str) -> Result<String> {
fh.write_all(help.as_bytes()).unwrap();
drop(fh);
- args.push(file.as_os_str());
- let res = std::process::Command::new(&editor).args(&args).status();
+ let (cmd, args) = if contains_shell_metacharacters(&editor) {
+ let mut cmdline = std::ffi::OsString::new();
+ cmdline.extend([
+ editor.as_ref(),
+ std::ffi::OsStr::new(" "),
+ file.as_os_str(),
+ ]);
+
+ let editor_args = vec![std::ffi::OsString::from("-c"), cmdline];
+ (std::path::Path::new("/bin/sh"), editor_args)
+ } else {
+ let editor = std::path::Path::new(&editor);
+ let mut editor_args = vec![];
+
+ match editor.file_name() {
+ Some(editor) => match editor.to_str() {
+ Some("vim" | "nvim") => {
+ // disable swap files and viminfo for password entry
+ editor_args.push(std::ffi::OsString::from("-ni"));
+ editor_args.push(std::ffi::OsString::from("NONE"));
+ }
+ _ => {
+ // other editor support welcomed
+ }
+ },
+ None => {
+ return Err(Error::InvalidEditor {
+ var: var.to_string(),
+ editor: editor.as_os_str().to_os_string(),
+ })
+ }
+ }
+ editor_args.push(file.clone().into_os_string());
+ (editor, editor_args)
+ };
+
+ let res = std::process::Command::new(&cmd).args(&args).status();
match res {
Ok(res) => {
if !res.success() {
return Err(Error::FailedToRunEditor {
- editor: editor.to_owned(),
+ editor: cmd.to_owned(),
+ args,
res,
});
}
}
Err(err) => {
return Err(Error::FailedToFindEditor {
- editor: editor.to_owned(),
+ editor: cmd.to_owned(),
err,
})
}
@@ -63,3 +78,10 @@ pub fn edit(contents: &str, help: &str) -> Result<String> {
Ok(contents)
}
+
+fn contains_shell_metacharacters(cmd: &std::ffi::OsStr) -> bool {
+ match cmd.to_str() {
+ Some(s) => s.contains(&[' ', '$', '\'', '"'][..]),
+ None => false,
+ }
+}
diff --git a/src/error.rs b/src/error.rs
index d584e53..8116de2 100644
--- a/src/error.rs
+++ b/src/error.rs
@@ -35,11 +35,13 @@ pub enum Error {
},
#[error(
- "failed to run editor {}: {res:?}",
+ "failed to run editor {} {}: {res:?}",
.editor.to_string_lossy(),
+ .args.iter().map(|s| s.to_string_lossy()).collect::<Vec<_>>().join(" ")
)]
FailedToRunEditor {
editor: std::path::PathBuf,
+ args: Vec<std::ffi::OsString>,
res: std::process::ExitStatus,
},