]> Cypherpunks repositories - gostls13.git/commitdiff
encoding/xml: error when closing tag does not match opening tag
authorConstantin Konstantinidis <constantinkonstantinidis@gmail.com>
Sun, 15 Apr 2018 09:26:32 +0000 (11:26 +0200)
committerGopher Robot <gobot@golang.org>
Wed, 9 Nov 2022 03:01:28 +0000 (03:01 +0000)
Comparing opening and closing tag is done using the prefix when available.
Documentation states that Token returns URI in the Space part of the Name.
Translation has been moved for the End tag before the namespace is removed
from the stack.

After closing a tag using a namespace, the valid namespace must be taken
from the opening tag. Tests added.

Fixes #20685

Change-Id: I4d90b19f7e21a76663f0ea1c1db6c6bf9fd2a389
Reviewed-on: https://go-review.googlesource.com/c/go/+/107255
Run-TryBot: Ian Lance Taylor <iant@golang.org>
Reviewed-by: Ian Lance Taylor <iant@google.com>
TryBot-Result: Gopher Robot <gobot@golang.org>
Auto-Submit: Ian Lance Taylor <iant@google.com>
Reviewed-by: Michael Knyszek <mknyszek@google.com>
Run-TryBot: Ian Lance Taylor <iant@google.com>

src/encoding/xml/xml.go
src/encoding/xml/xml_test.go

index 50a91a897fb1953b05500ecb6d6026fdd1619ed2..d4509dfc851f55de9adf31237b2b375c870a8ec0 100644 (file)
@@ -314,15 +314,14 @@ func (d *Decoder) Token() (Token, error) {
                        }
                }
 
+               d.pushElement(t1.Name)
                d.translate(&t1.Name, true)
                for i := range t1.Attr {
                        d.translate(&t1.Attr[i].Name, false)
                }
-               d.pushElement(t1.Name)
                t = t1
 
        case EndElement:
-               d.translate(&t1.Name, true)
                if !d.popElement(&t1) {
                        return nil, d.err
                }
@@ -495,6 +494,8 @@ func (d *Decoder) popElement(t *EndElement) bool {
                return false
        }
 
+       d.translate(&t.Name, true)
+
        // Pop stack until a Start or EOF is on the top, undoing the
        // translations that were associated with the element we just closed.
        for d.stk != nil && d.stk.kind != stkStart && d.stk.kind != stkEOF {
index 15c5a7492fa0845d06cc9e30326a664581fcaf08..e20dc781a1273bd1d30d8e6009fc4db0b18d6823 100644 (file)
@@ -1059,6 +1059,41 @@ func TestIssue12417(t *testing.T) {
        }
 }
 
+func TestIssue20685(t *testing.T) {
+       testCases := []struct {
+               s  string
+               ok bool
+       }{
+               {`<x:book xmlns:x="abcd" xmlns:y="abcd"><unclosetag>one</x:book>`, false},
+               {`<x:book xmlns:x="abcd" xmlns:y="abcd">one</x:book>`, true},
+               {`<x:book xmlns:x="abcd" xmlns:y="abcd">one</y:book>`, false},
+               {`<x:book xmlns:y="abcd" xmlns:x="abcd">one</y:book>`, false},
+               {`<x:book xmlns:x="abcd">one</y:book>`, false},
+               {`<x:book>one</y:book>`, false},
+               {`<xbook>one</ybook>`, false},
+       }
+       for _, tc := range testCases {
+               d := NewDecoder(strings.NewReader(tc.s))
+               var err error
+               for {
+                       _, err = d.Token()
+                       if err != nil {
+                               if err == io.EOF {
+                                       err = nil
+                               }
+                               break
+                       }
+               }
+               if err != nil && tc.ok {
+                       t.Errorf("%q: Closing tag with namespace : expected no error, got %s", tc.s, err)
+                       continue
+               }
+               if err == nil && !tc.ok {
+                       t.Errorf("%q: Closing tag with namespace : expected error, got nil", tc.s)
+               }
+       }
+}
+
 func tokenMap(mapping func(t Token) Token) func(TokenReader) TokenReader {
        return func(src TokenReader) TokenReader {
                return mapper{