hclsyntax: do not panic when encountering a null + sequence (...)

Previously functions such as concat() would result in a panic if there
was a null element and a sequence, as in the included test. This PR adds
a check if the error index is outside of the range of arguments and
crafts an error that references the entire function instead of the null
argument.
This commit is contained in:
Kristin Laemmert 2020-06-03 09:13:36 -04:00
parent a20a69ce16
commit d9969e8731
2 changed files with 42 additions and 15 deletions

View File

@ -406,22 +406,39 @@ func (e *FunctionCallExpr) Value(ctx *hcl.EvalContext) (cty.Value, hcl.Diagnosti
} else { } else {
param = varParam param = varParam
} }
argExpr := e.Args[i]
// TODO: we should also unpick a PathError here and show the // this can happen if an argument is (incorrectly) null.
// path to the deep value where the error was detected. if i > len(e.Args)-1 {
diags = append(diags, &hcl.Diagnostic{ diags = append(diags, &hcl.Diagnostic{
Severity: hcl.DiagError, Severity: hcl.DiagError,
Summary: "Invalid function argument", Summary: "Invalid function argument",
Detail: fmt.Sprintf( Detail: fmt.Sprintf(
"Invalid value for %q parameter: %s.", "Invalid value for %q parameter: %s.",
param.Name, err, param.Name, err,
), ),
Subject: argExpr.StartRange().Ptr(), Subject: args[len(params)].StartRange().Ptr(),
Context: e.Range().Ptr(), Context: e.Range().Ptr(),
Expression: argExpr, Expression: e,
EvalContext: ctx, EvalContext: ctx,
}) })
} else {
argExpr := e.Args[i]
// TODO: we should also unpick a PathError here and show the
// path to the deep value where the error was detected.
diags = append(diags, &hcl.Diagnostic{
Severity: hcl.DiagError,
Summary: "Invalid function argument",
Detail: fmt.Sprintf(
"Invalid value for %q parameter: %s.",
param.Name, err,
),
Subject: argExpr.StartRange().Ptr(),
Context: e.Range().Ptr(),
Expression: argExpr,
EvalContext: ctx,
})
}
default: default:
diags = append(diags, &hcl.Diagnostic{ diags = append(diags, &hcl.Diagnostic{

View File

@ -312,6 +312,16 @@ upper(
cty.DynamicVal, cty.DynamicVal,
1, // too many function arguments 1, // too many function arguments
}, },
{
`concat([1, null]...)`,
&hcl.EvalContext{
Functions: map[string]function.Function{
"concat": stdlib.ConcatFunc,
},
},
cty.DynamicVal,
1, // argument cannot be null
},
{ {
`[]`, `[]`,
nil, nil,