...

Source file src/encoding/gob/gobencdec_test.go

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

View as plain text