@@ -133,6 +133,14 @@ type Service struct {
133
133
Extra2 interface {} `xml:"host>extra2"`
134
134
}
135
135
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
+
136
144
var nilStruct * Ship
137
145
138
146
type EmbedA struct {
@@ -189,6 +197,10 @@ type NameInField struct {
189
197
Foo Name `xml:"ns foo"`
190
198
}
191
199
200
+ type NameInFieldError struct {
201
+ Foo Name `xml:"ns "`
202
+ }
203
+
192
204
type AttrTest struct {
193
205
Int int `xml:",attr"`
194
206
Named int `xml:"int,attr"`
@@ -320,9 +332,22 @@ type MyMarshalerTest struct {
320
332
var _ Marshaler = (* MyMarshalerTest )(nil )
321
333
322
334
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 {
323
349
e .EncodeToken (start )
324
- e .EncodeToken (CharData ([]byte ("hello world" )))
325
- e .EncodeToken (EndElement {start .Name })
350
+ e .EncodeToken (CharData ("hello world" ))
326
351
return nil
327
352
}
328
353
@@ -791,6 +816,12 @@ var marshalTests = []struct {
791
816
`</service>` ,
792
817
MarshalOnly : true ,
793
818
},
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
+ },
794
825
{
795
826
Value : & struct {
796
827
XMLName struct {} `xml:"space top"`
@@ -955,6 +986,12 @@ var marshalTests = []struct {
955
986
ExpectXML : `<NameInField><foo xmlns="ns"><ignore></ignore></foo></NameInField>` ,
956
987
UnmarshalOnly : true ,
957
988
},
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
+ },
958
995
959
996
// Marshaling zero xml.Name uses the tag or field name.
960
997
{
@@ -1243,6 +1280,16 @@ var marshalTests = []struct {
1243
1280
ExpectXML : `<MyMarshalerTest>hello world</MyMarshalerTest>` ,
1244
1281
Value : & MyMarshalerTest {},
1245
1282
},
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
+ },
1246
1293
{
1247
1294
ExpectXML : `<MarshalerStruct Foo="hello world"></MarshalerStruct>` ,
1248
1295
Value : & MarshalerStruct {},
@@ -1694,6 +1741,27 @@ type BadAttr struct {
1694
1741
Name map [string ]string `xml:"name,attr"`
1695
1742
}
1696
1743
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
1697
1765
var marshalErrorTests = []struct {
1698
1766
Value interface {}
1699
1767
Err string
@@ -1730,6 +1798,22 @@ var marshalErrorTests = []struct {
1730
1798
Value : BadAttr {map [string ]string {"X" : "Y" }},
1731
1799
Err : `xml: unsupported type: map[string]string` ,
1732
1800
},
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
+ },
1733
1817
}
1734
1818
1735
1819
var marshalIndentTests = []struct {
@@ -1829,6 +1913,24 @@ func TestMarshalIndent(t *testing.T) {
1829
1913
}
1830
1914
}
1831
1915
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
+
1832
1934
type limitedBytesWriter struct {
1833
1935
w io.Writer
1834
1936
remain int // until writes fail
@@ -2020,6 +2122,12 @@ var encodeTokenTests = []struct {
2020
2122
ProcInst {"" , []byte ("Instruction?>" )},
2021
2123
},
2022
2124
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" ,
2023
2131
}, {
2024
2132
desc : "directive" ,
2025
2133
toks : []Token {
@@ -2364,6 +2472,28 @@ func TestProcInstEncodeToken(t *testing.T) {
2364
2472
}
2365
2473
}
2366
2474
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
+
2367
2497
func TestDecodeEncode (t * testing.T ) {
2368
2498
var in , out bytes.Buffer
2369
2499
in .WriteString (`<?xml version="1.0" encoding="UTF-8"?>
@@ -2473,7 +2603,6 @@ func TestIssue16158(t *testing.T) {
2473
2603
}
2474
2604
2475
2605
// Issue 20953. Crash on invalid XMLName attribute.
2476
-
2477
2606
type InvalidXMLName struct {
2478
2607
XMLName Name `xml:"error"`
2479
2608
Type struct {
0 commit comments