diff --git a/marshal.go b/marshal.go index dcddad8..e921a80 100644 --- a/marshal.go +++ b/marshal.go @@ -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) diff --git a/marshal_test.go b/marshal_test.go index fec1662..33ab64a 100644 --- a/marshal_test.go +++ b/marshal_test.go @@ -1458,7 +1458,7 @@ OuterField2 = 1024 type InnerStruct struct { InnerField1 string InnerField2 int - EmbedStruct struct{ + EmbedStruct struct { EmbedField string } } @@ -1466,7 +1466,7 @@ OuterField2 = 1024 type OuterStruct struct { OuterField1 string OuterField2 int - TreeField *Tree + TreeField *Tree } tree, err := Load(` @@ -1487,7 +1487,7 @@ InnerField2 = 2048 } actual, _ := Marshal(out) - if !bytes.Equal(actual, expected){ + if !bytes.Equal(actual, expected) { t.Errorf("Bad marshal: expected %s, got %s", expected, actual) } } @@ -2739,7 +2739,7 @@ InnerField2 = 2048 type InnerStruct struct { InnerField1 string InnerField2 int - EmbedStruct struct{ + EmbedStruct struct { EmbedField string } } @@ -2747,7 +2747,7 @@ InnerField2 = 2048 type OuterStruct struct { OuterField1 string OuterField2 int - TreeField *Tree + TreeField *Tree } out := OuterStruct{} @@ -2755,10 +2755,10 @@ InnerField2 = 2048 expected := InnerStruct{ "In", 2048, - struct{ + struct { EmbedField string }{ - EmbedField:"Embed", + EmbedField: "Embed", }, } if err := Unmarshal(toml, &out); err != nil { @@ -2768,7 +2768,25 @@ InnerField2 = 2048 t.Fatal(err) } - if !reflect.DeepEqual(actual, expected){ + if !reflect.DeepEqual(actual, expected) { 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") + } +}