Fix decoding of pointer of empty interface type

This commit is contained in:
Masaaki Goshima 2021-02-12 20:05:44 +09:00
parent 336ad146cc
commit 6ebd44bb93
1 changed files with 16 additions and 9 deletions

View File

@ -13,6 +13,12 @@ type interfaceDecoder struct {
} }
func newInterfaceDecoder(typ *rtype, structName, fieldName string) *interfaceDecoder { func newInterfaceDecoder(typ *rtype, structName, fieldName string) *interfaceDecoder {
if typ == emptyInterfaceType {
// If type is the same as emptyInterface ( `interface{}` ),
// the address of `*interface{}` type will be passed when actually decoding,
// so type must be converted to pointer type.
typ = type2rtype(reflect.New(rtype2type(typ)).Type())
}
return &interfaceDecoder{ return &interfaceDecoder{
typ: typ, typ: typ,
structName: structName, structName: structName,
@ -32,7 +38,8 @@ func (d *interfaceDecoder) numDecoder(s *stream) decoder {
} }
var ( var (
interfaceMapType = type2rtype( emptyInterfaceType = type2rtype(reflect.TypeOf((*interface{})(nil)).Elem())
interfaceMapType = type2rtype(
reflect.TypeOf((*map[string]interface{})(nil)).Elem(), reflect.TypeOf((*map[string]interface{})(nil)).Elem(),
) )
stringType = type2rtype( stringType = type2rtype(
@ -82,7 +89,7 @@ func (d *interfaceDecoder) decodeStreamEmptyInterface(s *stream, p unsafe.Pointe
stringType, stringType,
newStringDecoder(d.structName, d.fieldName), newStringDecoder(d.structName, d.fieldName),
interfaceMapType.Elem(), interfaceMapType.Elem(),
newInterfaceDecoder(d.typ, d.structName, d.fieldName), newInterfaceDecoder(emptyInterfaceType, d.structName, d.fieldName),
d.structName, d.structName,
d.fieldName, d.fieldName,
).decodeStream(s, ptr); err != nil { ).decodeStream(s, ptr); err != nil {
@ -94,9 +101,9 @@ func (d *interfaceDecoder) decodeStreamEmptyInterface(s *stream, p unsafe.Pointe
var v []interface{} var v []interface{}
ptr := unsafe.Pointer(&v) ptr := unsafe.Pointer(&v)
if err := newSliceDecoder( if err := newSliceDecoder(
newInterfaceDecoder(d.typ, d.structName, d.fieldName), newInterfaceDecoder(emptyInterfaceType, d.structName, d.fieldName),
d.typ, emptyInterfaceType,
d.typ.Size(), emptyInterfaceType.Size(),
d.structName, d.structName,
d.fieldName, d.fieldName,
).decodeStream(s, ptr); err != nil { ).decodeStream(s, ptr); err != nil {
@ -246,7 +253,7 @@ func (d *interfaceDecoder) decodeEmptyInterface(buf []byte, cursor int64, p unsa
stringType, stringType,
newStringDecoder(d.structName, d.fieldName), newStringDecoder(d.structName, d.fieldName),
interfaceMapType.Elem(), interfaceMapType.Elem(),
newInterfaceDecoder(d.typ, d.structName, d.fieldName), newInterfaceDecoder(emptyInterfaceType, d.structName, d.fieldName),
d.structName, d.fieldName, d.structName, d.fieldName,
) )
cursor, err := dec.decode(buf, cursor, ptr) cursor, err := dec.decode(buf, cursor, ptr)
@ -259,9 +266,9 @@ func (d *interfaceDecoder) decodeEmptyInterface(buf []byte, cursor int64, p unsa
var v []interface{} var v []interface{}
ptr := unsafe.Pointer(&v) ptr := unsafe.Pointer(&v)
dec := newSliceDecoder( dec := newSliceDecoder(
newInterfaceDecoder(d.typ, d.structName, d.fieldName), newInterfaceDecoder(emptyInterfaceType, d.structName, d.fieldName),
d.typ, emptyInterfaceType,
d.typ.Size(), emptyInterfaceType.Size(),
d.structName, d.fieldName, d.structName, d.fieldName,
) )
cursor, err := dec.decode(buf, cursor, ptr) cursor, err := dec.decode(buf, cursor, ptr)