|
| 1 | +// Copyright 2023 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 | +package quic |
| 6 | + |
| 7 | +import ( |
| 8 | + "bytes" |
| 9 | + "testing" |
| 10 | +) |
| 11 | + |
| 12 | +func TestConsumeVarint(t *testing.T) { |
| 13 | + for _, test := range []struct { |
| 14 | + b []byte |
| 15 | + want uint64 |
| 16 | + wantLen int |
| 17 | + }{ |
| 18 | + {[]byte{0x00}, 0, 1}, |
| 19 | + {[]byte{0x3f}, 63, 1}, |
| 20 | + {[]byte{0x40, 0x00}, 0, 2}, |
| 21 | + {[]byte{0x7f, 0xff}, 16383, 2}, |
| 22 | + {[]byte{0x80, 0x00, 0x00, 0x00}, 0, 4}, |
| 23 | + {[]byte{0xbf, 0xff, 0xff, 0xff}, 1073741823, 4}, |
| 24 | + {[]byte{0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, 0, 8}, |
| 25 | + {[]byte{0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff}, 4611686018427387903, 8}, |
| 26 | + // Example cases from https://www.rfc-editor.org/rfc/rfc9000.html#section-a.1 |
| 27 | + {[]byte{0xc2, 0x19, 0x7c, 0x5e, 0xff, 0x14, 0xe8, 0x8c}, 151288809941952652, 8}, |
| 28 | + {[]byte{0x9d, 0x7f, 0x3e, 0x7d}, 494878333, 4}, |
| 29 | + {[]byte{0x7b, 0xbd}, 15293, 2}, |
| 30 | + {[]byte{0x25}, 37, 1}, |
| 31 | + {[]byte{0x40, 0x25}, 37, 2}, |
| 32 | + } { |
| 33 | + got, gotLen := consumeVarint(test.b) |
| 34 | + if got != test.want || gotLen != test.wantLen { |
| 35 | + t.Errorf("consumeVarint(%x) = %v, %v; want %v, %v", test.b, got, gotLen, test.want, test.wantLen) |
| 36 | + } |
| 37 | + // Extra data in the buffer is ignored. |
| 38 | + b := append(test.b, 0) |
| 39 | + got, gotLen = consumeVarint(b) |
| 40 | + if got != test.want || gotLen != test.wantLen { |
| 41 | + t.Errorf("consumeVarint(%x) = %v, %v; want %v, %v", b, got, gotLen, test.want, test.wantLen) |
| 42 | + } |
| 43 | + // Short buffer results in an error. |
| 44 | + for i := 1; i <= len(test.b); i++ { |
| 45 | + b = test.b[:len(test.b)-i] |
| 46 | + got, gotLen = consumeVarint(b) |
| 47 | + if got != 0 || gotLen >= 0 { |
| 48 | + t.Errorf("consumeVarint(%x) = %v, %v; want 0, -1", b, got, gotLen) |
| 49 | + } |
| 50 | + } |
| 51 | + } |
| 52 | +} |
| 53 | + |
| 54 | +func TestAppendVarint(t *testing.T) { |
| 55 | + for _, test := range []struct { |
| 56 | + v uint64 |
| 57 | + want []byte |
| 58 | + }{ |
| 59 | + {0, []byte{0x00}}, |
| 60 | + {63, []byte{0x3f}}, |
| 61 | + {16383, []byte{0x7f, 0xff}}, |
| 62 | + {1073741823, []byte{0xbf, 0xff, 0xff, 0xff}}, |
| 63 | + {4611686018427387903, []byte{0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff}}, |
| 64 | + // Example cases from https://www.rfc-editor.org/rfc/rfc9000.html#section-a.1 |
| 65 | + {151288809941952652, []byte{0xc2, 0x19, 0x7c, 0x5e, 0xff, 0x14, 0xe8, 0x8c}}, |
| 66 | + {494878333, []byte{0x9d, 0x7f, 0x3e, 0x7d}}, |
| 67 | + {15293, []byte{0x7b, 0xbd}}, |
| 68 | + {37, []byte{0x25}}, |
| 69 | + } { |
| 70 | + got := appendVarint([]byte{}, test.v) |
| 71 | + if !bytes.Equal(got, test.want) { |
| 72 | + t.Errorf("AppendVarint(nil, %v) = %x, want %x", test.v, got, test.want) |
| 73 | + } |
| 74 | + if gotLen, wantLen := sizeVarint(test.v), len(got); gotLen != wantLen { |
| 75 | + t.Errorf("SizeVarint(%v) = %v, want %v", test.v, gotLen, wantLen) |
| 76 | + } |
| 77 | + } |
| 78 | +} |
| 79 | + |
| 80 | +func TestConsumeUint32(t *testing.T) { |
| 81 | + for _, test := range []struct { |
| 82 | + b []byte |
| 83 | + want uint32 |
| 84 | + wantLen int |
| 85 | + }{ |
| 86 | + {[]byte{0x01, 0x02, 0x03, 0x04}, 0x01020304, 4}, |
| 87 | + {[]byte{0x01, 0x02, 0x03}, 0, -1}, |
| 88 | + } { |
| 89 | + if got, n := consumeUint32(test.b); got != test.want || n != test.wantLen { |
| 90 | + t.Errorf("consumeUint32(%x) = %v, %v; want %v, %v", test.b, got, n, test.want, test.wantLen) |
| 91 | + } |
| 92 | + } |
| 93 | +} |
| 94 | + |
| 95 | +func TestConsumeUint64(t *testing.T) { |
| 96 | + for _, test := range []struct { |
| 97 | + b []byte |
| 98 | + want uint64 |
| 99 | + wantLen int |
| 100 | + }{ |
| 101 | + {[]byte{0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08}, 0x0102030405060708, 8}, |
| 102 | + {[]byte{0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07}, 0, -1}, |
| 103 | + } { |
| 104 | + if got, n := consumeUint64(test.b); got != test.want || n != test.wantLen { |
| 105 | + t.Errorf("consumeUint32(%x) = %v, %v; want %v, %v", test.b, got, n, test.want, test.wantLen) |
| 106 | + } |
| 107 | + } |
| 108 | +} |
| 109 | + |
| 110 | +func TestConsumeVarintBytes(t *testing.T) { |
| 111 | + for _, test := range []struct { |
| 112 | + b []byte |
| 113 | + want []byte |
| 114 | + wantLen int |
| 115 | + }{ |
| 116 | + {[]byte{0x00}, []byte{}, 1}, |
| 117 | + {[]byte{0x40, 0x00}, []byte{}, 2}, |
| 118 | + {[]byte{0x04, 0x01, 0x02, 0x03, 0x04}, []byte{0x01, 0x02, 0x03, 0x04}, 5}, |
| 119 | + {[]byte{0x40, 0x04, 0x01, 0x02, 0x03, 0x04}, []byte{0x01, 0x02, 0x03, 0x04}, 6}, |
| 120 | + } { |
| 121 | + got, gotLen := consumeVarintBytes(test.b) |
| 122 | + if !bytes.Equal(got, test.want) || gotLen != test.wantLen { |
| 123 | + t.Errorf("consumeVarintBytes(%x) = {%x}, %v; want {%x}, %v", test.b, got, gotLen, test.want, test.wantLen) |
| 124 | + } |
| 125 | + // Extra data in the buffer is ignored. |
| 126 | + b := append(test.b, 0) |
| 127 | + got, gotLen = consumeVarintBytes(b) |
| 128 | + if !bytes.Equal(got, test.want) || gotLen != test.wantLen { |
| 129 | + t.Errorf("consumeVarintBytes(%x) = {%x}, %v; want {%x}, %v", b, got, gotLen, test.want, test.wantLen) |
| 130 | + } |
| 131 | + // Short buffer results in an error. |
| 132 | + for i := 1; i <= len(test.b); i++ { |
| 133 | + b = test.b[:len(test.b)-i] |
| 134 | + got, gotLen := consumeVarintBytes(b) |
| 135 | + if len(got) > 0 || gotLen > 0 { |
| 136 | + t.Errorf("consumeVarintBytes(%x) = {%x}, %v; want {}, -1", b, got, gotLen) |
| 137 | + } |
| 138 | + } |
| 139 | + |
| 140 | + } |
| 141 | +} |
| 142 | + |
| 143 | +func TestConsumeVarintBytesErrors(t *testing.T) { |
| 144 | + for _, b := range [][]byte{ |
| 145 | + {0x01}, |
| 146 | + {0x40, 0x01}, |
| 147 | + } { |
| 148 | + got, gotLen := consumeVarintBytes(b) |
| 149 | + if len(got) > 0 || gotLen > 0 { |
| 150 | + t.Errorf("consumeVarintBytes(%x) = {%x}, %v; want {}, -1", b, got, gotLen) |
| 151 | + } |
| 152 | + } |
| 153 | +} |
| 154 | + |
| 155 | +func TestConsumeUint8Bytes(t *testing.T) { |
| 156 | + for _, test := range []struct { |
| 157 | + b []byte |
| 158 | + want []byte |
| 159 | + wantLen int |
| 160 | + }{ |
| 161 | + {[]byte{0x00}, []byte{}, 1}, |
| 162 | + {[]byte{0x01, 0x00}, []byte{0x00}, 2}, |
| 163 | + {[]byte{0x04, 0x01, 0x02, 0x03, 0x04}, []byte{0x01, 0x02, 0x03, 0x04}, 5}, |
| 164 | + } { |
| 165 | + got, gotLen := consumeUint8Bytes(test.b) |
| 166 | + if !bytes.Equal(got, test.want) || gotLen != test.wantLen { |
| 167 | + t.Errorf("consumeUint8Bytes(%x) = {%x}, %v; want {%x}, %v", test.b, got, gotLen, test.want, test.wantLen) |
| 168 | + } |
| 169 | + // Extra data in the buffer is ignored. |
| 170 | + b := append(test.b, 0) |
| 171 | + got, gotLen = consumeUint8Bytes(b) |
| 172 | + if !bytes.Equal(got, test.want) || gotLen != test.wantLen { |
| 173 | + t.Errorf("consumeUint8Bytes(%x) = {%x}, %v; want {%x}, %v", b, got, gotLen, test.want, test.wantLen) |
| 174 | + } |
| 175 | + // Short buffer results in an error. |
| 176 | + for i := 1; i <= len(test.b); i++ { |
| 177 | + b = test.b[:len(test.b)-i] |
| 178 | + got, gotLen := consumeUint8Bytes(b) |
| 179 | + if len(got) > 0 || gotLen > 0 { |
| 180 | + t.Errorf("consumeUint8Bytes(%x) = {%x}, %v; want {}, -1", b, got, gotLen) |
| 181 | + } |
| 182 | + } |
| 183 | + |
| 184 | + } |
| 185 | +} |
| 186 | + |
| 187 | +func TestConsumeUint8BytesErrors(t *testing.T) { |
| 188 | + for _, b := range [][]byte{ |
| 189 | + {0x01}, |
| 190 | + {0x04, 0x01, 0x02, 0x03}, |
| 191 | + } { |
| 192 | + got, gotLen := consumeUint8Bytes(b) |
| 193 | + if len(got) > 0 || gotLen > 0 { |
| 194 | + t.Errorf("consumeUint8Bytes(%x) = {%x}, %v; want {}, -1", b, got, gotLen) |
| 195 | + } |
| 196 | + } |
| 197 | +} |
| 198 | + |
| 199 | +func TestAppendUint8Bytes(t *testing.T) { |
| 200 | + var got []byte |
| 201 | + got = appendUint8Bytes(got, []byte{}) |
| 202 | + got = appendUint8Bytes(got, []byte{0xaa, 0xbb}) |
| 203 | + want := []byte{ |
| 204 | + 0x00, |
| 205 | + 0x02, 0xaa, 0xbb, |
| 206 | + } |
| 207 | + if !bytes.Equal(got, want) { |
| 208 | + t.Errorf("appendUint8Bytes {}, {aabb} = {%x}; want {%x}", got, want) |
| 209 | + } |
| 210 | +} |
| 211 | + |
| 212 | +func TestAppendVarintBytes(t *testing.T) { |
| 213 | + var got []byte |
| 214 | + got = appendVarintBytes(got, []byte{}) |
| 215 | + got = appendVarintBytes(got, []byte{0xaa, 0xbb}) |
| 216 | + want := []byte{ |
| 217 | + 0x00, |
| 218 | + 0x02, 0xaa, 0xbb, |
| 219 | + } |
| 220 | + if !bytes.Equal(got, want) { |
| 221 | + t.Errorf("appendVarintBytes {}, {aabb} = {%x}; want {%x}", got, want) |
| 222 | + } |
| 223 | +} |
0 commit comments