1use nu_utils::escape_quote_string;
2
3fn string_should_be_quoted(input: &str) -> bool {
4 input.starts_with('$')
5 || input.chars().any(|c| {
6 c == ' '
7 || c == '('
8 || c == '\''
9 || c == '`'
10 || c == '"'
11 || c == '\\'
12 || c == ';'
13 || c == '|'
14 })
15}
16
17pub fn escape_for_script_arg(input: &str) -> String {
25 if input.starts_with("--") {
27 if let Some((arg_name, arg_val)) = input.split_once('=') {
28 let arg_val = if string_should_be_quoted(arg_val) {
30 escape_quote_string(arg_val)
31 } else {
32 arg_val.into()
33 };
34
35 return format!("{arg_name}={arg_val}");
36 } else {
37 return input.into();
38 }
39 }
40 if string_should_be_quoted(input) {
41 escape_quote_string(input)
42 } else {
43 input.into()
44 }
45}
46
47#[cfg(test)]
48mod test {
49 use super::escape_for_script_arg;
50
51 #[test]
52 fn test_not_extra_quote() {
53 assert_eq!(escape_for_script_arg("word"), "word".to_string());
56 assert_eq!(escape_for_script_arg("8"), "8".to_string());
57 }
58
59 #[test]
60 fn test_quote_special() {
61 let cases = vec![
62 ("two words", r#""two words""#),
63 ("$nake", r#""$nake""#),
64 ("`123", r#""`123""#),
65 ("this|cat", r#""this|cat""#),
66 ("this;cat", r#""this;cat""#),
67 ];
68
69 for (input, expected) in cases {
70 assert_eq!(escape_for_script_arg(input).as_str(), expected);
71 }
72 }
73
74 #[test]
75 fn test_arg_with_flag() {
76 assert_eq!(escape_for_script_arg("--linux"), "--linux".to_string());
79 assert_eq!(
80 escape_for_script_arg("--version=v5.2"),
81 "--version=v5.2".to_string()
82 );
83
84 assert_eq!(escape_for_script_arg("--version"), "--version".to_string());
87 assert_eq!(escape_for_script_arg("v5.2"), "v5.2".to_string());
88 }
89
90 #[test]
91 fn test_flag_arg_with_values_contains_special() {
92 assert_eq!(
95 escape_for_script_arg("--version='xx yy'"),
96 r#"--version="'xx yy'""#.to_string()
97 );
98 assert_eq!(
99 escape_for_script_arg("--separator=`"),
100 r#"--separator="`""#.to_string()
101 );
102 }
103
104 #[test]
105 fn test_escape() {
106 assert_eq!(escape_for_script_arg(r"\"), r#""\\""#.to_string());
109 assert_eq!(
110 escape_for_script_arg(r#"--arg=""#),
111 r#"--arg="\"""#.to_string()
112 );
113 }
114}