Skip to content

Commit

Permalink
KeysFunc: apply top-level marks to result
Browse files Browse the repository at this point in the history
  • Loading branch information
mildwonkey committed Apr 20, 2021
1 parent c65249e commit 62cea37
Show file tree
Hide file tree
Showing 2 changed files with 6 additions and 50 deletions.
14 changes: 6 additions & 8 deletions cty/function/stdlib/collection.go
Original file line number Diff line number Diff line change
Expand Up @@ -564,9 +564,7 @@ var KeysFunc = function.New(&function.Spec{
}
},
Impl: func(args []cty.Value, retType cty.Type) (cty.Value, error) {
// Since map keys cannot be marked, we don't need to preserve the deeply-nested marks.
m, marks := args[0].Unmark()
m, _ = m.UnmarkDeep()
m, marks := args[0].UnmarkDeep()
var keys []cty.Value

switch {
Expand All @@ -579,26 +577,26 @@ var KeysFunc = function.New(&function.Spec{
}
sort.Strings(names) // same ordering guaranteed by cty's ElementIterator
if len(names) == 0 {
return cty.EmptyTupleVal.WithMarks(marks), nil
return cty.EmptyTupleVal, nil
}
keys = make([]cty.Value, len(names))
for i, name := range names {
keys[i] = cty.StringVal(name)
}
return cty.TupleVal(keys).WithMarks(marks), nil
return cty.TupleVal(keys), nil
default:
if !m.IsKnown() {
return cty.UnknownVal(retType).WithMarks(marks), nil
return cty.UnknownVal(retType), nil
}

// cty guarantees that ElementIterator will iterate in lexicographical
// order by key.
for it := m.ElementIterator(); it.Next(); {
for it := args[0].ElementIterator(); it.Next(); {
k, _ := it.Element()
keys = append(keys, k)
}
if len(keys) == 0 {
return cty.ListValEmpty(cty.String).WithMarks(marks), nil
return cty.ListValEmpty(cty.String), nil
}
return cty.ListVal(keys).WithMarks(marks), nil
}
Expand Down
42 changes: 0 additions & 42 deletions cty/function/stdlib/collection_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -1328,48 +1328,6 @@ func TestZipMap(t *testing.T) {
}
}

func TestKeys(t *testing.T) {
tests := []struct {
Collection cty.Value
Want cty.Value
Err bool
}{
{
cty.MapVal(map[string]cty.Value{"hello": cty.StringVal("world")}),
cty.ListVal([]cty.Value{cty.StringVal("hello")}),
false,
},
{ // The map itself is not marked, just an inner element.
cty.MapVal(map[string]cty.Value{"hello": cty.StringVal("world").Mark("a")}),
cty.ListVal([]cty.Value{cty.StringVal("hello")}),
false,
},
{ // The entire map is marked, and we refuse to risk returning sensitive keys.
cty.MapVal(map[string]cty.Value{"hello": cty.StringVal("world")}).Mark("a"),
cty.NilVal,
false,
},
}

for _, test := range tests {
t.Run(fmt.Sprintf("Keys(%#v)", test.Collection), func(t *testing.T) {
got, err := Keys(test.Collection)
if test.Err {
if err == nil {
t.Fatal("succeeded; want error")
}
return
} else if err != nil {
t.Fatalf("unexpected error: %s", err)
}

if !got.RawEquals(test.Want) {
t.Errorf("wrong result\ngot: %#v\nwant: %#v", got, test.Want)
}
})
}
}

func TestKeys(t *testing.T) {
tests := []struct {
Collection cty.Value
Expand Down

0 comments on commit 62cea37

Please sign in to comment.