]> Cypherpunks repositories - gostls13.git/commitdiff
encoding/xml: allow overriding by empty namespace
authorConstantin Konstantinidis <constantinkonstantinidis@gmail.com>
Tue, 5 Jul 2022 05:46:07 +0000 (07:46 +0200)
committerGopher Robot <gobot@golang.org>
Tue, 31 Jan 2023 18:23:50 +0000 (18:23 +0000)
The namespace defined by xmlns="value" can be overridden in every included tag
by the empty namespace xmlns="" without a prefix.

Method to calculate indent of XML handles depth of tag and its associated namespace is
still active even when no indent is required.

An XMLName field in a struct means that namespace must be enforced even if empty.
This occurs only on an inner tag as an override of any non-empty namespace of its outer tag.
An attribute is added to have the required namespace display.

Fixes #7113

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

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

index 07b6042da87bf929dd2c3256187fa704b05841e8..0c3cc0dc3618a18958a61918f1ba34400860f197 100644 (file)
@@ -543,6 +543,11 @@ func (p *printer) marshalValue(val reflect.Value, finfo *fieldInfo, startTemplat
                }
        }
 
+       // If a name was found, namespace is overridden with an empty space
+       if tinfo.xmlname != nil && start.Name.Space == "" &&
+               len(p.tags) != 0 && p.tags[len(p.tags)-1].Space != "" {
+               start.Attr = append(start.Attr, Attr{Name{"", xmlnsPrefix}, ""})
+       }
        if err := p.writeStart(&start); err != nil {
                return err
        }
index 30fb94da6df16fc3d92c49184ad514a586c6b28e..8205ac31484d848d97b44e8e4dbd08b3efd20006 100644 (file)
@@ -1059,6 +1059,56 @@ func TestIssue12417(t *testing.T) {
        }
 }
 
+func TestIssue7113(t *testing.T) {
+       type C struct {
+               XMLName Name `xml:""` // Sets empty namespace
+       }
+
+       type A struct {
+               XMLName Name `xml:""`
+               C       C    `xml:""`
+       }
+
+       var a A
+       structSpace := "b"
+       xmlTest := `<A xmlns="` + structSpace + `"><C xmlns=""></C></A>`
+       t.Log(xmlTest)
+       err := Unmarshal([]byte(xmlTest), &a)
+       if err != nil {
+               t.Fatal(err)
+       }
+
+       if a.XMLName.Space != structSpace {
+               t.Errorf("overidding with empty namespace: unmarshalling, got %s, want %s\n", a.XMLName.Space, structSpace)
+       }
+       if len(a.C.XMLName.Space) != 0 {
+               t.Fatalf("overidding with empty namespace: unmarshalling, got %s, want empty\n", a.C.XMLName.Space)
+       }
+
+       var b []byte
+       b, err = Marshal(&a)
+       if err != nil {
+               t.Fatal(err)
+       }
+       if len(a.C.XMLName.Space) != 0 {
+               t.Errorf("overidding with empty namespace: marshaling, got %s in C tag which should be empty\n", a.C.XMLName.Space)
+       }
+       if string(b) != xmlTest {
+               t.Fatalf("overidding with empty namespace: marshalling, got %s, want %s\n", b, xmlTest)
+       }
+       var c A
+       err = Unmarshal(b, &c)
+       if err != nil {
+               t.Fatalf("second Unmarshal failed: %s", err)
+       }
+       if c.XMLName.Space != "b" {
+               t.Errorf("overidding with empty namespace: after marshaling & unmarshaling, XML name space: got %s, want %s\n", a.XMLName.Space, structSpace)
+       }
+       if len(c.C.XMLName.Space) != 0 {
+               t.Errorf("overidding with empty namespace: after marshaling & unmarshaling, got %s, want empty\n", a.C.XMLName.Space)
+       }
+}
+
 func TestIssue20396(t *testing.T) {
 
        var attrError = UnmarshalError("XML syntax error on line 1: expected attribute name in element")