hugo

Unnamed repository; edit this file 'description' to name the repository.

git clone git://git.shimmy1996.com/hugo.git
commit 74ea81b885adc64d0194df461cbc85667294d16e
parent 577522bd45078fef46655d38f3e831d1df6b2744
Author: Cameron Moore <moorereason@gmail.com>
Date:   Thu, 23 Feb 2017 22:35:20 -0600

tplimpl: return an error on unsupported type in isSet

Fixes #3092

Diffstat:
Mtpl/tplimpl/template_funcs.go | 10++++++----
Mtpl/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
@@ -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
@@ -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 {