codekingpro/portable-devtools
114k
1// Copyright 2009 The Go Authors. All rights reserved.2// Use of this source code is governed by a BSD-style3// license that can be found in the LICENSE file.4 5package gob6 7import (8 "bytes"9 "errors"10 "flag"11 "math"12 "math/rand"13 "reflect"14 "strings"15 "testing"16 "time"17 "unsafe"18)19 20var doFuzzTests = flag.Bool("gob.fuzz", false, "run the fuzz tests, which are large and very slow")21 22// Guarantee encoding format by comparing some encodings to hand-written values23type EncodeT struct {24 x uint6425 b []byte26}27 28var encodeT = []EncodeT{29 {0x00, []byte{0x00}},30 {0x0F, []byte{0x0F}},31 {0xFF, []byte{0xFF, 0xFF}},32 {0xFFFF, []byte{0xFE, 0xFF, 0xFF}},33 {0xFFFFFF, []byte{0xFD, 0xFF, 0xFF, 0xFF}},34 {0xFFFFFFFF, []byte{0xFC, 0xFF, 0xFF, 0xFF, 0xFF}},35 {0xFFFFFFFFFF, []byte{0xFB, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}},36 {0xFFFFFFFFFFFF, []byte{0xFA, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}},37 {0xFFFFFFFFFFFFFF, []byte{0xF9, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}},38 {0xFFFFFFFFFFFFFFFF, []byte{0xF8, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}},39 {0x1111, []byte{0xFE, 0x11, 0x11}},40 {0x1111111111111111, []byte{0xF8, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11}},41 {0x8888888888888888, []byte{0xF8, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88}},42 {1 << 63, []byte{0xF8, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}},43}44 45// testError is meant to be used as a deferred function to turn a panic(gobError) into a46// plain test.Error call.47func testError(t *testing.T) {48 if e := recover(); e != nil {49 t.Error(e.(gobError).err) // Will re-panic if not one of our errors, such as a runtime error.50 }51}52 53func newDecBuffer(data []byte) *decBuffer {54 return &decBuffer{55 data: data,56 }57}58 59// Test basic encode/decode routines for unsigned integers60func TestUintCodec(t *testing.T) {61 defer testError(t)62 b := new(encBuffer)63 encState := newEncoderState(b)64 for _, tt := range encodeT {65 b.Reset()66 encState.encodeUint(tt.x)67 if !bytes.Equal(tt.b, b.Bytes()) {68 t.Errorf("encodeUint: %#x encode: expected % x got % x", tt.x, tt.b, b.Bytes())69 }70 }71 for u := uint64(0); ; u = (u + 1) * 7 {72 b.Reset()73 encState.encodeUint(u)74 decState := newDecodeState(newDecBuffer(b.Bytes()))75 v := decState.decodeUint()76 if u != v {77 t.Errorf("Encode/Decode: sent %#x received %#x", u, v)78 }79 if u&(1<<63) != 0 {80 break81 }82 }83}84 85func verifyInt(i int64, t *testing.T) {86 defer testError(t)87 var b = new(encBuffer)88 encState := newEncoderState(b)89 encState.encodeInt(i)90 decState := newDecodeState(newDecBuffer(b.Bytes()))91 j := decState.decodeInt()92 if i != j {93 t.Errorf("Encode/Decode: sent %#x received %#x", uint64(i), uint64(j))94 }95}96 97// Test basic encode/decode routines for signed integers98func TestIntCodec(t *testing.T) {99 for u := uint64(0); ; u = (u + 1) * 7 {100 // Do positive and negative values101 i := int64(u)102 verifyInt(i, t)103 verifyInt(-i, t)104 verifyInt(^i, t)105 if u&(1<<63) != 0 {106 break107 }108 }109 verifyInt(-1<<63, t) // a tricky case110}111 112// The result of encoding a true boolean with field number 7113var boolResult = []byte{0x07, 0x01}114 115// The result of encoding a number 17 with field number 7116var signedResult = []byte{0x07, 2 * 17}117var unsignedResult = []byte{0x07, 17}118var floatResult = []byte{0x07, 0xFE, 0x31, 0x40}119 120// The result of encoding a number 17+19i with field number 7121var complexResult = []byte{0x07, 0xFE, 0x31, 0x40, 0xFE, 0x33, 0x40}122 123// The result of encoding "hello" with field number 7124var bytesResult = []byte{0x07, 0x05, 'h', 'e', 'l', 'l', 'o'}125 126func newDecodeState(buf *decBuffer) *decoderState {127 d := new(decoderState)128 d.b = buf129 return d130}131 132func newEncoderState(b *encBuffer) *encoderState {133 b.Reset()134 state := &encoderState{enc: nil, b: b}135 state.fieldnum = -1136 return state137}138 139// Test instruction execution for encoding.140// Do not run the machine yet; instead do individual instructions crafted by hand.141func TestScalarEncInstructions(t *testing.T) {142 var b = new(encBuffer)143 144 // bool145 {146 var data bool = true147 instr := &encInstr{encBool, 6, nil, 0}148 state := newEncoderState(b)149 instr.op(instr, state, reflect.ValueOf(data))150 if !bytes.Equal(boolResult, b.Bytes()) {151 t.Errorf("bool enc instructions: expected % x got % x", boolResult, b.Bytes())152 }153 }154 155 // int156 {157 b.Reset()158 var data int = 17159 instr := &encInstr{encInt, 6, nil, 0}160 state := newEncoderState(b)161 instr.op(instr, state, reflect.ValueOf(data))162 if !bytes.Equal(signedResult, b.Bytes()) {163 t.Errorf("int enc instructions: expected % x got % x", signedResult, b.Bytes())164 }165 }166 167 // uint168 {169 b.Reset()170 var data uint = 17171 instr := &encInstr{encUint, 6, nil, 0}172 state := newEncoderState(b)173 instr.op(instr, state, reflect.ValueOf(data))174 if !bytes.Equal(unsignedResult, b.Bytes()) {175 t.Errorf("uint enc instructions: expected % x got % x", unsignedResult, b.Bytes())176 }177 }178 179 // int8180 {181 b.Reset()182 var data int8 = 17183 instr := &encInstr{encInt, 6, nil, 0}184 state := newEncoderState(b)185 instr.op(instr, state, reflect.ValueOf(data))186 if !bytes.Equal(signedResult, b.Bytes()) {187 t.Errorf("int8 enc instructions: expected % x got % x", signedResult, b.Bytes())188 }189 }190 191 // uint8192 {193 b.Reset()194 var data uint8 = 17195 instr := &encInstr{encUint, 6, nil, 0}196 state := newEncoderState(b)197 instr.op(instr, state, reflect.ValueOf(data))198 if !bytes.Equal(unsignedResult, b.Bytes()) {199 t.Errorf("uint8 enc instructions: expected % x got % x", unsignedResult, b.Bytes())200 }201 }202 203 // int16204 {205 b.Reset()206 var data int16 = 17207 instr := &encInstr{encInt, 6, nil, 0}208 state := newEncoderState(b)209 instr.op(instr, state, reflect.ValueOf(data))210 if !bytes.Equal(signedResult, b.Bytes()) {211 t.Errorf("int16 enc instructions: expected % x got % x", signedResult, b.Bytes())212 }213 }214 215 // uint16216 {217 b.Reset()218 var data uint16 = 17219 instr := &encInstr{encUint, 6, nil, 0}220 state := newEncoderState(b)221 instr.op(instr, state, reflect.ValueOf(data))222 if !bytes.Equal(unsignedResult, b.Bytes()) {223 t.Errorf("uint16 enc instructions: expected % x got % x", unsignedResult, b.Bytes())224 }225 }226 227 // int32228 {229 b.Reset()230 var data int32 = 17231 instr := &encInstr{encInt, 6, nil, 0}232 state := newEncoderState(b)233 instr.op(instr, state, reflect.ValueOf(data))234 if !bytes.Equal(signedResult, b.Bytes()) {235 t.Errorf("int32 enc instructions: expected % x got % x", signedResult, b.Bytes())236 }237 }238 239 // uint32240 {241 b.Reset()242 var data uint32 = 17243 instr := &encInstr{encUint, 6, nil, 0}244 state := newEncoderState(b)245 instr.op(instr, state, reflect.ValueOf(data))246 if !bytes.Equal(unsignedResult, b.Bytes()) {247 t.Errorf("uint32 enc instructions: expected % x got % x", unsignedResult, b.Bytes())248 }249 }250 251 // int64252 {253 b.Reset()254 var data int64 = 17255 instr := &encInstr{encInt, 6, nil, 0}256 state := newEncoderState(b)257 instr.op(instr, state, reflect.ValueOf(data))258 if !bytes.Equal(signedResult, b.Bytes()) {259 t.Errorf("int64 enc instructions: expected % x got % x", signedResult, b.Bytes())260 }261 }262 263 // uint64264 {265 b.Reset()266 var data uint64 = 17267 instr := &encInstr{encUint, 6, nil, 0}268 state := newEncoderState(b)269 instr.op(instr, state, reflect.ValueOf(data))270 if !bytes.Equal(unsignedResult, b.Bytes()) {271 t.Errorf("uint64 enc instructions: expected % x got % x", unsignedResult, b.Bytes())272 }273 }274 275 // float32276 {277 b.Reset()278 var data float32 = 17279 instr := &encInstr{encFloat, 6, nil, 0}280 state := newEncoderState(b)281 instr.op(instr, state, reflect.ValueOf(data))282 if !bytes.Equal(floatResult, b.Bytes()) {283 t.Errorf("float32 enc instructions: expected % x got % x", floatResult, b.Bytes())284 }285 }286 287 // float64288 {289 b.Reset()290 var data float64 = 17291 instr := &encInstr{encFloat, 6, nil, 0}292 state := newEncoderState(b)293 instr.op(instr, state, reflect.ValueOf(data))294 if !bytes.Equal(floatResult, b.Bytes()) {295 t.Errorf("float64 enc instructions: expected % x got % x", floatResult, b.Bytes())296 }297 }298 299 // bytes == []uint8300 {301 b.Reset()302 data := []byte("hello")303 instr := &encInstr{encUint8Array, 6, nil, 0}304 state := newEncoderState(b)305 instr.op(instr, state, reflect.ValueOf(data))306 if !bytes.Equal(bytesResult, b.Bytes()) {307 t.Errorf("bytes enc instructions: expected % x got % x", bytesResult, b.Bytes())308 }309 }310 311 // string312 {313 b.Reset()314 var data string = "hello"315 instr := &encInstr{encString, 6, nil, 0}316 state := newEncoderState(b)317 instr.op(instr, state, reflect.ValueOf(data))318 if !bytes.Equal(bytesResult, b.Bytes()) {319 t.Errorf("string enc instructions: expected % x got % x", bytesResult, b.Bytes())320 }321 }322}323 324func execDec(instr *decInstr, state *decoderState, t *testing.T, value reflect.Value) {325 defer testError(t)326 v := int(state.decodeUint())327 if v+state.fieldnum != 6 {328 t.Fatalf("decoding field number %d, got %d", 6, v+state.fieldnum)329 }330 instr.op(instr, state, value.Elem())331 state.fieldnum = 6332}333 334func newDecodeStateFromData(data []byte) *decoderState {335 b := newDecBuffer(data)336 state := newDecodeState(b)337 state.fieldnum = -1338 return state339}340 341// Test instruction execution for decoding.342// Do not run the machine yet; instead do individual instructions crafted by hand.343func TestScalarDecInstructions(t *testing.T) {344 ovfl := errors.New("overflow")345 346 // bool347 {348 var data bool349 instr := &decInstr{decBool, 6, nil, ovfl}350 state := newDecodeStateFromData(boolResult)351 execDec(instr, state, t, reflect.ValueOf(&data))352 if data != true {353 t.Errorf("bool a = %v not true", data)354 }355 }356 // int357 {358 var data int359 instr := &decInstr{decOpTable[reflect.Int], 6, nil, ovfl}360 state := newDecodeStateFromData(signedResult)361 execDec(instr, state, t, reflect.ValueOf(&data))362 if data != 17 {363 t.Errorf("int a = %v not 17", data)364 }365 }366 367 // uint368 {369 var data uint370 instr := &decInstr{decOpTable[reflect.Uint], 6, nil, ovfl}371 state := newDecodeStateFromData(unsignedResult)372 execDec(instr, state, t, reflect.ValueOf(&data))373 if data != 17 {374 t.Errorf("uint a = %v not 17", data)375 }376 }377 378 // int8379 {380 var data int8381 instr := &decInstr{decInt8, 6, nil, ovfl}382 state := newDecodeStateFromData(signedResult)383 execDec(instr, state, t, reflect.ValueOf(&data))384 if data != 17 {385 t.Errorf("int8 a = %v not 17", data)386 }387 }388 389 // uint8390 {391 var data uint8392 instr := &decInstr{decUint8, 6, nil, ovfl}393 state := newDecodeStateFromData(unsignedResult)394 execDec(instr, state, t, reflect.ValueOf(&data))395 if data != 17 {396 t.Errorf("uint8 a = %v not 17", data)397 }398 }399 400 // int16401 {402 var data int16403 instr := &decInstr{decInt16, 6, nil, ovfl}404 state := newDecodeStateFromData(signedResult)405 execDec(instr, state, t, reflect.ValueOf(&data))406 if data != 17 {407 t.Errorf("int16 a = %v not 17", data)408 }409 }410 411 // uint16412 {413 var data uint16414 instr := &decInstr{decUint16, 6, nil, ovfl}415 state := newDecodeStateFromData(unsignedResult)416 execDec(instr, state, t, reflect.ValueOf(&data))417 if data != 17 {418 t.Errorf("uint16 a = %v not 17", data)419 }420 }421 422 // int32423 {424 var data int32425 instr := &decInstr{decInt32, 6, nil, ovfl}426 state := newDecodeStateFromData(signedResult)427 execDec(instr, state, t, reflect.ValueOf(&data))428 if data != 17 {429 t.Errorf("int32 a = %v not 17", data)430 }431 }432 433 // uint32434 {435 var data uint32436 instr := &decInstr{decUint32, 6, nil, ovfl}437 state := newDecodeStateFromData(unsignedResult)438 execDec(instr, state, t, reflect.ValueOf(&data))439 if data != 17 {440 t.Errorf("uint32 a = %v not 17", data)441 }442 }443 444 // uintptr445 {446 var data uintptr447 instr := &decInstr{decOpTable[reflect.Uintptr], 6, nil, ovfl}448 state := newDecodeStateFromData(unsignedResult)449 execDec(instr, state, t, reflect.ValueOf(&data))450 if data != 17 {451 t.Errorf("uintptr a = %v not 17", data)452 }453 }454 455 // int64456 {457 var data int64458 instr := &decInstr{decInt64, 6, nil, ovfl}459 state := newDecodeStateFromData(signedResult)460 execDec(instr, state, t, reflect.ValueOf(&data))461 if data != 17 {462 t.Errorf("int64 a = %v not 17", data)463 }464 }465 466 // uint64467 {468 var data uint64469 instr := &decInstr{decUint64, 6, nil, ovfl}470 state := newDecodeStateFromData(unsignedResult)471 execDec(instr, state, t, reflect.ValueOf(&data))472 if data != 17 {473 t.Errorf("uint64 a = %v not 17", data)474 }475 }476 477 // float32478 {479 var data float32480 instr := &decInstr{decFloat32, 6, nil, ovfl}481 state := newDecodeStateFromData(floatResult)482 execDec(instr, state, t, reflect.ValueOf(&data))483 if data != 17 {484 t.Errorf("float32 a = %v not 17", data)485 }486 }487 488 // float64489 {490 var data float64491 instr := &decInstr{decFloat64, 6, nil, ovfl}492 state := newDecodeStateFromData(floatResult)493 execDec(instr, state, t, reflect.ValueOf(&data))494 if data != 17 {495 t.Errorf("float64 a = %v not 17", data)496 }497 }498 499 // complex64500 {501 var data complex64502 instr := &decInstr{decOpTable[reflect.Complex64], 6, nil, ovfl}503 state := newDecodeStateFromData(complexResult)504 execDec(instr, state, t, reflect.ValueOf(&data))505 if data != 17+19i {506 t.Errorf("complex a = %v not 17+19i", data)507 }508 }509 510 // complex128511 {512 var data complex128513 instr := &decInstr{decOpTable[reflect.Complex128], 6, nil, ovfl}514 state := newDecodeStateFromData(complexResult)515 execDec(instr, state, t, reflect.ValueOf(&data))516 if data != 17+19i {517 t.Errorf("complex a = %v not 17+19i", data)518 }519 }520 521 // bytes == []uint8522 {523 var data []byte524 instr := &decInstr{decUint8Slice, 6, nil, ovfl}525 state := newDecodeStateFromData(bytesResult)526 execDec(instr, state, t, reflect.ValueOf(&data))527 if string(data) != "hello" {528 t.Errorf(`bytes a = %q not "hello"`, string(data))529 }530 }531 532 // string533 {534 var data string535 instr := &decInstr{decString, 6, nil, ovfl}536 state := newDecodeStateFromData(bytesResult)537 execDec(instr, state, t, reflect.ValueOf(&data))538 if data != "hello" {539 t.Errorf(`bytes a = %q not "hello"`, data)540 }541 }542}543 544func TestEndToEnd(t *testing.T) {545 type T2 struct {546 T string547 }548 type T3 struct {549 X float64550 Z *int551 }552 type T1 struct {553 A, B, C int554 M map[string]*float64555 M2 map[int]T3556 Mstring map[string]string557 Mintptr map[int]*int558 Mcomp map[complex128]complex128559 Marr map[[2]string][2]*float64560 EmptyMap map[string]int // to check that we receive a non-nil map.561 N *[3]float64562 Strs *[2]string563 Int64s *[]int64564 RI complex64565 S string566 Y []byte567 T *T2568 }569 pi := 3.14159570 e := 2.71828571 two := 2.0572 meaning := 42573 fingers := 5574 s1 := "string1"575 s2 := "string2"576 var comp1 complex128 = complex(1.0, 1.0)577 var comp2 complex128 = complex(1.0, 1.0)578 var arr1 [2]string579 arr1[0] = s1580 arr1[1] = s2581 var arr2 [2]string582 arr2[0] = s2583 arr2[1] = s1584 var floatArr1 [2]*float64585 floatArr1[0] = &pi586 floatArr1[1] = &e587 var floatArr2 [2]*float64588 floatArr2[0] = &e589 floatArr2[1] = &two590 t1 := &T1{591 A: 17,592 B: 18,593 C: -5,594 M: map[string]*float64{"pi": &pi, "e": &e},595 M2: map[int]T3{4: {X: pi, Z: &meaning}, 10: {X: e, Z: &fingers}},596 Mstring: map[string]string{"pi": "3.14", "e": "2.71"},597 Mintptr: map[int]*int{meaning: &fingers, fingers: &meaning},598 Mcomp: map[complex128]complex128{comp1: comp2, comp2: comp1},599 Marr: map[[2]string][2]*float64{arr1: floatArr1, arr2: floatArr2},600 EmptyMap: make(map[string]int),601 N: &[3]float64{1.5, 2.5, 3.5},602 Strs: &[2]string{s1, s2},603 Int64s: &[]int64{77, 89, 123412342134},604 RI: 17 - 23i,605 S: "Now is the time",606 Y: []byte("hello, sailor"),607 T: &T2{"this is T2"},608 }609 b := new(bytes.Buffer)610 err := NewEncoder(b).Encode(t1)611 if err != nil {612 t.Error("encode:", err)613 }614 var _t1 T1615 err = NewDecoder(b).Decode(&_t1)616 if err != nil {617 t.Fatal("decode:", err)618 }619 if !reflect.DeepEqual(t1, &_t1) {620 t.Errorf("encode expected %v got %v", *t1, _t1)621 }622 // Be absolutely sure the received map is non-nil.623 if t1.EmptyMap == nil {624 t.Errorf("nil map sent")625 }626 if _t1.EmptyMap == nil {627 t.Errorf("nil map received")628 }629}630 631func TestOverflow(t *testing.T) {632 type inputT struct {633 Maxi int64634 Mini int64635 Maxu uint64636 Maxf float64637 Minf float64638 Maxc complex128639 Minc complex128640 }641 var it inputT642 var err error643 b := new(bytes.Buffer)644 enc := NewEncoder(b)645 dec := NewDecoder(b)646 647 // int8648 b.Reset()649 it = inputT{650 Maxi: math.MaxInt8 + 1,651 }652 type outi8 struct {653 Maxi int8654 Mini int8655 }656 var o1 outi8657 enc.Encode(it)658 err = dec.Decode(&o1)659 if err == nil || err.Error() != `value for "Maxi" out of range` {660 t.Error("wrong overflow error for int8:", err)661 }662 it = inputT{663 Mini: math.MinInt8 - 1,664 }665 b.Reset()666 enc.Encode(it)667 err = dec.Decode(&o1)668 if err == nil || err.Error() != `value for "Mini" out of range` {669 t.Error("wrong underflow error for int8:", err)670 }671 672 // int16673 b.Reset()674 it = inputT{675 Maxi: math.MaxInt16 + 1,676 }677 type outi16 struct {678 Maxi int16679 Mini int16680 }681 var o2 outi16682 enc.Encode(it)683 err = dec.Decode(&o2)684 if err == nil || err.Error() != `value for "Maxi" out of range` {685 t.Error("wrong overflow error for int16:", err)686 }687 it = inputT{688 Mini: math.MinInt16 - 1,689 }690 b.Reset()691 enc.Encode(it)692 err = dec.Decode(&o2)693 if err == nil || err.Error() != `value for "Mini" out of range` {694 t.Error("wrong underflow error for int16:", err)695 }696 697 // int32698 b.Reset()699 it = inputT{700 Maxi: math.MaxInt32 + 1,701 }702 type outi32 struct {703 Maxi int32704 Mini int32705 }706 var o3 outi32707 enc.Encode(it)708 err = dec.Decode(&o3)709 if err == nil || err.Error() != `value for "Maxi" out of range` {710 t.Error("wrong overflow error for int32:", err)711 }712 it = inputT{713 Mini: math.MinInt32 - 1,714 }715 b.Reset()716 enc.Encode(it)717 err = dec.Decode(&o3)718 if err == nil || err.Error() != `value for "Mini" out of range` {719 t.Error("wrong underflow error for int32:", err)720 }721 722 // uint8723 b.Reset()724 it = inputT{725 Maxu: math.MaxUint8 + 1,726 }727 type outu8 struct {728 Maxu uint8729 }730 var o4 outu8731 enc.Encode(it)732 err = dec.Decode(&o4)733 if err == nil || err.Error() != `value for "Maxu" out of range` {734 t.Error("wrong overflow error for uint8:", err)735 }736 737 // uint16738 b.Reset()739 it = inputT{740 Maxu: math.MaxUint16 + 1,741 }742 type outu16 struct {743 Maxu uint16744 }745 var o5 outu16746 enc.Encode(it)747 err = dec.Decode(&o5)748 if err == nil || err.Error() != `value for "Maxu" out of range` {749 t.Error("wrong overflow error for uint16:", err)750 }751 752 // uint32753 b.Reset()754 it = inputT{755 Maxu: math.MaxUint32 + 1,756 }757 type outu32 struct {758 Maxu uint32759 }760 var o6 outu32761 enc.Encode(it)762 err = dec.Decode(&o6)763 if err == nil || err.Error() != `value for "Maxu" out of range` {764 t.Error("wrong overflow error for uint32:", err)765 }766 767 // float32768 b.Reset()769 it = inputT{770 Maxf: math.MaxFloat32 * 2,771 }772 type outf32 struct {773 Maxf float32774 Minf float32775 }776 var o7 outf32777 enc.Encode(it)778 err = dec.Decode(&o7)779 if err == nil || err.Error() != `value for "Maxf" out of range` {780 t.Error("wrong overflow error for float32:", err)781 }782 783 // complex64784 b.Reset()785 it = inputT{786 Maxc: complex(math.MaxFloat32*2, math.MaxFloat32*2),787 }788 type outc64 struct {789 Maxc complex64790 Minc complex64791 }792 var o8 outc64793 enc.Encode(it)794 err = dec.Decode(&o8)795 if err == nil || err.Error() != `value for "Maxc" out of range` {796 t.Error("wrong overflow error for complex64:", err)797 }798}799 800func TestNesting(t *testing.T) {801 type RT struct {802 A string803 Next *RT804 }805 rt := new(RT)806 rt.A = "level1"807 rt.Next = new(RT)808 rt.Next.A = "level2"809 b := new(bytes.Buffer)810 NewEncoder(b).Encode(rt)811 var drt RT812 dec := NewDecoder(b)813 err := dec.Decode(&drt)814 if err != nil {815 t.Fatal("decoder error:", err)816 }817 if drt.A != rt.A {818 t.Errorf("nesting: encode expected %v got %v", *rt, drt)819 }820 if drt.Next == nil {821 t.Errorf("nesting: recursion failed")822 }823 if drt.Next.A != rt.Next.A {824 t.Errorf("nesting: encode expected %v got %v", *rt.Next, *drt.Next)825 }826}827 828// These three structures have the same data with different indirections829type T0 struct {830 A int831 B int832 C int833 D int834}835type T1 struct {836 A int837 B *int838 C **int839 D ***int840}841type T2 struct {842 A ***int843 B **int844 C *int845 D int846}847 848func TestAutoIndirection(t *testing.T) {849 // First transfer t1 into t0850 var t1 T1851 t1.A = 17852 t1.B = new(int)853 *t1.B = 177854 t1.C = new(*int)855 *t1.C = new(int)856 **t1.C = 1777857 t1.D = new(**int)858 *t1.D = new(*int)859 **t1.D = new(int)860 ***t1.D = 17777861 b := new(bytes.Buffer)862 enc := NewEncoder(b)863 enc.Encode(t1)864 dec := NewDecoder(b)865 var t0 T0866 dec.Decode(&t0)867 if t0.A != 17 || t0.B != 177 || t0.C != 1777 || t0.D != 17777 {868 t.Errorf("t1->t0: expected {17 177 1777 17777}; got %v", t0)869 }870 871 // Now transfer t2 into t0872 var t2 T2873 t2.D = 17777874 t2.C = new(int)875 *t2.C = 1777876 t2.B = new(*int)877 *t2.B = new(int)878 **t2.B = 177879 t2.A = new(**int)880 *t2.A = new(*int)881 **t2.A = new(int)882 ***t2.A = 17883 b.Reset()884 enc.Encode(t2)885 t0 = T0{}886 dec.Decode(&t0)887 if t0.A != 17 || t0.B != 177 || t0.C != 1777 || t0.D != 17777 {888 t.Errorf("t2->t0 expected {17 177 1777 17777}; got %v", t0)889 }890 891 // Now transfer t0 into t1892 t0 = T0{17, 177, 1777, 17777}893 b.Reset()894 enc.Encode(t0)895 t1 = T1{}896 dec.Decode(&t1)897 if t1.A != 17 || *t1.B != 177 || **t1.C != 1777 || ***t1.D != 17777 {898 t.Errorf("t0->t1 expected {17 177 1777 17777}; got {%d %d %d %d}", t1.A, *t1.B, **t1.C, ***t1.D)899 }900 901 // Now transfer t0 into t2902 b.Reset()903 enc.Encode(t0)904 t2 = T2{}905 dec.Decode(&t2)906 if ***t2.A != 17 || **t2.B != 177 || *t2.C != 1777 || t2.D != 17777 {907 t.Errorf("t0->t2 expected {17 177 1777 17777}; got {%d %d %d %d}", ***t2.A, **t2.B, *t2.C, t2.D)908 }909 910 // Now do t2 again but without pre-allocated pointers.911 b.Reset()912 enc.Encode(t0)913 ***t2.A = 0914 **t2.B = 0915 *t2.C = 0916 t2.D = 0917 dec.Decode(&t2)918 if ***t2.A != 17 || **t2.B != 177 || *t2.C != 1777 || t2.D != 17777 {919 t.Errorf("t0->t2 expected {17 177 1777 17777}; got {%d %d %d %d}", ***t2.A, **t2.B, *t2.C, t2.D)920 }921}922 923type RT0 struct {924 A int925 B string926 C float64927}928type RT1 struct {929 C float64930 B string931 A int932 NotSet string933}934 935func TestReorderedFields(t *testing.T) {936 var rt0 RT0937 rt0.A = 17938 rt0.B = "hello"939 rt0.C = 3.14159940 b := new(bytes.Buffer)941 NewEncoder(b).Encode(rt0)942 dec := NewDecoder(b)943 var rt1 RT1944 // Wire type is RT0, local type is RT1.945 err := dec.Decode(&rt1)946 if err != nil {947 t.Fatal("decode error:", err)948 }949 if rt0.A != rt1.A || rt0.B != rt1.B || rt0.C != rt1.C {950 t.Errorf("rt1->rt0: expected %v; got %v", rt0, rt1)951 }952}953 954// Like an RT0 but with fields we'll ignore on the decode side.955type IT0 struct {956 A int64957 B string958 Ignore_d []int959 Ignore_e [3]float64960 Ignore_f bool961 Ignore_g string962 Ignore_h []byte963 Ignore_i *RT1964 Ignore_m map[string]int965 C float64966}967 968func TestIgnoredFields(t *testing.T) {969 var it0 IT0970 it0.A = 17971 it0.B = "hello"972 it0.C = 3.14159973 it0.Ignore_d = []int{1, 2, 3}974 it0.Ignore_e[0] = 1.0975 it0.Ignore_e[1] = 2.0976 it0.Ignore_e[2] = 3.0977 it0.Ignore_f = true978 it0.Ignore_g = "pay no attention"979 it0.Ignore_h = []byte("to the curtain")980 it0.Ignore_i = &RT1{3.1, "hi", 7, "hello"}981 it0.Ignore_m = map[string]int{"one": 1, "two": 2}982 983 b := new(bytes.Buffer)984 NewEncoder(b).Encode(it0)985 dec := NewDecoder(b)986 var rt1 RT1987 // Wire type is IT0, local type is RT1.988 err := dec.Decode(&rt1)989 if err != nil {990 t.Error("error: ", err)991 }992 if int(it0.A) != rt1.A || it0.B != rt1.B || it0.C != rt1.C {993 t.Errorf("rt0->rt1: expected %v; got %v", it0, rt1)994 }995}996 997func TestBadRecursiveType(t *testing.T) {998 type Rec ***Rec999 var rec Rec1000 b := new(bytes.Buffer)1001 err := NewEncoder(b).Encode(&rec)1002 if err == nil {1003 t.Error("expected error; got none")1004 } else if !strings.Contains(err.Error(), "recursive") {1005 t.Error("expected recursive type error; got", err)1006 }1007 // Can't test decode easily because we can't encode one, so we can't pass one to a Decoder.1008}1009 1010type Indirect struct {1011 A ***[3]int1012 S ***[]int1013 M ****map[string]int1014}1015 1016type Direct struct {1017 A [3]int1018 S []int1019 M map[string]int1020}1021 1022func TestIndirectSliceMapArray(t *testing.T) {1023 // Marshal indirect, unmarshal to direct.1024 i := new(Indirect)1025 i.A = new(**[3]int)1026 *i.A = new(*[3]int)1027 **i.A = new([3]int)1028 ***i.A = [3]int{1, 2, 3}1029 i.S = new(**[]int)1030 *i.S = new(*[]int)1031 **i.S = new([]int)1032 ***i.S = []int{4, 5, 6}1033 i.M = new(***map[string]int)1034 *i.M = new(**map[string]int)1035 **i.M = new(*map[string]int)1036 ***i.M = new(map[string]int)1037 ****i.M = map[string]int{"one": 1, "two": 2, "three": 3}1038 b := new(bytes.Buffer)1039 NewEncoder(b).Encode(i)1040 dec := NewDecoder(b)1041 var d Direct1042 err := dec.Decode(&d)1043 if err != nil {1044 t.Error("error: ", err)1045 }1046 if len(d.A) != 3 || d.A[0] != 1 || d.A[1] != 2 || d.A[2] != 3 {1047 t.Errorf("indirect to direct: d.A is %v not %v", d.A, ***i.A)1048 }1049 if len(d.S) != 3 || d.S[0] != 4 || d.S[1] != 5 || d.S[2] != 6 {1050 t.Errorf("indirect to direct: d.S is %v not %v", d.S, ***i.S)1051 }1052 if len(d.M) != 3 || d.M["one"] != 1 || d.M["two"] != 2 || d.M["three"] != 3 {1053 t.Errorf("indirect to direct: d.M is %v not %v", d.M, ***i.M)1054 }1055 // Marshal direct, unmarshal to indirect.1056 d.A = [3]int{11, 22, 33}1057 d.S = []int{44, 55, 66}1058 d.M = map[string]int{"four": 4, "five": 5, "six": 6}1059 i = new(Indirect)1060 b.Reset()1061 NewEncoder(b).Encode(d)1062 dec = NewDecoder(b)1063 err = dec.Decode(&i)1064 if err != nil {1065 t.Fatal("error: ", err)1066 }1067 if len(***i.A) != 3 || (***i.A)[0] != 11 || (***i.A)[1] != 22 || (***i.A)[2] != 33 {1068 t.Errorf("direct to indirect: ***i.A is %v not %v", ***i.A, d.A)1069 }1070 if len(***i.S) != 3 || (***i.S)[0] != 44 || (***i.S)[1] != 55 || (***i.S)[2] != 66 {1071 t.Errorf("direct to indirect: ***i.S is %v not %v", ***i.S, ***i.S)1072 }1073 if len(****i.M) != 3 || (****i.M)["four"] != 4 || (****i.M)["five"] != 5 || (****i.M)["six"] != 6 {1074 t.Errorf("direct to indirect: ****i.M is %v not %v", ****i.M, d.M)1075 }1076}1077 1078// An interface with several implementations1079type Squarer interface {1080 Square() int1081}1082 1083type Int int1084 1085func (i Int) Square() int {1086 return int(i * i)1087}1088 1089type Float float641090 1091func (f Float) Square() int {1092 return int(f * f)1093}1094 1095type Vector []int1096 1097func (v Vector) Square() int {1098 sum := 01099 for _, x := range v {1100 sum += x * x1101 }1102 return sum1103}1104 1105type Point struct {1106 X, Y int1107}1108 1109func (p Point) Square() int {1110 return p.X*p.X + p.Y*p.Y1111}1112 1113// A struct with interfaces in it.1114type InterfaceItem struct {1115 I int1116 Sq1, Sq2, Sq3 Squarer1117 F float641118 Sq []Squarer1119}1120 1121// The same struct without interfaces1122type NoInterfaceItem struct {1123 I int1124 F float641125}1126 1127func TestInterface(t *testing.T) {1128 iVal := Int(3)1129 fVal := Float(5)1130 // Sending a Vector will require that the receiver define a type in the middle of1131 // receiving the value for item2.1132 vVal := Vector{1, 2, 3}1133 b := new(bytes.Buffer)1134 item1 := &InterfaceItem{1, iVal, fVal, vVal, 11.5, []Squarer{iVal, fVal, nil, vVal}}1135 // Register the types.1136 Register(Int(0))1137 Register(Float(0))1138 Register(Vector{})1139 err := NewEncoder(b).Encode(item1)1140 if err != nil {1141 t.Error("expected no encode error; got", err)1142 }1143 1144 item2 := InterfaceItem{}1145 err = NewDecoder(b).Decode(&item2)1146 if err != nil {1147 t.Fatal("decode:", err)1148 }1149 if item2.I != item1.I {1150 t.Error("normal int did not decode correctly")1151 }1152 if item2.Sq1 == nil || item2.Sq1.Square() != iVal.Square() {1153 t.Error("Int did not decode correctly")1154 }1155 if item2.Sq2 == nil || item2.Sq2.Square() != fVal.Square() {1156 t.Error("Float did not decode correctly")1157 }1158 if item2.Sq3 == nil || item2.Sq3.Square() != vVal.Square() {1159 t.Error("Vector did not decode correctly")1160 }1161 if item2.F != item1.F {1162 t.Error("normal float did not decode correctly")1163 }1164 // Now check that we received a slice of Squarers correctly, including a nil element1165 if len(item1.Sq) != len(item2.Sq) {1166 t.Fatalf("[]Squarer length wrong: got %d; expected %d", len(item2.Sq), len(item1.Sq))1167 }1168 for i, v1 := range item1.Sq {1169 v2 := item2.Sq[i]1170 if v1 == nil || v2 == nil {1171 if v1 != nil || v2 != nil {1172 t.Errorf("item %d inconsistent nils", i)1173 }1174 } else if v1.Square() != v2.Square() {1175 t.Errorf("item %d inconsistent values: %v %v", i, v1, v2)1176 }1177 }1178}1179 1180// A struct with all basic types, stored in interfaces.1181type BasicInterfaceItem struct {1182 Int, Int8, Int16, Int32, Int64 any1183 Uint, Uint8, Uint16, Uint32, Uint64 any1184 Float32, Float64 any1185 Complex64, Complex128 any1186 Bool any1187 String any1188 Bytes any1189}1190 1191func TestInterfaceBasic(t *testing.T) {1192 b := new(bytes.Buffer)1193 item1 := &BasicInterfaceItem{1194 int(1), int8(1), int16(1), int32(1), int64(1),1195 uint(1), uint8(1), uint16(1), uint32(1), uint64(1),1196 float32(1), 1.0,1197 complex64(1i), complex128(1i),1198 true,1199 "hello",1200 []byte("sailor"),