forked from mitchellh/mapstructure
-
Notifications
You must be signed in to change notification settings - Fork 34
Open
Description
When composing multiple decoding hooks with DecodeNil set and using the mapstructure:",remain" tag it is possible to trigger a panic in mapstructure.
Minimal reproduction code
func main() {
v := make(map[string]any)
v["m"] = nil
var result struct {
V map[string]any `mapstructure:",remain"`
}
hook := func(f reflect.Kind, t reflect.Kind, data any) (any, error) {
return data, nil
}
dec, _ := mapstructure.NewDecoder(&mapstructure.DecoderConfig{
DecodeHook: mapstructure.ComposeDecodeHookFunc(
hook, hook,
),
DecodeNil: true,
Result: &result,
})
dec.Decode(&v)
fmt.Printf("%+v\n", result)
}Output
panic: reflect: call of reflect.Value.Interface on zero Value
goroutine 1 [running]:
reflect.valueInterface({0x0?, 0x0?, 0x0?}, 0x0?)
/opt/homebrew/Cellar/go/1.24.0/libexec/src/reflect/value.go:1486 +0xfc
reflect.Value.Interface(...)
/opt/homebrew/Cellar/go/1.24.0/libexec/src/reflect/value.go:1481
github.com/go-viper/mapstructure/v2.cachedDecodeHook.func2({0x0?, 0x0?, 0x10272cfe0?}, {0x1027324e0?, 0x1400012c120?, 0x1026ecaa0?})
/Users/zoey/go/pkg/mod/github.com/go-viper/mapstructure/[email protected]/decode_hooks.go:51 +0x50
github.com/go-viper/mapstructure/v2.ComposeDecodeHookFunc.func1({0x1027324e0?, 0x1028295e0?, 0x14000146f68?}, {0x1027324e0?, 0x1400012c120?, 0x10296fac8?})
/Users/zoey/go/pkg/mod/github.com/go-viper/mapstructure/[email protected]/decode_hooks.go:99 +0xc0
github.com/go-viper/mapstructure/v2.cachedDecodeHook.func3({0x1027324e0?, 0x1028295e0?, 0x14000146fb8?}, {0x1027324e0?, 0x1400012c120?, 0x102688338?})
/Users/zoey/go/pkg/mod/github.com/go-viper/mapstructure/[email protected]/decode_hooks.go:55 +0x34
github.com/go-viper/mapstructure/v2.(*Decoder).decode(0x1400012c0b0, {0x14000116030, 0x16}, {0x0, 0x0}, {0x1027324e0?, 0x1400012c120?, 0x10271d234?})
/Users/zoey/go/pkg/mod/github.com/go-viper/mapstructure/[email protected]/mapstructure.go:532 +0x498
github.com/go-viper/mapstructure/v2.(*Decoder).decodeMapFromMap(0x1400012c0b0, {0x0, 0x0}, {0x102736600?, 0x14000112300?, 0x102736600?}, {0x102736580?, 0x1400010c048?, 0x14000147298?}, {0x102736580?, ...})
/Users/zoey/go/pkg/mod/github.com/go-viper/mapstructure/[email protected]/mapstructure.go:1029 +0x4ec
github.com/go-viper/mapstructure/v2.(*Decoder).decodeMap(0x1400012c0b0, {0x0, 0x0}, {0x102736600, 0x14000112300}, {0x102736580?, 0x1400010c048?, 0x0?})
/Users/zoey/go/pkg/mod/github.com/go-viper/mapstructure/[email protected]/mapstructure.go:955 +0x28c
github.com/go-viper/mapstructure/v2.(*Decoder).decodeStructFromMap(0x1400012c0b0, {0x0, 0x0}, {0x102736580?, 0x1400010c040?, 0x195?}, {0x102736200?, 0x1400010c048?, 0x199?})
/Users/zoey/go/pkg/mod/github.com/go-viper/mapstructure/[email protected]/mapstructure.go:1592 +0x13d4
github.com/go-viper/mapstructure/v2.(*Decoder).decodeStruct(0x1400012c0b0, {0x0, 0x0}, {0x10272a900?, 0x1400010c040?}, {0x102736200?, 0x1400010c048?, 0x1026e0efc?})
/Users/zoey/go/pkg/mod/github.com/go-viper/mapstructure/[email protected]/mapstructure.go:1388 +0x438
github.com/go-viper/mapstructure/v2.(*Decoder).decode(0x1400012c0b0, {0x0, 0x0}, {0x10272a900, 0x1400010c040}, {0x102736200?, 0x1400010c048?, 0x1026ec720?})
/Users/zoey/go/pkg/mod/github.com/go-viper/mapstructure/[email protected]/mapstructure.go:559 +0x71c
github.com/go-viper/mapstructure/v2.(*Decoder).Decode(0x1400012c0b0, {0x10272a900, 0x1400010c040})
/Users/zoey/go/pkg/mod/github.com/go-viper/mapstructure/[email protected]/mapstructure.go:461 +0xb4
main.main()
/Users/zoey/repos/jsonerrorstest/main.go:156 +0x150
exit status 2
In ComposeDecodeHookFunc the value of f reflect.Value may have f.Kind() == reflect.Interface and f.IsNil() == true, performing reflect.ValueOf() on f with these properties results in an invalid reflect.Value.
Metadata
Metadata
Assignees
Labels
No labels