squash: validate type of sqashed fields also (bug-fix)
If the user adds a 'squash' tag to a non-struct type, the call to
structType.NumField() will silently fail, the application stops.
Fixed by adding an error if the squashed field's type is not struct.
diff --git a/mapstructure.go b/mapstructure.go
index 319a8b4..a367a95 100644
--- a/mapstructure.go
+++ b/mapstructure.go
@@ -623,11 +623,12 @@
structs = structs[1:]
structType := structVal.Type()
+
for i := 0; i < structType.NumField(); i++ {
fieldType := structType.Field(i)
+ fieldKind := fieldType.Type.Kind()
if fieldType.Anonymous {
- fieldKind := fieldType.Type.Kind()
if fieldKind != reflect.Struct {
errors = appendErrors(errors,
fmt.Errorf("%s: unsupported type: %s", fieldType.Name, fieldKind))
@@ -646,7 +647,12 @@
}
if squash {
- structs = append(structs, val.FieldByName(fieldType.Name))
+ if fieldKind != reflect.Struct {
+ errors = appendErrors(errors,
+ fmt.Errorf("%s: unsupported type for squash: %s", fieldType.Name, fieldKind))
+ } else {
+ structs = append(structs, val.FieldByName(fieldType.Name))
+ }
continue
}
diff --git a/mapstructure_test.go b/mapstructure_test.go
index 99fa5e0..45e7284 100644
--- a/mapstructure_test.go
+++ b/mapstructure_test.go
@@ -3,6 +3,7 @@
import (
"reflect"
"sort"
+ "strings"
"testing"
)
@@ -36,6 +37,10 @@
Vunique string
}
+type SquashOnNonStructType struct {
+ InvalidSquashType int `mapstructure:",squash"`
+}
+
type Map struct {
Vfoo string
Vother map[string]string
@@ -270,6 +275,22 @@
}
}
+func TestDecode_SquashOnNonStructType(t *testing.T) {
+ t.Parallel()
+
+ input := map[string]interface{}{
+ "InvalidSquashType": 42,
+ }
+
+ var result SquashOnNonStructType
+ err := Decode(input, &result)
+ if err == nil {
+ t.Fatal("unexpected success decoding invalid squash field type")
+ } else if !strings.Contains(err.Error(), "unsupported type for squash") {
+ t.Fatalf("unexpected error message for invalid squash field type: %s", err)
+ }
+}
+
func TestDecode_DecodeHook(t *testing.T) {
t.Parallel()