diff options
| author | Rob Pike <r@golang.org> | 2010-11-08 15:33:00 -0800 |
|---|---|---|
| committer | Rob Pike <r@golang.org> | 2010-11-08 15:33:00 -0800 |
| commit | e9c901dbf4673443cc151d2e53100c0ebff48a44 (patch) | |
| tree | 34a1d9b0cab22ecfdb1867efec2d77ac76a4fa79 | |
| parent | 9f19392f1ab275ad97454477a64ed1a016edc30f (diff) | |
| download | go-e9c901dbf4673443cc151d2e53100c0ebff48a44.tar.xz | |
json: don't indirect before testing for custom unmarshaler
Fixes #1260.
R=gri
CC=golang-dev
https://golang.org/cl/2994041
| -rw-r--r-- | src/pkg/json/decode.go | 4 | ||||
| -rw-r--r-- | src/pkg/json/decode_test.go | 22 |
2 files changed, 25 insertions, 1 deletions
diff --git a/src/pkg/json/decode.go b/src/pkg/json/decode.go index 71ebd6daf6..b6c575cc84 100644 --- a/src/pkg/json/decode.go +++ b/src/pkg/json/decode.go @@ -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 } diff --git a/src/pkg/json/decode_test.go b/src/pkg/json/decode_test.go index c7d176a581..b805d3d82f 100644 --- a/src/pkg/json/decode_test.go +++ b/src/pkg/json/decode_test.go @@ -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) { |
