Skip to content

fix: a heredoc closing marker may carry trailing whitespace (#343) - #349

Open
livingstaccato wants to merge 1 commit into
amplify-education:mainfrom
livingstaccato:fix/heredoc-marker-trailing-space
Open

fix: a heredoc closing marker may carry trailing whitespace (#343)#349
livingstaccato wants to merge 1 commit into
amplify-education:mainfrom
livingstaccato:fix/heredoc-marker-trailing-space

Conversation

@livingstaccato

@livingstaccato livingstaccato commented Sep 2, 2026

Copy link
Copy Markdown
Contributor

Fixes #343.

What

The spec puts the delimiter "alone on its own line", and Terraform's scanner ends the heredoc at a line holding the word and nothing else that matters — trailing spaces and tabs included. Both heredoc terminals required the newline to follow the word immediately:

hcl2.loads("a = <<EOF\nbody\nEOF  \nb = 1\n")
# lark.exceptions.UnexpectedToken: Unexpected token Token('STRING_CHARS', ...)

So EOF was not a marker at all. The heredoc ran on, swallowed the rest of the file, and the parse failed with an error pointing somewhere else entirely.

OpenTofu v1.12.5 reads the same file as a = "body\n", b = 1.

Why it matters more than it looks

Trailing whitespace is invisible. It survives copy-paste, it is left behind by editors that do not trim it, and it is exactly the kind of thing nobody inspects — so a file someone has been running through Terraform for months can fail here, with a message that names a line far from the real one.

What is still body text

Only whitespace is permitted after the word. EOFX and EOF x remain content, and OpenTofu agrees: it reads

a = <<EOF
EOF x
body
EOF  

as "EOF x\nbody\n", closing at the last line rather than the first.

The change is \s*(?P=heredoc)\r?\n\s*(?P=heredoc)[ \t]*\r?\n in both HEREDOC_TEMPLATE and HEREDOC_TEMPLATE_TRIM, with eleven tests covering the forms that close and the two that do not, plus the indented and CRLF cases that already worked.

Merging

This one is independent: it touches hcl2/hcl2.lark and nothing else any other open pull request of mine changes, so it can land in any order.


This pull request, and the investigation behind it, were produced by an AI assistant (Claude) working on behalf of the author. Please review with that provenance in mind.

…n#343)

The spec puts the delimiter "alone on its own line", and Terraform's
scanner ends the heredoc at a line holding the word and nothing else
that matters -- trailing spaces and tabs included. Both terminals
required the newline to follow the word immediately, so `EOF  ` was not
a marker: the heredoc ran on, swallowed the rest of the file, and the
parse failed with an error pointing somewhere else entirely.

Trailing whitespace is invisible, survives copy-paste, and is left by
editors that do not trim it, so a file someone has been running through
Terraform for months could fail here for a reason nothing in the message
suggests.

Only whitespace: `EOFX` and `EOF x` are still body text, which OpenTofu
agrees with -- it reads `<<EOF\nEOF x\nbody\nEOF  \n` as "EOF x\nbody\n"
and closes at the last line.
@livingstaccato

livingstaccato commented Sep 2, 2026

Copy link
Copy Markdown
Contributor Author

Please hold off on merging this one for now — I want to do another review pass over it before it goes in. Opened as a draft for that reason; I will mark it ready and say so here once I am done.

@livingstaccato
livingstaccato marked this pull request as ready for review September 3, 2026 02:01
@livingstaccato
livingstaccato requested a review from a team as a code owner September 3, 2026 02:01
@livingstaccato

livingstaccato commented Sep 3, 2026

Copy link
Copy Markdown
Contributor Author

Review pass done, so the hold above no longer applies — this is ready for review now.

Rebased on current main; GitHub reports it mergeable as it stands.

🤖 Drafted with Claude Code.

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.

A heredoc whose closing marker has trailing spaces fails to parse, though Terraform accepts it

1 participant