~samwhited/xmpp

aa9442829739fc9aac18c755c97c1b895d10bdd6 — Sam Whited 9 months ago 668bf0e
stream: fix stream error unmarshaling

Signed-off-by: Sam Whited <sam@samwhited.com>
2 files changed, 26 insertions(+), 13 deletions(-)

M CHANGELOG.md
M stream/error.go
M CHANGELOG.md => CHANGELOG.md +1 -0
@@ 48,6 48,7 @@ All notable changes to this project will be documented in this file.
- dial: dialing an XMPP connection where no xmpps SRV records exist no longer
  results in an error (fallback works correctly)
- roster: fix infinite loop marshaling lists of items
- stream: errors are now unmarshaled correctly
- xmpp: the Encode methods no longer sometimes duplicate the xmlns attribute
- xmpp: stream errors are now unmarshaled and returned from `Serve` and during
  session negotiation

M stream/error.go => stream/error.go +25 -13
@@ 190,20 190,32 @@ func (s Error) Error() string {
// UnmarshalXML satisfies the xml package's Unmarshaler interface and allows
// StreamError's to be correctly unmarshaled from XML.
func (s *Error) UnmarshalXML(d *xml.Decoder, start xml.StartElement) error {
	se := struct {
		XMLName xml.Name
		Err     struct {
			XMLName  xml.Name
			InnerXML []byte `xml:",innerxml"`
		} `xml:",any"`
	}{}
	err := d.DecodeElement(&se, &start)
	if err != nil {
		return err
	for {
		tok, err := d.Token()
		if err != nil {
			return err
		}

		var start xml.StartElement
		switch tt := tok.(type) {
		case xml.StartElement:
			start = tt
		case xml.EndElement:
			// This is the end element, everything else has been unmarshaled or skipped.
			return nil
		default:
			continue
		}

		switch {
		case start.Name.Local == "text" && start.Name.Space == ErrorNS:
		case start.Name.Space == ErrorNS:
			s.Err = start.Name.Local
		}
		if err = d.Skip(); err != nil {
			return err
		}
	}
	s.Err = se.Err.XMLName.Local
	// TODO: s.InnerXML = se.Err.InnerXML
	return nil
}

// MarshalXML satisfies the xml package's Marshaler interface and allows