From 474d64d26e8eb8d40bbe2d481513a2070d85ee54 Mon Sep 17 00:00:00 2001 From: Rob Pike Date: Fri, 16 Dec 2011 11:52:58 -0800 Subject: [PATCH] encoding/gob: arrays are zero only if their elements are zero R=golang-dev, rsc CC=golang-dev https://golang.org/cl/5494059 --- src/pkg/encoding/gob/encode.go | 9 +++++++- src/pkg/encoding/gob/gobencdec_test.go | 30 +++++++++++++++++++++----- 2 files changed, 33 insertions(+), 6 deletions(-) diff --git a/src/pkg/encoding/gob/encode.go b/src/pkg/encoding/gob/encode.go index 11afa02ea5..f05b17c309 100644 --- a/src/pkg/encoding/gob/encode.go +++ b/src/pkg/encoding/gob/encode.go @@ -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. func isZero(val reflect.Value) bool { 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 case reflect.Bool: return !val.Bool() diff --git a/src/pkg/encoding/gob/gobencdec_test.go b/src/pkg/encoding/gob/gobencdec_test.go index 5cab411591..b8dfeeb515 100644 --- a/src/pkg/encoding/gob/gobencdec_test.go +++ b/src/pkg/encoding/gob/gobencdec_test.go @@ -529,28 +529,48 @@ func TestGobEncoderExtraIndirect(t *testing.T) { } // 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 S string I int + A isZeroBugArray } -func TestGobEncodeTime(t *testing.T) { - x := TimeBug{time.Now(), "hello", -55} +type isZeroBugArray [2]uint8 + +// 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) enc := NewEncoder(b) err := enc.Encode(x) if err != nil { t.Fatal("encode:", err) } - var y TimeBug + var y isZeroBug dec := NewDecoder(b) err = dec.Decode(&y) if err != nil { t.Fatal("decode:", err) } if x != y { - t.Fatal("%v != %v", x, y) + t.Fatalf("%v != %v", x, y) } }