1
0

fix(windows): improve backslash handling in command lexer

Handle multiple backslashes before quotes correctly by counting them and applying Windows command line parsing rules. Even number of backslashes before quote are treated as escape sequences, odd number as literal quotes.
This commit is contained in:
2025-10-22 20:27:40 +08:00
parent 563ab483fc
commit 217d3d5fd3

View File

@ -251,26 +251,33 @@ impl<I: Iterator<Item = char>> Iterator for CmdLexer<I> {
// Handle backslash // Handle backslash
'\\' => { '\\' => {
if let Some(pc) = self.chars.peek().copied() { // Eat backslash as much as possible and count it.
match pc { let mut backslashes: usize = 1;
'\\' => { while self.chars.peek().copied() == Some('\\') {
// Double backslash are treated as single backslash self.chars.next();
self.chars.next(); backslashes += 1;
token.push(pc); }
}
'"' => { if self.chars.peek().copied() == Some('"') {
// Backslash with an quote is interpreted as an literal quote // Rule: backslashes before a double quote are special
self.chars.next();
token.push(pc); // consume the "
} let quote = self.chars.next().unwrap();
_ => {
// Treated as normal backslash // Even number: backslashes become half, quote is delimiter
token.push(c); // Odd number: backslashes become half, quote is literal
} let num_slashes = backslashes / 2;
let is_literal_quote = backslashes % 2 != 0;
token.push_str(&"\\".repeat(num_slashes));
if is_literal_quote {
token.push(quote);
} else {
in_quotes = !in_quotes;
} }
} else { } else {
// There is no more chars, treat it as normal. // Not followed by quote: treat all backslashes literally
token.push(c); token.push_str(&"\\".repeat(backslashes));
} }
} }