tpl: Cast IsSet key to int for indexed types
authorCameron Moore <moorereason@gmail.com>
Wed, 3 Oct 2018 01:29:20 +0000 (20:29 -0500)
committerBjørn Erik Pedersen <bjorn.erik.pedersen@gmail.com>
Wed, 3 Oct 2018 06:36:27 +0000 (09:36 +0300)
Don't assume that the user sends an int as the key when checking against
indexed types.

Fixes #3681

tpl/collections/collections.go
tpl/collections/collections_test.go

index 1d817077f5c543c2083764da43112ffbc0c13ac5..6d11d75f4d1bb66ec595641f3e51b99bacd53a28 100644 (file)
@@ -344,7 +344,11 @@ func (ns *Namespace) IsSet(a interface{}, key interface{}) (bool, error) {
 
        switch av.Kind() {
        case reflect.Array, reflect.Chan, reflect.Slice:
-               if int64(av.Len()) > kv.Int() {
+               k, err := cast.ToIntE(key)
+               if err != nil {
+                       return false, fmt.Errorf("isset unable to use key of type %T as index", key)
+               }
+               if av.Len() > k {
                        return true, nil
                }
        case reflect.Map:
index 8f122569c578da046c30286d1573a749efe16d74..dc8929f39fece04a4c1e54703ac321a5ccceb206 100644 (file)
@@ -438,22 +438,24 @@ func TestIsSet(t *testing.T) {
                key    interface{}
                expect bool
                isErr  bool
-               errStr string
        }{
-               {[]interface{}{1, 2, 3, 5}, 2, true, false, ""},
-               {[]interface{}{1, 2, 3, 5}, 22, false, false, ""},
+               {[]interface{}{1, 2, 3, 5}, 2, true, false},
+               {[]interface{}{1, 2, 3, 5}, "2", true, false},
+               {[]interface{}{1, 2, 3, 5}, 2.0, true, false},
 
-               {map[string]interface{}{"a": 1, "b": 2}, "b", true, false, ""},
-               {map[string]interface{}{"a": 1, "b": 2}, "bc", false, false, ""},
+               {[]interface{}{1, 2, 3, 5}, 22, false, false},
 
-               {time.Now(), "Day", false, false, ""},
-               {nil, "nil", false, false, ""},
+               {map[string]interface{}{"a": 1, "b": 2}, "b", true, false},
+               {map[string]interface{}{"a": 1, "b": 2}, "bc", false, false},
+
+               {time.Now(), "Day", false, false},
+               {nil, "nil", false, false},
+               {[]interface{}{1, 2, 3, 5}, TstX{}, false, true},
        } {
                errMsg := fmt.Sprintf("[%d] %v", i, test)
 
                result, err := ns.IsSet(test.a, test.key)
                if test.isErr {
-                       assert.EqualError(t, err, test.errStr, errMsg)
                        continue
                }