From bf2d095d861f748920a56b2302a185e52ae6d1b1 Mon Sep 17 00:00:00 2001 From: James Bardin Date: Fri, 7 Apr 2023 13:08:33 -0400 Subject: [PATCH] cty: Path.Apply should not panic with marked collections The return value of `HasIndex` can contain marks, so `IndexStep.Apply` must strip those marks before checking `True`. --- cty/path.go | 4 ++- cty/path_test.go | 64 ++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 67 insertions(+), 1 deletion(-) diff --git a/cty/path.go b/cty/path.go index 636e68c6..4995a8c7 100644 --- a/cty/path.go +++ b/cty/path.go @@ -225,7 +225,9 @@ func (s IndexStep) Apply(val Value) (Value, error) { return NilVal, errors.New("key value not number or string") } - has := val.HasIndex(s.Key) + // This value needs to be stripped of marks to check True(), but Index will + // apply the correct marks for the result. + has, _ := val.HasIndex(s.Key).Unmark() if !has.IsKnown() { return UnknownVal(val.Type().ElementType()), nil } diff --git a/cty/path_test.go b/cty/path_test.go index 84d0fe2b..93eaafc3 100644 --- a/cty/path_test.go +++ b/cty/path_test.go @@ -96,6 +96,70 @@ func TestPathApply(t *testing.T) { cty.NilVal, `at step 0: cannot access attributes on a null value`, }, + { + cty.ListVal([]cty.Value{ + cty.ListVal([]cty.Value{cty.StringVal("hello")}).Mark(2), + }).Mark(1), + (cty.Path)(nil).Index(cty.NumberIntVal(0)).Index(cty.NumberIntVal(0)), + cty.StringVal("hello").Mark(1).Mark(2), + ``, + }, + { + cty.TupleVal([]cty.Value{ + cty.ListVal([]cty.Value{cty.StringVal("hello")}).Mark(2), + }).Mark(1), + (cty.Path)(nil).Index(cty.NumberIntVal(0)).Index(cty.NumberIntVal(0)), + cty.StringVal("hello").Mark(1).Mark(2), + ``, + }, + { + cty.MapVal(map[string]cty.Value{ + "hello": cty.StringVal("there"), + }).Mark(1), + (cty.Path)(nil).Index(cty.StringVal("hello")), + cty.StringVal("there").Mark(1), + ``, + }, + { + cty.ObjectVal(map[string]cty.Value{ + "hello": cty.StringVal("there"), + }).Mark(1), + cty.GetAttrPath("hello"), + cty.StringVal("there").Mark(1), + ``, + }, + { + cty.ListVal([]cty.Value{ + cty.StringVal("hello").Mark(1), + }), + (cty.Path)(nil).Index(cty.NumberIntVal(0)), + cty.StringVal("hello").Mark(1), + ``, + }, + { + cty.TupleVal([]cty.Value{ + cty.StringVal("hello").Mark(1), + }), + (cty.Path)(nil).Index(cty.NumberIntVal(0)), + cty.StringVal("hello").Mark(1), + ``, + }, + { + cty.MapVal(map[string]cty.Value{ + "hello": cty.StringVal("there").Mark(1), + }), + (cty.Path)(nil).Index(cty.StringVal("hello")), + cty.StringVal("there").Mark(1), + ``, + }, + { + cty.ObjectVal(map[string]cty.Value{ + "hello": cty.StringVal("there").Mark(1), + }), + cty.GetAttrPath("hello"), + cty.StringVal("there").Mark(1), + ``, + }, } for _, test := range tests {