Fix decodeSlice to check input type before calling its Len method
diff --git a/mapstructure.go b/mapstructure.go index 0c23d8b..62fe1be 100644 --- a/mapstructure.go +++ b/mapstructure.go
@@ -470,16 +470,13 @@ dataValKind := dataVal.Kind() valType := val.Type() valElemType := valType.Elem() - - // Make a new slice to hold our result, same size as the original data. sliceType := reflect.SliceOf(valElemType) - valSlice := reflect.MakeSlice(sliceType, dataVal.Len(), dataVal.Len()) // Check input type if dataValKind != reflect.Array && dataValKind != reflect.Slice { // Accept empty map instead of array/slice in weakly typed mode if d.config.WeaklyTypedInput && dataVal.Kind() == reflect.Map && dataVal.Len() == 0 { - val.Set(valSlice) + val.Set(reflect.MakeSlice(sliceType, 0, 0)) return nil } else { return fmt.Errorf( @@ -487,6 +484,9 @@ } } + // Make a new slice to hold our result, same size as the original data. + valSlice := reflect.MakeSlice(sliceType, dataVal.Len(), dataVal.Len()) + // Accumulate any errors errors := make([]string, 0)
diff --git a/mapstructure_test.go b/mapstructure_test.go index e82d508..3147f55 100644 --- a/mapstructure_test.go +++ b/mapstructure_test.go
@@ -593,6 +593,21 @@ testSliceInput(t, inputStringSlicePointer, outputStringSlice) } +func TestInvalidSlice(t *testing.T) { + t.Parallel() + + input := map[string]interface{}{ + "vfoo": "foo", + "vbar": 42, + } + + result := Slice{} + err := Decode(input, &result) + if err == nil { + t.Errorf("expected failure") + } +} + func TestSliceOfStruct(t *testing.T) { t.Parallel()