command/jsonplan: Fix sensitive/unknown crash

When rendering the JSON plan sensitivity output, if the plan contained
unknown collection or structural types, Terraform would crash. We need
to detect unknown values before attempting to iterate them.

Unknown collection or structural values cannot have sensitive contents
accidentally displayed, as those values are not known until after apply.
As a result we return an empty value of the appropriate type for the
sensitivity mapping.
This commit is contained in:
Alisdair McDiarmid 2021-03-31 14:28:59 -04:00
parent 788c57a7c3
commit ff32fab41a
2 changed files with 26 additions and 0 deletions

View File

@ -522,6 +522,11 @@ func sensitiveAsBool(val cty.Value) cty.Value {
case val.IsNull(), ty.IsPrimitiveType(), ty.Equals(cty.DynamicPseudoType):
return cty.False
case ty.IsListType() || ty.IsTupleType() || ty.IsSetType():
if !val.IsKnown() {
// If the collection is unknown we can't say anything about the
// sensitivity of its contents
return cty.EmptyTupleVal
}
length := val.LengthInt()
if length == 0 {
// If there are no elements then we can't have sensitive values
@ -540,6 +545,11 @@ func sensitiveAsBool(val cty.Value) cty.Value {
// indistinguishable in JSON.
return cty.TupleVal(vals)
case ty.IsMapType() || ty.IsObjectType():
if !val.IsKnown() {
// If the map/object is unknown we can't say anything about the
// sensitivity of its attributes
return cty.EmptyObjectVal
}
var length int
switch {
case ty.IsMapType():

View File

@ -447,6 +447,22 @@ func TestSensitiveAsBool(t *testing.T) {
cty.EmptyObjectVal,
}),
},
{
cty.ObjectVal(map[string]cty.Value{
"list": cty.UnknownVal(cty.List(cty.String)),
"set": cty.UnknownVal(cty.Set(cty.Bool)),
"tuple": cty.UnknownVal(cty.Tuple([]cty.Type{cty.String, cty.Number})),
"map": cty.UnknownVal(cty.Map(cty.String)),
"object": cty.UnknownVal(cty.Object(map[string]cty.Type{"a": cty.String})),
}),
cty.ObjectVal(map[string]cty.Value{
"list": cty.EmptyTupleVal,
"set": cty.EmptyTupleVal,
"tuple": cty.EmptyTupleVal,
"map": cty.EmptyObjectVal,
"object": cty.EmptyObjectVal,
}),
},
}
for _, test := range tests {