From: Rob Pike Date: Tue, 14 Dec 2010 23:04:52 +0000 (-0800) Subject: gob: Register should use the original type, not the indirected one. X-Git-Tag: weekly.2010-12-15~17 X-Git-Url: http://www.git.cypherpunks.su/?a=commitdiff_plain;h=8132bb1c7458431a5324364d63a7e46ec01fa499;p=gostls13.git 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 --- 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 }