From 1ff8552d80777107b425447ed0ac0e0dd219cceb Mon Sep 17 00:00:00 2001 From: Hank Donnay Date: Tue, 28 Apr 2020 09:22:47 -0400 Subject: [PATCH] oval: allow empty date attr Signed-off-by: Hank Donnay --- oval/date_test.go | 13 +++++++++++++ oval/types.go | 21 ++++++++++++++++++--- 2 files changed, 31 insertions(+), 3 deletions(-) diff --git a/oval/date_test.go b/oval/date_test.go index f26cdb6..7e7e4cc 100644 --- a/oval/date_test.go +++ b/oval/date_test.go @@ -3,6 +3,7 @@ package oval import ( "encoding/xml" "os" + "strings" "testing" "time" @@ -124,3 +125,15 @@ func TestUbuntuDates(t *testing.T) { } } } + +func TestPointlessElement(t *testing.T) { + const doc = xml.Header + `
` + var got struct { + Date Date `xml:"issued"` + } + + rd := strings.NewReader(doc) + if err := xml.NewDecoder(rd).Decode(&got); err != nil { + t.Error(err) + } +} diff --git a/oval/types.go b/oval/types.go index 2c80097..b5cf5f1 100644 --- a/oval/types.go +++ b/oval/types.go @@ -111,6 +111,8 @@ type Date struct { var ( _ xml.Unmarshaler = (*Date)(nil) _ xml.UnmarshalerAttr = (*Date)(nil) + + emptyValue = (time.Time{}).Add(1) ) // UnmarshalXML implements xml.Unmarshaler. @@ -126,10 +128,17 @@ func (d *Date) UnmarshalXML(dec *xml.Decoder, start xml.StartElement) error { if err := dec.DecodeElement(&s, &start); err != nil { return err } - // If the date is set but an empty string is the inner element, then the - // date was set by an attr. - if s == "" && !d.Date.IsZero() { + switch { + case d.Date.Equal(emptyValue): + // If we set the date to this sentinel value, then this element is + // pointless but we need to not return an error. + d.Date = time.Time{} + return nil + case s == "" && !d.Date.IsZero(): + // If the date is set but an empty string is the inner element, then the + // date was set by an attr. return nil + default: } var err error // Try a variety of formats, because everything is terrible. @@ -156,6 +165,12 @@ func (d *Date) UnmarshalXMLAttr(attr xml.Attr) error { if attr.Name.Local != name.Local { return xml.UnmarshalError(fmt.Sprintf("unexpected attr : %v", attr)) } + // We want to allow for an empty value, because some vendors can't be + // bothered to remove empty entities from their database. + if attr.Value == "" { + d.Date = emptyValue + return nil + } var err error d.Date, err = time.Parse(dsfmt, attr.Value) if err != nil {