diff --git a/decode_value.go b/decode_value.go index d2ff2ae..4938fc8 100644 --- a/decode_value.go +++ b/decode_value.go @@ -55,13 +55,6 @@ func getDecoder(typ reflect.Type) decoderFunc { } func _getDecoder(typ reflect.Type) decoderFunc { - kind := typ.Kind() - - if kind == reflect.Ptr { - if _, ok := typeDecMap.Load(typ.Elem()); ok { - return ptrValueDecoder(typ) - } - } if typ.Implements(customDecoderType) { return nilAwareDecoder(typ, decodeCustomValue) @@ -76,6 +69,15 @@ func _getDecoder(typ reflect.Type) decoderFunc { return nilAwareDecoder(typ, unmarshalTextValue) } + kind := typ.Kind() + if kind == reflect.Ptr { + //if kind is ptr, like &msgpack.RawMessage, will use wrong cache msgpack.RawMessage => ptrValueDecoder + //and goto ptrValueDecoder if has nil code then panic + if _, ok := typeDecMap.Load(typ.Elem()); ok { + return ptrValueDecoder(typ) + } + } + // Addressable struct field value. if kind != reflect.Ptr { ptr := reflect.PtrTo(typ) @@ -126,7 +128,8 @@ func ptrValueDecoder(typ reflect.Type) decoderFunc { decoder := getDecoder(typ.Elem()) return func(d *Decoder, v reflect.Value) error { if d.hasNilCode() { - if !v.IsNil() { + //nil code but v can't set and panic error + if !v.IsNil() && v.CanSet() { v.Set(reflect.Zero(v.Type())) } return d.DecodeNil()