From b8ec36539763e76b62519ef09ddeeb6b6e73fb0c Mon Sep 17 00:00:00 2001 From: Harshavardhana Date: Mon, 29 Mar 2021 23:52:30 -0700 Subject: [PATCH] unmarshal both LegalHold and ObjectLockLegalHold XML types (#11921) Because of silly AWS S3 behavior we to handle both types. fixes #11920 --- pkg/bucket/lifecycle/lifecycle.go | 6 +++-- pkg/bucket/object/lock/lock.go | 35 +++++++++++++++++++++++++++++ pkg/bucket/object/lock/lock_test.go | 18 +++++++++++++++ 3 files changed, 57 insertions(+), 2 deletions(-) diff --git a/pkg/bucket/lifecycle/lifecycle.go b/pkg/bucket/lifecycle/lifecycle.go index d71af4864..bba514cd3 100644 --- a/pkg/bucket/lifecycle/lifecycle.go +++ b/pkg/bucket/lifecycle/lifecycle.go @@ -18,6 +18,7 @@ package lifecycle import ( "encoding/xml" + "fmt" "io" "strings" "time" @@ -71,7 +72,8 @@ func (lc *Lifecycle) UnmarshalXML(d *xml.Decoder, start xml.StartElement) (err e switch start.Name.Local { case "LifecycleConfiguration", "BucketLifecycleConfiguration": default: - return errUnknownXMLTag + return xml.UnmarshalError(fmt.Sprintf("expected element type / but have <%s>", + start.Name.Local)) } for { // Read tokens from the XML document in a stream. @@ -93,7 +95,7 @@ func (lc *Lifecycle) UnmarshalXML(d *xml.Decoder, start xml.StartElement) (err e } lc.Rules = append(lc.Rules, r) default: - return errUnknownXMLTag + return xml.UnmarshalError(fmt.Sprintf("expected element type but have <%s>", se.Name.Local)) } } } diff --git a/pkg/bucket/object/lock/lock.go b/pkg/bucket/object/lock/lock.go index 44656ffb6..3aacf467e 100644 --- a/pkg/bucket/object/lock/lock.go +++ b/pkg/bucket/object/lock/lock.go @@ -489,6 +489,41 @@ type ObjectLegalHold struct { Status LegalHoldStatus `xml:"Status,omitempty"` } +// UnmarshalXML - decodes XML data. +func (l *ObjectLegalHold) UnmarshalXML(d *xml.Decoder, start xml.StartElement) (err error) { + switch start.Name.Local { + case "LegalHold", "ObjectLockLegalHold": + default: + return xml.UnmarshalError(fmt.Sprintf("expected element type / but have <%s>", + start.Name.Local)) + } + for { + // Read tokens from the XML document in a stream. + t, err := d.Token() + if err != nil { + if err == io.EOF { + break + } + return err + } + + switch se := t.(type) { + case xml.StartElement: + switch se.Name.Local { + case "Status": + var st LegalHoldStatus + if err = d.DecodeElement(&st, &se); err != nil { + return err + } + l.Status = st + default: + return xml.UnmarshalError(fmt.Sprintf("expected element type but have <%s>", se.Name.Local)) + } + } + } + return nil +} + // IsEmpty returns true if struct is empty func (l *ObjectLegalHold) IsEmpty() bool { return !l.Status.Valid() diff --git a/pkg/bucket/object/lock/lock_test.go b/pkg/bucket/object/lock/lock_test.go index 6e50364e8..9c4eb3b0f 100644 --- a/pkg/bucket/object/lock/lock_test.go +++ b/pkg/bucket/object/lock/lock_test.go @@ -18,6 +18,7 @@ package lock import ( "encoding/xml" + "errors" "fmt" "net/http" "reflect" @@ -467,6 +468,23 @@ func TestParseObjectLegalHold(t *testing.T) { expectedErr: nil, expectErr: false, }, + { + value: `ON`, + expectedErr: nil, + expectErr: false, + }, + // invalid Status key + { + value: `ON`, + expectedErr: errors.New("expected element type but have "), + expectErr: true, + }, + // invalid XML attr + { + value: `ON`, + expectedErr: errors.New("expected element type / but have "), + expectErr: true, + }, { value: `On`, expectedErr: ErrMalformedXML,