diff options
author | Sarah Adams <shadams@google.com> | 2017-03-20 16:11:46 -0700 |
---|---|---|
committer | Ian Lance Taylor <iant@golang.org> | 2017-03-22 23:33:36 +0000 |
commit | 0a0186fb7832928c9b5b1966854a8abc31678ea8 (patch) | |
tree | fe23a6bf8f67191dc3cb01e93cc2fc9e54fc3307 /src/encoding/xml/read.go | |
parent | 1295b745d13fe1402d5b645c9c20cc3adf85d563 (diff) | |
download | go-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.go | 19 |
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 |