Skip to content

Commit 851ecea

Browse files
hopehookianlancetaylor
authored andcommitted
encoding/xml: embedded reference to substruct causes XML marshaller to panic on encoding
When encoding a xml attribute is zero value (IsValid == false), we need a `continue` to jump over the attribute. If not, followed marshalAttr function will panic. Fixes: #50164 Change-Id: I42e064558e7becfbf47728b14cbf5c7afa1e8798 Reviewed-on: https://go-review.googlesource.com/c/go/+/385514 Reviewed-by: Daniel Martí <[email protected]> Trust: Daniel Martí <[email protected]> Run-TryBot: Daniel Martí <[email protected]> TryBot-Result: Gopher Robot <[email protected]> Reviewed-by: Ian Lance Taylor <[email protected]>
1 parent 0261fa6 commit 851ecea

File tree

2 files changed

+37
-1
lines changed

2 files changed

+37
-1
lines changed

src/encoding/xml/marshal.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -512,7 +512,7 @@ func (p *printer) marshalValue(val reflect.Value, finfo *fieldInfo, startTemplat
512512
}
513513
fv := finfo.value(val, dontInitNilPointers)
514514

515-
if finfo.flags&fOmitEmpty != 0 && isEmptyValue(fv) {
515+
if finfo.flags&fOmitEmpty != 0 && (!fv.IsValid() || isEmptyValue(fv)) {
516516
continue
517517
}
518518

src/encoding/xml/marshal_test.go

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2495,3 +2495,39 @@ func TestInvalidXMLName(t *testing.T) {
24952495
t.Errorf("error %q does not contain %q", err, want)
24962496
}
24972497
}
2498+
2499+
// Issue 50164. Crash on zero value XML attribute.
2500+
type LayerOne struct {
2501+
XMLName Name `xml:"l1"`
2502+
2503+
Value *float64 `xml:"value,omitempty"`
2504+
*LayerTwo `xml:",omitempty"`
2505+
}
2506+
2507+
type LayerTwo struct {
2508+
ValueTwo *int `xml:"value_two,attr,omitempty"`
2509+
}
2510+
2511+
func TestMarshalZeroValue(t *testing.T) {
2512+
proofXml := `<l1><value>1.2345</value></l1>`
2513+
var l1 LayerOne
2514+
err := Unmarshal([]byte(proofXml), &l1)
2515+
if err != nil {
2516+
t.Fatalf("unmarshal XML error: %v", err)
2517+
}
2518+
want := float64(1.2345)
2519+
got := *l1.Value
2520+
if got != want {
2521+
t.Fatalf("unexpected unmarshal result, want %f but got %f", want, got)
2522+
}
2523+
2524+
// Marshal again (or Encode again)
2525+
// In issue 50164, here `Marshal(l1)` will panic because of the zero value of xml attribute ValueTwo `value_two`.
2526+
anotherXML, err := Marshal(l1)
2527+
if err != nil {
2528+
t.Fatalf("marshal XML error: %v", err)
2529+
}
2530+
if string(anotherXML) != proofXml {
2531+
t.Fatalf("unexpected unmarshal result, want %q but got %q", proofXml, anotherXML)
2532+
}
2533+
}

0 commit comments

Comments
 (0)