decode: fix pointers and fix null into string Fixes bug #1133337. R=jameinel CC= https://codereview.appspot.com/8019043
diff --git a/decode.go b/decode.go index a60dfdb..b03f36e 100644 --- a/decode.go +++ b/decode.go
@@ -308,8 +308,10 @@ } switch out.Kind() { case reflect.String: - out.SetString(n.value) - good = true + if resolved != nil { + out.SetString(n.value) + good = true + } case reflect.Interface: if resolved == nil { out.Set(reflect.Zero(out.Type())) @@ -360,6 +362,13 @@ case nil: out.Set(reflect.Zero(out.Type())) good = true + default: + if out.Type().Elem() == reflect.TypeOf(resolved) { + elem := reflect.New(out.Type().Elem()) + elem.Elem().Set(reflect.ValueOf(resolved)) + out.Set(elem) + good = true + } } } return good
diff --git a/decode_test.go b/decode_test.go index aaa950c..5e5663b 100644 --- a/decode_test.go +++ b/decode_test.go
@@ -23,8 +23,7 @@ {"v: 10", map[string]interface{}{"v": 10}}, {"v: 0b10", map[string]interface{}{"v": 2}}, {"v: 0xA", map[string]interface{}{"v": 10}}, - {"v: 4294967296", map[string]interface{}{"v": int64(4294967296)}}, - {"v: 4294967296", map[string]int64{"v": int64(4294967296)}}, + {"v: 4294967296", map[string]int64{"v": 4294967296}}, {"v: 0.1", map[string]interface{}{"v": 0.1}}, {"v: .1", map[string]interface{}{"v": 0.1}}, {"v: .Inf", map[string]interface{}{"v": math.Inf(+1)}}, @@ -122,6 +121,10 @@ } }{struct{ C int }{1}, struct{ C int }{1}}}, {"a: &a [1, 2]\nb: *a", &struct{ B []int }{[]int{1, 2}}}, + + // BUG #1133337 + {"foo: ''", map[string]*string{"foo": new(string)}}, + {"foo: null", map[string]string{}}, } func (s *S) TestUnmarshal(c *C) {
diff --git a/goyaml.go b/goyaml.go index 518ddeb..3de01c0 100644 --- a/goyaml.go +++ b/goyaml.go
@@ -59,7 +59,7 @@ // If an internal pointer within a struct is not initialized, goyaml // will initialize it if necessary for unmarshalling the provided data, // but the struct provided as out must not be a nil pointer. -// +// // The type of the decoded values and the type of out will be considered, // and Unmarshal() will do the best possible job to unmarshal values // appropriately. It is NOT considered an error, though, to skip values @@ -83,7 +83,7 @@ // } // var T t // goyaml.Unmarshal([]byte("a: 1\nb: 2"), &t) -// +// func Unmarshal(in []byte, out interface{}) (err error) { defer handleErr(&err) d := newDecoder()