blob: 3c38673df2630d8b0d42ed2e2b7508057cb6fc4a [file] [log] [blame]
QUICHE teama6ef0a62019-03-07 20:34:33 -05001// Copyright (c) 2012 The Chromium Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#include "net/third_party/quiche/src/quic/core/quic_data_writer.h"
6
7#include <cstdint>
dschinazicf5b1e22019-07-17 18:35:17 -07008#include <cstring>
QUICHE teama6ef0a62019-03-07 20:34:33 -05009
10#include "net/third_party/quiche/src/quic/core/quic_connection_id.h"
11#include "net/third_party/quiche/src/quic/core/quic_data_reader.h"
12#include "net/third_party/quiche/src/quic/core/quic_utils.h"
QUICHE team0131a5b2019-03-20 15:23:27 -070013#include "net/third_party/quiche/src/quic/platform/api/quic_expect_bug.h"
QUICHE teama6ef0a62019-03-07 20:34:33 -050014#include "net/third_party/quiche/src/quic/platform/api/quic_flags.h"
15#include "net/third_party/quiche/src/quic/platform/api/quic_test.h"
16#include "net/third_party/quiche/src/quic/test_tools/quic_test_utils.h"
bnc4e9283d2019-12-17 07:08:57 -080017#include "net/third_party/quiche/src/common/platform/api/quiche_arraysize.h"
QUICHE team173c48f2019-11-19 16:34:44 -080018#include "net/third_party/quiche/src/common/platform/api/quiche_endian.h"
dmcardlecf0bfcf2019-12-13 08:08:21 -080019#include "net/third_party/quiche/src/common/platform/api/quiche_str_cat.h"
20#include "net/third_party/quiche/src/common/platform/api/quiche_string_piece.h"
QUICHE teama6ef0a62019-03-07 20:34:33 -050021
22namespace quic {
23namespace test {
24namespace {
25
26char* AsChars(unsigned char* data) {
27 return reinterpret_cast<char*>(data);
28}
29
30struct TestParams {
QUICHE team173c48f2019-11-19 16:34:44 -080031 explicit TestParams(quiche::Endianness endianness) : endianness(endianness) {}
QUICHE teama6ef0a62019-03-07 20:34:33 -050032
QUICHE team173c48f2019-11-19 16:34:44 -080033 quiche::Endianness endianness;
QUICHE teama6ef0a62019-03-07 20:34:33 -050034};
35
dschinazi142051a2019-09-18 18:17:29 -070036// Used by ::testing::PrintToStringParamName().
37std::string PrintToString(const TestParams& p) {
dmcardlecf0bfcf2019-12-13 08:08:21 -080038 return quiche::QuicheStrCat(
QUICHE team173c48f2019-11-19 16:34:44 -080039 (p.endianness == quiche::NETWORK_BYTE_ORDER ? "Network" : "Host"),
40 "ByteOrder");
dschinazi142051a2019-09-18 18:17:29 -070041}
42
QUICHE teama6ef0a62019-03-07 20:34:33 -050043std::vector<TestParams> GetTestParams() {
44 std::vector<TestParams> params;
QUICHE team173c48f2019-11-19 16:34:44 -080045 for (quiche::Endianness endianness :
46 {quiche::NETWORK_BYTE_ORDER, quiche::HOST_BYTE_ORDER}) {
QUICHE teama6ef0a62019-03-07 20:34:33 -050047 params.push_back(TestParams(endianness));
48 }
49 return params;
50}
51
52class QuicDataWriterTest : public QuicTestWithParam<TestParams> {};
53
QUICHE team0131a5b2019-03-20 15:23:27 -070054INSTANTIATE_TEST_SUITE_P(QuicDataWriterTests,
55 QuicDataWriterTest,
dschinazi142051a2019-09-18 18:17:29 -070056 ::testing::ValuesIn(GetTestParams()),
57 ::testing::PrintToStringParamName());
QUICHE teama6ef0a62019-03-07 20:34:33 -050058
59TEST_P(QuicDataWriterTest, SanityCheckUFloat16Consts) {
60 // Check the arithmetic on the constants - otherwise the values below make
61 // no sense.
62 EXPECT_EQ(30, kUFloat16MaxExponent);
63 EXPECT_EQ(11, kUFloat16MantissaBits);
64 EXPECT_EQ(12, kUFloat16MantissaEffectiveBits);
65 EXPECT_EQ(UINT64_C(0x3FFC0000000), kUFloat16MaxValue);
66}
67
68TEST_P(QuicDataWriterTest, WriteUFloat16) {
69 struct TestCase {
70 uint64_t decoded;
71 uint16_t encoded;
72 };
73 TestCase test_cases[] = {
74 // Small numbers represent themselves.
75 {0, 0},
76 {1, 1},
77 {2, 2},
78 {3, 3},
79 {4, 4},
80 {5, 5},
81 {6, 6},
82 {7, 7},
83 {15, 15},
84 {31, 31},
85 {42, 42},
86 {123, 123},
87 {1234, 1234},
88 // Check transition through 2^11.
89 {2046, 2046},
90 {2047, 2047},
91 {2048, 2048},
92 {2049, 2049},
93 // Running out of mantissa at 2^12.
94 {4094, 4094},
95 {4095, 4095},
96 {4096, 4096},
97 {4097, 4096},
98 {4098, 4097},
99 {4099, 4097},
100 {4100, 4098},
101 {4101, 4098},
102 // Check transition through 2^13.
103 {8190, 6143},
104 {8191, 6143},
105 {8192, 6144},
106 {8193, 6144},
107 {8194, 6144},
108 {8195, 6144},
109 {8196, 6145},
110 {8197, 6145},
111 // Half-way through the exponents.
112 {0x7FF8000, 0x87FF},
113 {0x7FFFFFF, 0x87FF},
114 {0x8000000, 0x8800},
115 {0xFFF0000, 0x8FFF},
116 {0xFFFFFFF, 0x8FFF},
117 {0x10000000, 0x9000},
118 // Transition into the largest exponent.
119 {0x1FFFFFFFFFE, 0xF7FF},
120 {0x1FFFFFFFFFF, 0xF7FF},
121 {0x20000000000, 0xF800},
122 {0x20000000001, 0xF800},
123 {0x2003FFFFFFE, 0xF800},
124 {0x2003FFFFFFF, 0xF800},
125 {0x20040000000, 0xF801},
126 {0x20040000001, 0xF801},
127 // Transition into the max value and clamping.
128 {0x3FF80000000, 0xFFFE},
129 {0x3FFBFFFFFFF, 0xFFFE},
130 {0x3FFC0000000, 0xFFFF},
131 {0x3FFC0000001, 0xFFFF},
132 {0x3FFFFFFFFFF, 0xFFFF},
133 {0x40000000000, 0xFFFF},
134 {0xFFFFFFFFFFFFFFFF, 0xFFFF},
135 };
136 int num_test_cases = sizeof(test_cases) / sizeof(test_cases[0]);
137
138 for (int i = 0; i < num_test_cases; ++i) {
139 char buffer[2];
140 QuicDataWriter writer(2, buffer, GetParam().endianness);
141 EXPECT_TRUE(writer.WriteUFloat16(test_cases[i].decoded));
142 uint16_t result = *reinterpret_cast<uint16_t*>(writer.data());
QUICHE team173c48f2019-11-19 16:34:44 -0800143 if (GetParam().endianness == quiche::NETWORK_BYTE_ORDER) {
144 result = quiche::QuicheEndian::HostToNet16(result);
QUICHE teama6ef0a62019-03-07 20:34:33 -0500145 }
146 EXPECT_EQ(test_cases[i].encoded, result);
147 }
148}
149
150TEST_P(QuicDataWriterTest, ReadUFloat16) {
151 struct TestCase {
152 uint64_t decoded;
153 uint16_t encoded;
154 };
155 TestCase test_cases[] = {
156 // There are fewer decoding test cases because encoding truncates, and
157 // decoding returns the smallest expansion.
158 // Small numbers represent themselves.
159 {0, 0},
160 {1, 1},
161 {2, 2},
162 {3, 3},
163 {4, 4},
164 {5, 5},
165 {6, 6},
166 {7, 7},
167 {15, 15},
168 {31, 31},
169 {42, 42},
170 {123, 123},
171 {1234, 1234},
172 // Check transition through 2^11.
173 {2046, 2046},
174 {2047, 2047},
175 {2048, 2048},
176 {2049, 2049},
177 // Running out of mantissa at 2^12.
178 {4094, 4094},
179 {4095, 4095},
180 {4096, 4096},
181 {4098, 4097},
182 {4100, 4098},
183 // Check transition through 2^13.
184 {8190, 6143},
185 {8192, 6144},
186 {8196, 6145},
187 // Half-way through the exponents.
188 {0x7FF8000, 0x87FF},
189 {0x8000000, 0x8800},
190 {0xFFF0000, 0x8FFF},
191 {0x10000000, 0x9000},
192 // Transition into the largest exponent.
193 {0x1FFE0000000, 0xF7FF},
194 {0x20000000000, 0xF800},
195 {0x20040000000, 0xF801},
196 // Transition into the max value.
197 {0x3FF80000000, 0xFFFE},
198 {0x3FFC0000000, 0xFFFF},
199 };
200 int num_test_cases = sizeof(test_cases) / sizeof(test_cases[0]);
201
202 for (int i = 0; i < num_test_cases; ++i) {
203 uint16_t encoded_ufloat = test_cases[i].encoded;
QUICHE team173c48f2019-11-19 16:34:44 -0800204 if (GetParam().endianness == quiche::NETWORK_BYTE_ORDER) {
205 encoded_ufloat = quiche::QuicheEndian::HostToNet16(encoded_ufloat);
QUICHE teama6ef0a62019-03-07 20:34:33 -0500206 }
207 QuicDataReader reader(reinterpret_cast<char*>(&encoded_ufloat), 2,
208 GetParam().endianness);
209 uint64_t value;
210 EXPECT_TRUE(reader.ReadUFloat16(&value));
211 EXPECT_EQ(test_cases[i].decoded, value);
212 }
213}
214
215TEST_P(QuicDataWriterTest, RoundTripUFloat16) {
216 // Just test all 16-bit encoded values. 0 and max already tested above.
217 uint64_t previous_value = 0;
218 for (uint16_t i = 1; i < 0xFFFF; ++i) {
219 // Read the two bytes.
220 uint16_t read_number = i;
QUICHE team173c48f2019-11-19 16:34:44 -0800221 if (GetParam().endianness == quiche::NETWORK_BYTE_ORDER) {
222 read_number = quiche::QuicheEndian::HostToNet16(read_number);
QUICHE teama6ef0a62019-03-07 20:34:33 -0500223 }
224 QuicDataReader reader(reinterpret_cast<char*>(&read_number), 2,
225 GetParam().endianness);
226 uint64_t value;
227 // All values must be decodable.
228 EXPECT_TRUE(reader.ReadUFloat16(&value));
229 // Check that small numbers represent themselves
230 if (i < 4097) {
231 EXPECT_EQ(i, value);
232 }
233 // Check there's monotonic growth.
234 EXPECT_LT(previous_value, value);
235 // Check that precision is within 0.5% away from the denormals.
236 if (i > 2000) {
237 EXPECT_GT(previous_value * 1005, value * 1000);
238 }
239 // Check we're always within the promised range.
240 EXPECT_LT(value, UINT64_C(0x3FFC0000000));
241 previous_value = value;
242 char buffer[6];
243 QuicDataWriter writer(6, buffer, GetParam().endianness);
244 EXPECT_TRUE(writer.WriteUFloat16(value - 1));
245 EXPECT_TRUE(writer.WriteUFloat16(value));
246 EXPECT_TRUE(writer.WriteUFloat16(value + 1));
247 // Check minimal decoding (previous decoding has previous encoding).
248 uint16_t encoded1 = *reinterpret_cast<uint16_t*>(writer.data());
249 uint16_t encoded2 = *reinterpret_cast<uint16_t*>(writer.data() + 2);
250 uint16_t encoded3 = *reinterpret_cast<uint16_t*>(writer.data() + 4);
QUICHE team173c48f2019-11-19 16:34:44 -0800251 if (GetParam().endianness == quiche::NETWORK_BYTE_ORDER) {
252 encoded1 = quiche::QuicheEndian::NetToHost16(encoded1);
253 encoded2 = quiche::QuicheEndian::NetToHost16(encoded2);
254 encoded3 = quiche::QuicheEndian::NetToHost16(encoded3);
QUICHE teama6ef0a62019-03-07 20:34:33 -0500255 }
256 EXPECT_EQ(i - 1, encoded1);
257 // Check roundtrip.
258 EXPECT_EQ(i, encoded2);
259 // Check next decoding.
260 EXPECT_EQ(i < 4096 ? i + 1 : i, encoded3);
261 }
262}
263
264TEST_P(QuicDataWriterTest, WriteConnectionId) {
265 QuicConnectionId connection_id =
266 TestConnectionId(UINT64_C(0x0011223344556677));
267 char big_endian[] = {
268 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77,
269 };
bnc4e9283d2019-12-17 07:08:57 -0800270 EXPECT_EQ(connection_id.length(), QUICHE_ARRAYSIZE(big_endian));
dschinazib012d212019-08-01 18:07:26 -0700271 ASSERT_LE(connection_id.length(), 255);
272 char buffer[255];
QUICHE teama6ef0a62019-03-07 20:34:33 -0500273 QuicDataWriter writer(connection_id.length(), buffer, GetParam().endianness);
274 EXPECT_TRUE(writer.WriteConnectionId(connection_id));
275 test::CompareCharArraysWithHexError("connection_id", buffer,
276 connection_id.length(), big_endian,
277 connection_id.length());
278
279 QuicConnectionId read_connection_id;
280 QuicDataReader reader(buffer, connection_id.length(), GetParam().endianness);
bnc4e9283d2019-12-17 07:08:57 -0800281 EXPECT_TRUE(reader.ReadConnectionId(&read_connection_id,
282 QUICHE_ARRAYSIZE(big_endian)));
QUICHE teama6ef0a62019-03-07 20:34:33 -0500283 EXPECT_EQ(connection_id, read_connection_id);
284}
285
dschinazicf5b1e22019-07-17 18:35:17 -0700286TEST_P(QuicDataWriterTest, LengthPrefixedConnectionId) {
287 QuicConnectionId connection_id =
288 TestConnectionId(UINT64_C(0x0011223344556677));
289 char length_prefixed_connection_id[] = {
290 0x08, 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77,
291 };
bnc4e9283d2019-12-17 07:08:57 -0800292 EXPECT_EQ(QUICHE_ARRAYSIZE(length_prefixed_connection_id),
dschinazicf5b1e22019-07-17 18:35:17 -0700293 kConnectionIdLengthSize + connection_id.length());
dschinazib012d212019-08-01 18:07:26 -0700294 char buffer[kConnectionIdLengthSize + 255] = {};
bnc4e9283d2019-12-17 07:08:57 -0800295 QuicDataWriter writer(QUICHE_ARRAYSIZE(buffer), buffer);
dschinazicf5b1e22019-07-17 18:35:17 -0700296 EXPECT_TRUE(writer.WriteLengthPrefixedConnectionId(connection_id));
297 test::CompareCharArraysWithHexError(
298 "WriteLengthPrefixedConnectionId", buffer, writer.length(),
299 length_prefixed_connection_id,
bnc4e9283d2019-12-17 07:08:57 -0800300 QUICHE_ARRAYSIZE(length_prefixed_connection_id));
dschinazicf5b1e22019-07-17 18:35:17 -0700301
302 // Verify that writing length then connection ID produces the same output.
bnc4e9283d2019-12-17 07:08:57 -0800303 memset(buffer, 0, QUICHE_ARRAYSIZE(buffer));
304 QuicDataWriter writer2(QUICHE_ARRAYSIZE(buffer), buffer);
dschinazicf5b1e22019-07-17 18:35:17 -0700305 EXPECT_TRUE(writer2.WriteUInt8(connection_id.length()));
306 EXPECT_TRUE(writer2.WriteConnectionId(connection_id));
307 test::CompareCharArraysWithHexError(
308 "Write length then ConnectionId", buffer, writer2.length(),
309 length_prefixed_connection_id,
bnc4e9283d2019-12-17 07:08:57 -0800310 QUICHE_ARRAYSIZE(length_prefixed_connection_id));
dschinazicf5b1e22019-07-17 18:35:17 -0700311
312 QuicConnectionId read_connection_id;
bnc4e9283d2019-12-17 07:08:57 -0800313 QuicDataReader reader(buffer, QUICHE_ARRAYSIZE(buffer));
dschinazicf5b1e22019-07-17 18:35:17 -0700314 EXPECT_TRUE(reader.ReadLengthPrefixedConnectionId(&read_connection_id));
315 EXPECT_EQ(connection_id, read_connection_id);
316
317 // Verify that reading length then connection ID produces the same output.
318 uint8_t read_connection_id_length2 = 33;
319 QuicConnectionId read_connection_id2;
bnc4e9283d2019-12-17 07:08:57 -0800320 QuicDataReader reader2(buffer, QUICHE_ARRAYSIZE(buffer));
dschinazicf5b1e22019-07-17 18:35:17 -0700321 ASSERT_TRUE(reader2.ReadUInt8(&read_connection_id_length2));
322 EXPECT_EQ(connection_id.length(), read_connection_id_length2);
323 EXPECT_TRUE(reader2.ReadConnectionId(&read_connection_id2,
324 read_connection_id_length2));
325 EXPECT_EQ(connection_id, read_connection_id2);
326}
327
QUICHE teama6ef0a62019-03-07 20:34:33 -0500328TEST_P(QuicDataWriterTest, EmptyConnectionIds) {
329 QuicConnectionId empty_connection_id = EmptyQuicConnectionId();
330 char buffer[2];
bnc4e9283d2019-12-17 07:08:57 -0800331 QuicDataWriter writer(QUICHE_ARRAYSIZE(buffer), buffer,
332 GetParam().endianness);
QUICHE teama6ef0a62019-03-07 20:34:33 -0500333 EXPECT_TRUE(writer.WriteConnectionId(empty_connection_id));
334 EXPECT_TRUE(writer.WriteUInt8(1));
335 EXPECT_TRUE(writer.WriteConnectionId(empty_connection_id));
336 EXPECT_TRUE(writer.WriteUInt8(2));
337 EXPECT_TRUE(writer.WriteConnectionId(empty_connection_id));
338 EXPECT_FALSE(writer.WriteUInt8(3));
339
340 EXPECT_EQ(buffer[0], 1);
341 EXPECT_EQ(buffer[1], 2);
342
343 QuicConnectionId read_connection_id = TestConnectionId();
344 uint8_t read_byte;
bnc4e9283d2019-12-17 07:08:57 -0800345 QuicDataReader reader(buffer, QUICHE_ARRAYSIZE(buffer),
346 GetParam().endianness);
QUICHE teama6ef0a62019-03-07 20:34:33 -0500347 EXPECT_TRUE(reader.ReadConnectionId(&read_connection_id, 0));
348 EXPECT_EQ(read_connection_id, empty_connection_id);
349 EXPECT_TRUE(reader.ReadUInt8(&read_byte));
350 EXPECT_EQ(read_byte, 1);
351 // Reset read_connection_id to something else to verify that
352 // ReadConnectionId properly sets it back to empty.
353 read_connection_id = TestConnectionId();
354 EXPECT_TRUE(reader.ReadConnectionId(&read_connection_id, 0));
355 EXPECT_EQ(read_connection_id, empty_connection_id);
356 EXPECT_TRUE(reader.ReadUInt8(&read_byte));
357 EXPECT_EQ(read_byte, 2);
358 read_connection_id = TestConnectionId();
359 EXPECT_TRUE(reader.ReadConnectionId(&read_connection_id, 0));
360 EXPECT_EQ(read_connection_id, empty_connection_id);
361 EXPECT_FALSE(reader.ReadUInt8(&read_byte));
362}
363
364TEST_P(QuicDataWriterTest, WriteTag) {
365 char CHLO[] = {
366 'C',
367 'H',
368 'L',
369 'O',
370 };
371 const int kBufferLength = sizeof(QuicTag);
372 char buffer[kBufferLength];
373 QuicDataWriter writer(kBufferLength, buffer, GetParam().endianness);
374 writer.WriteTag(kCHLO);
375 test::CompareCharArraysWithHexError("CHLO", buffer, kBufferLength, CHLO,
376 kBufferLength);
377
378 QuicTag read_chlo;
379 QuicDataReader reader(buffer, kBufferLength, GetParam().endianness);
380 reader.ReadTag(&read_chlo);
381 EXPECT_EQ(kCHLO, read_chlo);
382}
383
384TEST_P(QuicDataWriterTest, Write16BitUnsignedIntegers) {
385 char little_endian16[] = {0x22, 0x11};
386 char big_endian16[] = {0x11, 0x22};
387 char buffer16[2];
388 {
389 uint16_t in_memory16 = 0x1122;
390 QuicDataWriter writer(2, buffer16, GetParam().endianness);
391 writer.WriteUInt16(in_memory16);
392 test::CompareCharArraysWithHexError(
393 "uint16_t", buffer16, 2,
QUICHE team173c48f2019-11-19 16:34:44 -0800394 GetParam().endianness == quiche::NETWORK_BYTE_ORDER ? big_endian16
395 : little_endian16,
QUICHE teama6ef0a62019-03-07 20:34:33 -0500396 2);
397
398 uint16_t read_number16;
399 QuicDataReader reader(buffer16, 2, GetParam().endianness);
400 reader.ReadUInt16(&read_number16);
401 EXPECT_EQ(in_memory16, read_number16);
402 }
403
404 {
405 uint64_t in_memory16 = 0x0000000000001122;
406 QuicDataWriter writer(2, buffer16, GetParam().endianness);
407 writer.WriteBytesToUInt64(2, in_memory16);
408 test::CompareCharArraysWithHexError(
409 "uint16_t", buffer16, 2,
QUICHE team173c48f2019-11-19 16:34:44 -0800410 GetParam().endianness == quiche::NETWORK_BYTE_ORDER ? big_endian16
411 : little_endian16,
QUICHE teama6ef0a62019-03-07 20:34:33 -0500412 2);
413
414 uint64_t read_number16;
415 QuicDataReader reader(buffer16, 2, GetParam().endianness);
416 reader.ReadBytesToUInt64(2, &read_number16);
417 EXPECT_EQ(in_memory16, read_number16);
418 }
419}
420
421TEST_P(QuicDataWriterTest, Write24BitUnsignedIntegers) {
422 char little_endian24[] = {0x33, 0x22, 0x11};
423 char big_endian24[] = {0x11, 0x22, 0x33};
424 char buffer24[3];
425 uint64_t in_memory24 = 0x0000000000112233;
426 QuicDataWriter writer(3, buffer24, GetParam().endianness);
427 writer.WriteBytesToUInt64(3, in_memory24);
428 test::CompareCharArraysWithHexError(
429 "uint24", buffer24, 3,
QUICHE team173c48f2019-11-19 16:34:44 -0800430 GetParam().endianness == quiche::NETWORK_BYTE_ORDER ? big_endian24
431 : little_endian24,
QUICHE teama6ef0a62019-03-07 20:34:33 -0500432 3);
433
434 uint64_t read_number24;
435 QuicDataReader reader(buffer24, 3, GetParam().endianness);
436 reader.ReadBytesToUInt64(3, &read_number24);
437 EXPECT_EQ(in_memory24, read_number24);
438}
439
440TEST_P(QuicDataWriterTest, Write32BitUnsignedIntegers) {
441 char little_endian32[] = {0x44, 0x33, 0x22, 0x11};
442 char big_endian32[] = {0x11, 0x22, 0x33, 0x44};
443 char buffer32[4];
444 {
445 uint32_t in_memory32 = 0x11223344;
446 QuicDataWriter writer(4, buffer32, GetParam().endianness);
447 writer.WriteUInt32(in_memory32);
448 test::CompareCharArraysWithHexError(
449 "uint32_t", buffer32, 4,
QUICHE team173c48f2019-11-19 16:34:44 -0800450 GetParam().endianness == quiche::NETWORK_BYTE_ORDER ? big_endian32
451 : little_endian32,
QUICHE teama6ef0a62019-03-07 20:34:33 -0500452 4);
453
454 uint32_t read_number32;
455 QuicDataReader reader(buffer32, 4, GetParam().endianness);
456 reader.ReadUInt32(&read_number32);
457 EXPECT_EQ(in_memory32, read_number32);
458 }
459
460 {
461 uint64_t in_memory32 = 0x11223344;
462 QuicDataWriter writer(4, buffer32, GetParam().endianness);
463 writer.WriteBytesToUInt64(4, in_memory32);
464 test::CompareCharArraysWithHexError(
465 "uint32_t", buffer32, 4,
QUICHE team173c48f2019-11-19 16:34:44 -0800466 GetParam().endianness == quiche::NETWORK_BYTE_ORDER ? big_endian32
467 : little_endian32,
QUICHE teama6ef0a62019-03-07 20:34:33 -0500468 4);
469
470 uint64_t read_number32;
471 QuicDataReader reader(buffer32, 4, GetParam().endianness);
472 reader.ReadBytesToUInt64(4, &read_number32);
473 EXPECT_EQ(in_memory32, read_number32);
474 }
475}
476
477TEST_P(QuicDataWriterTest, Write40BitUnsignedIntegers) {
478 uint64_t in_memory40 = 0x0000001122334455;
479 char little_endian40[] = {0x55, 0x44, 0x33, 0x22, 0x11};
480 char big_endian40[] = {0x11, 0x22, 0x33, 0x44, 0x55};
481 char buffer40[5];
482 QuicDataWriter writer(5, buffer40, GetParam().endianness);
483 writer.WriteBytesToUInt64(5, in_memory40);
484 test::CompareCharArraysWithHexError(
485 "uint40", buffer40, 5,
QUICHE team173c48f2019-11-19 16:34:44 -0800486 GetParam().endianness == quiche::NETWORK_BYTE_ORDER ? big_endian40
487 : little_endian40,
QUICHE teama6ef0a62019-03-07 20:34:33 -0500488 5);
489
490 uint64_t read_number40;
491 QuicDataReader reader(buffer40, 5, GetParam().endianness);
492 reader.ReadBytesToUInt64(5, &read_number40);
493 EXPECT_EQ(in_memory40, read_number40);
494}
495
496TEST_P(QuicDataWriterTest, Write48BitUnsignedIntegers) {
497 uint64_t in_memory48 = 0x0000112233445566;
498 char little_endian48[] = {0x66, 0x55, 0x44, 0x33, 0x22, 0x11};
499 char big_endian48[] = {0x11, 0x22, 0x33, 0x44, 0x55, 0x66};
500 char buffer48[6];
501 QuicDataWriter writer(6, buffer48, GetParam().endianness);
502 writer.WriteBytesToUInt64(6, in_memory48);
503 test::CompareCharArraysWithHexError(
504 "uint48", buffer48, 6,
QUICHE team173c48f2019-11-19 16:34:44 -0800505 GetParam().endianness == quiche::NETWORK_BYTE_ORDER ? big_endian48
506 : little_endian48,
QUICHE teama6ef0a62019-03-07 20:34:33 -0500507 6);
508
509 uint64_t read_number48;
510 QuicDataReader reader(buffer48, 6, GetParam().endianness);
511 reader.ReadBytesToUInt64(6., &read_number48);
512 EXPECT_EQ(in_memory48, read_number48);
513}
514
515TEST_P(QuicDataWriterTest, Write56BitUnsignedIntegers) {
516 uint64_t in_memory56 = 0x0011223344556677;
517 char little_endian56[] = {0x77, 0x66, 0x55, 0x44, 0x33, 0x22, 0x11};
518 char big_endian56[] = {0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77};
519 char buffer56[7];
520 QuicDataWriter writer(7, buffer56, GetParam().endianness);
521 writer.WriteBytesToUInt64(7, in_memory56);
522 test::CompareCharArraysWithHexError(
523 "uint56", buffer56, 7,
QUICHE team173c48f2019-11-19 16:34:44 -0800524 GetParam().endianness == quiche::NETWORK_BYTE_ORDER ? big_endian56
525 : little_endian56,
QUICHE teama6ef0a62019-03-07 20:34:33 -0500526 7);
527
528 uint64_t read_number56;
529 QuicDataReader reader(buffer56, 7, GetParam().endianness);
530 reader.ReadBytesToUInt64(7, &read_number56);
531 EXPECT_EQ(in_memory56, read_number56);
532}
533
534TEST_P(QuicDataWriterTest, Write64BitUnsignedIntegers) {
535 uint64_t in_memory64 = 0x1122334455667788;
536 unsigned char little_endian64[] = {0x88, 0x77, 0x66, 0x55,
537 0x44, 0x33, 0x22, 0x11};
538 unsigned char big_endian64[] = {0x11, 0x22, 0x33, 0x44,
539 0x55, 0x66, 0x77, 0x88};
540 char buffer64[8];
541 QuicDataWriter writer(8, buffer64, GetParam().endianness);
542 writer.WriteBytesToUInt64(8, in_memory64);
543 test::CompareCharArraysWithHexError(
544 "uint64_t", buffer64, 8,
QUICHE team173c48f2019-11-19 16:34:44 -0800545 GetParam().endianness == quiche::NETWORK_BYTE_ORDER
546 ? AsChars(big_endian64)
547 : AsChars(little_endian64),
QUICHE teama6ef0a62019-03-07 20:34:33 -0500548 8);
549
550 uint64_t read_number64;
551 QuicDataReader reader(buffer64, 8, GetParam().endianness);
552 reader.ReadBytesToUInt64(8, &read_number64);
553 EXPECT_EQ(in_memory64, read_number64);
554
555 QuicDataWriter writer2(8, buffer64, GetParam().endianness);
556 writer2.WriteUInt64(in_memory64);
557 test::CompareCharArraysWithHexError(
558 "uint64_t", buffer64, 8,
QUICHE team173c48f2019-11-19 16:34:44 -0800559 GetParam().endianness == quiche::NETWORK_BYTE_ORDER
560 ? AsChars(big_endian64)
561 : AsChars(little_endian64),
QUICHE teama6ef0a62019-03-07 20:34:33 -0500562 8);
563 read_number64 = 0u;
564 QuicDataReader reader2(buffer64, 8, GetParam().endianness);
565 reader2.ReadUInt64(&read_number64);
566 EXPECT_EQ(in_memory64, read_number64);
567}
568
569TEST_P(QuicDataWriterTest, WriteIntegers) {
570 char buf[43];
571 uint8_t i8 = 0x01;
572 uint16_t i16 = 0x0123;
573 uint32_t i32 = 0x01234567;
574 uint64_t i64 = 0x0123456789ABCDEF;
575 QuicDataWriter writer(46, buf, GetParam().endianness);
576 for (size_t i = 0; i < 10; ++i) {
577 switch (i) {
578 case 0u:
579 EXPECT_TRUE(writer.WriteBytesToUInt64(i, i64));
580 break;
581 case 1u:
582 EXPECT_TRUE(writer.WriteUInt8(i8));
583 EXPECT_TRUE(writer.WriteBytesToUInt64(i, i64));
584 break;
585 case 2u:
586 EXPECT_TRUE(writer.WriteUInt16(i16));
587 EXPECT_TRUE(writer.WriteBytesToUInt64(i, i64));
588 break;
589 case 3u:
590 EXPECT_TRUE(writer.WriteBytesToUInt64(i, i64));
591 break;
592 case 4u:
593 EXPECT_TRUE(writer.WriteUInt32(i32));
594 EXPECT_TRUE(writer.WriteBytesToUInt64(i, i64));
595 break;
596 case 5u:
597 case 6u:
598 case 7u:
599 case 8u:
600 EXPECT_TRUE(writer.WriteBytesToUInt64(i, i64));
601 break;
602 default:
603 EXPECT_FALSE(writer.WriteBytesToUInt64(i, i64));
604 }
605 }
606
607 QuicDataReader reader(buf, 46, GetParam().endianness);
608 for (size_t i = 0; i < 10; ++i) {
609 uint8_t read8;
610 uint16_t read16;
611 uint32_t read32;
612 uint64_t read64;
613 switch (i) {
614 case 0u:
615 EXPECT_TRUE(reader.ReadBytesToUInt64(i, &read64));
616 EXPECT_EQ(0u, read64);
617 break;
618 case 1u:
619 EXPECT_TRUE(reader.ReadUInt8(&read8));
620 EXPECT_TRUE(reader.ReadBytesToUInt64(i, &read64));
621 EXPECT_EQ(i8, read8);
622 EXPECT_EQ(0xEFu, read64);
623 break;
624 case 2u:
625 EXPECT_TRUE(reader.ReadUInt16(&read16));
626 EXPECT_TRUE(reader.ReadBytesToUInt64(i, &read64));
627 EXPECT_EQ(i16, read16);
628 EXPECT_EQ(0xCDEFu, read64);
629 break;
630 case 3u:
631 EXPECT_TRUE(reader.ReadBytesToUInt64(i, &read64));
632 EXPECT_EQ(0xABCDEFu, read64);
633 break;
634 case 4u:
635 EXPECT_TRUE(reader.ReadUInt32(&read32));
636 EXPECT_TRUE(reader.ReadBytesToUInt64(i, &read64));
637 EXPECT_EQ(i32, read32);
638 EXPECT_EQ(0x89ABCDEFu, read64);
639 break;
640 case 5u:
641 EXPECT_TRUE(reader.ReadBytesToUInt64(i, &read64));
642 EXPECT_EQ(0x6789ABCDEFu, read64);
643 break;
644 case 6u:
645 EXPECT_TRUE(reader.ReadBytesToUInt64(i, &read64));
646 EXPECT_EQ(0x456789ABCDEFu, read64);
647 break;
648 case 7u:
649 EXPECT_TRUE(reader.ReadBytesToUInt64(i, &read64));
650 EXPECT_EQ(0x23456789ABCDEFu, read64);
651 break;
652 case 8u:
653 EXPECT_TRUE(reader.ReadBytesToUInt64(i, &read64));
654 EXPECT_EQ(0x0123456789ABCDEFu, read64);
655 break;
656 default:
657 EXPECT_FALSE(reader.ReadBytesToUInt64(i, &read64));
658 }
659 }
660}
661
662TEST_P(QuicDataWriterTest, WriteBytes) {
663 char bytes[] = {0, 1, 2, 3, 4, 5, 6, 7, 8};
bnc4e9283d2019-12-17 07:08:57 -0800664 char buf[QUICHE_ARRAYSIZE(bytes)];
665 QuicDataWriter writer(QUICHE_ARRAYSIZE(buf), buf, GetParam().endianness);
666 EXPECT_TRUE(writer.WriteBytes(bytes, QUICHE_ARRAYSIZE(bytes)));
667 for (unsigned int i = 0; i < QUICHE_ARRAYSIZE(bytes); ++i) {
QUICHE teama6ef0a62019-03-07 20:34:33 -0500668 EXPECT_EQ(bytes[i], buf[i]);
669 }
670}
671
672const int kVarIntBufferLength = 1024;
673
674// Encodes and then decodes a specified value, checks that the
675// value that was encoded is the same as the decoded value, the length
676// is correct, and that after decoding, all data in the buffer has
677// been consumed..
678// Returns true if everything works, false if not.
679bool EncodeDecodeValue(uint64_t value_in, char* buffer, size_t size_of_buffer) {
680 // Init the buffer to all 0, just for cleanliness. Makes for better
681 // output if, in debugging, we need to dump out the buffer.
682 memset(buffer, 0, size_of_buffer);
683 // make a writer. Note that for IETF encoding
684 // we do not care about endianness... It's always big-endian,
685 // but the c'tor expects to be told what endianness is in force...
QUICHE team173c48f2019-11-19 16:34:44 -0800686 QuicDataWriter writer(size_of_buffer, buffer,
687 quiche::Endianness::NETWORK_BYTE_ORDER);
QUICHE teama6ef0a62019-03-07 20:34:33 -0500688
689 // Try to write the value.
690 if (writer.WriteVarInt62(value_in) != true) {
691 return false;
692 }
693 // Look at the value we encoded. Determine how much should have been
694 // used based on the value, and then check the state of the writer
695 // to see that it matches.
696 size_t expected_length = 0;
697 if (value_in <= 0x3f) {
698 expected_length = 1;
699 } else if (value_in <= 0x3fff) {
700 expected_length = 2;
701 } else if (value_in <= 0x3fffffff) {
702 expected_length = 4;
703 } else {
704 expected_length = 8;
705 }
706 if (writer.length() != expected_length) {
707 return false;
708 }
709
710 // set up a reader, just the length we've used, no more, no less.
711 QuicDataReader reader(buffer, expected_length,
QUICHE team173c48f2019-11-19 16:34:44 -0800712 quiche::Endianness::NETWORK_BYTE_ORDER);
QUICHE teama6ef0a62019-03-07 20:34:33 -0500713 uint64_t value_out;
714
715 if (reader.ReadVarInt62(&value_out) == false) {
716 return false;
717 }
718 if (value_in != value_out) {
719 return false;
720 }
721 // We only write one value so there had better be nothing left to read
722 return reader.IsDoneReading();
723}
724
725// Test that 8-byte-encoded Variable Length Integers are properly laid
726// out in the buffer.
727TEST_P(QuicDataWriterTest, VarInt8Layout) {
728 char buffer[1024];
729
730 // Check that the layout of bytes in the buffer is correct. Bytes
731 // are always encoded big endian...
732 memset(buffer, 0, sizeof(buffer));
733 QuicDataWriter writer(sizeof(buffer), static_cast<char*>(buffer),
QUICHE team173c48f2019-11-19 16:34:44 -0800734 quiche::Endianness::NETWORK_BYTE_ORDER);
QUICHE teama6ef0a62019-03-07 20:34:33 -0500735 EXPECT_TRUE(writer.WriteVarInt62(UINT64_C(0x3142f3e4d5c6b7a8)));
736 EXPECT_EQ(static_cast<unsigned char>(*(writer.data() + 0)),
737 (0x31 + 0xc0)); // 0xc0 for encoding
738 EXPECT_EQ(static_cast<unsigned char>(*(writer.data() + 1)), 0x42);
739 EXPECT_EQ(static_cast<unsigned char>(*(writer.data() + 2)), 0xf3);
740 EXPECT_EQ(static_cast<unsigned char>(*(writer.data() + 3)), 0xe4);
741 EXPECT_EQ(static_cast<unsigned char>(*(writer.data() + 4)), 0xd5);
742 EXPECT_EQ(static_cast<unsigned char>(*(writer.data() + 5)), 0xc6);
743 EXPECT_EQ(static_cast<unsigned char>(*(writer.data() + 6)), 0xb7);
744 EXPECT_EQ(static_cast<unsigned char>(*(writer.data() + 7)), 0xa8);
745}
746
747// Test that 4-byte-encoded Variable Length Integers are properly laid
748// out in the buffer.
749TEST_P(QuicDataWriterTest, VarInt4Layout) {
750 char buffer[1024];
751
752 // Check that the layout of bytes in the buffer is correct. Bytes
753 // are always encoded big endian...
754 memset(buffer, 0, sizeof(buffer));
755 QuicDataWriter writer(sizeof(buffer), static_cast<char*>(buffer),
QUICHE team173c48f2019-11-19 16:34:44 -0800756 quiche::Endianness::NETWORK_BYTE_ORDER);
QUICHE teama6ef0a62019-03-07 20:34:33 -0500757 EXPECT_TRUE(writer.WriteVarInt62(0x3243f4e5));
758 EXPECT_EQ(static_cast<unsigned char>(*(writer.data() + 0)),
759 (0x32 + 0x80)); // 0x80 for encoding
760 EXPECT_EQ(static_cast<unsigned char>(*(writer.data() + 1)), 0x43);
761 EXPECT_EQ(static_cast<unsigned char>(*(writer.data() + 2)), 0xf4);
762 EXPECT_EQ(static_cast<unsigned char>(*(writer.data() + 3)), 0xe5);
763}
764
765// Test that 2-byte-encoded Variable Length Integers are properly laid
766// out in the buffer.
767TEST_P(QuicDataWriterTest, VarInt2Layout) {
768 char buffer[1024];
769
770 // Check that the layout of bytes in the buffer is correct. Bytes
771 // are always encoded big endian...
772 memset(buffer, 0, sizeof(buffer));
773 QuicDataWriter writer(sizeof(buffer), static_cast<char*>(buffer),
QUICHE team173c48f2019-11-19 16:34:44 -0800774 quiche::Endianness::NETWORK_BYTE_ORDER);
QUICHE teama6ef0a62019-03-07 20:34:33 -0500775 EXPECT_TRUE(writer.WriteVarInt62(0x3647));
776 EXPECT_EQ(static_cast<unsigned char>(*(writer.data() + 0)),
777 (0x36 + 0x40)); // 0x40 for encoding
778 EXPECT_EQ(static_cast<unsigned char>(*(writer.data() + 1)), 0x47);
779}
780
781// Test that 1-byte-encoded Variable Length Integers are properly laid
782// out in the buffer.
783TEST_P(QuicDataWriterTest, VarInt1Layout) {
784 char buffer[1024];
785
786 // Check that the layout of bytes in the buffer
787 // is correct. Bytes are always encoded big endian...
788 memset(buffer, 0, sizeof(buffer));
789 QuicDataWriter writer(sizeof(buffer), static_cast<char*>(buffer),
QUICHE team173c48f2019-11-19 16:34:44 -0800790 quiche::Endianness::NETWORK_BYTE_ORDER);
QUICHE teama6ef0a62019-03-07 20:34:33 -0500791 EXPECT_TRUE(writer.WriteVarInt62(0x3f));
792 EXPECT_EQ(static_cast<unsigned char>(*(writer.data() + 0)), 0x3f);
793}
794
795// Test certain, targeted, values that are expected to succeed:
796// 0, 1,
797// 0x3e, 0x3f, 0x40, 0x41 (around the 1-2 byte transitions)
798// 0x3ffe, 0x3fff, 0x4000, 0x4001 (the 2-4 byte transition)
799// 0x3ffffffe, 0x3fffffff, 0x40000000, 0x40000001 (the 4-8 byte
800// transition)
801// 0x3ffffffffffffffe, 0x3fffffffffffffff, (the highest valid values)
802// 0xfe, 0xff, 0x100, 0x101,
803// 0xfffe, 0xffff, 0x10000, 0x10001,
804// 0xfffffe, 0xffffff, 0x1000000, 0x1000001,
805// 0xfffffffe, 0xffffffff, 0x100000000, 0x100000001,
806// 0xfffffffffe, 0xffffffffff, 0x10000000000, 0x10000000001,
807// 0xfffffffffffe, 0xffffffffffff, 0x1000000000000, 0x1000000000001,
808// 0xfffffffffffffe, 0xffffffffffffff, 0x100000000000000, 0x100000000000001,
809TEST_P(QuicDataWriterTest, VarIntGoodTargetedValues) {
810 char buffer[kVarIntBufferLength];
811 uint64_t passing_values[] = {
812 0,
813 1,
814 0x3e,
815 0x3f,
816 0x40,
817 0x41,
818 0x3ffe,
819 0x3fff,
820 0x4000,
821 0x4001,
822 0x3ffffffe,
823 0x3fffffff,
824 0x40000000,
825 0x40000001,
826 0x3ffffffffffffffe,
827 0x3fffffffffffffff,
828 0xfe,
829 0xff,
830 0x100,
831 0x101,
832 0xfffe,
833 0xffff,
834 0x10000,
835 0x10001,
836 0xfffffe,
837 0xffffff,
838 0x1000000,
839 0x1000001,
840 0xfffffffe,
841 0xffffffff,
842 0x100000000,
843 0x100000001,
844 0xfffffffffe,
845 0xffffffffff,
846 0x10000000000,
847 0x10000000001,
848 0xfffffffffffe,
849 0xffffffffffff,
850 0x1000000000000,
851 0x1000000000001,
852 0xfffffffffffffe,
853 0xffffffffffffff,
854 0x100000000000000,
855 0x100000000000001,
856 };
857 for (uint64_t test_val : passing_values) {
858 EXPECT_TRUE(
859 EncodeDecodeValue(test_val, static_cast<char*>(buffer), sizeof(buffer)))
860 << " encode/decode of " << test_val << " failed";
861 }
862}
863//
864// Test certain, targeted, values where failure is expected (the
865// values are invalid w.r.t. IETF VarInt encoding):
866// 0x4000000000000000, 0x4000000000000001, ( Just above max allowed value)
867// 0xfffffffffffffffe, 0xffffffffffffffff, (should fail)
868TEST_P(QuicDataWriterTest, VarIntBadTargetedValues) {
869 char buffer[kVarIntBufferLength];
870 uint64_t failing_values[] = {
871 0x4000000000000000,
872 0x4000000000000001,
873 0xfffffffffffffffe,
874 0xffffffffffffffff,
875 };
876 for (uint64_t test_val : failing_values) {
877 EXPECT_FALSE(
878 EncodeDecodeValue(test_val, static_cast<char*>(buffer), sizeof(buffer)))
879 << " encode/decode of " << test_val << " succeeded, but was an "
880 << "invalid value";
881 }
882}
883
884// Following tests all try to fill the buffer with multiple values,
885// go one value more than the buffer can accommodate, then read
886// the successfully encoded values, and try to read the unsuccessfully
887// encoded value. The following is the number of values to encode.
888const int kMultiVarCount = 1000;
889
890// Test writing & reading multiple 8-byte-encoded varints
891TEST_P(QuicDataWriterTest, MultiVarInt8) {
892 uint64_t test_val;
893 char buffer[8 * kMultiVarCount];
894 memset(buffer, 0, sizeof(buffer));
895 QuicDataWriter writer(sizeof(buffer), static_cast<char*>(buffer),
QUICHE team173c48f2019-11-19 16:34:44 -0800896 quiche::Endianness::NETWORK_BYTE_ORDER);
QUICHE teama6ef0a62019-03-07 20:34:33 -0500897 // Put N values into the buffer. Adding i to the value ensures that
898 // each value is different so we can detect if we overwrite values,
899 // or read the same value over and over.
900 for (int i = 0; i < kMultiVarCount; i++) {
901 EXPECT_TRUE(writer.WriteVarInt62(UINT64_C(0x3142f3e4d5c6b7a8) + i));
902 }
903 EXPECT_EQ(writer.length(), 8u * kMultiVarCount);
904
905 // N+1st should fail, the buffer is full.
906 EXPECT_FALSE(writer.WriteVarInt62(UINT64_C(0x3142f3e4d5c6b7a8)));
907
908 // Now we should be able to read out the N values that were
909 // successfully encoded.
QUICHE team173c48f2019-11-19 16:34:44 -0800910 QuicDataReader reader(buffer, sizeof(buffer),
911 quiche::Endianness::NETWORK_BYTE_ORDER);
QUICHE teama6ef0a62019-03-07 20:34:33 -0500912 for (int i = 0; i < kMultiVarCount; i++) {
913 EXPECT_TRUE(reader.ReadVarInt62(&test_val));
914 EXPECT_EQ(test_val, (UINT64_C(0x3142f3e4d5c6b7a8) + i));
915 }
916 // And the N+1st should fail.
917 EXPECT_FALSE(reader.ReadVarInt62(&test_val));
918}
919
920// Test writing & reading multiple 4-byte-encoded varints
921TEST_P(QuicDataWriterTest, MultiVarInt4) {
922 uint64_t test_val;
923 char buffer[4 * kMultiVarCount];
924 memset(buffer, 0, sizeof(buffer));
925 QuicDataWriter writer(sizeof(buffer), static_cast<char*>(buffer),
QUICHE team173c48f2019-11-19 16:34:44 -0800926 quiche::Endianness::NETWORK_BYTE_ORDER);
QUICHE teama6ef0a62019-03-07 20:34:33 -0500927 // Put N values into the buffer. Adding i to the value ensures that
928 // each value is different so we can detect if we overwrite values,
929 // or read the same value over and over.
930 for (int i = 0; i < kMultiVarCount; i++) {
931 EXPECT_TRUE(writer.WriteVarInt62(UINT64_C(0x3142f3e4) + i));
932 }
933 EXPECT_EQ(writer.length(), 4u * kMultiVarCount);
934
935 // N+1st should fail, the buffer is full.
936 EXPECT_FALSE(writer.WriteVarInt62(UINT64_C(0x3142f3e4)));
937
938 // Now we should be able to read out the N values that were
939 // successfully encoded.
QUICHE team173c48f2019-11-19 16:34:44 -0800940 QuicDataReader reader(buffer, sizeof(buffer),
941 quiche::Endianness::NETWORK_BYTE_ORDER);
QUICHE teama6ef0a62019-03-07 20:34:33 -0500942 for (int i = 0; i < kMultiVarCount; i++) {
943 EXPECT_TRUE(reader.ReadVarInt62(&test_val));
944 EXPECT_EQ(test_val, (UINT64_C(0x3142f3e4) + i));
945 }
946 // And the N+1st should fail.
947 EXPECT_FALSE(reader.ReadVarInt62(&test_val));
948}
949
950// Test writing & reading multiple 2-byte-encoded varints
951TEST_P(QuicDataWriterTest, MultiVarInt2) {
952 uint64_t test_val;
953 char buffer[2 * kMultiVarCount];
954 memset(buffer, 0, sizeof(buffer));
955 QuicDataWriter writer(sizeof(buffer), static_cast<char*>(buffer),
QUICHE team173c48f2019-11-19 16:34:44 -0800956 quiche::Endianness::NETWORK_BYTE_ORDER);
QUICHE teama6ef0a62019-03-07 20:34:33 -0500957 // Put N values into the buffer. Adding i to the value ensures that
958 // each value is different so we can detect if we overwrite values,
959 // or read the same value over and over.
960 for (int i = 0; i < kMultiVarCount; i++) {
961 EXPECT_TRUE(writer.WriteVarInt62(UINT64_C(0x3142) + i));
962 }
963 EXPECT_EQ(writer.length(), 2u * kMultiVarCount);
964
965 // N+1st should fail, the buffer is full.
966 EXPECT_FALSE(writer.WriteVarInt62(UINT64_C(0x3142)));
967
968 // Now we should be able to read out the N values that were
969 // successfully encoded.
QUICHE team173c48f2019-11-19 16:34:44 -0800970 QuicDataReader reader(buffer, sizeof(buffer),
971 quiche::Endianness::NETWORK_BYTE_ORDER);
QUICHE teama6ef0a62019-03-07 20:34:33 -0500972 for (int i = 0; i < kMultiVarCount; i++) {
973 EXPECT_TRUE(reader.ReadVarInt62(&test_val));
974 EXPECT_EQ(test_val, (UINT64_C(0x3142) + i));
975 }
976 // And the N+1st should fail.
977 EXPECT_FALSE(reader.ReadVarInt62(&test_val));
978}
979
980// Test writing & reading multiple 1-byte-encoded varints
981TEST_P(QuicDataWriterTest, MultiVarInt1) {
982 uint64_t test_val;
983 char buffer[1 * kMultiVarCount];
984 memset(buffer, 0, sizeof(buffer));
985 QuicDataWriter writer(sizeof(buffer), static_cast<char*>(buffer),
QUICHE team173c48f2019-11-19 16:34:44 -0800986 quiche::Endianness::NETWORK_BYTE_ORDER);
QUICHE teama6ef0a62019-03-07 20:34:33 -0500987 // Put N values into the buffer. Adding i to the value ensures that
988 // each value is different so we can detect if we overwrite values,
989 // or read the same value over and over. &0xf ensures we do not
990 // overflow the max value for single-byte encoding.
991 for (int i = 0; i < kMultiVarCount; i++) {
992 EXPECT_TRUE(writer.WriteVarInt62(UINT64_C(0x30) + (i & 0xf)));
993 }
994 EXPECT_EQ(writer.length(), 1u * kMultiVarCount);
995
996 // N+1st should fail, the buffer is full.
997 EXPECT_FALSE(writer.WriteVarInt62(UINT64_C(0x31)));
998
999 // Now we should be able to read out the N values that were
1000 // successfully encoded.
QUICHE team173c48f2019-11-19 16:34:44 -08001001 QuicDataReader reader(buffer, sizeof(buffer),
1002 quiche::Endianness::NETWORK_BYTE_ORDER);
QUICHE teama6ef0a62019-03-07 20:34:33 -05001003 for (int i = 0; i < kMultiVarCount; i++) {
1004 EXPECT_TRUE(reader.ReadVarInt62(&test_val));
1005 EXPECT_EQ(test_val, (UINT64_C(0x30) + (i & 0xf)));
1006 }
1007 // And the N+1st should fail.
1008 EXPECT_FALSE(reader.ReadVarInt62(&test_val));
1009}
1010
1011// Test writing varints with a forced length.
1012TEST_P(QuicDataWriterTest, VarIntFixedLength) {
1013 char buffer[90];
1014 memset(buffer, 0, sizeof(buffer));
1015 QuicDataWriter writer(sizeof(buffer), static_cast<char*>(buffer),
QUICHE team173c48f2019-11-19 16:34:44 -08001016 quiche::Endianness::NETWORK_BYTE_ORDER);
QUICHE teama6ef0a62019-03-07 20:34:33 -05001017
1018 writer.WriteVarInt62(1, VARIABLE_LENGTH_INTEGER_LENGTH_1);
1019 writer.WriteVarInt62(1, VARIABLE_LENGTH_INTEGER_LENGTH_2);
1020 writer.WriteVarInt62(1, VARIABLE_LENGTH_INTEGER_LENGTH_4);
1021 writer.WriteVarInt62(1, VARIABLE_LENGTH_INTEGER_LENGTH_8);
1022
1023 writer.WriteVarInt62(63, VARIABLE_LENGTH_INTEGER_LENGTH_1);
1024 writer.WriteVarInt62(63, VARIABLE_LENGTH_INTEGER_LENGTH_2);
1025 writer.WriteVarInt62(63, VARIABLE_LENGTH_INTEGER_LENGTH_4);
1026 writer.WriteVarInt62(63, VARIABLE_LENGTH_INTEGER_LENGTH_8);
1027
1028 writer.WriteVarInt62(64, VARIABLE_LENGTH_INTEGER_LENGTH_2);
1029 writer.WriteVarInt62(64, VARIABLE_LENGTH_INTEGER_LENGTH_4);
1030 writer.WriteVarInt62(64, VARIABLE_LENGTH_INTEGER_LENGTH_8);
1031
1032 writer.WriteVarInt62(16383, VARIABLE_LENGTH_INTEGER_LENGTH_2);
1033 writer.WriteVarInt62(16383, VARIABLE_LENGTH_INTEGER_LENGTH_4);
1034 writer.WriteVarInt62(16383, VARIABLE_LENGTH_INTEGER_LENGTH_8);
1035
1036 writer.WriteVarInt62(16384, VARIABLE_LENGTH_INTEGER_LENGTH_4);
1037 writer.WriteVarInt62(16384, VARIABLE_LENGTH_INTEGER_LENGTH_8);
1038
1039 writer.WriteVarInt62(1073741823, VARIABLE_LENGTH_INTEGER_LENGTH_4);
1040 writer.WriteVarInt62(1073741823, VARIABLE_LENGTH_INTEGER_LENGTH_8);
1041
1042 writer.WriteVarInt62(1073741824, VARIABLE_LENGTH_INTEGER_LENGTH_8);
1043
QUICHE team173c48f2019-11-19 16:34:44 -08001044 QuicDataReader reader(buffer, sizeof(buffer),
1045 quiche::Endianness::NETWORK_BYTE_ORDER);
QUICHE teama6ef0a62019-03-07 20:34:33 -05001046
1047 uint64_t test_val = 0;
1048 for (int i = 0; i < 4; ++i) {
1049 EXPECT_TRUE(reader.ReadVarInt62(&test_val));
1050 EXPECT_EQ(test_val, 1u);
1051 }
1052 for (int i = 0; i < 4; ++i) {
1053 EXPECT_TRUE(reader.ReadVarInt62(&test_val));
1054 EXPECT_EQ(test_val, 63u);
1055 }
1056
1057 for (int i = 0; i < 3; ++i) {
1058 EXPECT_TRUE(reader.ReadVarInt62(&test_val));
1059 EXPECT_EQ(test_val, 64u);
1060 }
1061 for (int i = 0; i < 3; ++i) {
1062 EXPECT_TRUE(reader.ReadVarInt62(&test_val));
1063 EXPECT_EQ(test_val, 16383u);
1064 }
1065
1066 for (int i = 0; i < 2; ++i) {
1067 EXPECT_TRUE(reader.ReadVarInt62(&test_val));
1068 EXPECT_EQ(test_val, 16384u);
1069 }
1070 for (int i = 0; i < 2; ++i) {
1071 EXPECT_TRUE(reader.ReadVarInt62(&test_val));
1072 EXPECT_EQ(test_val, 1073741823u);
1073 }
1074
1075 EXPECT_TRUE(reader.ReadVarInt62(&test_val));
1076 EXPECT_EQ(test_val, 1073741824u);
1077
1078 // We are at the end of the buffer so this should fail.
1079 EXPECT_FALSE(reader.ReadVarInt62(&test_val));
1080}
1081
1082// Test encoding/decoding stream-id values.
1083void EncodeDecodeStreamId(uint64_t value_in, bool expected_decode_result) {
1084 char buffer[1 * kMultiVarCount];
1085 memset(buffer, 0, sizeof(buffer));
1086
1087 // Encode the given Stream ID.
1088 QuicDataWriter writer(sizeof(buffer), static_cast<char*>(buffer),
QUICHE team173c48f2019-11-19 16:34:44 -08001089 quiche::Endianness::NETWORK_BYTE_ORDER);
QUICHE teama6ef0a62019-03-07 20:34:33 -05001090 EXPECT_TRUE(writer.WriteVarInt62(value_in));
1091
QUICHE team173c48f2019-11-19 16:34:44 -08001092 QuicDataReader reader(buffer, sizeof(buffer),
1093 quiche::Endianness::NETWORK_BYTE_ORDER);
QUICHE teama6ef0a62019-03-07 20:34:33 -05001094 QuicStreamId received_stream_id;
fkastenholz3c4eabf2019-04-22 07:49:59 -07001095 bool read_result = reader.ReadVarIntU32(&received_stream_id);
QUICHE teama6ef0a62019-03-07 20:34:33 -05001096 EXPECT_EQ(expected_decode_result, read_result);
1097 if (read_result) {
1098 EXPECT_EQ(value_in, received_stream_id);
1099 }
1100}
1101
1102// Test writing & reading stream-ids of various value.
1103TEST_P(QuicDataWriterTest, StreamId1) {
1104 // Check a 1-byte QuicStreamId, should work
1105 EncodeDecodeStreamId(UINT64_C(0x15), true);
1106
1107 // Check a 2-byte QuicStream ID. It should work.
1108 EncodeDecodeStreamId(UINT64_C(0x1567), true);
1109
1110 // Check a QuicStreamId that requires 4 bytes of encoding
1111 // This should work.
1112 EncodeDecodeStreamId(UINT64_C(0x34567890), true);
1113
1114 // Check a QuicStreamId that requires 8 bytes of encoding
1115 // but whose value is in the acceptable range.
1116 // This should work.
1117 EncodeDecodeStreamId(UINT64_C(0xf4567890), true);
1118
1119 // Check QuicStreamIds that require 8 bytes of encoding
1120 // and whose value is not acceptable.
1121 // This should fail.
1122 EncodeDecodeStreamId(UINT64_C(0x100000000), false);
1123 EncodeDecodeStreamId(UINT64_C(0x3fffffffffffffff), false);
1124}
1125
1126TEST_P(QuicDataWriterTest, WriteRandomBytes) {
1127 char buffer[20];
1128 char expected[20];
1129 for (size_t i = 0; i < 20; ++i) {
1130 expected[i] = 'r';
1131 }
1132 MockRandom random;
1133 QuicDataWriter writer(20, buffer, GetParam().endianness);
1134 EXPECT_FALSE(writer.WriteRandomBytes(&random, 30));
1135
1136 EXPECT_TRUE(writer.WriteRandomBytes(&random, 20));
1137 test::CompareCharArraysWithHexError("random", buffer, 20, expected, 20);
1138}
1139
1140TEST_P(QuicDataWriterTest, PeekVarInt62Length) {
1141 // In range [0, 63], variable length should be 1 byte.
1142 char buffer[20];
QUICHE team173c48f2019-11-19 16:34:44 -08001143 QuicDataWriter writer(20, buffer, quiche::NETWORK_BYTE_ORDER);
QUICHE teama6ef0a62019-03-07 20:34:33 -05001144 EXPECT_TRUE(writer.WriteVarInt62(50));
QUICHE team173c48f2019-11-19 16:34:44 -08001145 QuicDataReader reader(buffer, 20, quiche::NETWORK_BYTE_ORDER);
QUICHE teama6ef0a62019-03-07 20:34:33 -05001146 EXPECT_EQ(1, reader.PeekVarInt62Length());
1147 // In range (63-16383], variable length should be 2 byte2.
1148 char buffer2[20];
QUICHE team173c48f2019-11-19 16:34:44 -08001149 QuicDataWriter writer2(20, buffer2, quiche::NETWORK_BYTE_ORDER);
QUICHE teama6ef0a62019-03-07 20:34:33 -05001150 EXPECT_TRUE(writer2.WriteVarInt62(100));
QUICHE team173c48f2019-11-19 16:34:44 -08001151 QuicDataReader reader2(buffer2, 20, quiche::NETWORK_BYTE_ORDER);
QUICHE teama6ef0a62019-03-07 20:34:33 -05001152 EXPECT_EQ(2, reader2.PeekVarInt62Length());
1153 // In range (16383, 1073741823], variable length should be 4 bytes.
1154 char buffer3[20];
QUICHE team173c48f2019-11-19 16:34:44 -08001155 QuicDataWriter writer3(20, buffer3, quiche::NETWORK_BYTE_ORDER);
QUICHE teama6ef0a62019-03-07 20:34:33 -05001156 EXPECT_TRUE(writer3.WriteVarInt62(20000));
QUICHE team173c48f2019-11-19 16:34:44 -08001157 QuicDataReader reader3(buffer3, 20, quiche::NETWORK_BYTE_ORDER);
QUICHE teama6ef0a62019-03-07 20:34:33 -05001158 EXPECT_EQ(4, reader3.PeekVarInt62Length());
1159 // In range (1073741823, 4611686018427387903], variable length should be 8
1160 // bytes.
1161 char buffer4[20];
QUICHE team173c48f2019-11-19 16:34:44 -08001162 QuicDataWriter writer4(20, buffer4, quiche::NETWORK_BYTE_ORDER);
QUICHE teama6ef0a62019-03-07 20:34:33 -05001163 EXPECT_TRUE(writer4.WriteVarInt62(2000000000));
QUICHE team173c48f2019-11-19 16:34:44 -08001164 QuicDataReader reader4(buffer4, 20, quiche::NETWORK_BYTE_ORDER);
QUICHE teama6ef0a62019-03-07 20:34:33 -05001165 EXPECT_EQ(8, reader4.PeekVarInt62Length());
1166}
1167
QUICHE team0131a5b2019-03-20 15:23:27 -07001168TEST_P(QuicDataWriterTest, InvalidConnectionIdLengthRead) {
dschinaziffa83552019-12-17 11:00:23 -08001169 SetQuicRestartFlag(quic_allow_very_long_connection_ids, false);
1170 // TODO(dschinazi) delete this test when we deprecate
1171 // quic_allow_very_long_connection_ids.
dschinazib953d022019-08-01 18:05:58 -07001172 static const uint8_t bad_connection_id_length = 200;
dschinazib012d212019-08-01 18:07:26 -07001173 static_assert(
1174 bad_connection_id_length > kQuicMaxConnectionIdAllVersionsLength,
1175 "bad lengths");
dschinazib953d022019-08-01 18:05:58 -07001176 char buffer[255] = {};
1177 QuicDataReader reader(buffer, sizeof(buffer));
QUICHE team0131a5b2019-03-20 15:23:27 -07001178 QuicConnectionId connection_id;
1179 bool ok;
1180 EXPECT_QUIC_BUG(
1181 ok = reader.ReadConnectionId(&connection_id, bad_connection_id_length),
dmcardlecf0bfcf2019-12-13 08:08:21 -08001182 quiche::QuicheStrCat(
1183 "Attempted to read connection ID with length too high ",
1184 static_cast<int>(bad_connection_id_length)));
QUICHE team0131a5b2019-03-20 15:23:27 -07001185 EXPECT_FALSE(ok);
1186}
1187
fkastenholz3c4eabf2019-04-22 07:49:59 -07001188// Test that ReadVarIntU32 works properly. Tests a valid stream count
1189// (a 32 bit number) and an invalid one (a >32 bit number)
1190TEST_P(QuicDataWriterTest, ValidU32) {
1191 char buffer[1024];
1192 memset(buffer, 0, sizeof(buffer));
1193 QuicDataWriter writer(sizeof(buffer), static_cast<char*>(buffer),
QUICHE team173c48f2019-11-19 16:34:44 -08001194 quiche::Endianness::NETWORK_BYTE_ORDER);
fkastenholz3c4eabf2019-04-22 07:49:59 -07001195 QuicDataReader reader(buffer, sizeof(buffer));
1196 const QuicStreamCount write_stream_count = 0xffeeddcc;
1197 EXPECT_TRUE(writer.WriteVarInt62(write_stream_count));
1198 QuicStreamCount read_stream_count;
1199 EXPECT_TRUE(reader.ReadVarIntU32(&read_stream_count));
1200 EXPECT_EQ(write_stream_count, read_stream_count);
1201}
1202
1203TEST_P(QuicDataWriterTest, InvalidU32) {
1204 char buffer[1024];
1205 memset(buffer, 0, sizeof(buffer));
1206 QuicDataWriter writer(sizeof(buffer), static_cast<char*>(buffer),
QUICHE team173c48f2019-11-19 16:34:44 -08001207 quiche::Endianness::NETWORK_BYTE_ORDER);
fkastenholz3c4eabf2019-04-22 07:49:59 -07001208 QuicDataReader reader(buffer, sizeof(buffer));
1209 EXPECT_TRUE(writer.WriteVarInt62(UINT64_C(0x1ffeeddcc)));
1210 QuicStreamCount read_stream_count = 123456;
1211 EXPECT_FALSE(reader.ReadVarIntU32(&read_stream_count));
1212 // If the value is bad, read_stream_count ought not change.
1213 EXPECT_EQ(123456u, read_stream_count);
1214}
1215
nharper55fa6132019-05-07 19:37:21 -07001216TEST_P(QuicDataWriterTest, Seek) {
1217 char buffer[3] = {};
bnc4e9283d2019-12-17 07:08:57 -08001218 QuicDataWriter writer(QUICHE_ARRAYSIZE(buffer), buffer,
1219 GetParam().endianness);
nharper55fa6132019-05-07 19:37:21 -07001220 EXPECT_TRUE(writer.WriteUInt8(42));
1221 EXPECT_TRUE(writer.Seek(1));
1222 EXPECT_TRUE(writer.WriteUInt8(3));
1223
1224 char expected[] = {42, 0, 3};
bnc4e9283d2019-12-17 07:08:57 -08001225 for (size_t i = 0; i < QUICHE_ARRAYSIZE(expected); ++i) {
nharper55fa6132019-05-07 19:37:21 -07001226 EXPECT_EQ(buffer[i], expected[i]);
1227 }
1228}
1229
1230TEST_P(QuicDataWriterTest, SeekTooFarFails) {
1231 char buffer[20];
1232
1233 // Check that one can seek to the end of the writer, but not past.
1234 {
bnc4e9283d2019-12-17 07:08:57 -08001235 QuicDataWriter writer(QUICHE_ARRAYSIZE(buffer), buffer,
nharper55fa6132019-05-07 19:37:21 -07001236 GetParam().endianness);
1237 EXPECT_TRUE(writer.Seek(20));
1238 EXPECT_FALSE(writer.Seek(1));
1239 }
1240
1241 // Seeking several bytes past the end fails.
1242 {
bnc4e9283d2019-12-17 07:08:57 -08001243 QuicDataWriter writer(QUICHE_ARRAYSIZE(buffer), buffer,
nharper55fa6132019-05-07 19:37:21 -07001244 GetParam().endianness);
1245 EXPECT_FALSE(writer.Seek(100));
1246 }
1247
1248 // Seeking so far that arithmetic overflow could occur also fails.
1249 {
bnc4e9283d2019-12-17 07:08:57 -08001250 QuicDataWriter writer(QUICHE_ARRAYSIZE(buffer), buffer,
nharper55fa6132019-05-07 19:37:21 -07001251 GetParam().endianness);
1252 EXPECT_TRUE(writer.Seek(10));
1253 EXPECT_FALSE(writer.Seek(std::numeric_limits<size_t>::max()));
1254 }
1255}
1256
dschinazi4b5a68a2019-08-15 15:45:36 -07001257TEST_P(QuicDataWriterTest, PayloadReads) {
1258 char buffer[16] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16};
1259 char expected_first_read[4] = {1, 2, 3, 4};
1260 char expected_remaining[12] = {5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16};
1261 QuicDataReader reader(buffer, sizeof(buffer));
1262 char first_read_buffer[4] = {};
1263 EXPECT_TRUE(reader.ReadBytes(first_read_buffer, sizeof(first_read_buffer)));
1264 test::CompareCharArraysWithHexError(
1265 "first read", first_read_buffer, sizeof(first_read_buffer),
1266 expected_first_read, sizeof(expected_first_read));
dmcardlecf0bfcf2019-12-13 08:08:21 -08001267 quiche::QuicheStringPiece peeked_remaining_payload =
1268 reader.PeekRemainingPayload();
dschinazi4b5a68a2019-08-15 15:45:36 -07001269 test::CompareCharArraysWithHexError(
1270 "peeked_remaining_payload", peeked_remaining_payload.data(),
1271 peeked_remaining_payload.length(), expected_remaining,
1272 sizeof(expected_remaining));
dmcardlecf0bfcf2019-12-13 08:08:21 -08001273 quiche::QuicheStringPiece full_payload = reader.FullPayload();
dschinazi4b5a68a2019-08-15 15:45:36 -07001274 test::CompareCharArraysWithHexError("full_payload", full_payload.data(),
1275 full_payload.length(), buffer,
1276 sizeof(buffer));
dmcardlecf0bfcf2019-12-13 08:08:21 -08001277 quiche::QuicheStringPiece read_remaining_payload =
1278 reader.ReadRemainingPayload();
dschinazi4b5a68a2019-08-15 15:45:36 -07001279 test::CompareCharArraysWithHexError(
1280 "read_remaining_payload", read_remaining_payload.data(),
1281 read_remaining_payload.length(), expected_remaining,
1282 sizeof(expected_remaining));
1283 EXPECT_TRUE(reader.IsDoneReading());
dmcardlecf0bfcf2019-12-13 08:08:21 -08001284 quiche::QuicheStringPiece full_payload2 = reader.FullPayload();
dschinazi4b5a68a2019-08-15 15:45:36 -07001285 test::CompareCharArraysWithHexError("full_payload2", full_payload2.data(),
1286 full_payload2.length(), buffer,
1287 sizeof(buffer));
1288}
1289
QUICHE teama6ef0a62019-03-07 20:34:33 -05001290} // namespace
1291} // namespace test
1292} // namespace quic