Commit bc1152a3 authored by Kyle Lemons's avatar Kyle Lemons Committed by Andrew Gerrand

encoding/gob: handle encoding of different indirects of GobEncoder

Fixes #4647.

R=r, golang-dev
CC=golang-dev
https://golang.org/cl/7085051
parent f31f9a61
...@@ -137,8 +137,8 @@ func (enc *Encoder) sendType(w io.Writer, state *encoderState, origt reflect.Typ ...@@ -137,8 +137,8 @@ func (enc *Encoder) sendType(w io.Writer, state *encoderState, origt reflect.Typ
ut := userType(origt) ut := userType(origt)
if ut.isGobEncoder { if ut.isGobEncoder {
// The rules are different: regardless of the underlying type's representation, // The rules are different: regardless of the underlying type's representation,
// we need to tell the other side that this exact type is a GobEncoder. // we need to tell the other side that the base type is a GobEncoder.
return enc.sendActualType(w, state, ut, ut.user) return enc.sendActualType(w, state, ut, ut.base)
} }
// It's a concrete value, so drill down to the base type. // It's a concrete value, so drill down to the base type.
......
...@@ -142,6 +142,18 @@ type GobTest5 struct { ...@@ -142,6 +142,18 @@ type GobTest5 struct {
V *ValueGobber V *ValueGobber
} }
type GobTest6 struct {
X int // guarantee we have something in common with GobTest*
V ValueGobber
W *ValueGobber
}
type GobTest7 struct {
X int // guarantee we have something in common with GobTest*
V *ValueGobber
W ValueGobber
}
type GobTestIgnoreEncoder struct { type GobTestIgnoreEncoder struct {
X int // guarantee we have something in common with GobTest* X int // guarantee we have something in common with GobTest*
} }
...@@ -360,6 +372,61 @@ func TestGobEncoderValueEncoder(t *testing.T) { ...@@ -360,6 +372,61 @@ func TestGobEncoderValueEncoder(t *testing.T) {
} }
} }
// Test that we can use a value then a pointer type of a GobEncoder
// in the same encoded value. Bug 4647.
func TestGobEncoderValueThenPointer(t *testing.T) {
v := ValueGobber("forty-two")
w := ValueGobber("six-by-nine")
// this was a bug: encoding a GobEncoder by value before a GobEncoder
// pointer would cause duplicate type definitions to be sent.
b := new(bytes.Buffer)
enc := NewEncoder(b)
if err := enc.Encode(GobTest6{42, v, &w}); err != nil {
t.Fatal("encode error:", err)
}
dec := NewDecoder(b)
x := new(GobTest6)
if err := dec.Decode(x); err != nil {
t.Fatal("decode error:", err)
}
if got, want := x.V, v; got != want {
t.Errorf("v = %q, want %q", got, want)
}
if got, want := v.W, w; got == nil {
t.Errorf("w = nil, want %q", want)
} else if *got != want {
t.Errorf("w = %q, want %q", *got, want)
}
}
// Test that we can use a pointer then a value type of a GobEncoder
// in the same encoded value.
func TestGobEncoderPointerThenValue(t *testing.T) {
v := ValueGobber("forty-two")
w := ValueGobber("six-by-nine")
b := new(bytes.Buffer)
enc := NewEncoder(b)
if err := enc.Encode(GobTest7{42, &v, w}); err != nil {
t.Fatal("encode error:", err)
}
dec := NewDecoder(b)
x := new(GobTest7)
if err := dec.Decode(x); err != nil {
t.Fatal("decode error:", err)
}
if got, want := x.V, v; got == nil {
t.Errorf("v = nil, want %q", want)
} else if *got != want {
t.Errorf("v = %q, want %q", got, want)
}
if got, want := v.W, w; got != want {
t.Errorf("w = %q, want %q", got, want)
}
}
func TestGobEncoderFieldTypeError(t *testing.T) { func TestGobEncoderFieldTypeError(t *testing.T) {
// GobEncoder to non-decoder: error // GobEncoder to non-decoder: error
b := new(bytes.Buffer) b := new(bytes.Buffer)
......
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