From f2f7dd7632bfc062e68d1d41ecce5aac3ff464a8 Mon Sep 17 00:00:00 2001 From: Alisdair McDiarmid Date: Fri, 18 Dec 2020 14:36:38 -0500 Subject: [PATCH] hclsyntax: Fix another template loop panic If individual template expressions in a loop have marks, merge those marks into the final result when joining. --- hclsyntax/expression_template.go | 7 ++++++- hclsyntax/expression_template_test.go | 28 +++++++++++++++++++++++++++ 2 files changed, 34 insertions(+), 1 deletion(-) diff --git a/hclsyntax/expression_template.go b/hclsyntax/expression_template.go index dfce942..0b7e07a 100644 --- a/hclsyntax/expression_template.go +++ b/hclsyntax/expression_template.go @@ -153,6 +153,7 @@ func (e *TemplateJoinExpr) Value(ctx *hcl.EvalContext) (cty.Value, hcl.Diagnosti } tuple, marks := tuple.Unmark() + allMarks := []cty.ValueMarks{marks} buf := &bytes.Buffer{} it := tuple.ElementIterator() for it.Next() { @@ -193,10 +194,14 @@ func (e *TemplateJoinExpr) Value(ctx *hcl.EvalContext) (cty.Value, hcl.Diagnosti return cty.UnknownVal(cty.String).WithMarks(marks), diags } + strVal, strValMarks := strVal.Unmark() + if len(strValMarks) > 0 { + allMarks = append(allMarks, strValMarks) + } buf.WriteString(strVal.AsString()) } - return cty.StringVal(buf.String()).WithMarks(marks), diags + return cty.StringVal(buf.String()).WithMarks(allMarks...), diags } func (e *TemplateJoinExpr) Range() hcl.Range { diff --git a/hclsyntax/expression_template_test.go b/hclsyntax/expression_template_test.go index 6219c50..ef830cb 100644 --- a/hclsyntax/expression_template_test.go +++ b/hclsyntax/expression_template_test.go @@ -330,6 +330,34 @@ trim`, cty.StringVal("foobarbaz").Mark("sensitive"), 0, }, + { // marks on individual elements propagate to the result + `%{ for s in secrets }${s}%{ endfor }`, + &hcl.EvalContext{ + Variables: map[string]cty.Value{ + "secrets": cty.ListVal([]cty.Value{ + cty.StringVal("foo"), + cty.StringVal("bar").Mark("sensitive"), + cty.StringVal("baz"), + }), + }, + }, + cty.StringVal("foobarbaz").Mark("sensitive"), + 0, + }, + { // lots of marks! + `%{ for s in secrets }${s}%{ endfor }`, + &hcl.EvalContext{ + Variables: map[string]cty.Value{ + "secrets": cty.ListVal([]cty.Value{ + cty.StringVal("foo").Mark("x"), + cty.StringVal("bar").Mark("y"), + cty.StringVal("baz").Mark("z"), + }).Mark("x"), // second instance of x + }, + }, + cty.StringVal("foobarbaz").WithMarks(cty.NewValueMarks("x", "y", "z")), + 0, + }, } for _, test := range tests {