dont't panic when marshal from nil or unmarshal to nil interface or pointer (#353)

This commit is contained in:
Allen
2020-04-15 20:41:18 +08:00
committed by GitHub
parent 8e8d2a6aad
commit 145b18309a
2 changed files with 39 additions and 8 deletions
+13
View File
@@ -281,6 +281,9 @@ func (e *Encoder) SetTagMultiline(v string) *Encoder {
func (e *Encoder) marshal(v interface{}) ([]byte, error) {
mtype := reflect.TypeOf(v)
if mtype == nil {
return []byte{}, errors.New("nil cannot be marshaled to TOML")
}
switch mtype.Kind() {
case reflect.Struct, reflect.Map:
@@ -288,6 +291,9 @@ func (e *Encoder) marshal(v interface{}) ([]byte, error) {
if mtype.Elem().Kind() != reflect.Struct {
return []byte{}, errors.New("Only pointer to struct can be marshaled to TOML")
}
if reflect.ValueOf(v).IsNil() {
return []byte{}, errors.New("nil pointer cannot be marshaled to TOML")
}
default:
return []byte{}, errors.New("Only a struct or map can be marshaled to TOML")
}
@@ -538,6 +544,9 @@ func (d *Decoder) SetTagName(v string) *Decoder {
func (d *Decoder) unmarshal(v interface{}) error {
mtype := reflect.TypeOf(v)
if mtype == nil {
return errors.New("nil cannot be unmarshaled from TOML")
}
if mtype.Kind() != reflect.Ptr {
return errors.New("only a pointer to struct or map can be unmarshaled from TOML")
}
@@ -550,6 +559,10 @@ func (d *Decoder) unmarshal(v interface{}) error {
return errors.New("only a pointer to struct or map can be unmarshaled from TOML")
}
if reflect.ValueOf(v).IsNil() {
return errors.New("nil pointer cannot be unmarshaled from TOML")
}
vv := reflect.ValueOf(v).Elem()
sval, err := d.valueFromTree(elem, d.tval, &vv)
+18
View File
@@ -2772,3 +2772,21 @@ InnerField2 = 2048
t.Errorf("Bad unmarshal: expected %v, got %v", expected, actual)
}
}
func TestMarshalNil(t *testing.T) {
if _, err := Marshal(nil); err == nil {
t.Errorf("Expected err from nil marshal")
}
if _, err := Marshal((*struct{})(nil)); err == nil {
t.Errorf("Expected err from nil marshal")
}
}
func TestUnmarshalNil(t *testing.T) {
if err := Unmarshal([]byte(`whatever = "whatever"`), nil); err == nil {
t.Errorf("Expected err from nil marshal")
}
if err := Unmarshal([]byte(`whatever = "whatever"`), (*struct{})(nil)); err == nil {
t.Errorf("Expected err from nil marshal")
}
}