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()