// TestVarIntNonCanonical ensures variable length integers that are not encoded // canonically return the expected error. func TestVarIntNonCanonical(t *testing.T) { pver := wire.ProtocolVersion tests := []struct { name string // Test name for easier identification in []byte // Value to decode pver uint32 // Protocol version for wire encoding }{ { "0 encoded with 3 bytes", []byte{0xfd, 0x00, 0x00}, pver, }, { "max single-byte value encoded with 3 bytes", []byte{0xfd, 0xfc, 0x00}, pver, }, { "0 encoded with 5 bytes", []byte{0xfe, 0x00, 0x00, 0x00, 0x00}, pver, }, { "max three-byte value encoded with 5 bytes", []byte{0xfe, 0xff, 0xff, 0x00, 0x00}, pver, }, { "0 encoded with 9 bytes", []byte{0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, pver, }, { "max five-byte value encoded with 9 bytes", []byte{0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00}, pver, }, } t.Logf("Running %d tests", len(tests)) for i, test := range tests { // Decode from wire format. rbuf := bytes.NewReader(test.in) val, err := wire.TstReadVarInt(rbuf, test.pver) if _, ok := err.(*wire.MessageError); !ok { t.Errorf("readVarInt #%d (%s) unexpected error %v", i, test.name, err) continue } if val != 0 { t.Errorf("readVarInt #%d (%s)\n got: %d want: 0", i, test.name, val) continue } } }
// TestVarIntWireErrors performs negative tests against wire encode and decode // of variable length integers to confirm error paths work correctly. func TestVarIntWireErrors(t *testing.T) { pver := wire.ProtocolVersion tests := []struct { in uint64 // Value to encode buf []byte // Wire encoding pver uint32 // Protocol version for wire encoding max int // Max size of fixed buffer to induce errors writeErr error // Expected write error readErr error // Expected read error }{ // Force errors on discriminant. {0, []byte{0x00}, pver, 0, io.ErrShortWrite, io.EOF}, // Force errors on 2-byte read/write. {0xfd, []byte{0xfd}, pver, 2, io.ErrShortWrite, io.ErrUnexpectedEOF}, // Force errors on 4-byte read/write. {0x10000, []byte{0xfe}, pver, 2, io.ErrShortWrite, io.ErrUnexpectedEOF}, // Force errors on 8-byte read/write. {0x100000000, []byte{0xff}, pver, 2, io.ErrShortWrite, io.ErrUnexpectedEOF}, } t.Logf("Running %d tests", len(tests)) for i, test := range tests { // Encode to wire format. w := newFixedWriter(test.max) err := wire.TstWriteVarInt(w, test.pver, test.in) if err != test.writeErr { t.Errorf("writeVarInt #%d wrong error got: %v, want: %v", i, err, test.writeErr) continue } // Decode from wire format. r := newFixedReader(test.max, test.buf) _, err = wire.TstReadVarInt(r, test.pver) if err != test.readErr { t.Errorf("readVarInt #%d wrong error got: %v, want: %v", i, err, test.readErr) continue } } }
// TestVarIntWire tests wire encode and decode for variable length integers. func TestVarIntWire(t *testing.T) { pver := wire.ProtocolVersion tests := []struct { in uint64 // Value to encode out uint64 // Expected decoded value buf []byte // Wire encoding pver uint32 // Protocol version for wire encoding }{ // Latest protocol version. // Single byte {0, 0, []byte{0x00}, pver}, // Max single byte {0xfc, 0xfc, []byte{0xfc}, pver}, // Min 2-byte {0xfd, 0xfd, []byte{0xfd, 0x0fd, 0x00}, pver}, // Max 2-byte {0xffff, 0xffff, []byte{0xfd, 0xff, 0xff}, pver}, // Min 4-byte {0x10000, 0x10000, []byte{0xfe, 0x00, 0x00, 0x01, 0x00}, pver}, // Max 4-byte {0xffffffff, 0xffffffff, []byte{0xfe, 0xff, 0xff, 0xff, 0xff}, pver}, // Min 8-byte { 0x100000000, 0x100000000, []byte{0xff, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00}, pver, }, // Max 8-byte { 0xffffffffffffffff, 0xffffffffffffffff, []byte{0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff}, pver, }, } t.Logf("Running %d tests", len(tests)) for i, test := range tests { // Encode to wire format. var buf bytes.Buffer err := wire.TstWriteVarInt(&buf, test.pver, test.in) if err != nil { t.Errorf("writeVarInt #%d error %v", i, err) continue } if !bytes.Equal(buf.Bytes(), test.buf) { t.Errorf("writeVarInt #%d\n got: %s want: %s", i, spew.Sdump(buf.Bytes()), spew.Sdump(test.buf)) continue } // Decode from wire format. rbuf := bytes.NewReader(test.buf) val, err := wire.TstReadVarInt(rbuf, test.pver) if err != nil { t.Errorf("readVarInt #%d error %v", i, err) continue } if val != test.out { t.Errorf("readVarInt #%d\n got: %d want: %d", i, val, test.out) continue } } }