aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRob Pike <r@golang.org>2010-12-14 15:04:52 -0800
committerRob Pike <r@golang.org>2010-12-14 15:04:52 -0800
commit8132bb1c7458431a5324364d63a7e46ec01fa499 (patch)
tree36ddf8da8d5ae18213cc06e6359074a2013c873c
parent56452c53ee6313799c9654c2e136c93356a616e5 (diff)
downloadgo-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.go29
-rw-r--r--src/pkg/gob/type.go4
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
}