Skip to content

Commit b459166

Browse files
iwdgogopherbot
authored andcommitted
encoding/xml: add check of namespaces to detect field names conflicts
Test added. Fixes #8535 Change-Id: Ic89c2781e81d963a653180812748b3fc95fb7fae Reviewed-on: https://go-review.googlesource.com/c/go/+/106575 Run-TryBot: Ian Lance Taylor <[email protected]> Run-TryBot: Ian Lance Taylor <[email protected]> Reviewed-by: Ian Lance Taylor <[email protected]> TryBot-Result: Gopher Robot <[email protected]> Auto-Submit: Ian Lance Taylor <[email protected]> Reviewed-by: Michael Knyszek <[email protected]>
1 parent fe4e59e commit b459166

File tree

2 files changed

+91
-1
lines changed

2 files changed

+91
-1
lines changed

src/encoding/xml/typeinfo.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -292,7 +292,7 @@ Loop:
292292
conflicts = append(conflicts, i)
293293
}
294294
} else {
295-
if newf.name == oldf.name {
295+
if newf.name == oldf.name && newf.xmlns == oldf.xmlns {
296296
conflicts = append(conflicts, i)
297297
}
298298
}

src/encoding/xml/xml_test.go

Lines changed: 90 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -916,6 +916,96 @@ func TestIssue5880(t *testing.T) {
916916
}
917917
}
918918

919+
func TestIssue8535(t *testing.T) {
920+
921+
type ExampleConflict struct {
922+
XMLName Name `xml:"example"`
923+
Link string `xml:"link"`
924+
AtomLink string `xml:"http://www.w3.org/2005/Atom link"` // Same name in a different name space
925+
}
926+
testCase := `<example>
927+
<title>Example</title>
928+
<link>http://example.com/default</link> <!-- not assigned -->
929+
<link>http://example.com/home</link> <!-- not assigned -->
930+
<ns:link xmlns:ns="http://www.w3.org/2005/Atom">http://example.com/ns</ns:link>
931+
</example>`
932+
933+
var dest ExampleConflict
934+
d := NewDecoder(strings.NewReader(testCase))
935+
if err := d.Decode(&dest); err != nil {
936+
t.Fatal(err)
937+
}
938+
}
939+
940+
func TestEncodeXMLNS(t *testing.T) {
941+
testCases := []struct {
942+
f func() ([]byte, error)
943+
want string
944+
ok bool
945+
}{
946+
{encodeXMLNS1, `<Test xmlns="http://example.com/ns"><Body>hello world</Body></Test>`, true},
947+
{encodeXMLNS2, `<Test><body xmlns="http://example.com/ns">hello world</body></Test>`, true},
948+
{encodeXMLNS3, `<Test xmlns="http://example.com/ns"><Body>hello world</Body></Test>`, true},
949+
{encodeXMLNS4, `<Test xmlns="http://example.com/ns"><Body>hello world</Body></Test>`, false},
950+
}
951+
952+
for i, tc := range testCases {
953+
if b, err := tc.f(); err == nil {
954+
if got, want := string(b), tc.want; got != want {
955+
t.Errorf("%d: got %s, want %s \n", i, got, want)
956+
}
957+
} else {
958+
t.Errorf("%d: marshal failed with %s", i, err)
959+
}
960+
}
961+
}
962+
963+
func encodeXMLNS1() ([]byte, error) {
964+
965+
type T struct {
966+
XMLName Name `xml:"Test"`
967+
Ns string `xml:"xmlns,attr"`
968+
Body string
969+
}
970+
971+
s := &T{Ns: "http://example.com/ns", Body: "hello world"}
972+
return Marshal(s)
973+
}
974+
975+
func encodeXMLNS2() ([]byte, error) {
976+
977+
type Test struct {
978+
Body string `xml:"http://example.com/ns body"`
979+
}
980+
981+
s := &Test{Body: "hello world"}
982+
return Marshal(s)
983+
}
984+
985+
func encodeXMLNS3() ([]byte, error) {
986+
987+
type Test struct {
988+
XMLName Name `xml:"http://example.com/ns Test"`
989+
Body string
990+
}
991+
992+
//s := &Test{XMLName: Name{"http://example.com/ns",""}, Body: "hello world"} is unusable as the "-" is missing
993+
// as documentation states
994+
s := &Test{Body: "hello world"}
995+
return Marshal(s)
996+
}
997+
998+
func encodeXMLNS4() ([]byte, error) {
999+
1000+
type Test struct {
1001+
Ns string `xml:"xmlns,attr"`
1002+
Body string
1003+
}
1004+
1005+
s := &Test{Ns: "http://example.com/ns", Body: "hello world"}
1006+
return Marshal(s)
1007+
}
1008+
9191009
func TestIssue11405(t *testing.T) {
9201010
testCases := []string{
9211011
"<root>",

0 commit comments

Comments
 (0)