]> Cypherpunks repositories - gostls13.git/commitdiff
json: don't indirect before testing for custom unmarshaler
authorRob Pike <r@golang.org>
Mon, 8 Nov 2010 23:33:00 +0000 (15:33 -0800)
committerRob Pike <r@golang.org>
Mon, 8 Nov 2010 23:33:00 +0000 (15:33 -0800)
Fixes #1260.

R=gri
CC=golang-dev
https://golang.org/cl/2994041

src/pkg/json/decode.go
src/pkg/json/decode_test.go

index 71ebd6daf6483072fd9acf4cbe6967aaa9d30d7c..b6c575cc8440f4fe0ff2fdb02a30b59e159fa2ca 100644 (file)
@@ -128,7 +128,9 @@ func (d *decodeState) unmarshal(v interface{}) (err os.Error) {
        }
 
        d.scan.reset()
-       d.value(pv.Elem())
+       // We decode rv not pv.Elem because the Unmarshaler interface
+       // test must be applied at the top level of the value.
+       d.value(rv)
        return d.savedError
 }
 
index c7d176a5817f39846fc11a0bd4d71ae2a2fd3e6a..b805d3d82f7b610c3de990d002bec85c520e77ce 100644 (file)
@@ -23,6 +23,24 @@ type tx struct {
 
 var txType = reflect.Typeof((*tx)(nil)).(*reflect.PtrType).Elem().(*reflect.StructType)
 
+// A type that can unmarshal itself.
+
+type unmarshaler struct {
+       T bool
+}
+
+func (u *unmarshaler) UnmarshalJSON(b []byte) os.Error {
+       *u = unmarshaler{true} // All we need to see that UnmarshalJson is called.
+       return nil
+}
+
+var (
+       um0, um1 unmarshaler // target2 of unmarshaling
+       ump      = &um1
+       umtrue   = unmarshaler{true}
+)
+
+
 type unmarshalTest struct {
        in  string
        ptr interface{}
@@ -56,6 +74,10 @@ var unmarshalTests = []unmarshalTest{
        {pallValueCompact, new(All), pallValue, nil},
        {pallValueIndent, new(*All), &pallValue, nil},
        {pallValueCompact, new(*All), &pallValue, nil},
+
+       // unmarshal interface test
+       {`{"T":false}`, &um0, umtrue, nil}, // use "false" so test will fail if custom unmarshaler is not called
+       {`{"T":false}`, &ump, &umtrue, nil},
 }
 
 func TestMarshal(t *testing.T) {