Commit 474d64d2 authored by Rob Pike's avatar Rob Pike

encoding/gob: arrays are zero only if their elements are zero

R=golang-dev, rsc
CC=golang-dev
https://golang.org/cl/5494059
parent 4fb5f544
...@@ -469,7 +469,14 @@ func (enc *Encoder) encodeInterface(b *bytes.Buffer, iv reflect.Value) { ...@@ -469,7 +469,14 @@ func (enc *Encoder) encodeInterface(b *bytes.Buffer, iv reflect.Value) {
// isZero returns whether the value is the zero of its type. // isZero returns whether the value is the zero of its type.
func isZero(val reflect.Value) bool { func isZero(val reflect.Value) bool {
switch val.Kind() { switch val.Kind() {
case reflect.Array, reflect.Map, reflect.Slice, reflect.String: case reflect.Array:
for i := 0; i < val.Len(); i++ {
if !isZero(val.Index(i)) {
return false
}
}
return true
case reflect.Map, reflect.Slice, reflect.String:
return val.Len() == 0 return val.Len() == 0
case reflect.Bool: case reflect.Bool:
return !val.Bool() return !val.Bool()
......
...@@ -529,28 +529,48 @@ func TestGobEncoderExtraIndirect(t *testing.T) { ...@@ -529,28 +529,48 @@ func TestGobEncoderExtraIndirect(t *testing.T) {
} }
// Another bug: this caused a crash with the new Go1 Time type. // Another bug: this caused a crash with the new Go1 Time type.
// We throw in a gob-encoding array, to test another case of isZero
type TimeBug struct { type isZeroBug struct {
T time.Time T time.Time
S string S string
I int I int
A isZeroBugArray
} }
func TestGobEncodeTime(t *testing.T) { type isZeroBugArray [2]uint8
x := TimeBug{time.Now(), "hello", -55}
// Receiver is value, not pointer, to test isZero of array.
func (a isZeroBugArray) GobEncode() (b []byte, e error) {
b = append(b, a[:]...)
return b, nil
}
func (a *isZeroBugArray) GobDecode(data []byte) error {
println("DECODE")
if len(data) != len(a) {
return io.EOF
}
a[0] = data[0]
a[1] = data[1]
return nil
}
func TestGobEncodeIsZero(t *testing.T) {
x := isZeroBug{time.Now(), "hello", -55, isZeroBugArray{1, 2}}
b := new(bytes.Buffer) b := new(bytes.Buffer)
enc := NewEncoder(b) enc := NewEncoder(b)
err := enc.Encode(x) err := enc.Encode(x)
if err != nil { if err != nil {
t.Fatal("encode:", err) t.Fatal("encode:", err)
} }
var y TimeBug var y isZeroBug
dec := NewDecoder(b) dec := NewDecoder(b)
err = dec.Decode(&y) err = dec.Decode(&y)
if err != nil { if err != nil {
t.Fatal("decode:", err) t.Fatal("decode:", err)
} }
if x != y { if x != y {
t.Fatal("%v != %v", x, y) t.Fatalf("%v != %v", x, y)
} }
} }
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