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.
This commit is contained in:
Alisdair McDiarmid 2020-12-09 15:00:19 -05:00
parent d8c5050248
commit b857e806ff
2 changed files with 22 additions and 1 deletions

View File

@ -317,13 +317,17 @@ func (e *FunctionCallExpr) Value(ctx *hcl.EvalContext) (cty.Value, hcl.Diagnosti
return cty.DynamicVal, diags 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 := make([]Expression, 0, (len(args)-1)+expandVal.LengthInt())
newArgs = append(newArgs, args[:len(args)-1]...) newArgs = append(newArgs, args[:len(args)-1]...)
it := expandVal.ElementIterator() it := expandVal.ElementIterator()
for it.Next() { for it.Next() {
_, val := it.Element() _, val := it.Element()
newArgs = append(newArgs, &LiteralValueExpr{ newArgs = append(newArgs, &LiteralValueExpr{
Val: val, Val: val.WithMarks(marks),
SrcRange: expandExpr.Range(), SrcRange: expandExpr.Range(),
}) })
} }

View File

@ -1594,6 +1594,23 @@ EOT
cty.NumberIntVal(1), cty.NumberIntVal(1),
0, 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 { for _, test := range tests {