aboutsummaryrefslogtreecommitdiff
path: root/src/encoding/xml/read.go
diff options
context:
space:
mode:
authorSarah Adams <shadams@google.com>2017-03-20 16:11:46 -0700
committerIan Lance Taylor <iant@golang.org>2017-03-22 23:33:36 +0000
commit0a0186fb7832928c9b5b1966854a8abc31678ea8 (patch)
treefe23a6bf8f67191dc3cb01e93cc2fc9e54fc3307 /src/encoding/xml/read.go
parent1295b745d13fe1402d5b645c9c20cc3adf85d563 (diff)
downloadgo-0a0186fb7832928c9b5b1966854a8abc31678ea8.tar.gz
go-0a0186fb7832928c9b5b1966854a8abc31678ea8.zip
encoding/xml: unmarshal allow empty, non-string values
When unmarshaling, if an element is empty, eg. '<tag></tag>', and destination type is int, uint, float or bool, do not attempt to parse value (""). Set to its zero value instead. Fixes #13417 Change-Id: I2d79f6d8f39192bb277b1a9129727d5abbb2dd1f Reviewed-on: https://go-review.googlesource.com/38386 Reviewed-by: Ian Lance Taylor <iant@golang.org> Run-TryBot: Ian Lance Taylor <iant@golang.org> TryBot-Result: Gobot Gobot <gobot@golang.org>
Diffstat (limited to 'src/encoding/xml/read.go')
-rw-r--r--src/encoding/xml/read.go19
1 files changed, 19 insertions, 0 deletions
diff --git a/src/encoding/xml/read.go b/src/encoding/xml/read.go
index b90271fed3..000d9fbd0e 100644
--- a/src/encoding/xml/read.go
+++ b/src/encoding/xml/read.go
@@ -120,6 +120,9 @@ import (
// Unmarshal maps an XML element to a pointer by setting the pointer
// to a freshly allocated value and then mapping the element to that value.
//
+// A missing element or empty attribute value will be unmarshaled as a zero value.
+// If the field is a slice, a zero value will be appended to the field. Otherwise, the
+// field will be set to its zero value.
func Unmarshal(data []byte, v interface{}) error {
return NewDecoder(bytes.NewReader(data)).Decode(v)
}
@@ -607,24 +610,40 @@ func copyValue(dst reflect.Value, src []byte) (err error) {
default:
return errors.New("cannot unmarshal into " + dst0.Type().String())
case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
+ if len(src) == 0 {
+ dst.SetInt(0)
+ return nil
+ }
itmp, err := strconv.ParseInt(string(src), 10, dst.Type().Bits())
if err != nil {
return err
}
dst.SetInt(itmp)
case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:
+ if len(src) == 0 {
+ dst.SetUint(0)
+ return nil
+ }
utmp, err := strconv.ParseUint(string(src), 10, dst.Type().Bits())
if err != nil {
return err
}
dst.SetUint(utmp)
case reflect.Float32, reflect.Float64:
+ if len(src) == 0 {
+ dst.SetFloat(0)
+ return nil
+ }
ftmp, err := strconv.ParseFloat(string(src), dst.Type().Bits())
if err != nil {
return err
}
dst.SetFloat(ftmp)
case reflect.Bool:
+ if len(src) == 0 {
+ dst.SetBool(false)
+ return nil
+ }
value, err := strconv.ParseBool(strings.TrimSpace(string(src)))
if err != nil {
return err