From b857e806ffef73f9370bb301029df15c72095286 Mon Sep 17 00:00:00 2001 From: Alisdair McDiarmid Date: Wed, 9 Dec 2020 15:00:19 -0500 Subject: [PATCH] hclsyntax: Fix panic when expanding marked funargs Functions which accept multiple parameters can be called with the expansion operator, `...`. When doing so, we must unmark the expanded argument value before transforming it into a collection of function arguments. To ensure that any marks applied to the collection are preserved, we transfer the collection marks to the individual elements as we build the argument list. --- hclsyntax/expression.go | 6 +++++- hclsyntax/expression_test.go | 17 +++++++++++++++++ 2 files changed, 22 insertions(+), 1 deletion(-) diff --git a/hclsyntax/expression.go b/hclsyntax/expression.go index 3b167be..e995110 100644 --- a/hclsyntax/expression.go +++ b/hclsyntax/expression.go @@ -317,13 +317,17 @@ func (e *FunctionCallExpr) Value(ctx *hcl.EvalContext) (cty.Value, hcl.Diagnosti return cty.DynamicVal, diags } + // When expanding arguments from a collection, we must first unmark + // the collection itself, and apply any marks directly to the + // elements. This ensures that marks propagate correctly. + expandVal, marks := expandVal.Unmark() newArgs := make([]Expression, 0, (len(args)-1)+expandVal.LengthInt()) newArgs = append(newArgs, args[:len(args)-1]...) it := expandVal.ElementIterator() for it.Next() { _, val := it.Element() newArgs = append(newArgs, &LiteralValueExpr{ - Val: val, + Val: val.WithMarks(marks), SrcRange: expandExpr.Range(), }) } diff --git a/hclsyntax/expression_test.go b/hclsyntax/expression_test.go index 9885b89..1fd4f51 100644 --- a/hclsyntax/expression_test.go +++ b/hclsyntax/expression_test.go @@ -1594,6 +1594,23 @@ EOT cty.NumberIntVal(1), 0, }, + { // marked argument expansion + `min(xs...)`, + &hcl.EvalContext{ + Functions: map[string]function.Function{ + "min": stdlib.MinFunc, + }, + Variables: map[string]cty.Value{ + "xs": cty.ListVal([]cty.Value{ + cty.NumberIntVal(3), + cty.NumberIntVal(1), + cty.NumberIntVal(4), + }).Mark("sensitive"), + }, + }, + cty.NumberIntVal(1).Mark("sensitive"), + 0, + }, } for _, test := range tests {