// Copyright 2023 The Go Authors. All rights reserved. // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. //go:build go1.21 package quic import ( "bytes" "testing" ) func TestConsumeVarint(t *testing.T) { for _, test := range []struct { b []byte want uint64 wantLen int }{ {[]byte{0x00}, 0, 1}, {[]byte{0x3f}, 63, 1}, {[]byte{0x40, 0x00}, 0, 2}, {[]byte{0x7f, 0xff}, 16383, 2}, {[]byte{0x80, 0x00, 0x00, 0x00}, 0, 4}, {[]byte{0xbf, 0xff, 0xff, 0xff}, 1073741823, 4}, {[]byte{0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, 0, 8}, {[]byte{0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff}, 4611686018427387903, 8}, // Example cases from https://www.rfc-editor.org/rfc/rfc9000.html#section-a.1 {[]byte{0xc2, 0x19, 0x7c, 0x5e, 0xff, 0x14, 0xe8, 0x8c}, 151288809941952652, 8}, {[]byte{0x9d, 0x7f, 0x3e, 0x7d}, 494878333, 4}, {[]byte{0x7b, 0xbd}, 15293, 2}, {[]byte{0x25}, 37, 1}, {[]byte{0x40, 0x25}, 37, 2}, } { got, gotLen := consumeVarint(test.b) if got != test.want || gotLen != test.wantLen { t.Errorf("consumeVarint(%x) = %v, %v; want %v, %v", test.b, got, gotLen, test.want, test.wantLen) } // Extra data in the buffer is ignored. b := append(test.b, 0) got, gotLen = consumeVarint(b) if got != test.want || gotLen != test.wantLen { t.Errorf("consumeVarint(%x) = %v, %v; want %v, %v", b, got, gotLen, test.want, test.wantLen) } // Short buffer results in an error. for i := 1; i <= len(test.b); i++ { b = test.b[:len(test.b)-i] got, gotLen = consumeVarint(b) if got != 0 || gotLen >= 0 { t.Errorf("consumeVarint(%x) = %v, %v; want 0, -1", b, got, gotLen) } } } } func TestAppendVarint(t *testing.T) { for _, test := range []struct { v uint64 want []byte }{ {0, []byte{0x00}}, {63, []byte{0x3f}}, {16383, []byte{0x7f, 0xff}}, {1073741823, []byte{0xbf, 0xff, 0xff, 0xff}}, {4611686018427387903, []byte{0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff}}, // Example cases from https://www.rfc-editor.org/rfc/rfc9000.html#section-a.1 {151288809941952652, []byte{0xc2, 0x19, 0x7c, 0x5e, 0xff, 0x14, 0xe8, 0x8c}}, {494878333, []byte{0x9d, 0x7f, 0x3e, 0x7d}}, {15293, []byte{0x7b, 0xbd}}, {37, []byte{0x25}}, } { got := appendVarint([]byte{}, test.v) if !bytes.Equal(got, test.want) { t.Errorf("AppendVarint(nil, %v) = %x, want %x", test.v, got, test.want) } if gotLen, wantLen := sizeVarint(test.v), len(got); gotLen != wantLen { t.Errorf("SizeVarint(%v) = %v, want %v", test.v, gotLen, wantLen) } } } func TestConsumeUint32(t *testing.T) { for _, test := range []struct { b []byte want uint32 wantLen int }{ {[]byte{0x01, 0x02, 0x03, 0x04}, 0x01020304, 4}, {[]byte{0x01, 0x02, 0x03}, 0, -1}, } { if got, n := consumeUint32(test.b); got != test.want || n != test.wantLen { t.Errorf("consumeUint32(%x) = %v, %v; want %v, %v", test.b, got, n, test.want, test.wantLen) } } } func TestConsumeUint64(t *testing.T) { for _, test := range []struct { b []byte want uint64 wantLen int }{ {[]byte{0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08}, 0x0102030405060708, 8}, {[]byte{0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07}, 0, -1}, } { if got, n := consumeUint64(test.b); got != test.want || n != test.wantLen { t.Errorf("consumeUint32(%x) = %v, %v; want %v, %v", test.b, got, n, test.want, test.wantLen) } } } func TestConsumeVarintBytes(t *testing.T) { for _, test := range []struct { b []byte want []byte wantLen int }{ {[]byte{0x00}, []byte{}, 1}, {[]byte{0x40, 0x00}, []byte{}, 2}, {[]byte{0x04, 0x01, 0x02, 0x03, 0x04}, []byte{0x01, 0x02, 0x03, 0x04}, 5}, {[]byte{0x40, 0x04, 0x01, 0x02, 0x03, 0x04}, []byte{0x01, 0x02, 0x03, 0x04}, 6}, } { got, gotLen := consumeVarintBytes(test.b) if !bytes.Equal(got, test.want) || gotLen != test.wantLen { t.Errorf("consumeVarintBytes(%x) = {%x}, %v; want {%x}, %v", test.b, got, gotLen, test.want, test.wantLen) } // Extra data in the buffer is ignored. b := append(test.b, 0) got, gotLen = consumeVarintBytes(b) if !bytes.Equal(got, test.want) || gotLen != test.wantLen { t.Errorf("consumeVarintBytes(%x) = {%x}, %v; want {%x}, %v", b, got, gotLen, test.want, test.wantLen) } // Short buffer results in an error. for i := 1; i <= len(test.b); i++ { b = test.b[:len(test.b)-i] got, gotLen := consumeVarintBytes(b) if len(got) > 0 || gotLen > 0 { t.Errorf("consumeVarintBytes(%x) = {%x}, %v; want {}, -1", b, got, gotLen) } } } } func TestConsumeVarintBytesErrors(t *testing.T) { for _, b := range [][]byte{ {0x01}, {0x40, 0x01}, } { got, gotLen := consumeVarintBytes(b) if len(got) > 0 || gotLen > 0 { t.Errorf("consumeVarintBytes(%x) = {%x}, %v; want {}, -1", b, got, gotLen) } } } func TestConsumeUint8Bytes(t *testing.T) { for _, test := range []struct { b []byte want []byte wantLen int }{ {[]byte{0x00}, []byte{}, 1}, {[]byte{0x01, 0x00}, []byte{0x00}, 2}, {[]byte{0x04, 0x01, 0x02, 0x03, 0x04}, []byte{0x01, 0x02, 0x03, 0x04}, 5}, } { got, gotLen := consumeUint8Bytes(test.b) if !bytes.Equal(got, test.want) || gotLen != test.wantLen { t.Errorf("consumeUint8Bytes(%x) = {%x}, %v; want {%x}, %v", test.b, got, gotLen, test.want, test.wantLen) } // Extra data in the buffer is ignored. b := append(test.b, 0) got, gotLen = consumeUint8Bytes(b) if !bytes.Equal(got, test.want) || gotLen != test.wantLen { t.Errorf("consumeUint8Bytes(%x) = {%x}, %v; want {%x}, %v", b, got, gotLen, test.want, test.wantLen) } // Short buffer results in an error. for i := 1; i <= len(test.b); i++ { b = test.b[:len(test.b)-i] got, gotLen := consumeUint8Bytes(b) if len(got) > 0 || gotLen > 0 { t.Errorf("consumeUint8Bytes(%x) = {%x}, %v; want {}, -1", b, got, gotLen) } } } } func TestConsumeUint8BytesErrors(t *testing.T) { for _, b := range [][]byte{ {0x01}, {0x04, 0x01, 0x02, 0x03}, } { got, gotLen := consumeUint8Bytes(b) if len(got) > 0 || gotLen > 0 { t.Errorf("consumeUint8Bytes(%x) = {%x}, %v; want {}, -1", b, got, gotLen) } } } func TestAppendUint8Bytes(t *testing.T) { var got []byte got = appendUint8Bytes(got, []byte{}) got = appendUint8Bytes(got, []byte{0xaa, 0xbb}) want := []byte{ 0x00, 0x02, 0xaa, 0xbb, } if !bytes.Equal(got, want) { t.Errorf("appendUint8Bytes {}, {aabb} = {%x}; want {%x}", got, want) } } func TestAppendVarintBytes(t *testing.T) { var got []byte got = appendVarintBytes(got, []byte{}) got = appendVarintBytes(got, []byte{0xaa, 0xbb}) want := []byte{ 0x00, 0x02, 0xaa, 0xbb, } if !bytes.Equal(got, want) { t.Errorf("appendVarintBytes {}, {aabb} = {%x}; want {%x}", got, want) } }