dont't panic when marshal from nil or unmarshal to nil interface or pointer (#353)
This commit is contained in:
+13
@@ -281,6 +281,9 @@ func (e *Encoder) SetTagMultiline(v string) *Encoder {
|
|||||||
|
|
||||||
func (e *Encoder) marshal(v interface{}) ([]byte, error) {
|
func (e *Encoder) marshal(v interface{}) ([]byte, error) {
|
||||||
mtype := reflect.TypeOf(v)
|
mtype := reflect.TypeOf(v)
|
||||||
|
if mtype == nil {
|
||||||
|
return []byte{}, errors.New("nil cannot be marshaled to TOML")
|
||||||
|
}
|
||||||
|
|
||||||
switch mtype.Kind() {
|
switch mtype.Kind() {
|
||||||
case reflect.Struct, reflect.Map:
|
case reflect.Struct, reflect.Map:
|
||||||
@@ -288,6 +291,9 @@ func (e *Encoder) marshal(v interface{}) ([]byte, error) {
|
|||||||
if mtype.Elem().Kind() != reflect.Struct {
|
if mtype.Elem().Kind() != reflect.Struct {
|
||||||
return []byte{}, errors.New("Only pointer to struct can be marshaled to TOML")
|
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:
|
default:
|
||||||
return []byte{}, errors.New("Only a struct or map can be marshaled to TOML")
|
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 {
|
func (d *Decoder) unmarshal(v interface{}) error {
|
||||||
mtype := reflect.TypeOf(v)
|
mtype := reflect.TypeOf(v)
|
||||||
|
if mtype == nil {
|
||||||
|
return errors.New("nil cannot be unmarshaled from TOML")
|
||||||
|
}
|
||||||
if mtype.Kind() != reflect.Ptr {
|
if mtype.Kind() != reflect.Ptr {
|
||||||
return errors.New("only a pointer to struct or map can be unmarshaled from TOML")
|
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")
|
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()
|
vv := reflect.ValueOf(v).Elem()
|
||||||
|
|
||||||
sval, err := d.valueFromTree(elem, d.tval, &vv)
|
sval, err := d.valueFromTree(elem, d.tval, &vv)
|
||||||
|
|||||||
@@ -2772,3 +2772,21 @@ InnerField2 = 2048
|
|||||||
t.Errorf("Bad unmarshal: expected %v, got %v", expected, actual)
|
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")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user