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) {
|
||||
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)
|
||||
|
||||
+26
-8
@@ -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")
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user