From 74ea81b885adc64d0194df461cbc85667294d16e Mon Sep 17 00:00:00 2001 From: Cameron Moore Date: Thu, 23 Feb 2017 22:35:20 -0600 Subject: [PATCH] tplimpl: return an error on unsupported type in isSet Fixes #3092 --- tpl/tplimpl/template_funcs.go | 10 ++++++---- tpl/tplimpl/template_funcs_test.go | 30 ++++++++++++++++++++++++------ 2 files changed, 30 insertions(+), 10 deletions(-) diff --git a/tpl/tplimpl/template_funcs.go b/tpl/tplimpl/template_funcs.go index 20f46a4e2..d4eec5b2f 100644 --- a/tpl/tplimpl/template_funcs.go +++ b/tpl/tplimpl/template_funcs.go @@ -1276,22 +1276,24 @@ func (p pairList) sort() interface{} { // isSet returns whether a given array, channel, slice, or map has a key // defined. -func isSet(a interface{}, key interface{}) bool { +func isSet(a interface{}, key interface{}) (bool, error) { av := reflect.ValueOf(a) kv := reflect.ValueOf(key) switch av.Kind() { case reflect.Array, reflect.Chan, reflect.Slice: if int64(av.Len()) > kv.Int() { - return true + return true, nil } case reflect.Map: if kv.Type() == av.Type().Key() { - return av.MapIndex(kv).IsValid() + return av.MapIndex(kv).IsValid(), nil } + default: + return false, fmt.Errorf("unsupported type %q", av.Kind()) } - return false + return false, nil } // returnWhenSet returns a given value if it set. Otherwise, it returns an diff --git a/tpl/tplimpl/template_funcs_test.go b/tpl/tplimpl/template_funcs_test.go index db7533dd3..942e4e409 100644 --- a/tpl/tplimpl/template_funcs_test.go +++ b/tpl/tplimpl/template_funcs_test.go @@ -1017,13 +1017,31 @@ func TestIntersect(t *testing.T) { func TestIsSet(t *testing.T) { t.Parallel() - aSlice := []interface{}{1, 2, 3, 5} - aMap := map[string]interface{}{"a": 1, "b": 2} - assert.True(t, isSet(aSlice, 2)) - assert.True(t, isSet(aMap, "b")) - assert.False(t, isSet(aSlice, 22)) - assert.False(t, isSet(aMap, "bc")) + for _, test := range []struct { + src interface{} + key interface{} + res bool + isErr bool + errStr string + }{ + {[]interface{}{1, 2, 3, 5}, 2, true, false, ""}, + {[]interface{}{1, 2, 3, 5}, 22, false, false, ""}, + + {map[string]interface{}{"a": 1, "b": 2}, "b", true, false, ""}, + {map[string]interface{}{"a": 1, "b": 2}, "bc", false, false, ""}, + + {time.Now(), 1, false, true, `unsupported type "struct"`}, + } { + res, err := isSet(test.src, test.key) + if test.isErr { + assert.EqualError(t, err, test.errStr) + continue + } + + assert.NoError(t, err) + assert.Equal(t, test.res, res) + } } func (x *TstX) TstRp() string {