Commit 8132bb1c authored by Rob Pike's avatar Rob Pike

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
parent 56452c53
......@@ -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)
}
}
......@@ -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
}
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment