fix bug where unmarshalling into improper type causes panic. Add test for this

This commit is contained in:
Dan Laine 2020-03-26 15:14:45 -04:00
parent 541f762b55
commit c1abff8c3d
2 changed files with 44 additions and 0 deletions

View File

@ -324,6 +324,11 @@ func (c codec) unmarshal(p *wrappers.Packer, field reflect.Value) error {
if !ok {
return errUnmarshalUnregisteredType
}
// Ensure struct actually does implement the interface
fieldType := field.Type()
if !typ.Implements(fieldType) {
return fmt.Errorf("%s does not implement interface %s", typ, fieldType)
}
concreteInstancePtr := reflect.New(typ) // instance of the proper type
// Unmarshal into the struct
if err := c.unmarshal(p, concreteInstancePtr.Elem()); err != nil {

View File

@ -538,3 +538,42 @@ func TestTooLargeUnmarshal(t *testing.T) {
t.Fatalf("Should have errored due to too many bytes provided")
}
}
type outerInterface interface {
ToInt() int
}
type outer struct {
Interface outerInterface `serialize:"true"`
}
type innerInterface struct{}
func (it *innerInterface) ToInt() int {
return 0
}
type innerNoInterface struct{}
// Ensure deserializing structs into the wrong interface errors gracefully
func TestUnmarshalInvalidInterface(t *testing.T) {
codec := NewDefault()
codec.RegisterType(&innerInterface{})
codec.RegisterType(&innerNoInterface{})
{
bytes := []byte{0, 0, 0, 0}
s := outer{}
if err := codec.Unmarshal(bytes, &s); err != nil {
t.Fatal(err)
}
}
{
bytes := []byte{0, 0, 0, 1}
s := outer{}
if err := codec.Unmarshal(bytes, &s); err == nil {
t.Fatalf("should have errored")
}
}
}