Home | History | Annotate | Download | only in gob
      1 // Copyright 2011 The Go Authors. All rights reserved.
      2 // Use of this source code is governed by a BSD-style
      3 // license that can be found in the LICENSE file.
      4 
      5 // This file contains tests of the GobEncoder/GobDecoder support.
      6 
      7 package gob
      8 
      9 import (
     10 	"bytes"
     11 	"errors"
     12 	"fmt"
     13 	"io"
     14 	"net"
     15 	"strings"
     16 	"testing"
     17 	"time"
     18 )
     19 
     20 // Types that implement the GobEncoder/Decoder interfaces.
     21 
     22 type ByteStruct struct {
     23 	a byte // not an exported field
     24 }
     25 
     26 type StringStruct struct {
     27 	s string // not an exported field
     28 }
     29 
     30 type ArrayStruct struct {
     31 	a [8192]byte // not an exported field
     32 }
     33 
     34 type Gobber int
     35 
     36 type ValueGobber string // encodes with a value, decodes with a pointer.
     37 
     38 type BinaryGobber int
     39 
     40 type BinaryValueGobber string
     41 
     42 type TextGobber int
     43 
     44 type TextValueGobber string
     45 
     46 // The relevant methods
     47 
     48 func (g *ByteStruct) GobEncode() ([]byte, error) {
     49 	b := make([]byte, 3)
     50 	b[0] = g.a
     51 	b[1] = g.a + 1
     52 	b[2] = g.a + 2
     53 	return b, nil
     54 }
     55 
     56 func (g *ByteStruct) GobDecode(data []byte) error {
     57 	if g == nil {
     58 		return errors.New("NIL RECEIVER")
     59 	}
     60 	// Expect N sequential-valued bytes.
     61 	if len(data) == 0 {
     62 		return io.EOF
     63 	}
     64 	g.a = data[0]
     65 	for i, c := range data {
     66 		if c != g.a+byte(i) {
     67 			return errors.New("invalid data sequence")
     68 		}
     69 	}
     70 	return nil
     71 }
     72 
     73 func (g *StringStruct) GobEncode() ([]byte, error) {
     74 	return []byte(g.s), nil
     75 }
     76 
     77 func (g *StringStruct) GobDecode(data []byte) error {
     78 	// Expect N sequential-valued bytes.
     79 	if len(data) == 0 {
     80 		return io.EOF
     81 	}
     82 	a := data[0]
     83 	for i, c := range data {
     84 		if c != a+byte(i) {
     85 			return errors.New("invalid data sequence")
     86 		}
     87 	}
     88 	g.s = string(data)
     89 	return nil
     90 }
     91 
     92 func (a *ArrayStruct) GobEncode() ([]byte, error) {
     93 	return a.a[:], nil
     94 }
     95 
     96 func (a *ArrayStruct) GobDecode(data []byte) error {
     97 	if len(data) != len(a.a) {
     98 		return errors.New("wrong length in array decode")
     99 	}
    100 	copy(a.a[:], data)
    101 	return nil
    102 }
    103 
    104 func (g *Gobber) GobEncode() ([]byte, error) {
    105 	return []byte(fmt.Sprintf("VALUE=%d", *g)), nil
    106 }
    107 
    108 func (g *Gobber) GobDecode(data []byte) error {
    109 	_, err := fmt.Sscanf(string(data), "VALUE=%d", (*int)(g))
    110 	return err
    111 }
    112 
    113 func (g *BinaryGobber) MarshalBinary() ([]byte, error) {
    114 	return []byte(fmt.Sprintf("VALUE=%d", *g)), nil
    115 }
    116 
    117 func (g *BinaryGobber) UnmarshalBinary(data []byte) error {
    118 	_, err := fmt.Sscanf(string(data), "VALUE=%d", (*int)(g))
    119 	return err
    120 }
    121 
    122 func (g *TextGobber) MarshalText() ([]byte, error) {
    123 	return []byte(fmt.Sprintf("VALUE=%d", *g)), nil
    124 }
    125 
    126 func (g *TextGobber) UnmarshalText(data []byte) error {
    127 	_, err := fmt.Sscanf(string(data), "VALUE=%d", (*int)(g))
    128 	return err
    129 }
    130 
    131 func (v ValueGobber) GobEncode() ([]byte, error) {
    132 	return []byte(fmt.Sprintf("VALUE=%s", v)), nil
    133 }
    134 
    135 func (v *ValueGobber) GobDecode(data []byte) error {
    136 	_, err := fmt.Sscanf(string(data), "VALUE=%s", (*string)(v))
    137 	return err
    138 }
    139 
    140 func (v BinaryValueGobber) MarshalBinary() ([]byte, error) {
    141 	return []byte(fmt.Sprintf("VALUE=%s", v)), nil
    142 }
    143 
    144 func (v *BinaryValueGobber) UnmarshalBinary(data []byte) error {
    145 	_, err := fmt.Sscanf(string(data), "VALUE=%s", (*string)(v))
    146 	return err
    147 }
    148 
    149 func (v TextValueGobber) MarshalText() ([]byte, error) {
    150 	return []byte(fmt.Sprintf("VALUE=%s", v)), nil
    151 }
    152 
    153 func (v *TextValueGobber) UnmarshalText(data []byte) error {
    154 	_, err := fmt.Sscanf(string(data), "VALUE=%s", (*string)(v))
    155 	return err
    156 }
    157 
    158 // Structs that include GobEncodable fields.
    159 
    160 type GobTest0 struct {
    161 	X int // guarantee we have  something in common with GobTest*
    162 	G *ByteStruct
    163 }
    164 
    165 type GobTest1 struct {
    166 	X int // guarantee we have  something in common with GobTest*
    167 	G *StringStruct
    168 }
    169 
    170 type GobTest2 struct {
    171 	X int    // guarantee we have  something in common with GobTest*
    172 	G string // not a GobEncoder - should give us errors
    173 }
    174 
    175 type GobTest3 struct {
    176 	X int // guarantee we have  something in common with GobTest*
    177 	G *Gobber
    178 	B *BinaryGobber
    179 	T *TextGobber
    180 }
    181 
    182 type GobTest4 struct {
    183 	X  int // guarantee we have  something in common with GobTest*
    184 	V  ValueGobber
    185 	BV BinaryValueGobber
    186 	TV TextValueGobber
    187 }
    188 
    189 type GobTest5 struct {
    190 	X  int // guarantee we have  something in common with GobTest*
    191 	V  *ValueGobber
    192 	BV *BinaryValueGobber
    193 	TV *TextValueGobber
    194 }
    195 
    196 type GobTest6 struct {
    197 	X  int // guarantee we have  something in common with GobTest*
    198 	V  ValueGobber
    199 	W  *ValueGobber
    200 	BV BinaryValueGobber
    201 	BW *BinaryValueGobber
    202 	TV TextValueGobber
    203 	TW *TextValueGobber
    204 }
    205 
    206 type GobTest7 struct {
    207 	X  int // guarantee we have  something in common with GobTest*
    208 	V  *ValueGobber
    209 	W  ValueGobber
    210 	BV *BinaryValueGobber
    211 	BW BinaryValueGobber
    212 	TV *TextValueGobber
    213 	TW TextValueGobber
    214 }
    215 
    216 type GobTestIgnoreEncoder struct {
    217 	X int // guarantee we have  something in common with GobTest*
    218 }
    219 
    220 type GobTestValueEncDec struct {
    221 	X int          // guarantee we have  something in common with GobTest*
    222 	G StringStruct // not a pointer.
    223 }
    224 
    225 type GobTestIndirectEncDec struct {
    226 	X int             // guarantee we have  something in common with GobTest*
    227 	G ***StringStruct // indirections to the receiver.
    228 }
    229 
    230 type GobTestArrayEncDec struct {
    231 	X int         // guarantee we have  something in common with GobTest*
    232 	A ArrayStruct // not a pointer.
    233 }
    234 
    235 type GobTestIndirectArrayEncDec struct {
    236 	X int            // guarantee we have  something in common with GobTest*
    237 	A ***ArrayStruct // indirections to a large receiver.
    238 }
    239 
    240 func TestGobEncoderField(t *testing.T) {
    241 	b := new(bytes.Buffer)
    242 	// First a field that's a structure.
    243 	enc := NewEncoder(b)
    244 	err := enc.Encode(GobTest0{17, &ByteStruct{'A'}})
    245 	if err != nil {
    246 		t.Fatal("encode error:", err)
    247 	}
    248 	dec := NewDecoder(b)
    249 	x := new(GobTest0)
    250 	err = dec.Decode(x)
    251 	if err != nil {
    252 		t.Fatal("decode error:", err)
    253 	}
    254 	if x.G.a != 'A' {
    255 		t.Errorf("expected 'A' got %c", x.G.a)
    256 	}
    257 	// Now a field that's not a structure.
    258 	b.Reset()
    259 	gobber := Gobber(23)
    260 	bgobber := BinaryGobber(24)
    261 	tgobber := TextGobber(25)
    262 	err = enc.Encode(GobTest3{17, &gobber, &bgobber, &tgobber})
    263 	if err != nil {
    264 		t.Fatal("encode error:", err)
    265 	}
    266 	y := new(GobTest3)
    267 	err = dec.Decode(y)
    268 	if err != nil {
    269 		t.Fatal("decode error:", err)
    270 	}
    271 	if *y.G != 23 || *y.B != 24 || *y.T != 25 {
    272 		t.Errorf("expected '23 got %d", *y.G)
    273 	}
    274 }
    275 
    276 // Even though the field is a value, we can still take its address
    277 // and should be able to call the methods.
    278 func TestGobEncoderValueField(t *testing.T) {
    279 	b := new(bytes.Buffer)
    280 	// First a field that's a structure.
    281 	enc := NewEncoder(b)
    282 	err := enc.Encode(&GobTestValueEncDec{17, StringStruct{"HIJKL"}})
    283 	if err != nil {
    284 		t.Fatal("encode error:", err)
    285 	}
    286 	dec := NewDecoder(b)
    287 	x := new(GobTestValueEncDec)
    288 	err = dec.Decode(x)
    289 	if err != nil {
    290 		t.Fatal("decode error:", err)
    291 	}
    292 	if x.G.s != "HIJKL" {
    293 		t.Errorf("expected `HIJKL` got %s", x.G.s)
    294 	}
    295 }
    296 
    297 // GobEncode/Decode should work even if the value is
    298 // more indirect than the receiver.
    299 func TestGobEncoderIndirectField(t *testing.T) {
    300 	b := new(bytes.Buffer)
    301 	// First a field that's a structure.
    302 	enc := NewEncoder(b)
    303 	s := &StringStruct{"HIJKL"}
    304 	sp := &s
    305 	err := enc.Encode(GobTestIndirectEncDec{17, &sp})
    306 	if err != nil {
    307 		t.Fatal("encode error:", err)
    308 	}
    309 	dec := NewDecoder(b)
    310 	x := new(GobTestIndirectEncDec)
    311 	err = dec.Decode(x)
    312 	if err != nil {
    313 		t.Fatal("decode error:", err)
    314 	}
    315 	if (***x.G).s != "HIJKL" {
    316 		t.Errorf("expected `HIJKL` got %s", (***x.G).s)
    317 	}
    318 }
    319 
    320 // Test with a large field with methods.
    321 func TestGobEncoderArrayField(t *testing.T) {
    322 	b := new(bytes.Buffer)
    323 	enc := NewEncoder(b)
    324 	var a GobTestArrayEncDec
    325 	a.X = 17
    326 	for i := range a.A.a {
    327 		a.A.a[i] = byte(i)
    328 	}
    329 	err := enc.Encode(&a)
    330 	if err != nil {
    331 		t.Fatal("encode error:", err)
    332 	}
    333 	dec := NewDecoder(b)
    334 	x := new(GobTestArrayEncDec)
    335 	err = dec.Decode(x)
    336 	if err != nil {
    337 		t.Fatal("decode error:", err)
    338 	}
    339 	for i, v := range x.A.a {
    340 		if v != byte(i) {
    341 			t.Errorf("expected %x got %x", byte(i), v)
    342 			break
    343 		}
    344 	}
    345 }
    346 
    347 // Test an indirection to a large field with methods.
    348 func TestGobEncoderIndirectArrayField(t *testing.T) {
    349 	b := new(bytes.Buffer)
    350 	enc := NewEncoder(b)
    351 	var a GobTestIndirectArrayEncDec
    352 	a.X = 17
    353 	var array ArrayStruct
    354 	ap := &array
    355 	app := &ap
    356 	a.A = &app
    357 	for i := range array.a {
    358 		array.a[i] = byte(i)
    359 	}
    360 	err := enc.Encode(a)
    361 	if err != nil {
    362 		t.Fatal("encode error:", err)
    363 	}
    364 	dec := NewDecoder(b)
    365 	x := new(GobTestIndirectArrayEncDec)
    366 	err = dec.Decode(x)
    367 	if err != nil {
    368 		t.Fatal("decode error:", err)
    369 	}
    370 	for i, v := range (***x.A).a {
    371 		if v != byte(i) {
    372 			t.Errorf("expected %x got %x", byte(i), v)
    373 			break
    374 		}
    375 	}
    376 }
    377 
    378 // As long as the fields have the same name and implement the
    379 // interface, we can cross-connect them. Not sure it's useful
    380 // and may even be bad but it works and it's hard to prevent
    381 // without exposing the contents of the object, which would
    382 // defeat the purpose.
    383 func TestGobEncoderFieldsOfDifferentType(t *testing.T) {
    384 	// first, string in field to byte in field
    385 	b := new(bytes.Buffer)
    386 	enc := NewEncoder(b)
    387 	err := enc.Encode(GobTest1{17, &StringStruct{"ABC"}})
    388 	if err != nil {
    389 		t.Fatal("encode error:", err)
    390 	}
    391 	dec := NewDecoder(b)
    392 	x := new(GobTest0)
    393 	err = dec.Decode(x)
    394 	if err != nil {
    395 		t.Fatal("decode error:", err)
    396 	}
    397 	if x.G.a != 'A' {
    398 		t.Errorf("expected 'A' got %c", x.G.a)
    399 	}
    400 	// now the other direction, byte in field to string in field
    401 	b.Reset()
    402 	err = enc.Encode(GobTest0{17, &ByteStruct{'X'}})
    403 	if err != nil {
    404 		t.Fatal("encode error:", err)
    405 	}
    406 	y := new(GobTest1)
    407 	err = dec.Decode(y)
    408 	if err != nil {
    409 		t.Fatal("decode error:", err)
    410 	}
    411 	if y.G.s != "XYZ" {
    412 		t.Fatalf("expected `XYZ` got %q", y.G.s)
    413 	}
    414 }
    415 
    416 // Test that we can encode a value and decode into a pointer.
    417 func TestGobEncoderValueEncoder(t *testing.T) {
    418 	// first, string in field to byte in field
    419 	b := new(bytes.Buffer)
    420 	enc := NewEncoder(b)
    421 	err := enc.Encode(GobTest4{17, ValueGobber("hello"), BinaryValueGobber(""), TextValueGobber("")})
    422 	if err != nil {
    423 		t.Fatal("encode error:", err)
    424 	}
    425 	dec := NewDecoder(b)
    426 	x := new(GobTest5)
    427 	err = dec.Decode(x)
    428 	if err != nil {
    429 		t.Fatal("decode error:", err)
    430 	}
    431 	if *x.V != "hello" || *x.BV != "" || *x.TV != "" {
    432 		t.Errorf("expected `hello` got %s", *x.V)
    433 	}
    434 }
    435 
    436 // Test that we can use a value then a pointer type of a GobEncoder
    437 // in the same encoded value. Bug 4647.
    438 func TestGobEncoderValueThenPointer(t *testing.T) {
    439 	v := ValueGobber("forty-two")
    440 	w := ValueGobber("six-by-nine")
    441 	bv := BinaryValueGobber("1nanocentury")
    442 	bw := BinaryValueGobber("seconds")
    443 	tv := TextValueGobber("gravitationalacceleration")
    444 	tw := TextValueGobber("ft/s")
    445 
    446 	// this was a bug: encoding a GobEncoder by value before a GobEncoder
    447 	// pointer would cause duplicate type definitions to be sent.
    448 
    449 	b := new(bytes.Buffer)
    450 	enc := NewEncoder(b)
    451 	if err := enc.Encode(GobTest6{42, v, &w, bv, &bw, tv, &tw}); err != nil {
    452 		t.Fatal("encode error:", err)
    453 	}
    454 	dec := NewDecoder(b)
    455 	x := new(GobTest6)
    456 	if err := dec.Decode(x); err != nil {
    457 		t.Fatal("decode error:", err)
    458 	}
    459 
    460 	if got, want := x.V, v; got != want {
    461 		t.Errorf("v = %q, want %q", got, want)
    462 	}
    463 	if got, want := x.W, w; got == nil {
    464 		t.Errorf("w = nil, want %q", want)
    465 	} else if *got != want {
    466 		t.Errorf("w = %q, want %q", *got, want)
    467 	}
    468 
    469 	if got, want := x.BV, bv; got != want {
    470 		t.Errorf("bv = %q, want %q", got, want)
    471 	}
    472 	if got, want := x.BW, bw; got == nil {
    473 		t.Errorf("bw = nil, want %q", want)
    474 	} else if *got != want {
    475 		t.Errorf("bw = %q, want %q", *got, want)
    476 	}
    477 
    478 	if got, want := x.TV, tv; got != want {
    479 		t.Errorf("tv = %q, want %q", got, want)
    480 	}
    481 	if got, want := x.TW, tw; got == nil {
    482 		t.Errorf("tw = nil, want %q", want)
    483 	} else if *got != want {
    484 		t.Errorf("tw = %q, want %q", *got, want)
    485 	}
    486 }
    487 
    488 // Test that we can use a pointer then a value type of a GobEncoder
    489 // in the same encoded value.
    490 func TestGobEncoderPointerThenValue(t *testing.T) {
    491 	v := ValueGobber("forty-two")
    492 	w := ValueGobber("six-by-nine")
    493 	bv := BinaryValueGobber("1nanocentury")
    494 	bw := BinaryValueGobber("seconds")
    495 	tv := TextValueGobber("gravitationalacceleration")
    496 	tw := TextValueGobber("ft/s")
    497 
    498 	b := new(bytes.Buffer)
    499 	enc := NewEncoder(b)
    500 	if err := enc.Encode(GobTest7{42, &v, w, &bv, bw, &tv, tw}); err != nil {
    501 		t.Fatal("encode error:", err)
    502 	}
    503 	dec := NewDecoder(b)
    504 	x := new(GobTest7)
    505 	if err := dec.Decode(x); err != nil {
    506 		t.Fatal("decode error:", err)
    507 	}
    508 
    509 	if got, want := x.V, v; got == nil {
    510 		t.Errorf("v = nil, want %q", want)
    511 	} else if *got != want {
    512 		t.Errorf("v = %q, want %q", *got, want)
    513 	}
    514 	if got, want := x.W, w; got != want {
    515 		t.Errorf("w = %q, want %q", got, want)
    516 	}
    517 
    518 	if got, want := x.BV, bv; got == nil {
    519 		t.Errorf("bv = nil, want %q", want)
    520 	} else if *got != want {
    521 		t.Errorf("bv = %q, want %q", *got, want)
    522 	}
    523 	if got, want := x.BW, bw; got != want {
    524 		t.Errorf("bw = %q, want %q", got, want)
    525 	}
    526 
    527 	if got, want := x.TV, tv; got == nil {
    528 		t.Errorf("tv = nil, want %q", want)
    529 	} else if *got != want {
    530 		t.Errorf("tv = %q, want %q", *got, want)
    531 	}
    532 	if got, want := x.TW, tw; got != want {
    533 		t.Errorf("tw = %q, want %q", got, want)
    534 	}
    535 }
    536 
    537 func TestGobEncoderFieldTypeError(t *testing.T) {
    538 	// GobEncoder to non-decoder: error
    539 	b := new(bytes.Buffer)
    540 	enc := NewEncoder(b)
    541 	err := enc.Encode(GobTest1{17, &StringStruct{"ABC"}})
    542 	if err != nil {
    543 		t.Fatal("encode error:", err)
    544 	}
    545 	dec := NewDecoder(b)
    546 	x := &GobTest2{}
    547 	err = dec.Decode(x)
    548 	if err == nil {
    549 		t.Fatal("expected decode error for mismatched fields (encoder to non-decoder)")
    550 	}
    551 	if !strings.Contains(err.Error(), "type") {
    552 		t.Fatal("expected type error; got", err)
    553 	}
    554 	// Non-encoder to GobDecoder: error
    555 	b.Reset()
    556 	err = enc.Encode(GobTest2{17, "ABC"})
    557 	if err != nil {
    558 		t.Fatal("encode error:", err)
    559 	}
    560 	y := &GobTest1{}
    561 	err = dec.Decode(y)
    562 	if err == nil {
    563 		t.Fatal("expected decode error for mismatched fields (non-encoder to decoder)")
    564 	}
    565 	if !strings.Contains(err.Error(), "type") {
    566 		t.Fatal("expected type error; got", err)
    567 	}
    568 }
    569 
    570 // Even though ByteStruct is a struct, it's treated as a singleton at the top level.
    571 func TestGobEncoderStructSingleton(t *testing.T) {
    572 	b := new(bytes.Buffer)
    573 	enc := NewEncoder(b)
    574 	err := enc.Encode(&ByteStruct{'A'})
    575 	if err != nil {
    576 		t.Fatal("encode error:", err)
    577 	}
    578 	dec := NewDecoder(b)
    579 	x := new(ByteStruct)
    580 	err = dec.Decode(x)
    581 	if err != nil {
    582 		t.Fatal("decode error:", err)
    583 	}
    584 	if x.a != 'A' {
    585 		t.Errorf("expected 'A' got %c", x.a)
    586 	}
    587 }
    588 
    589 func TestGobEncoderNonStructSingleton(t *testing.T) {
    590 	b := new(bytes.Buffer)
    591 	enc := NewEncoder(b)
    592 	var g Gobber = 1234
    593 	err := enc.Encode(&g)
    594 	if err != nil {
    595 		t.Fatal("encode error:", err)
    596 	}
    597 	dec := NewDecoder(b)
    598 	var x Gobber
    599 	err = dec.Decode(&x)
    600 	if err != nil {
    601 		t.Fatal("decode error:", err)
    602 	}
    603 	if x != 1234 {
    604 		t.Errorf("expected 1234 got %d", x)
    605 	}
    606 }
    607 
    608 func TestGobEncoderIgnoreStructField(t *testing.T) {
    609 	b := new(bytes.Buffer)
    610 	// First a field that's a structure.
    611 	enc := NewEncoder(b)
    612 	err := enc.Encode(GobTest0{17, &ByteStruct{'A'}})
    613 	if err != nil {
    614 		t.Fatal("encode error:", err)
    615 	}
    616 	dec := NewDecoder(b)
    617 	x := new(GobTestIgnoreEncoder)
    618 	err = dec.Decode(x)
    619 	if err != nil {
    620 		t.Fatal("decode error:", err)
    621 	}
    622 	if x.X != 17 {
    623 		t.Errorf("expected 17 got %c", x.X)
    624 	}
    625 }
    626 
    627 func TestGobEncoderIgnoreNonStructField(t *testing.T) {
    628 	b := new(bytes.Buffer)
    629 	// First a field that's a structure.
    630 	enc := NewEncoder(b)
    631 	gobber := Gobber(23)
    632 	bgobber := BinaryGobber(24)
    633 	tgobber := TextGobber(25)
    634 	err := enc.Encode(GobTest3{17, &gobber, &bgobber, &tgobber})
    635 	if err != nil {
    636 		t.Fatal("encode error:", err)
    637 	}
    638 	dec := NewDecoder(b)
    639 	x := new(GobTestIgnoreEncoder)
    640 	err = dec.Decode(x)
    641 	if err != nil {
    642 		t.Fatal("decode error:", err)
    643 	}
    644 	if x.X != 17 {
    645 		t.Errorf("expected 17 got %c", x.X)
    646 	}
    647 }
    648 
    649 func TestGobEncoderIgnoreNilEncoder(t *testing.T) {
    650 	b := new(bytes.Buffer)
    651 	// First a field that's a structure.
    652 	enc := NewEncoder(b)
    653 	err := enc.Encode(GobTest0{X: 18}) // G is nil
    654 	if err != nil {
    655 		t.Fatal("encode error:", err)
    656 	}
    657 	dec := NewDecoder(b)
    658 	x := new(GobTest0)
    659 	err = dec.Decode(x)
    660 	if err != nil {
    661 		t.Fatal("decode error:", err)
    662 	}
    663 	if x.X != 18 {
    664 		t.Errorf("expected x.X = 18, got %v", x.X)
    665 	}
    666 	if x.G != nil {
    667 		t.Errorf("expected x.G = nil, got %v", x.G)
    668 	}
    669 }
    670 
    671 type gobDecoderBug0 struct {
    672 	foo, bar string
    673 }
    674 
    675 func (br *gobDecoderBug0) String() string {
    676 	return br.foo + "-" + br.bar
    677 }
    678 
    679 func (br *gobDecoderBug0) GobEncode() ([]byte, error) {
    680 	return []byte(br.String()), nil
    681 }
    682 
    683 func (br *gobDecoderBug0) GobDecode(b []byte) error {
    684 	br.foo = "foo"
    685 	br.bar = "bar"
    686 	return nil
    687 }
    688 
    689 // This was a bug: the receiver has a different indirection level
    690 // than the variable.
    691 func TestGobEncoderExtraIndirect(t *testing.T) {
    692 	gdb := &gobDecoderBug0{"foo", "bar"}
    693 	buf := new(bytes.Buffer)
    694 	e := NewEncoder(buf)
    695 	if err := e.Encode(gdb); err != nil {
    696 		t.Fatalf("encode: %v", err)
    697 	}
    698 	d := NewDecoder(buf)
    699 	var got *gobDecoderBug0
    700 	if err := d.Decode(&got); err != nil {
    701 		t.Fatalf("decode: %v", err)
    702 	}
    703 	if got.foo != gdb.foo || got.bar != gdb.bar {
    704 		t.Errorf("got = %q, want %q", got, gdb)
    705 	}
    706 }
    707 
    708 // Another bug: this caused a crash with the new Go1 Time type.
    709 // We throw in a gob-encoding array, to test another case of isZero,
    710 // and a struct containing an nil interface, to test a third.
    711 type isZeroBug struct {
    712 	T time.Time
    713 	S string
    714 	I int
    715 	A isZeroBugArray
    716 	F isZeroBugInterface
    717 }
    718 
    719 type isZeroBugArray [2]uint8
    720 
    721 // Receiver is value, not pointer, to test isZero of array.
    722 func (a isZeroBugArray) GobEncode() (b []byte, e error) {
    723 	b = append(b, a[:]...)
    724 	return b, nil
    725 }
    726 
    727 func (a *isZeroBugArray) GobDecode(data []byte) error {
    728 	if len(data) != len(a) {
    729 		return io.EOF
    730 	}
    731 	a[0] = data[0]
    732 	a[1] = data[1]
    733 	return nil
    734 }
    735 
    736 type isZeroBugInterface struct {
    737 	I interface{}
    738 }
    739 
    740 func (i isZeroBugInterface) GobEncode() (b []byte, e error) {
    741 	return []byte{}, nil
    742 }
    743 
    744 func (i *isZeroBugInterface) GobDecode(data []byte) error {
    745 	return nil
    746 }
    747 
    748 func TestGobEncodeIsZero(t *testing.T) {
    749 	x := isZeroBug{time.Unix(1e9, 0), "hello", -55, isZeroBugArray{1, 2}, isZeroBugInterface{}}
    750 	b := new(bytes.Buffer)
    751 	enc := NewEncoder(b)
    752 	err := enc.Encode(x)
    753 	if err != nil {
    754 		t.Fatal("encode:", err)
    755 	}
    756 	var y isZeroBug
    757 	dec := NewDecoder(b)
    758 	err = dec.Decode(&y)
    759 	if err != nil {
    760 		t.Fatal("decode:", err)
    761 	}
    762 	if x != y {
    763 		t.Fatalf("%v != %v", x, y)
    764 	}
    765 }
    766 
    767 func TestGobEncodePtrError(t *testing.T) {
    768 	var err error
    769 	b := new(bytes.Buffer)
    770 	enc := NewEncoder(b)
    771 	err = enc.Encode(&err)
    772 	if err != nil {
    773 		t.Fatal("encode:", err)
    774 	}
    775 	dec := NewDecoder(b)
    776 	err2 := fmt.Errorf("foo")
    777 	err = dec.Decode(&err2)
    778 	if err != nil {
    779 		t.Fatal("decode:", err)
    780 	}
    781 	if err2 != nil {
    782 		t.Fatalf("expected nil, got %v", err2)
    783 	}
    784 }
    785 
    786 func TestNetIP(t *testing.T) {
    787 	// Encoding of net.IP{1,2,3,4} in Go 1.1.
    788 	enc := []byte{0x07, 0x0a, 0x00, 0x04, 0x01, 0x02, 0x03, 0x04}
    789 
    790 	var ip net.IP
    791 	err := NewDecoder(bytes.NewReader(enc)).Decode(&ip)
    792 	if err != nil {
    793 		t.Fatalf("decode: %v", err)
    794 	}
    795 	if ip.String() != "1.2.3.4" {
    796 		t.Errorf("decoded to %v, want 1.2.3.4", ip.String())
    797 	}
    798 }
    799