Skip to content

Commit f5ec1e2

Browse files
authored
Merge a828f1f into 144e0b1
2 parents 144e0b1 + a828f1f commit f5ec1e2

File tree

3 files changed

+487
-25
lines changed

3 files changed

+487
-25
lines changed

src/encoding/xml/marshal_test.go

Lines changed: 132 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -133,6 +133,14 @@ type Service struct {
133133
Extra2 interface{} `xml:"host>extra2"`
134134
}
135135

136+
type ServiceErrorNameConflict struct {
137+
XMLName struct{} `xml:"service"`
138+
Domain *Domain `xml:"host>domain"`
139+
Port *Port `xml:"host>portZZZ"`
140+
Extra1 interface{}
141+
Extra2 interface{} `xml:"host>extra2"`
142+
}
143+
136144
var nilStruct *Ship
137145

138146
type EmbedA struct {
@@ -189,6 +197,10 @@ type NameInField struct {
189197
Foo Name `xml:"ns foo"`
190198
}
191199

200+
type NameInFieldError struct {
201+
Foo Name `xml:"ns "`
202+
}
203+
192204
type AttrTest struct {
193205
Int int `xml:",attr"`
194206
Named int `xml:"int,attr"`
@@ -320,9 +332,22 @@ type MyMarshalerTest struct {
320332
var _ Marshaler = (*MyMarshalerTest)(nil)
321333

322334
func (m *MyMarshalerTest) MarshalXML(e *Encoder, start StartElement) error {
335+
return e.EncodeElement("hello world", start)
336+
}
337+
338+
type MyMarshalerTestErrorMissingName struct {
339+
}
340+
341+
func (m *MyMarshalerTestErrorMissingName) MarshalXML(e *Encoder, _ StartElement) error {
342+
return e.EncodeElement("hello world", StartElement{Name{"", ""}, nil})
343+
}
344+
345+
type MyMarshalerTestErrorNotClosed struct {
346+
}
347+
348+
func (m *MyMarshalerTestErrorNotClosed) MarshalXML(e *Encoder, start StartElement) error {
323349
e.EncodeToken(start)
324-
e.EncodeToken(CharData([]byte("hello world")))
325-
e.EncodeToken(EndElement{start.Name})
350+
e.EncodeToken(CharData("hello world"))
326351
return nil
327352
}
328353

@@ -791,6 +816,12 @@ var marshalTests = []struct {
791816
`</service>`,
792817
MarshalOnly: true,
793818
},
819+
{
820+
Value: &ServiceErrorNameConflict{Port: &Port{Number: "80"}},
821+
ExpectXML: `<service><host><port>80</port></host></service>`,
822+
MarshalError: `conflicts with name`,
823+
UnmarshalError: `conflicts with name`,
824+
},
794825
{
795826
Value: &struct {
796827
XMLName struct{} `xml:"space top"`
@@ -955,6 +986,12 @@ var marshalTests = []struct {
955986
ExpectXML: `<NameInField><foo xmlns="ns"><ignore></ignore></foo></NameInField>`,
956987
UnmarshalOnly: true,
957988
},
989+
{
990+
Value: &NameInFieldError{Name{Space: "ns", Local: "foo"}},
991+
ExpectXML: `<NameInField><foo xmlns="ns"></foo></NameInField>`,
992+
MarshalError: "xml: namespace without name in field",
993+
UnmarshalError: "xml: namespace without name in field",
994+
},
958995

959996
// Marshaling zero xml.Name uses the tag or field name.
960997
{
@@ -1243,6 +1280,16 @@ var marshalTests = []struct {
12431280
ExpectXML: `<MyMarshalerTest>hello world</MyMarshalerTest>`,
12441281
Value: &MyMarshalerTest{},
12451282
},
1283+
{
1284+
ExpectXML: `<MyMarshalerTest>hello world</MyMarshalerTest>`,
1285+
Value: &MyMarshalerTestErrorMissingName{},
1286+
MarshalError: "xml: EncodeElement of StartElement with missing name",
1287+
},
1288+
{
1289+
ExpectXML: `<MyMarshalerTest>hello world</MyMarshalerTest>`,
1290+
Value: &MyMarshalerTestErrorNotClosed{},
1291+
MarshalError: "MarshalXML wrote invalid XML",
1292+
},
12461293
{
12471294
ExpectXML: `<MarshalerStruct Foo="hello world"></MarshalerStruct>`,
12481295
Value: &MarshalerStruct{},
@@ -1694,6 +1741,27 @@ type BadAttr struct {
16941741
Name map[string]string `xml:"name,attr"`
16951742
}
16961743

1744+
type BadTag struct {
1745+
Comment string `xml:",comment,omitempty"`
1746+
}
1747+
1748+
type BadTagMultipleModes struct {
1749+
Comment string `xml:",attr,comment"`
1750+
}
1751+
1752+
type BadTagTrailingTag struct {
1753+
Comment string `xml:"comment>"`
1754+
}
1755+
1756+
type BadEmbed struct {
1757+
BadInnerEmbed
1758+
}
1759+
1760+
type BadInnerEmbed struct {
1761+
Field string `xml:"Field,attr,comment"`
1762+
}
1763+
1764+
// used by both TestMarshalErrors and TestMarshalIndentErrors
16971765
var marshalErrorTests = []struct {
16981766
Value interface{}
16991767
Err string
@@ -1730,6 +1798,22 @@ var marshalErrorTests = []struct {
17301798
Value: BadAttr{map[string]string{"X": "Y"}},
17311799
Err: `xml: unsupported type: map[string]string`,
17321800
},
1801+
{
1802+
Value: BadTag{"some comment"},
1803+
Err: `xml: invalid tag in field Comment of type xml.BadTag: ",comment,omitempty"`,
1804+
},
1805+
{
1806+
Value: BadTagMultipleModes{"some comment"},
1807+
Err: `xml: invalid tag in field Comment of type xml.BadTagMultipleModes: ",attr,comment"`,
1808+
},
1809+
{
1810+
Value: BadTagTrailingTag{"some comment"},
1811+
Err: `xml: trailing '>' in field Comment of type xml.BadTagTrailingTag`,
1812+
},
1813+
{
1814+
Value: BadEmbed{},
1815+
Err: `xml: invalid tag in field Field of type xml.BadInnerEmbed: "Field,attr,comment"`,
1816+
},
17331817
}
17341818

17351819
var marshalIndentTests = []struct {
@@ -1829,6 +1913,24 @@ func TestMarshalIndent(t *testing.T) {
18291913
}
18301914
}
18311915

1916+
func TestMarshalIndentErrors(t *testing.T) {
1917+
for idx, test := range marshalErrorTests {
1918+
data, err := MarshalIndent(test.Value, "", "")
1919+
if err == nil {
1920+
t.Errorf("#%d: marshalIndent(%#v) = [success] %q, want error %v", idx, test.Value, data, test.Err)
1921+
continue
1922+
}
1923+
if err.Error() != test.Err {
1924+
t.Errorf("#%d: marshalIndent(%#v) = [error] %v, want %v", idx, test.Value, err, test.Err)
1925+
}
1926+
if test.Kind != reflect.Invalid {
1927+
if kind := err.(*UnsupportedTypeError).Type.Kind(); kind != test.Kind {
1928+
t.Errorf("#%d: marshalIndent(%#v) = [error kind] %s, want %s", idx, test.Value, kind, test.Kind)
1929+
}
1930+
}
1931+
}
1932+
}
1933+
18321934
type limitedBytesWriter struct {
18331935
w io.Writer
18341936
remain int // until writes fail
@@ -2020,6 +2122,12 @@ var encodeTokenTests = []struct {
20202122
ProcInst{"", []byte("Instruction?>")},
20212123
},
20222124
err: "xml: EncodeToken of ProcInst with invalid Target",
2125+
}, {
2126+
desc: "proc instruction with endProcInst",
2127+
toks: []Token{
2128+
ProcInst{"Target", []byte("Instruction?>")},
2129+
},
2130+
err: "xml: EncodeToken of ProcInst containing ?> marker",
20232131
}, {
20242132
desc: "directive",
20252133
toks: []Token{
@@ -2364,6 +2472,28 @@ func TestProcInstEncodeToken(t *testing.T) {
23642472
}
23652473
}
23662474

2475+
func TestProcInstEncodeTokenBadNameString(t *testing.T) {
2476+
tests := []struct {
2477+
input ProcInst
2478+
}{
2479+
{ProcInst{"\xe6", []byte("Instruction")}},
2480+
{ProcInst{".", []byte("Instruction")}},
2481+
{ProcInst{"a\xe6", []byte("Instruction")}},
2482+
}
2483+
expectedError := `xml: EncodeToken of ProcInst with invalid Target`
2484+
2485+
for _, test := range tests {
2486+
var buf bytes.Buffer
2487+
enc := NewEncoder(&buf)
2488+
2489+
if err := enc.EncodeToken(test.input); err == nil {
2490+
t.Fatalf(`expected not receive expected error for input %s`, test.input)
2491+
} else if err.Error() != expectedError {
2492+
t.Fatalf(`err.Error() = "%s", want "%s"`, err.Error(), expectedError)
2493+
}
2494+
}
2495+
}
2496+
23672497
func TestDecodeEncode(t *testing.T) {
23682498
var in, out bytes.Buffer
23692499
in.WriteString(`<?xml version="1.0" encoding="UTF-8"?>
@@ -2473,7 +2603,6 @@ func TestIssue16158(t *testing.T) {
24732603
}
24742604

24752605
// Issue 20953. Crash on invalid XMLName attribute.
2476-
24772606
type InvalidXMLName struct {
24782607
XMLName Name `xml:"error"`
24792608
Type struct {

src/encoding/xml/read_test.go

Lines changed: 134 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
package xml
66

77
import (
8+
"errors"
89
"io"
910
"reflect"
1011
"strings"
@@ -332,7 +333,7 @@ var badPathTests = []struct {
332333
func TestUnmarshalBadPaths(t *testing.T) {
333334
for _, tt := range badPathTests {
334335
err := Unmarshal([]byte(pathTestString), tt.v)
335-
if !reflect.DeepEqual(err, tt.e) {
336+
if !strings.Contains(err.Error(), "conflicts with field") || !reflect.DeepEqual(err, tt.e) {
336337
t.Fatalf("Unmarshal with %#v didn't fail properly:\nhave %#v,\nwant %#v", tt.v, err, tt.e)
337338
}
338339
}
@@ -348,6 +349,18 @@ type TestThree struct {
348349
Attr string `xml:",attr"`
349350
}
350351

352+
func TestUnmarshalNonpointer(t *testing.T) {
353+
var x TestThree
354+
err := Unmarshal([]byte(withoutNameTypeData), x)
355+
errText := "non-pointer passed to Unmarshal"
356+
if err == nil {
357+
t.Errorf("[success], want error %v", errText)
358+
}
359+
if err.Error() != errText {
360+
t.Errorf("[error] %v, want %v", err, errText)
361+
}
362+
}
363+
351364
func TestUnmarshalWithoutNameType(t *testing.T) {
352365
var x TestThree
353366
if err := Unmarshal([]byte(withoutNameTypeData), &x); err != nil {
@@ -686,6 +699,126 @@ func TestUnmarshaler(t *testing.T) {
686699
}
687700
}
688701

702+
var errText = "UnmarshalXML failed"
703+
704+
type MyBodyError struct {
705+
Body string
706+
}
707+
708+
func (m *MyBodyError) UnmarshalXML(*Decoder, StartElement) error {
709+
return errors.New(errText)
710+
}
711+
712+
func TestUnmarshalerError(t *testing.T) {
713+
xml := `<?xml version="1.0" encoding="utf-8"?><Body>words</Body>`
714+
var m MyBodyError
715+
err := Unmarshal([]byte(xml), &m)
716+
717+
if err == nil {
718+
t.Errorf("[success], want error %v", errText)
719+
}
720+
if err.Error() != errText {
721+
t.Errorf("[error] %v, want %v", err, errText)
722+
}
723+
}
724+
725+
type MyBodyErrorText struct {
726+
Body string
727+
}
728+
729+
func (m MyBodyErrorText) UnmarshalText([]byte) error {
730+
return errors.New(errText)
731+
}
732+
733+
func TestUnmarshalerTextError(t *testing.T) {
734+
xml := `<?xml version="1.0" encoding="utf-8"?><Body>words</Body>`
735+
var m MyBodyErrorText
736+
err := Unmarshal([]byte(xml), &m)
737+
738+
if err == nil {
739+
t.Errorf("[success], want error %v", errText)
740+
}
741+
if err.Error() != errText {
742+
t.Errorf("[error] %v, want %v", err, errText)
743+
}
744+
}
745+
746+
func TestUnmarshalUnknownType(t *testing.T) {
747+
expectedError := `unknown type func()`
748+
var dst func()
749+
750+
if err := Unmarshal([]byte(pathTestString), &dst); err == nil || err.Error() != expectedError {
751+
t.Errorf("have %v, want %v", err, expectedError)
752+
}
753+
}
754+
755+
type XMLNameWithNamespace struct {
756+
XMLName Name `xml:"ns Test3"`
757+
}
758+
759+
func TestUnmarshalErrors(t *testing.T) {
760+
tests := []struct {
761+
input []byte
762+
expectedError string
763+
}{
764+
{[]byte(""), "EOF"},
765+
{[]byte("<a>bbb</a>"), `expected element type <Test3> but have <a>`},
766+
{[]byte(`<Test3 xmlns="namespace">inside</Test3>`), `expected element <Test3> in name space ns but have namespace`},
767+
{[]byte(`<Test3 xmlns="">inside</Test3>`), `expected element <Test3> in name space ns but have no name space`},
768+
}
769+
for _, test := range tests {
770+
var dst XMLNameWithNamespace
771+
772+
if err := Unmarshal(test.input, &dst); err == nil || err.Error() != test.expectedError {
773+
t.Errorf("have %v, want %v", err, test.expectedError)
774+
}
775+
}
776+
}
777+
778+
func TestSkip(t *testing.T) {
779+
xml := "<a>bbb</a><Person><name>nnn</name><uri>uuu</uri>wefwef</Person>"
780+
781+
var dst Person
782+
d := NewDecoder(strings.NewReader(xml))
783+
784+
// consume a start element
785+
if _, err := d.Token(); err != nil {
786+
t.Fatalf("expected d.Token() to succeed but got: :%v", err)
787+
}
788+
789+
// consume the rest until the matching end element
790+
if err := d.Skip(); err != nil {
791+
t.Fatalf("expected d.Skip() to succeed but got: :%v", err)
792+
}
793+
794+
if err := d.Decode(&dst); err != nil {
795+
t.Fatalf("expected d.Decode() to succeed but got: :%v", err)
796+
}
797+
}
798+
799+
func TestSkipErrors(t *testing.T) {
800+
tests := []struct {
801+
input string
802+
expectedError string
803+
}{
804+
{"<a>", `XML syntax error on line 1: unexpected EOF`},
805+
{"<a>bbbb<c>", `XML syntax error on line 1: unexpected EOF`},
806+
}
807+
808+
for _, test := range tests {
809+
d := NewDecoder(strings.NewReader(test.input))
810+
811+
// consume a start element
812+
if _, err := d.Token(); err != nil {
813+
t.Fatalf("expected d.Token() to succeed but got: :%v", err)
814+
}
815+
816+
if err := d.Skip(); err == nil || err.Error() != test.expectedError {
817+
t.Errorf("have %v, want %v", err, test.expectedError)
818+
}
819+
}
820+
}
821+
689822
type Pea struct {
690823
Cotelydon string
691824
}

0 commit comments

Comments
 (0)