diff --git a/src/encoding/xml/marshal_test.go b/src/encoding/xml/marshal_test.go index 11f451270a..5c79a48e7a 100644 --- a/src/encoding/xml/marshal_test.go +++ b/src/encoding/xml/marshal_test.go @@ -2441,3 +2441,22 @@ func TestIssue16158(t *testing.T) { t.Errorf("Unmarshal: expected error, got nil") } } + +// Issue 20953. Crash on invalid XMLName attribute. + +type InvalidXMLName struct { + XMLName Name `xml:"error"` + Type struct { + XMLName Name `xml:"type,attr"` + } +} + +func TestInvalidXMLName(t *testing.T) { + var buf bytes.Buffer + enc := NewEncoder(&buf) + if err := enc.Encode(InvalidXMLName{}); err == nil { + t.Error("unexpected success") + } else if want := "invalid tag"; !strings.Contains(err.Error(), want) { + t.Errorf("error %q does not contain %q", err, want) + } +} diff --git a/src/encoding/xml/typeinfo.go b/src/encoding/xml/typeinfo.go index 2e7ae935a8..48de3d7e9e 100644 --- a/src/encoding/xml/typeinfo.go +++ b/src/encoding/xml/typeinfo.go @@ -241,7 +241,7 @@ func lookupXMLName(typ reflect.Type) (xmlname *fieldInfo) { continue } finfo, err := structFieldInfo(typ, &f) - if finfo.name != "" && err == nil { + if err == nil && finfo.name != "" { return finfo } // Also consider errors as a non-existent field tag