Skip to content

Commit

Permalink
encoding/xml: add check of namespaces to detect field names conflicts
Browse files Browse the repository at this point in the history
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]>
  • Loading branch information
iwdgo authored and gopherbot committed Nov 9, 2022
1 parent fe4e59e commit b459166
Show file tree
Hide file tree
Showing 2 changed files with 91 additions and 1 deletion.
2 changes: 1 addition & 1 deletion src/encoding/xml/typeinfo.go
Original file line number Diff line number Diff line change
Expand Up @@ -292,7 +292,7 @@ Loop:
conflicts = append(conflicts, i)
}
} else {
if newf.name == oldf.name {
if newf.name == oldf.name && newf.xmlns == oldf.xmlns {
conflicts = append(conflicts, i)
}
}
Expand Down
90 changes: 90 additions & 0 deletions src/encoding/xml/xml_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -916,6 +916,96 @@ func TestIssue5880(t *testing.T) {
}
}

func TestIssue8535(t *testing.T) {

type ExampleConflict struct {
XMLName Name `xml:"example"`
Link string `xml:"link"`
AtomLink string `xml:"http://www.w3.org/2005/Atom link"` // Same name in a different name space
}
testCase := `<example>
<title>Example</title>
<link>http://example.com/default</link> <!-- not assigned -->
<link>http://example.com/home</link> <!-- not assigned -->
<ns:link xmlns:ns="http://www.w3.org/2005/Atom">http://example.com/ns</ns:link>
</example>`

var dest ExampleConflict
d := NewDecoder(strings.NewReader(testCase))
if err := d.Decode(&dest); err != nil {
t.Fatal(err)
}
}

func TestEncodeXMLNS(t *testing.T) {
testCases := []struct {
f func() ([]byte, error)
want string
ok bool
}{
{encodeXMLNS1, `<Test xmlns="http://example.com/ns"><Body>hello world</Body></Test>`, true},
{encodeXMLNS2, `<Test><body xmlns="http://example.com/ns">hello world</body></Test>`, true},
{encodeXMLNS3, `<Test xmlns="http://example.com/ns"><Body>hello world</Body></Test>`, true},
{encodeXMLNS4, `<Test xmlns="http://example.com/ns"><Body>hello world</Body></Test>`, false},
}

for i, tc := range testCases {
if b, err := tc.f(); err == nil {
if got, want := string(b), tc.want; got != want {
t.Errorf("%d: got %s, want %s \n", i, got, want)
}
} else {
t.Errorf("%d: marshal failed with %s", i, err)
}
}
}

func encodeXMLNS1() ([]byte, error) {

type T struct {
XMLName Name `xml:"Test"`
Ns string `xml:"xmlns,attr"`
Body string
}

s := &T{Ns: "http://example.com/ns", Body: "hello world"}
return Marshal(s)
}

func encodeXMLNS2() ([]byte, error) {

type Test struct {
Body string `xml:"http://example.com/ns body"`
}

s := &Test{Body: "hello world"}
return Marshal(s)
}

func encodeXMLNS3() ([]byte, error) {

type Test struct {
XMLName Name `xml:"http://example.com/ns Test"`
Body string
}

//s := &Test{XMLName: Name{"http://example.com/ns",""}, Body: "hello world"} is unusable as the "-" is missing
// as documentation states
s := &Test{Body: "hello world"}
return Marshal(s)
}

func encodeXMLNS4() ([]byte, error) {

type Test struct {
Ns string `xml:"xmlns,attr"`
Body string
}

s := &Test{Ns: "http://example.com/ns", Body: "hello world"}
return Marshal(s)
}

func TestIssue11405(t *testing.T) {
testCases := []string{
"<root>",
Expand Down

2 comments on commit b459166

@swanwish
Copy link

@swanwish swanwish commented on b459166 Feb 21, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This fix still has problem, unmarshal does not report error, but when there are conflict names, only one field can get value, please see the example at:

https://go.dev/play/p/oVK2cC3KExw

@ianlancetaylor
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We don't use GitHub for code review, and very few people see comments on GitHub commits. If you want to commit, please see https://go.dev/cl/106575.

In this case see also https://go.dev/cl/466295.

Please sign in to comment.