|
|
|
@ -45,13 +45,36 @@ impl<'a> From<&'a str> for Shellwords<'a> {
|
|
|
|
|
let mut words = Vec::new();
|
|
|
|
|
let mut parts = Vec::new();
|
|
|
|
|
let mut escaped = String::with_capacity(input.len());
|
|
|
|
|
let mut inside_variable_expansion = false;
|
|
|
|
|
|
|
|
|
|
let mut part_start = 0;
|
|
|
|
|
let mut unescaped_start = 0;
|
|
|
|
|
let mut end = 0;
|
|
|
|
|
|
|
|
|
|
for (i, c) in input.char_indices() {
|
|
|
|
|
state = match state {
|
|
|
|
|
if !inside_variable_expansion {
|
|
|
|
|
if c == '%' {
|
|
|
|
|
//%sh{this "should" be escaped}
|
|
|
|
|
if let Some(t) = input.get(i + 1..i + 3) {
|
|
|
|
|
if t == "sh" {
|
|
|
|
|
inside_variable_expansion = true;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
//%{this "should" be escaped}
|
|
|
|
|
if let Some(t) = input.get(i + 1..i + 2) {
|
|
|
|
|
if t == "{" {
|
|
|
|
|
inside_variable_expansion = true;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
} else {
|
|
|
|
|
if c == '}' {
|
|
|
|
|
inside_variable_expansion = false;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
state = if !inside_variable_expansion {
|
|
|
|
|
match state {
|
|
|
|
|
OnWhitespace => match c {
|
|
|
|
|
'"' => {
|
|
|
|
|
end = i;
|
|
|
|
@ -72,7 +95,7 @@ impl<'a> From<&'a str> for Shellwords<'a> {
|
|
|
|
|
}
|
|
|
|
|
c if c.is_ascii_whitespace() => {
|
|
|
|
|
end = i;
|
|
|
|
|
OnWhitespace
|
|
|
|
|
Unquoted
|
|
|
|
|
}
|
|
|
|
|
_ => Unquoted,
|
|
|
|
|
},
|
|
|
|
@ -127,6 +150,9 @@ impl<'a> From<&'a str> for Shellwords<'a> {
|
|
|
|
|
_ => Dquoted,
|
|
|
|
|
},
|
|
|
|
|
DquoteEscaped => Dquoted,
|
|
|
|
|
}
|
|
|
|
|
} else {
|
|
|
|
|
state
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
let c_len = c.len_utf8();
|
|
|
|
|