Skip to content

Commit

Permalink
function: don't pass marked values to a Type callback that isn't prep…
Browse files Browse the repository at this point in the history
…ared to accept them
  • Loading branch information
jbardin authored Mar 16, 2021
1 parent d1aeddc commit f2a1b41
Show file tree
Hide file tree
Showing 2 changed files with 60 additions and 4 deletions.
8 changes: 4 additions & 4 deletions cty/function/function.go
Original file line number Diff line number Diff line change
Expand Up @@ -142,15 +142,15 @@ func (f Function) ReturnTypeForValues(args []cty.Value) (ty cty.Type, err error)
for i, spec := range f.spec.Params {
val := posArgs[i]

if val.IsMarked() && !spec.AllowMarked {
if val.ContainsMarked() && !spec.AllowMarked {
// During type checking we just unmark values and discard their
// marks, under the assumption that during actual execution of
// the function we'll do similarly and then re-apply the marks
// afterwards. Note that this does mean that a function that
// inspects values (rather than just types) in its Type
// implementation can potentially fail to take into account marks,
// unless it specifically opts in to seeing them.
unmarked, _ := val.Unmark()
unmarked, _ := val.UnmarkDeep()
newArgs := make([]cty.Value, len(args))
copy(newArgs, args)
newArgs[i] = unmarked
Expand Down Expand Up @@ -183,9 +183,9 @@ func (f Function) ReturnTypeForValues(args []cty.Value) (ty cty.Type, err error)
for i, val := range varArgs {
realI := i + len(posArgs)

if val.IsMarked() && !spec.AllowMarked {
if val.ContainsMarked() && !spec.AllowMarked {
// See the similar block in the loop above for what's going on here.
unmarked, _ := val.Unmark()
unmarked, _ := val.UnmarkDeep()
newArgs := make([]cty.Value, len(args))
copy(newArgs, args)
newArgs[realI] = unmarked
Expand Down
56 changes: 56 additions & 0 deletions cty/function/function_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -122,6 +122,62 @@ func TestReturnTypeForValues(t *testing.T) {
Args: []cty.Value{cty.StringVal("hello")},
WantErr: true,
},
{
Spec: &Spec{
Params: []Parameter{
{
Type: cty.List(cty.DynamicPseudoType),
},
},
Type: func(args []cty.Value) (cty.Type, error) {
ty := cty.Number
for i, arg := range args {
if arg.ContainsMarked() {
return ty, fmt.Errorf("arg %d %#v contains marks", i, arg)
}
}
return ty, nil
},
Impl: stubImpl,
},
Args: []cty.Value{
cty.ListVal([]cty.Value{
cty.StringVal("ok").Mark("marked"),
}),
},
WantType: cty.Number,
},
{
Spec: &Spec{
Params: []Parameter{
{
Type: cty.List(cty.String),
},
},
VarParam: &Parameter{
Type: cty.List(cty.String),
},
Type: func(args []cty.Value) (cty.Type, error) {
ty := cty.Number
for i, arg := range args {
if arg.ContainsMarked() {
return ty, fmt.Errorf("arg %d %#v contains marks", i, arg)
}
}
return ty, nil
},
Impl: stubImpl,
},
Args: []cty.Value{
cty.ListVal([]cty.Value{
cty.StringVal("one"),
}),
cty.ListVal([]cty.Value{
cty.StringVal("two").Mark("marked"),
}),
},
WantType: cty.Number,
},
}

for i, test := range tests {
Expand Down

0 comments on commit f2a1b41

Please sign in to comment.