Skip to content

fix(parser): honor backslash-newline line continuations in here-documents - #3

Merged
cataggar merged 1 commit into
kfrom
fix/heredoc-line-continuation
Aug 16, 2026
Merged

cataggar merged 1 commit into
kfrom
fix/heredoc-line-continuation

Conversation

@cataggar

Copy link
Copy Markdown
Owner

Second defect found while running an 88k-line bash CLI (kenji-cli) under brush; surfaced as a diff in one subcommand's --help output.

Root cause

In a here-document whose delimiter is unquoted, bash removes a backslash-newline pair outright and joins the two lines. A backslash is only literal there when it precedes $, a backtick, or another backslash.

heredoc_escape_sequence covered those three characters but not newline, so the pair fell through to heredoc_literal_text and both the backslash and the newline were emitted verbatim.

$ cat <<EOF
> alpha \
> beta
> EOF
output
bash alpha beta
brush (before) alpha \ / beta

Fix

Add an explicit line-continuation rule and exclude it from the literal text rule. A quoted delimiter suppresses expansion entirely, so that path is untouched and continues to preserve the backslash — matching bash.

Testing

  • 4 new compat cases: unquoted continuation, quoted-delimiter (backslash preserved), continuation before an expansion, and a combined case exercising \$ / \` / \\ / continuation together
  • All 43 here-doc/here-string compat cases pass against the bash 5.2.15 oracle
  • brush-parser: 224/224 unit tests pass
  • cargo clippy and cargo fmt --check clean

…ents

In a here-document whose delimiter is unquoted, bash removes a
backslash-newline pair outright and joins the two lines; a backslash is
only literal there when it precedes `$`, a backtick, or another
backslash. `heredoc_escape_sequence` covered those three characters but
not newline, so the pair fell through to `heredoc_literal_text` and both
the backslash and the newline were emitted verbatim.

Add an explicit line-continuation rule and exclude it from the literal
text rule. A quoted delimiter suppresses expansion entirely, so that path
is untouched and continues to preserve the backslash, matching bash.

Before:                       After (and bash):
  $ cat <<EOF                   $ cat <<EOF
  > alpha \                     > alpha \
  > beta                        > beta
  > EOF                         > EOF
  alpha \                       alpha beta
  beta

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@cataggar
cataggar merged commit ce94d3e into k Aug 16, 2026
30 checks passed
@cataggar
cataggar deleted the fix/heredoc-line-continuation branch August 16, 2026 19:32
cataggar added a commit that referenced this pull request Aug 22, 2026
…ents (#3)

In a here-document whose delimiter is unquoted, bash removes a
backslash-newline pair outright and joins the two lines; a backslash is
only literal there when it precedes `$`, a backtick, or another
backslash. `heredoc_escape_sequence` covered those three characters but
not newline, so the pair fell through to `heredoc_literal_text` and both
the backslash and the newline were emitted verbatim.

Add an explicit line-continuation rule and exclude it from the literal
text rule. A quoted delimiter suppresses expansion entirely, so that path
is untouched and continues to preserve the backslash, matching bash.

Before:                       After (and bash):
  $ cat <<EOF                   $ cat <<EOF
  > alpha \                     > alpha \
  > beta                        > beta
  > EOF                         > EOF
  alpha \                       alpha beta
  beta

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant