Source file
src/encoding/gob/gobencdec_test.go
1
2
3
4
5
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
21
22 type ByteStruct struct {
23 a byte
24 }
25
26 type StringStruct struct {
27 s string
28 }
29
30 type ArrayStruct struct {
31 a [8192]byte
32 }
33
34 type Gobber int
35
36 type ValueGobber string
37
38 type BinaryGobber int
39
40 type BinaryValueGobber string
41
42 type TextGobber int
43
44 type TextValueGobber string
45
46
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
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
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
159
160 type GobTest0 struct {
161 X int
162 G *ByteStruct
163 }
164
165 type GobTest1 struct {
166 X int
167 G *StringStruct
168 }
169
170 type GobTest2 struct {
171 X int
172 G string
173 }
174
175 type GobTest3 struct {
176 X int
177 G *Gobber
178 B *BinaryGobber
179 T *TextGobber
180 }
181
182 type GobTest4 struct {
183 X int
184 V ValueGobber
185 BV BinaryValueGobber
186 TV TextValueGobber
187 }
188
189 type GobTest5 struct {
190 X int
191 V *ValueGobber
192 BV *BinaryValueGobber
193 TV *TextValueGobber
194 }
195
196 type GobTest6 struct {
197 X int
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
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
218 }
219
220 type GobTestValueEncDec struct {
221 X int
222 G StringStruct
223 }
224
225 type GobTestIndirectEncDec struct {
226 X int
227 G ***StringStruct
228 }
229
230 type GobTestArrayEncDec struct {
231 X int
232 A ArrayStruct
233 }
234
235 type GobTestIndirectArrayEncDec struct {
236 X int
237 A ***ArrayStruct
238 }
239
240 func TestGobEncoderField(t *testing.T) {
241 b := new(bytes.Buffer)
242
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
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
277
278 func TestGobEncoderValueField(t *testing.T) {
279 b := new(bytes.Buffer)
280
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
298
299 func TestGobEncoderIndirectField(t *testing.T) {
300 b := new(bytes.Buffer)
301
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
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
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
379
380
381
382
383 func TestGobEncoderFieldsOfDifferentType(t *testing.T) {
384
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
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
417 func TestGobEncoderValueEncoder(t *testing.T) {
418
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
437
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
447
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
489
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
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
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
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
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
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
652 enc := NewEncoder(b)
653 err := enc.Encode(GobTest0{X: 18})
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
690
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
709
710
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
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 any
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
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
View as plain text