Skip to content

A heredoc inside a function call splices raw newlines into expression source #340

Description

@livingstaccato

Summary

SerializationContext.inside_dollar_string tells a rule it is being
serialized into expression source rather than into a value. StringRule
checks it and keeps its quotes. HeredocTemplateRule and
HeredocTrimTemplateRule never read it, so a heredoc argument is written into
the expression as its bare body, newlines and all.

Reproduction

hcl2.loads("a = upper(<<E\nx\nE\n)\n",
           serialization_options=SerializationOptions(preserve_heredocs=False,
                                                      strip_string_quotes=True))
# {'a': '${upper(x)}'}

x is now a bare reference rather than a string, and with a multi-line body
the result contains a raw newline inside ${...}, which is not parseable HCL.
The quoted-string case one line away is correct: upper("x") gives
${upper("x")}.

Both << and <<- are affected: HeredocTemplateRule.serialize
(hcl2/rules/strings.py:164 at v8.1.3) and
HeredocTrimTemplateRule.serialize (:197) both take the context and pass it
to their child, but branch only on options.strip_string_quotes.
StringRule.serialize (:115) checks context.inside_dollar_string for
exactly this case.


This issue, 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.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions