1use nu_utils::escape_quote_string;
2
3fn string_should_be_quoted(input: &str) -> bool {
4 input.starts_with('$')
5 || input
6 .chars()
7 .any(|c| c == ' ' || c == '(' || c == '\'' || c == '`' || c == '"' || c == '\\')
8}
9
10pub fn escape_for_script_arg(input: &str) -> String {
18 if input.starts_with("--") {
20 if let Some((arg_name, arg_val)) = input.split_once('=') {
21 let arg_val = if string_should_be_quoted(arg_val) {
23 escape_quote_string(arg_val)
24 } else {
25 arg_val.into()
26 };
27
28 return format!("{arg_name}={arg_val}");
29 } else {
30 return input.into();
31 }
32 }
33 if string_should_be_quoted(input) {
34 escape_quote_string(input)
35 } else {
36 input.into()
37 }
38}
39
40#[cfg(test)]
41mod test {
42 use super::escape_for_script_arg;
43
44 #[test]
45 fn test_not_extra_quote() {
46 assert_eq!(escape_for_script_arg("word"), "word".to_string());
49 assert_eq!(escape_for_script_arg("8"), "8".to_string());
50 }
51
52 #[test]
53 fn test_quote_special() {
54 assert_eq!(
57 escape_for_script_arg("two words"),
58 r#""two words""#.to_string()
59 );
60 assert_eq!(escape_for_script_arg("$nake"), r#""$nake""#.to_string());
61 assert_eq!(escape_for_script_arg("`123"), r#""`123""#.to_string());
62 }
63
64 #[test]
65 fn test_arg_with_flag() {
66 assert_eq!(escape_for_script_arg("--linux"), "--linux".to_string());
69 assert_eq!(
70 escape_for_script_arg("--version=v5.2"),
71 "--version=v5.2".to_string()
72 );
73
74 assert_eq!(escape_for_script_arg("--version"), "--version".to_string());
77 assert_eq!(escape_for_script_arg("v5.2"), "v5.2".to_string());
78 }
79
80 #[test]
81 fn test_flag_arg_with_values_contains_special() {
82 assert_eq!(
85 escape_for_script_arg("--version='xx yy'"),
86 r#"--version="'xx yy'""#.to_string()
87 );
88 assert_eq!(
89 escape_for_script_arg("--separator=`"),
90 r#"--separator="`""#.to_string()
91 );
92 }
93
94 #[test]
95 fn test_escape() {
96 assert_eq!(escape_for_script_arg(r"\"), r#""\\""#.to_string());
99 assert_eq!(
100 escape_for_script_arg(r#"--arg=""#),
101 r#"--arg="\"""#.to_string()
102 );
103 }
104}