diff options
Diffstat (limited to 'libgo/go/encoding/xml')
-rw-r--r-- | libgo/go/encoding/xml/marshal.go | 2 | ||||
-rw-r--r-- | libgo/go/encoding/xml/marshal_test.go | 36 |
2 files changed, 37 insertions, 1 deletions
diff --git a/libgo/go/encoding/xml/marshal.go b/libgo/go/encoding/xml/marshal.go index 6859be0..7792ac7 100644 --- a/libgo/go/encoding/xml/marshal.go +++ b/libgo/go/encoding/xml/marshal.go @@ -512,7 +512,7 @@ func (p *printer) marshalValue(val reflect.Value, finfo *fieldInfo, startTemplat } fv := finfo.value(val, dontInitNilPointers) - if finfo.flags&fOmitEmpty != 0 && isEmptyValue(fv) { + if finfo.flags&fOmitEmpty != 0 && (!fv.IsValid() || isEmptyValue(fv)) { continue } diff --git a/libgo/go/encoding/xml/marshal_test.go b/libgo/go/encoding/xml/marshal_test.go index 115a93f..0b6965d 100644 --- a/libgo/go/encoding/xml/marshal_test.go +++ b/libgo/go/encoding/xml/marshal_test.go @@ -2499,3 +2499,39 @@ func TestInvalidXMLName(t *testing.T) { t.Errorf("error %q does not contain %q", err, want) } } + +// Issue 50164. Crash on zero value XML attribute. +type LayerOne struct { + XMLName Name `xml:"l1"` + + Value *float64 `xml:"value,omitempty"` + *LayerTwo `xml:",omitempty"` +} + +type LayerTwo struct { + ValueTwo *int `xml:"value_two,attr,omitempty"` +} + +func TestMarshalZeroValue(t *testing.T) { + proofXml := `<l1><value>1.2345</value></l1>` + var l1 LayerOne + err := Unmarshal([]byte(proofXml), &l1) + if err != nil { + t.Fatalf("unmarshal XML error: %v", err) + } + want := float64(1.2345) + got := *l1.Value + if got != want { + t.Fatalf("unexpected unmarshal result, want %f but got %f", want, got) + } + + // Marshal again (or Encode again) + // In issue 50164, here `Marshal(l1)` will panic because of the zero value of xml attribute ValueTwo `value_two`. + anotherXML, err := Marshal(l1) + if err != nil { + t.Fatalf("marshal XML error: %v", err) + } + if string(anotherXML) != proofXml { + t.Fatalf("unexpected unmarshal result, want %q but got %q", proofXml, anotherXML) + } +} |