diff options
author | Rob Pike <r@golang.org> | 2010-12-14 15:04:52 -0800 |
---|---|---|
committer | Rob Pike <r@golang.org> | 2010-12-14 15:04:52 -0800 |
commit | 8132bb1c7458431a5324364d63a7e46ec01fa499 (patch) | |
tree | 36ddf8da8d5ae18213cc06e6359074a2013c873c | |
parent | 56452c53ee6313799c9654c2e136c93356a616e5 (diff) | |
download | go-8132bb1c7458431a5324364d63a7e46ec01fa499.tar.gz go-8132bb1c7458431a5324364d63a7e46ec01fa499.zip |
gob: Register should use the original type, not the indirected one.
Fixes a bug reported on golang-nuts.
R=rsc, adg
CC=golang-dev
https://golang.org/cl/3641042
-rw-r--r-- | src/pkg/gob/encoder_test.go | 29 | ||||
-rw-r--r-- | src/pkg/gob/type.go | 4 |
2 files changed, 32 insertions, 1 deletions
diff --git a/src/pkg/gob/encoder_test.go b/src/pkg/gob/encoder_test.go index 91d85bb7ad..e5fc80837e 100644 --- a/src/pkg/gob/encoder_test.go +++ b/src/pkg/gob/encoder_test.go @@ -354,3 +354,32 @@ func TestStructNonStruct(t *testing.T) { t.Error("for non-struct/struct expected type error; got", err) } } + +type interfaceIndirectTestI interface { + F() bool +} + +type interfaceIndirectTestT struct{} + +func (this *interfaceIndirectTestT) F() bool { + return true +} + +// A version of a bug reported on golang-nuts. Also tests top-level +// slice of interfaces. The issue was registering *T caused T to be +// stored as the concrete type. +func TestInterfaceIndirect(t *testing.T) { + Register(&interfaceIndirectTestT{}) + b := new(bytes.Buffer) + w := []interfaceIndirectTestI{&interfaceIndirectTestT{}} + err := NewEncoder(b).Encode(w) + if err != nil { + t.Fatal("encode error:", err) + } + + var r []interfaceIndirectTestI + err = NewDecoder(b).Decode(&r) + if err != nil { + t.Fatal("decode error:", err) + } +} diff --git a/src/pkg/gob/type.go b/src/pkg/gob/type.go index d68c8773cf..1c2b2027ef 100644 --- a/src/pkg/gob/type.go +++ b/src/pkg/gob/type.go @@ -470,7 +470,9 @@ func RegisterName(name string, value interface{}) { if n, ok := concreteTypeToName[rt]; ok && n != name { panic("gob: registering duplicate names for " + rt.String()) } - nameToConcreteType[name] = rt + // Store the name and type provided by the user.... + nameToConcreteType[name] = reflect.Typeof(value) + // but the flattened type in the type table, since that's what decode needs. concreteTypeToName[rt] = name } |