diff --git a/.changes/v1.11/BUG FIXES-20250303-125722.yaml b/.changes/v1.11/BUG FIXES-20250303-125722.yaml new file mode 100644 index 0000000000..ca7b008227 --- /dev/null +++ b/.changes/v1.11/BUG FIXES-20250303-125722.yaml @@ -0,0 +1,5 @@ +kind: BUG FIXES +body: 'lang/funcs/transpose: Avoid crash due to map with null values' +time: 2025-03-03T12:57:22.400359Z +custom: + Issue: "36611" diff --git a/internal/lang/funcs/collection.go b/internal/lang/funcs/collection.go index e64ce85894..fd41620230 100644 --- a/internal/lang/funcs/collection.go +++ b/internal/lang/funcs/collection.go @@ -582,8 +582,14 @@ var TransposeFunc = function.New(&function.Spec{ for it := inputMap.ElementIterator(); it.Next(); { inKey, inVal := it.Element() + if inVal.IsNull() { + return cty.MapValEmpty(cty.List(cty.String)), errors.New("input must not contain null list") + } for iter := inVal.ElementIterator(); iter.Next(); { _, val := iter.Element() + if val.IsNull() { + return cty.MapValEmpty(cty.List(cty.String)), errors.New("input list must not contain null string") + } if !val.Type().Equals(cty.String) { return cty.MapValEmpty(cty.List(cty.String)), errors.New("input must be a map of lists of strings") } diff --git a/internal/lang/funcs/collection_test.go b/internal/lang/funcs/collection_test.go index 3f08edc029..e7fc9ab980 100644 --- a/internal/lang/funcs/collection_test.go +++ b/internal/lang/funcs/collection_test.go @@ -1833,6 +1833,37 @@ func TestTranspose(t *testing.T) { }).WithMarks(cty.NewValueMarks("beep", "boop", "bloop")), false, }, + { + cty.NullVal(cty.Map(cty.List(cty.String))), + cty.NilVal, + true, + }, + { + cty.MapVal(map[string]cty.Value{ + "test": cty.NullVal(cty.List(cty.String)), + }), + cty.NilVal, + true, + }, + { + cty.MapVal(map[string]cty.Value{ + "test": cty.ListVal([]cty.Value{cty.NullVal(cty.String)}), + }), + cty.NilVal, + true, + }, + { + cty.UnknownVal(cty.Map(cty.List(cty.String))), + cty.UnknownVal(cty.Map(cty.List(cty.String))).RefineNotNull(), + false, + }, + { + cty.MapVal(map[string]cty.Value{ + "test": cty.ListVal([]cty.Value{cty.UnknownVal(cty.String)}), + }), + cty.UnknownVal(cty.Map(cty.List(cty.String))).RefineNotNull(), + false, + }, } for _, test := range tests {