fix: allow escaping operator characters in unquoted words - #186
Merged
Conversation
A backslash before `;`, `&`, `|`, `<` or `>` now makes the character part of the word instead of being parsed as an operator, matching what quoting it already does. Previously `echo one \; two` emitted a literal backslash and then split the command at the semicolon. Closes denoland/deno#36401
|
Thanks for the quick response! |
Escaping an operator means a Windows path that ends in a separator and sits right before an operator (`cd .\foo\;echo hi`) now parses as one word. Treat `\\` immediately before an operator as two literal backslashes with the operator still terminating the word, which is what that spelling already did before the escape existed. The rule is scoped to that position, so `\\$FOO` keeps escaping the dollar sign. Also cover an escaped `>` after a file descriptor, a trailing escaped `&`, and the Windows path cases.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
A backslash currently only escapes a fixed set of characters (
$,`,",~,(,), and space). The operator characters;,&,|,<and>were not in that set, soecho one \; twoproduced a literal backslash asone word and then still split the command at the semicolon. Quoting the
character (
';'or";") already worked, so the escape form was silentlydoing the wrong thing rather than being unsupported.
This adds those five characters to the set that a backslash can escape in an
unquoted word, which makes the escapable set exactly match the set of
characters that terminate an unquoted word. Inside double quotes those
characters are already literal, so a backslash there keeps its own literal
meaning as it does in POSIX shells, and
"a\;b"is unchanged.A backslash is deliberately not made a general escape the way POSIX specifies,
because that would change the meaning of Windows paths such as
.\node_modules\.bin\xthat appear in real tasks. Such a path is onlyaffected when it ends in a separator that sits directly against an operator,
as in
cd .\foo\;echo hi— there the backslash now escapes the;. Writing\\before an operator keeps both backslashes literal and lets the operatorterminate the word, which is what that spelling already did, so the path stays
writable unquoted as
cd .\foo\\;echo hi. That carve-out is limited to theposition before an operator, so
\\$FOOstill escapes the dollar sign.Closes denoland/deno#36401