Skip to content

Commit 2f274d8

Browse files
committed
chore: partial eval fixes
1 parent 3f2dfba commit 2f274d8

1 file changed

Lines changed: 16 additions & 31 deletions

File tree

internal/hclparse/partial_eval.go

Lines changed: 16 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,6 @@ package hclparse
33
import (
44
"bytes"
55
"slices"
6-
"strings"
76

87
"github.com/hashicorp/hcl/v2"
98
"github.com/hashicorp/hcl/v2/hclsyntax"
@@ -136,15 +135,15 @@ func partialEvalTemplate(e *hclsyntax.TemplateExpr, args *EvalArgs) []byte {
136135

137136
for _, part := range e.Parts {
138137
if lit, ok := part.(*hclsyntax.LiteralValueExpr); ok {
139-
buf.WriteString(escapeHCLStringLit(lit.Val.AsString()))
138+
buf.Write(hclStringContent(lit.Val.AsString()))
140139

141140
continue
142141
}
143142

144143
if IsPure(part, args.Deferred) {
145144
val, diags := part.Value(args.EvalCtx)
146145
if !diags.HasErrors() && val.Type() == cty.String {
147-
buf.WriteString(escapeHCLStringLit(val.AsString()))
146+
buf.Write(hclStringContent(val.AsString()))
148147

149148
continue
150149
}
@@ -161,6 +160,20 @@ func partialEvalTemplate(e *hclsyntax.TemplateExpr, args *EvalArgs) []byte {
161160
return buf.Bytes()
162161
}
163162

163+
// hclStringContent returns the inner content of an HCL-escaped string
164+
// (without surrounding quotes). Uses hclwrite.TokensForValue for correct
165+
// escaping of all HCL special characters.
166+
func hclStringContent(s string) []byte {
167+
raw := hclwrite.TokensForValue(cty.StringVal(s)).Bytes()
168+
169+
// TokensForValue produces `"escaped content"` — strip the quotes.
170+
if len(raw) >= 2 {
171+
return raw[1 : len(raw)-1]
172+
}
173+
174+
return raw
175+
}
176+
164177
func partialEvalObject(e *hclsyntax.ObjectConsExpr, args *EvalArgs) []byte {
165178
var buf bytes.Buffer
166179

@@ -213,34 +226,6 @@ func partialEvalTuple(e *hclsyntax.TupleConsExpr, args *EvalArgs) []byte {
213226
return buf.Bytes()
214227
}
215228

216-
func escapeHCLStringLit(s string) string {
217-
var buf strings.Builder
218-
219-
buf.Grow(len(s))
220-
221-
for _, r := range s {
222-
switch r {
223-
case '\\':
224-
buf.WriteString(`\\`)
225-
case '"':
226-
buf.WriteString(`\"`)
227-
case '\n':
228-
buf.WriteString(`\n`)
229-
case '\r':
230-
buf.WriteString(`\r`)
231-
case '\t':
232-
buf.WriteString(`\t`)
233-
default:
234-
buf.WriteRune(r)
235-
}
236-
}
237-
238-
result := buf.String()
239-
result = strings.ReplaceAll(result, "${", "$${")
240-
result = strings.ReplaceAll(result, "%{", "%%{")
241-
242-
return result
243-
}
244229

245230
func valueToHCLBytes(val cty.Value) []byte {
246231
tokens := hclwrite.TokensForValue(val)

0 commit comments

Comments
 (0)