From 1431145afa6a6248a3b61b230c823519b8c64f71 Mon Sep 17 00:00:00 2001 From: Federico Terzi Date: Sat, 14 Nov 2020 20:52:02 +0100 Subject: [PATCH] Add option to disable passive argument injection in shell extension. Fix #513 --- src/extension/shell.rs | 71 +++++++++++++++++++++++++++++++----------- src/matcher/mod.rs | 2 +- 2 files changed, 54 insertions(+), 19 deletions(-) diff --git a/src/extension/shell.rs b/src/extension/shell.rs index fd0f43a..4e323a8 100644 --- a/src/extension/shell.rs +++ b/src/extension/shell.rs @@ -25,11 +25,8 @@ use std::collections::HashMap; use std::process::{Command, Output}; lazy_static! { - static ref POS_ARG_REGEX: Regex = if cfg!(target_os = "windows") { - Regex::new("%(?P\\d+)").unwrap() - } else { - Regex::new("\\$(?P\\d+)").unwrap() - }; + static ref UNIX_POS_ARG_REGEX: Regex = Regex::new("\\$(?P\\d+)").unwrap(); + static ref WIN_POS_ARG_REGEX: Regex = Regex::new("%(?P\\d+)").unwrap(); } pub enum Shell { @@ -121,6 +118,18 @@ impl Shell { _ => None, } } + + fn get_arg_regex(&self) -> &Regex { + let regex = match self { + Shell::Cmd | Shell::Powershell => { + &*WIN_POS_ARG_REGEX + } + _ => { + &*UNIX_POS_ARG_REGEX + } + }; + regex + } } impl Default for Shell { @@ -162,20 +171,13 @@ impl super::Extension for ShellExtension { return None; } - let original_cmd = cmd.unwrap().as_str().unwrap(); + let inject_args = params + .get(&Value::from("inject_args")) + .unwrap_or(&Value::from(false)) + .as_bool() + .unwrap_or(false); - // Render positional parameters in args - let cmd = POS_ARG_REGEX - .replace_all(&original_cmd, |caps: &Captures| { - let position_str = caps.name("pos").unwrap().as_str(); - let position = position_str.parse::().unwrap_or(-1); - if position >= 0 && position < args.len() as i32 { - args[position as usize].to_owned() - } else { - "".to_owned() - } - }) - .to_string(); + let original_cmd = cmd.unwrap().as_str().unwrap(); let shell_param = params.get(&Value::from("shell")); let shell = if let Some(shell_param) = shell_param { @@ -192,6 +194,23 @@ impl super::Extension for ShellExtension { Shell::default() }; + // Render positional parameters in args + let cmd = if inject_args { + shell.get_arg_regex() + .replace_all(&original_cmd, |caps: &Captures| { + let position_str = caps.name("pos").unwrap().as_str(); + let position = position_str.parse::().unwrap_or(-1); + if position >= 0 && position < args.len() as i32 { + args[position as usize].to_owned() + } else { + "".to_owned() + } + }) + .to_string() + } else { + original_cmd.to_owned() + }; + let env_variables = super::utils::convert_to_env_variables(&vars); let output = shell.execute_cmd(&cmd, &env_variables); @@ -348,6 +367,7 @@ mod tests { fn test_shell_args_unix() { let mut params = Mapping::new(); params.insert(Value::from("cmd"), Value::from("echo $0")); + params.insert(Value::from("inject_args"), Value::from(true)); let extension = ShellExtension::new(); let output = extension.calculate(¶ms, &vec!["hello".to_owned()], &HashMap::new()); @@ -357,11 +377,26 @@ mod tests { assert_eq!(output.unwrap(), ExtensionResult::Single("hello".to_owned())); } + #[test] + #[cfg(not(target_os = "windows"))] + fn test_shell_no_default_inject_args_unix() { + let mut params = Mapping::new(); + params.insert(Value::from("cmd"), Value::from("echo 'hey friend' | awk '{ print $2 }'")); + + let extension = ShellExtension::new(); + let output = extension.calculate(¶ms, &vec!["hello".to_owned()], &HashMap::new()); + + assert!(output.is_some()); + + assert_eq!(output.unwrap(), ExtensionResult::Single("friend".to_owned())); + } + #[test] #[cfg(target_os = "windows")] fn test_shell_args_windows() { let mut params = Mapping::new(); params.insert(Value::from("cmd"), Value::from("echo %0")); + params.insert(Value::from("inject_args"), Value::from(true)); let extension = ShellExtension::new(); let output = extension.calculate(¶ms, &vec!["hello".to_owned()], &HashMap::new()); diff --git a/src/matcher/mod.rs b/src/matcher/mod.rs index f6e09be..955e43c 100644 --- a/src/matcher/mod.rs +++ b/src/matcher/mod.rs @@ -330,7 +330,7 @@ fn default_markdown() -> Option { None } fn default_paragraph() -> bool { - true + false } fn default_html() -> Option { None