blob: 104df8d42ee56881893f0737ebf544afa949c65b [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"
13#include "net/third_party/quiche/src/quic/platform/api/quic_arraysize.h"
QUICHE team0131a5b2019-03-20 15:23:27 -070014#include "net/third_party/quiche/src/quic/platform/api/quic_expect_bug.h"
QUICHE teama6ef0a62019-03-07 20:34:33 -050015#include "net/third_party/quiche/src/quic/platform/api/quic_flags.h"
16#include "net/third_party/quiche/src/quic/platform/api/quic_test.h"
17#include "net/third_party/quiche/src/quic/test_tools/quic_test_utils.h"
QUICHE team173c48f2019-11-19 16:34:44 -080018#include "net/third_party/quiche/src/common/platform/api/quiche_endian.h"
QUICHE teama6ef0a62019-03-07 20:34:33 -050019
20namespace quic {
21namespace test {
22namespace {
23
24char* AsChars(unsigned char* data) {
25 return reinterpret_cast<char*>(data);
26}
27
28struct TestParams {
QUICHE team173c48f2019-11-19 16:34:44 -080029 explicit TestParams(quiche::Endianness endianness) : endianness(endianness) {}
QUICHE teama6ef0a62019-03-07 20:34:33 -050030
QUICHE team173c48f2019-11-19 16:34:44 -080031 quiche::Endianness endianness;
QUICHE teama6ef0a62019-03-07 20:34:33 -050032};
33
dschinazi142051a2019-09-18 18:17:29 -070034// Used by ::testing::PrintToStringParamName().
35std::string PrintToString(const TestParams& p) {
QUICHE team173c48f2019-11-19 16:34:44 -080036 return QuicStrCat(
37 (p.endianness == quiche::NETWORK_BYTE_ORDER ? "Network" : "Host"),
38 "ByteOrder");
dschinazi142051a2019-09-18 18:17:29 -070039}
40
QUICHE teama6ef0a62019-03-07 20:34:33 -050041std::vector<TestParams> GetTestParams() {
42 std::vector<TestParams> params;
QUICHE team173c48f2019-11-19 16:34:44 -080043 for (quiche::Endianness endianness :
44 {quiche::NETWORK_BYTE_ORDER, quiche::HOST_BYTE_ORDER}) {
QUICHE teama6ef0a62019-03-07 20:34:33 -050045 params.push_back(TestParams(endianness));
46 }
47 return params;
48}
49
50class QuicDataWriterTest : public QuicTestWithParam<TestParams> {};
51
QUICHE team0131a5b2019-03-20 15:23:27 -070052INSTANTIATE_TEST_SUITE_P(QuicDataWriterTests,
53 QuicDataWriterTest,
dschinazi142051a2019-09-18 18:17:29 -070054 ::testing::ValuesIn(GetTestParams()),
55 ::testing::PrintToStringParamName());
QUICHE teama6ef0a62019-03-07 20:34:33 -050056
57TEST_P(QuicDataWriterTest, SanityCheckUFloat16Consts) {
58 // Check the arithmetic on the constants - otherwise the values below make
59 // no sense.
60 EXPECT_EQ(30, kUFloat16MaxExponent);
61 EXPECT_EQ(11, kUFloat16MantissaBits);
62 EXPECT_EQ(12, kUFloat16MantissaEffectiveBits);
63 EXPECT_EQ(UINT64_C(0x3FFC0000000), kUFloat16MaxValue);
64}
65
66TEST_P(QuicDataWriterTest, WriteUFloat16) {
67 struct TestCase {
68 uint64_t decoded;
69 uint16_t encoded;
70 };
71 TestCase test_cases[] = {
72 // Small numbers represent themselves.
73 {0, 0},
74 {1, 1},
75 {2, 2},
76 {3, 3},
77 {4, 4},
78 {5, 5},
79 {6, 6},
80 {7, 7},
81 {15, 15},
82 {31, 31},
83 {42, 42},
84 {123, 123},
85 {1234, 1234},
86 // Check transition through 2^11.
87 {2046, 2046},
88 {2047, 2047},
89 {2048, 2048},
90 {2049, 2049},
91 // Running out of mantissa at 2^12.
92 {4094, 4094},
93 {4095, 4095},
94 {4096, 4096},
95 {4097, 4096},
96 {4098, 4097},
97 {4099, 4097},
98 {4100, 4098},
99 {4101, 4098},
100 // Check transition through 2^13.
101 {8190, 6143},
102 {8191, 6143},
103 {8192, 6144},
104 {8193, 6144},
105 {8194, 6144},
106 {8195, 6144},
107 {8196, 6145},
108 {8197, 6145},
109 // Half-way through the exponents.
110 {0x7FF8000, 0x87FF},
111 {0x7FFFFFF, 0x87FF},
112 {0x8000000, 0x8800},
113 {0xFFF0000, 0x8FFF},
114 {0xFFFFFFF, 0x8FFF},
115 {0x10000000, 0x9000},
116 // Transition into the largest exponent.
117 {0x1FFFFFFFFFE, 0xF7FF},
118 {0x1FFFFFFFFFF, 0xF7FF},
119 {0x20000000000, 0xF800},
120 {0x20000000001, 0xF800},
121 {0x2003FFFFFFE, 0xF800},
122 {0x2003FFFFFFF, 0xF800},
123 {0x20040000000, 0xF801},
124 {0x20040000001, 0xF801},
125 // Transition into the max value and clamping.
126 {0x3FF80000000, 0xFFFE},
127 {0x3FFBFFFFFFF, 0xFFFE},
128 {0x3FFC0000000, 0xFFFF},
129 {0x3FFC0000001, 0xFFFF},
130 {0x3FFFFFFFFFF, 0xFFFF},
131 {0x40000000000, 0xFFFF},
132 {0xFFFFFFFFFFFFFFFF, 0xFFFF},
133 };
134 int num_test_cases = sizeof(test_cases) / sizeof(test_cases[0]);
135
136 for (int i = 0; i < num_test_cases; ++i) {
137 char buffer[2];
138 QuicDataWriter writer(2, buffer, GetParam().endianness);
139 EXPECT_TRUE(writer.WriteUFloat16(test_cases[i].decoded));
140 uint16_t result = *reinterpret_cast<uint16_t*>(writer.data());
QUICHE team173c48f2019-11-19 16:34:44 -0800141 if (GetParam().endianness == quiche::NETWORK_BYTE_ORDER) {
142 result = quiche::QuicheEndian::HostToNet16(result);
QUICHE teama6ef0a62019-03-07 20:34:33 -0500143 }
144 EXPECT_EQ(test_cases[i].encoded, result);
145 }
146}
147
148TEST_P(QuicDataWriterTest, ReadUFloat16) {
149 struct TestCase {
150 uint64_t decoded;
151 uint16_t encoded;
152 };
153 TestCase test_cases[] = {
154 // There are fewer decoding test cases because encoding truncates, and
155 // decoding returns the smallest expansion.
156 // Small numbers represent themselves.
157 {0, 0},
158 {1, 1},
159 {2, 2},
160 {3, 3},
161 {4, 4},
162 {5, 5},
163 {6, 6},
164 {7, 7},
165 {15, 15},
166 {31, 31},
167 {42, 42},
168 {123, 123},
169 {1234, 1234},
170 // Check transition through 2^11.
171 {2046, 2046},
172 {2047, 2047},
173 {2048, 2048},
174 {2049, 2049},
175 // Running out of mantissa at 2^12.
176 {4094, 4094},
177 {4095, 4095},
178 {4096, 4096},
179 {4098, 4097},
180 {4100, 4098},
181 // Check transition through 2^13.
182 {8190, 6143},
183 {8192, 6144},
184 {8196, 6145},
185 // Half-way through the exponents.
186 {0x7FF8000, 0x87FF},
187 {0x8000000, 0x8800},
188 {0xFFF0000, 0x8FFF},
189 {0x10000000, 0x9000},
190 // Transition into the largest exponent.
191 {0x1FFE0000000, 0xF7FF},
192 {0x20000000000, 0xF800},
193 {0x20040000000, 0xF801},
194 // Transition into the max value.
195 {0x3FF80000000, 0xFFFE},
196 {0x3FFC0000000, 0xFFFF},
197 };
198 int num_test_cases = sizeof(test_cases) / sizeof(test_cases[0]);
199
200 for (int i = 0; i < num_test_cases; ++i) {
201 uint16_t encoded_ufloat = test_cases[i].encoded;
QUICHE team173c48f2019-11-19 16:34:44 -0800202 if (GetParam().endianness == quiche::NETWORK_BYTE_ORDER) {
203 encoded_ufloat = quiche::QuicheEndian::HostToNet16(encoded_ufloat);
QUICHE teama6ef0a62019-03-07 20:34:33 -0500204 }
205 QuicDataReader reader(reinterpret_cast<char*>(&encoded_ufloat), 2,
206 GetParam().endianness);
207 uint64_t value;
208 EXPECT_TRUE(reader.ReadUFloat16(&value));
209 EXPECT_EQ(test_cases[i].decoded, value);
210 }
211}
212
213TEST_P(QuicDataWriterTest, RoundTripUFloat16) {
214 // Just test all 16-bit encoded values. 0 and max already tested above.
215 uint64_t previous_value = 0;
216 for (uint16_t i = 1; i < 0xFFFF; ++i) {
217 // Read the two bytes.
218 uint16_t read_number = i;
QUICHE team173c48f2019-11-19 16:34:44 -0800219 if (GetParam().endianness == quiche::NETWORK_BYTE_ORDER) {
220 read_number = quiche::QuicheEndian::HostToNet16(read_number);
QUICHE teama6ef0a62019-03-07 20:34:33 -0500221 }
222 QuicDataReader reader(reinterpret_cast<char*>(&read_number), 2,
223 GetParam().endianness);
224 uint64_t value;
225 // All values must be decodable.
226 EXPECT_TRUE(reader.ReadUFloat16(&value));
227 // Check that small numbers represent themselves
228 if (i < 4097) {
229 EXPECT_EQ(i, value);
230 }
231 // Check there's monotonic growth.
232 EXPECT_LT(previous_value, value);
233 // Check that precision is within 0.5% away from the denormals.
234 if (i > 2000) {
235 EXPECT_GT(previous_value * 1005, value * 1000);
236 }
237 // Check we're always within the promised range.
238 EXPECT_LT(value, UINT64_C(0x3FFC0000000));
239 previous_value = value;
240 char buffer[6];
241 QuicDataWriter writer(6, buffer, GetParam().endianness);
242 EXPECT_TRUE(writer.WriteUFloat16(value - 1));
243 EXPECT_TRUE(writer.WriteUFloat16(value));
244 EXPECT_TRUE(writer.WriteUFloat16(value + 1));
245 // Check minimal decoding (previous decoding has previous encoding).
246 uint16_t encoded1 = *reinterpret_cast<uint16_t*>(writer.data());
247 uint16_t encoded2 = *reinterpret_cast<uint16_t*>(writer.data() + 2);
248 uint16_t encoded3 = *reinterpret_cast<uint16_t*>(writer.data() + 4);
QUICHE team173c48f2019-11-19 16:34:44 -0800249 if (GetParam().endianness == quiche::NETWORK_BYTE_ORDER) {
250 encoded1 = quiche::QuicheEndian::NetToHost16(encoded1);
251 encoded2 = quiche::QuicheEndian::NetToHost16(encoded2);
252 encoded3 = quiche::QuicheEndian::NetToHost16(encoded3);
QUICHE teama6ef0a62019-03-07 20:34:33 -0500253 }
254 EXPECT_EQ(i - 1, encoded1);
255 // Check roundtrip.
256 EXPECT_EQ(i, encoded2);
257 // Check next decoding.
258 EXPECT_EQ(i < 4096 ? i + 1 : i, encoded3);
259 }
260}
261
262TEST_P(QuicDataWriterTest, WriteConnectionId) {
263 QuicConnectionId connection_id =
264 TestConnectionId(UINT64_C(0x0011223344556677));
265 char big_endian[] = {
266 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77,
267 };
268 EXPECT_EQ(connection_id.length(), QUIC_ARRAYSIZE(big_endian));
dschinazib012d212019-08-01 18:07:26 -0700269 ASSERT_LE(connection_id.length(), 255);
270 char buffer[255];
QUICHE teama6ef0a62019-03-07 20:34:33 -0500271 QuicDataWriter writer(connection_id.length(), buffer, GetParam().endianness);
272 EXPECT_TRUE(writer.WriteConnectionId(connection_id));
273 test::CompareCharArraysWithHexError("connection_id", buffer,
274 connection_id.length(), big_endian,
275 connection_id.length());
276
277 QuicConnectionId read_connection_id;
278 QuicDataReader reader(buffer, connection_id.length(), GetParam().endianness);
279 EXPECT_TRUE(
280 reader.ReadConnectionId(&read_connection_id, QUIC_ARRAYSIZE(big_endian)));
281 EXPECT_EQ(connection_id, read_connection_id);
282}
283
dschinazicf5b1e22019-07-17 18:35:17 -0700284TEST_P(QuicDataWriterTest, LengthPrefixedConnectionId) {
285 QuicConnectionId connection_id =
286 TestConnectionId(UINT64_C(0x0011223344556677));
287 char length_prefixed_connection_id[] = {
288 0x08, 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77,
289 };
290 EXPECT_EQ(QUIC_ARRAYSIZE(length_prefixed_connection_id),
291 kConnectionIdLengthSize + connection_id.length());
dschinazib012d212019-08-01 18:07:26 -0700292 char buffer[kConnectionIdLengthSize + 255] = {};
dschinazicf5b1e22019-07-17 18:35:17 -0700293 QuicDataWriter writer(QUIC_ARRAYSIZE(buffer), buffer);
294 EXPECT_TRUE(writer.WriteLengthPrefixedConnectionId(connection_id));
295 test::CompareCharArraysWithHexError(
296 "WriteLengthPrefixedConnectionId", buffer, writer.length(),
297 length_prefixed_connection_id,
298 QUIC_ARRAYSIZE(length_prefixed_connection_id));
299
300 // Verify that writing length then connection ID produces the same output.
301 memset(buffer, 0, QUIC_ARRAYSIZE(buffer));
302 QuicDataWriter writer2(QUIC_ARRAYSIZE(buffer), buffer);
303 EXPECT_TRUE(writer2.WriteUInt8(connection_id.length()));
304 EXPECT_TRUE(writer2.WriteConnectionId(connection_id));
305 test::CompareCharArraysWithHexError(
306 "Write length then ConnectionId", buffer, writer2.length(),
307 length_prefixed_connection_id,
308 QUIC_ARRAYSIZE(length_prefixed_connection_id));
309
310 QuicConnectionId read_connection_id;
311 QuicDataReader reader(buffer, QUIC_ARRAYSIZE(buffer));
312 EXPECT_TRUE(reader.ReadLengthPrefixedConnectionId(&read_connection_id));
313 EXPECT_EQ(connection_id, read_connection_id);
314
315 // Verify that reading length then connection ID produces the same output.
316 uint8_t read_connection_id_length2 = 33;
317 QuicConnectionId read_connection_id2;
318 QuicDataReader reader2(buffer, QUIC_ARRAYSIZE(buffer));
319 ASSERT_TRUE(reader2.ReadUInt8(&read_connection_id_length2));
320 EXPECT_EQ(connection_id.length(), read_connection_id_length2);
321 EXPECT_TRUE(reader2.ReadConnectionId(&read_connection_id2,
322 read_connection_id_length2));
323 EXPECT_EQ(connection_id, read_connection_id2);
324}
325
QUICHE teama6ef0a62019-03-07 20:34:33 -0500326TEST_P(QuicDataWriterTest, EmptyConnectionIds) {
327 QuicConnectionId empty_connection_id = EmptyQuicConnectionId();
328 char buffer[2];
329 QuicDataWriter writer(QUIC_ARRAYSIZE(buffer), buffer, GetParam().endianness);
330 EXPECT_TRUE(writer.WriteConnectionId(empty_connection_id));
331 EXPECT_TRUE(writer.WriteUInt8(1));
332 EXPECT_TRUE(writer.WriteConnectionId(empty_connection_id));
333 EXPECT_TRUE(writer.WriteUInt8(2));
334 EXPECT_TRUE(writer.WriteConnectionId(empty_connection_id));
335 EXPECT_FALSE(writer.WriteUInt8(3));
336
337 EXPECT_EQ(buffer[0], 1);
338 EXPECT_EQ(buffer[1], 2);
339
340 QuicConnectionId read_connection_id = TestConnectionId();
341 uint8_t read_byte;
342 QuicDataReader reader(buffer, QUIC_ARRAYSIZE(buffer), GetParam().endianness);
343 EXPECT_TRUE(reader.ReadConnectionId(&read_connection_id, 0));
344 EXPECT_EQ(read_connection_id, empty_connection_id);
345 EXPECT_TRUE(reader.ReadUInt8(&read_byte));
346 EXPECT_EQ(read_byte, 1);
347 // Reset read_connection_id to something else to verify that
348 // ReadConnectionId properly sets it back to empty.
349 read_connection_id = TestConnectionId();
350 EXPECT_TRUE(reader.ReadConnectionId(&read_connection_id, 0));
351 EXPECT_EQ(read_connection_id, empty_connection_id);
352 EXPECT_TRUE(reader.ReadUInt8(&read_byte));
353 EXPECT_EQ(read_byte, 2);
354 read_connection_id = TestConnectionId();
355 EXPECT_TRUE(reader.ReadConnectionId(&read_connection_id, 0));
356 EXPECT_EQ(read_connection_id, empty_connection_id);
357 EXPECT_FALSE(reader.ReadUInt8(&read_byte));
358}
359
360TEST_P(QuicDataWriterTest, WriteTag) {
361 char CHLO[] = {
362 'C',
363 'H',
364 'L',
365 'O',
366 };
367 const int kBufferLength = sizeof(QuicTag);
368 char buffer[kBufferLength];
369 QuicDataWriter writer(kBufferLength, buffer, GetParam().endianness);
370 writer.WriteTag(kCHLO);
371 test::CompareCharArraysWithHexError("CHLO", buffer, kBufferLength, CHLO,
372 kBufferLength);
373
374 QuicTag read_chlo;
375 QuicDataReader reader(buffer, kBufferLength, GetParam().endianness);
376 reader.ReadTag(&read_chlo);
377 EXPECT_EQ(kCHLO, read_chlo);
378}
379
380TEST_P(QuicDataWriterTest, Write16BitUnsignedIntegers) {
381 char little_endian16[] = {0x22, 0x11};
382 char big_endian16[] = {0x11, 0x22};
383 char buffer16[2];
384 {
385 uint16_t in_memory16 = 0x1122;
386 QuicDataWriter writer(2, buffer16, GetParam().endianness);
387 writer.WriteUInt16(in_memory16);
388 test::CompareCharArraysWithHexError(
389 "uint16_t", buffer16, 2,
QUICHE team173c48f2019-11-19 16:34:44 -0800390 GetParam().endianness == quiche::NETWORK_BYTE_ORDER ? big_endian16
391 : little_endian16,
QUICHE teama6ef0a62019-03-07 20:34:33 -0500392 2);
393
394 uint16_t read_number16;
395 QuicDataReader reader(buffer16, 2, GetParam().endianness);
396 reader.ReadUInt16(&read_number16);
397 EXPECT_EQ(in_memory16, read_number16);
398 }
399
400 {
401 uint64_t in_memory16 = 0x0000000000001122;
402 QuicDataWriter writer(2, buffer16, GetParam().endianness);
403 writer.WriteBytesToUInt64(2, in_memory16);
404 test::CompareCharArraysWithHexError(
405 "uint16_t", buffer16, 2,
QUICHE team173c48f2019-11-19 16:34:44 -0800406 GetParam().endianness == quiche::NETWORK_BYTE_ORDER ? big_endian16
407 : little_endian16,
QUICHE teama6ef0a62019-03-07 20:34:33 -0500408 2);
409
410 uint64_t read_number16;
411 QuicDataReader reader(buffer16, 2, GetParam().endianness);
412 reader.ReadBytesToUInt64(2, &read_number16);
413 EXPECT_EQ(in_memory16, read_number16);
414 }
415}
416
417TEST_P(QuicDataWriterTest, Write24BitUnsignedIntegers) {
418 char little_endian24[] = {0x33, 0x22, 0x11};
419 char big_endian24[] = {0x11, 0x22, 0x33};
420 char buffer24[3];
421 uint64_t in_memory24 = 0x0000000000112233;
422 QuicDataWriter writer(3, buffer24, GetParam().endianness);
423 writer.WriteBytesToUInt64(3, in_memory24);
424 test::CompareCharArraysWithHexError(
425 "uint24", buffer24, 3,
QUICHE team173c48f2019-11-19 16:34:44 -0800426 GetParam().endianness == quiche::NETWORK_BYTE_ORDER ? big_endian24
427 : little_endian24,
QUICHE teama6ef0a62019-03-07 20:34:33 -0500428 3);
429
430 uint64_t read_number24;
431 QuicDataReader reader(buffer24, 3, GetParam().endianness);
432 reader.ReadBytesToUInt64(3, &read_number24);
433 EXPECT_EQ(in_memory24, read_number24);
434}
435
436TEST_P(QuicDataWriterTest, Write32BitUnsignedIntegers) {
437 char little_endian32[] = {0x44, 0x33, 0x22, 0x11};
438 char big_endian32[] = {0x11, 0x22, 0x33, 0x44};
439 char buffer32[4];
440 {
441 uint32_t in_memory32 = 0x11223344;
442 QuicDataWriter writer(4, buffer32, GetParam().endianness);
443 writer.WriteUInt32(in_memory32);
444 test::CompareCharArraysWithHexError(
445 "uint32_t", buffer32, 4,
QUICHE team173c48f2019-11-19 16:34:44 -0800446 GetParam().endianness == quiche::NETWORK_BYTE_ORDER ? big_endian32
447 : little_endian32,
QUICHE teama6ef0a62019-03-07 20:34:33 -0500448 4);
449
450 uint32_t read_number32;
451 QuicDataReader reader(buffer32, 4, GetParam().endianness);
452 reader.ReadUInt32(&read_number32);
453 EXPECT_EQ(in_memory32, read_number32);
454 }
455
456 {
457 uint64_t in_memory32 = 0x11223344;
458 QuicDataWriter writer(4, buffer32, GetParam().endianness);
459 writer.WriteBytesToUInt64(4, in_memory32);
460 test::CompareCharArraysWithHexError(
461 "uint32_t", buffer32, 4,
QUICHE team173c48f2019-11-19 16:34:44 -0800462 GetParam().endianness == quiche::NETWORK_BYTE_ORDER ? big_endian32
463 : little_endian32,
QUICHE teama6ef0a62019-03-07 20:34:33 -0500464 4);
465
466 uint64_t read_number32;
467 QuicDataReader reader(buffer32, 4, GetParam().endianness);
468 reader.ReadBytesToUInt64(4, &read_number32);
469 EXPECT_EQ(in_memory32, read_number32);
470 }
471}
472
473TEST_P(QuicDataWriterTest, Write40BitUnsignedIntegers) {
474 uint64_t in_memory40 = 0x0000001122334455;
475 char little_endian40[] = {0x55, 0x44, 0x33, 0x22, 0x11};
476 char big_endian40[] = {0x11, 0x22, 0x33, 0x44, 0x55};
477 char buffer40[5];
478 QuicDataWriter writer(5, buffer40, GetParam().endianness);
479 writer.WriteBytesToUInt64(5, in_memory40);
480 test::CompareCharArraysWithHexError(
481 "uint40", buffer40, 5,
QUICHE team173c48f2019-11-19 16:34:44 -0800482 GetParam().endianness == quiche::NETWORK_BYTE_ORDER ? big_endian40
483 : little_endian40,
QUICHE teama6ef0a62019-03-07 20:34:33 -0500484 5);
485
486 uint64_t read_number40;
487 QuicDataReader reader(buffer40, 5, GetParam().endianness);
488 reader.ReadBytesToUInt64(5, &read_number40);
489 EXPECT_EQ(in_memory40, read_number40);
490}
491
492TEST_P(QuicDataWriterTest, Write48BitUnsignedIntegers) {
493 uint64_t in_memory48 = 0x0000112233445566;
494 char little_endian48[] = {0x66, 0x55, 0x44, 0x33, 0x22, 0x11};
495 char big_endian48[] = {0x11, 0x22, 0x33, 0x44, 0x55, 0x66};
496 char buffer48[6];
497 QuicDataWriter writer(6, buffer48, GetParam().endianness);
498 writer.WriteBytesToUInt64(6, in_memory48);
499 test::CompareCharArraysWithHexError(
500 "uint48", buffer48, 6,
QUICHE team173c48f2019-11-19 16:34:44 -0800501 GetParam().endianness == quiche::NETWORK_BYTE_ORDER ? big_endian48
502 : little_endian48,
QUICHE teama6ef0a62019-03-07 20:34:33 -0500503 6);
504
505 uint64_t read_number48;
506 QuicDataReader reader(buffer48, 6, GetParam().endianness);
507 reader.ReadBytesToUInt64(6., &read_number48);
508 EXPECT_EQ(in_memory48, read_number48);
509}
510
511TEST_P(QuicDataWriterTest, Write56BitUnsignedIntegers) {
512 uint64_t in_memory56 = 0x0011223344556677;
513 char little_endian56[] = {0x77, 0x66, 0x55, 0x44, 0x33, 0x22, 0x11};
514 char big_endian56[] = {0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77};
515 char buffer56[7];
516 QuicDataWriter writer(7, buffer56, GetParam().endianness);
517 writer.WriteBytesToUInt64(7, in_memory56);
518 test::CompareCharArraysWithHexError(
519 "uint56", buffer56, 7,
QUICHE team173c48f2019-11-19 16:34:44 -0800520 GetParam().endianness == quiche::NETWORK_BYTE_ORDER ? big_endian56
521 : little_endian56,
QUICHE teama6ef0a62019-03-07 20:34:33 -0500522 7);
523
524 uint64_t read_number56;
525 QuicDataReader reader(buffer56, 7, GetParam().endianness);
526 reader.ReadBytesToUInt64(7, &read_number56);
527 EXPECT_EQ(in_memory56, read_number56);
528}
529
530TEST_P(QuicDataWriterTest, Write64BitUnsignedIntegers) {
531 uint64_t in_memory64 = 0x1122334455667788;
532 unsigned char little_endian64[] = {0x88, 0x77, 0x66, 0x55,
533 0x44, 0x33, 0x22, 0x11};
534 unsigned char big_endian64[] = {0x11, 0x22, 0x33, 0x44,
535 0x55, 0x66, 0x77, 0x88};
536 char buffer64[8];
537 QuicDataWriter writer(8, buffer64, GetParam().endianness);
538 writer.WriteBytesToUInt64(8, in_memory64);
539 test::CompareCharArraysWithHexError(
540 "uint64_t", buffer64, 8,
QUICHE team173c48f2019-11-19 16:34:44 -0800541 GetParam().endianness == quiche::NETWORK_BYTE_ORDER
542 ? AsChars(big_endian64)
543 : AsChars(little_endian64),
QUICHE teama6ef0a62019-03-07 20:34:33 -0500544 8);
545
546 uint64_t read_number64;
547 QuicDataReader reader(buffer64, 8, GetParam().endianness);
548 reader.ReadBytesToUInt64(8, &read_number64);
549 EXPECT_EQ(in_memory64, read_number64);
550
551 QuicDataWriter writer2(8, buffer64, GetParam().endianness);
552 writer2.WriteUInt64(in_memory64);
553 test::CompareCharArraysWithHexError(
554 "uint64_t", buffer64, 8,
QUICHE team173c48f2019-11-19 16:34:44 -0800555 GetParam().endianness == quiche::NETWORK_BYTE_ORDER
556 ? AsChars(big_endian64)
557 : AsChars(little_endian64),
QUICHE teama6ef0a62019-03-07 20:34:33 -0500558 8);
559 read_number64 = 0u;
560 QuicDataReader reader2(buffer64, 8, GetParam().endianness);
561 reader2.ReadUInt64(&read_number64);
562 EXPECT_EQ(in_memory64, read_number64);
563}
564
565TEST_P(QuicDataWriterTest, WriteIntegers) {
566 char buf[43];
567 uint8_t i8 = 0x01;
568 uint16_t i16 = 0x0123;
569 uint32_t i32 = 0x01234567;
570 uint64_t i64 = 0x0123456789ABCDEF;
571 QuicDataWriter writer(46, buf, GetParam().endianness);
572 for (size_t i = 0; i < 10; ++i) {
573 switch (i) {
574 case 0u:
575 EXPECT_TRUE(writer.WriteBytesToUInt64(i, i64));
576 break;
577 case 1u:
578 EXPECT_TRUE(writer.WriteUInt8(i8));
579 EXPECT_TRUE(writer.WriteBytesToUInt64(i, i64));
580 break;
581 case 2u:
582 EXPECT_TRUE(writer.WriteUInt16(i16));
583 EXPECT_TRUE(writer.WriteBytesToUInt64(i, i64));
584 break;
585 case 3u:
586 EXPECT_TRUE(writer.WriteBytesToUInt64(i, i64));
587 break;
588 case 4u:
589 EXPECT_TRUE(writer.WriteUInt32(i32));
590 EXPECT_TRUE(writer.WriteBytesToUInt64(i, i64));
591 break;
592 case 5u:
593 case 6u:
594 case 7u:
595 case 8u:
596 EXPECT_TRUE(writer.WriteBytesToUInt64(i, i64));
597 break;
598 default:
599 EXPECT_FALSE(writer.WriteBytesToUInt64(i, i64));
600 }
601 }
602
603 QuicDataReader reader(buf, 46, GetParam().endianness);
604 for (size_t i = 0; i < 10; ++i) {
605 uint8_t read8;
606 uint16_t read16;
607 uint32_t read32;
608 uint64_t read64;
609 switch (i) {
610 case 0u:
611 EXPECT_TRUE(reader.ReadBytesToUInt64(i, &read64));
612 EXPECT_EQ(0u, read64);
613 break;
614 case 1u:
615 EXPECT_TRUE(reader.ReadUInt8(&read8));
616 EXPECT_TRUE(reader.ReadBytesToUInt64(i, &read64));
617 EXPECT_EQ(i8, read8);
618 EXPECT_EQ(0xEFu, read64);
619 break;
620 case 2u:
621 EXPECT_TRUE(reader.ReadUInt16(&read16));
622 EXPECT_TRUE(reader.ReadBytesToUInt64(i, &read64));
623 EXPECT_EQ(i16, read16);
624 EXPECT_EQ(0xCDEFu, read64);
625 break;
626 case 3u:
627 EXPECT_TRUE(reader.ReadBytesToUInt64(i, &read64));
628 EXPECT_EQ(0xABCDEFu, read64);
629 break;
630 case 4u:
631 EXPECT_TRUE(reader.ReadUInt32(&read32));
632 EXPECT_TRUE(reader.ReadBytesToUInt64(i, &read64));
633 EXPECT_EQ(i32, read32);
634 EXPECT_EQ(0x89ABCDEFu, read64);
635 break;
636 case 5u:
637 EXPECT_TRUE(reader.ReadBytesToUInt64(i, &read64));
638 EXPECT_EQ(0x6789ABCDEFu, read64);
639 break;
640 case 6u:
641 EXPECT_TRUE(reader.ReadBytesToUInt64(i, &read64));
642 EXPECT_EQ(0x456789ABCDEFu, read64);
643 break;
644 case 7u:
645 EXPECT_TRUE(reader.ReadBytesToUInt64(i, &read64));
646 EXPECT_EQ(0x23456789ABCDEFu, read64);
647 break;
648 case 8u:
649 EXPECT_TRUE(reader.ReadBytesToUInt64(i, &read64));
650 EXPECT_EQ(0x0123456789ABCDEFu, read64);
651 break;
652 default:
653 EXPECT_FALSE(reader.ReadBytesToUInt64(i, &read64));
654 }
655 }
656}
657
658TEST_P(QuicDataWriterTest, WriteBytes) {
659 char bytes[] = {0, 1, 2, 3, 4, 5, 6, 7, 8};
660 char buf[QUIC_ARRAYSIZE(bytes)];
661 QuicDataWriter writer(QUIC_ARRAYSIZE(buf), buf, GetParam().endianness);
662 EXPECT_TRUE(writer.WriteBytes(bytes, QUIC_ARRAYSIZE(bytes)));
663 for (unsigned int i = 0; i < QUIC_ARRAYSIZE(bytes); ++i) {
664 EXPECT_EQ(bytes[i], buf[i]);
665 }
666}
667
668const int kVarIntBufferLength = 1024;
669
670// Encodes and then decodes a specified value, checks that the
671// value that was encoded is the same as the decoded value, the length
672// is correct, and that after decoding, all data in the buffer has
673// been consumed..
674// Returns true if everything works, false if not.
675bool EncodeDecodeValue(uint64_t value_in, char* buffer, size_t size_of_buffer) {
676 // Init the buffer to all 0, just for cleanliness. Makes for better
677 // output if, in debugging, we need to dump out the buffer.
678 memset(buffer, 0, size_of_buffer);
679 // make a writer. Note that for IETF encoding
680 // we do not care about endianness... It's always big-endian,
681 // but the c'tor expects to be told what endianness is in force...
QUICHE team173c48f2019-11-19 16:34:44 -0800682 QuicDataWriter writer(size_of_buffer, buffer,
683 quiche::Endianness::NETWORK_BYTE_ORDER);
QUICHE teama6ef0a62019-03-07 20:34:33 -0500684
685 // Try to write the value.
686 if (writer.WriteVarInt62(value_in) != true) {
687 return false;
688 }
689 // Look at the value we encoded. Determine how much should have been
690 // used based on the value, and then check the state of the writer
691 // to see that it matches.
692 size_t expected_length = 0;
693 if (value_in <= 0x3f) {
694 expected_length = 1;
695 } else if (value_in <= 0x3fff) {
696 expected_length = 2;
697 } else if (value_in <= 0x3fffffff) {
698 expected_length = 4;
699 } else {
700 expected_length = 8;
701 }
702 if (writer.length() != expected_length) {
703 return false;
704 }
705
706 // set up a reader, just the length we've used, no more, no less.
707 QuicDataReader reader(buffer, expected_length,
QUICHE team173c48f2019-11-19 16:34:44 -0800708 quiche::Endianness::NETWORK_BYTE_ORDER);
QUICHE teama6ef0a62019-03-07 20:34:33 -0500709 uint64_t value_out;
710
711 if (reader.ReadVarInt62(&value_out) == false) {
712 return false;
713 }
714 if (value_in != value_out) {
715 return false;
716 }
717 // We only write one value so there had better be nothing left to read
718 return reader.IsDoneReading();
719}
720
721// Test that 8-byte-encoded Variable Length Integers are properly laid
722// out in the buffer.
723TEST_P(QuicDataWriterTest, VarInt8Layout) {
724 char buffer[1024];
725
726 // Check that the layout of bytes in the buffer is correct. Bytes
727 // are always encoded big endian...
728 memset(buffer, 0, sizeof(buffer));
729 QuicDataWriter writer(sizeof(buffer), static_cast<char*>(buffer),
QUICHE team173c48f2019-11-19 16:34:44 -0800730 quiche::Endianness::NETWORK_BYTE_ORDER);
QUICHE teama6ef0a62019-03-07 20:34:33 -0500731 EXPECT_TRUE(writer.WriteVarInt62(UINT64_C(0x3142f3e4d5c6b7a8)));
732 EXPECT_EQ(static_cast<unsigned char>(*(writer.data() + 0)),
733 (0x31 + 0xc0)); // 0xc0 for encoding
734 EXPECT_EQ(static_cast<unsigned char>(*(writer.data() + 1)), 0x42);
735 EXPECT_EQ(static_cast<unsigned char>(*(writer.data() + 2)), 0xf3);
736 EXPECT_EQ(static_cast<unsigned char>(*(writer.data() + 3)), 0xe4);
737 EXPECT_EQ(static_cast<unsigned char>(*(writer.data() + 4)), 0xd5);
738 EXPECT_EQ(static_cast<unsigned char>(*(writer.data() + 5)), 0xc6);
739 EXPECT_EQ(static_cast<unsigned char>(*(writer.data() + 6)), 0xb7);
740 EXPECT_EQ(static_cast<unsigned char>(*(writer.data() + 7)), 0xa8);
741}
742
743// Test that 4-byte-encoded Variable Length Integers are properly laid
744// out in the buffer.
745TEST_P(QuicDataWriterTest, VarInt4Layout) {
746 char buffer[1024];
747
748 // Check that the layout of bytes in the buffer is correct. Bytes
749 // are always encoded big endian...
750 memset(buffer, 0, sizeof(buffer));
751 QuicDataWriter writer(sizeof(buffer), static_cast<char*>(buffer),
QUICHE team173c48f2019-11-19 16:34:44 -0800752 quiche::Endianness::NETWORK_BYTE_ORDER);
QUICHE teama6ef0a62019-03-07 20:34:33 -0500753 EXPECT_TRUE(writer.WriteVarInt62(0x3243f4e5));
754 EXPECT_EQ(static_cast<unsigned char>(*(writer.data() + 0)),
755 (0x32 + 0x80)); // 0x80 for encoding
756 EXPECT_EQ(static_cast<unsigned char>(*(writer.data() + 1)), 0x43);
757 EXPECT_EQ(static_cast<unsigned char>(*(writer.data() + 2)), 0xf4);
758 EXPECT_EQ(static_cast<unsigned char>(*(writer.data() + 3)), 0xe5);
759}
760
761// Test that 2-byte-encoded Variable Length Integers are properly laid
762// out in the buffer.
763TEST_P(QuicDataWriterTest, VarInt2Layout) {
764 char buffer[1024];
765
766 // Check that the layout of bytes in the buffer is correct. Bytes
767 // are always encoded big endian...
768 memset(buffer, 0, sizeof(buffer));
769 QuicDataWriter writer(sizeof(buffer), static_cast<char*>(buffer),
QUICHE team173c48f2019-11-19 16:34:44 -0800770 quiche::Endianness::NETWORK_BYTE_ORDER);
QUICHE teama6ef0a62019-03-07 20:34:33 -0500771 EXPECT_TRUE(writer.WriteVarInt62(0x3647));
772 EXPECT_EQ(static_cast<unsigned char>(*(writer.data() + 0)),
773 (0x36 + 0x40)); // 0x40 for encoding
774 EXPECT_EQ(static_cast<unsigned char>(*(writer.data() + 1)), 0x47);
775}
776
777// Test that 1-byte-encoded Variable Length Integers are properly laid
778// out in the buffer.
779TEST_P(QuicDataWriterTest, VarInt1Layout) {
780 char buffer[1024];
781
782 // Check that the layout of bytes in the buffer
783 // is correct. Bytes are always encoded big endian...
784 memset(buffer, 0, sizeof(buffer));
785 QuicDataWriter writer(sizeof(buffer), static_cast<char*>(buffer),
QUICHE team173c48f2019-11-19 16:34:44 -0800786 quiche::Endianness::NETWORK_BYTE_ORDER);
QUICHE teama6ef0a62019-03-07 20:34:33 -0500787 EXPECT_TRUE(writer.WriteVarInt62(0x3f));
788 EXPECT_EQ(static_cast<unsigned char>(*(writer.data() + 0)), 0x3f);
789}
790
791// Test certain, targeted, values that are expected to succeed:
792// 0, 1,
793// 0x3e, 0x3f, 0x40, 0x41 (around the 1-2 byte transitions)
794// 0x3ffe, 0x3fff, 0x4000, 0x4001 (the 2-4 byte transition)
795// 0x3ffffffe, 0x3fffffff, 0x40000000, 0x40000001 (the 4-8 byte
796// transition)
797// 0x3ffffffffffffffe, 0x3fffffffffffffff, (the highest valid values)
798// 0xfe, 0xff, 0x100, 0x101,
799// 0xfffe, 0xffff, 0x10000, 0x10001,
800// 0xfffffe, 0xffffff, 0x1000000, 0x1000001,
801// 0xfffffffe, 0xffffffff, 0x100000000, 0x100000001,
802// 0xfffffffffe, 0xffffffffff, 0x10000000000, 0x10000000001,
803// 0xfffffffffffe, 0xffffffffffff, 0x1000000000000, 0x1000000000001,
804// 0xfffffffffffffe, 0xffffffffffffff, 0x100000000000000, 0x100000000000001,
805TEST_P(QuicDataWriterTest, VarIntGoodTargetedValues) {
806 char buffer[kVarIntBufferLength];
807 uint64_t passing_values[] = {
808 0,
809 1,
810 0x3e,
811 0x3f,
812 0x40,
813 0x41,
814 0x3ffe,
815 0x3fff,
816 0x4000,
817 0x4001,
818 0x3ffffffe,
819 0x3fffffff,
820 0x40000000,
821 0x40000001,
822 0x3ffffffffffffffe,
823 0x3fffffffffffffff,
824 0xfe,
825 0xff,
826 0x100,
827 0x101,
828 0xfffe,
829 0xffff,
830 0x10000,
831 0x10001,
832 0xfffffe,
833 0xffffff,
834 0x1000000,
835 0x1000001,
836 0xfffffffe,
837 0xffffffff,
838 0x100000000,
839 0x100000001,
840 0xfffffffffe,
841 0xffffffffff,
842 0x10000000000,
843 0x10000000001,
844 0xfffffffffffe,
845 0xffffffffffff,
846 0x1000000000000,
847 0x1000000000001,
848 0xfffffffffffffe,
849 0xffffffffffffff,
850 0x100000000000000,
851 0x100000000000001,
852 };
853 for (uint64_t test_val : passing_values) {
854 EXPECT_TRUE(
855 EncodeDecodeValue(test_val, static_cast<char*>(buffer), sizeof(buffer)))
856 << " encode/decode of " << test_val << " failed";
857 }
858}
859//
860// Test certain, targeted, values where failure is expected (the
861// values are invalid w.r.t. IETF VarInt encoding):
862// 0x4000000000000000, 0x4000000000000001, ( Just above max allowed value)
863// 0xfffffffffffffffe, 0xffffffffffffffff, (should fail)
864TEST_P(QuicDataWriterTest, VarIntBadTargetedValues) {
865 char buffer[kVarIntBufferLength];
866 uint64_t failing_values[] = {
867 0x4000000000000000,
868 0x4000000000000001,
869 0xfffffffffffffffe,
870 0xffffffffffffffff,
871 };
872 for (uint64_t test_val : failing_values) {
873 EXPECT_FALSE(
874 EncodeDecodeValue(test_val, static_cast<char*>(buffer), sizeof(buffer)))
875 << " encode/decode of " << test_val << " succeeded, but was an "
876 << "invalid value";
877 }
878}
879
880// Following tests all try to fill the buffer with multiple values,
881// go one value more than the buffer can accommodate, then read
882// the successfully encoded values, and try to read the unsuccessfully
883// encoded value. The following is the number of values to encode.
884const int kMultiVarCount = 1000;
885
886// Test writing & reading multiple 8-byte-encoded varints
887TEST_P(QuicDataWriterTest, MultiVarInt8) {
888 uint64_t test_val;
889 char buffer[8 * kMultiVarCount];
890 memset(buffer, 0, sizeof(buffer));
891 QuicDataWriter writer(sizeof(buffer), static_cast<char*>(buffer),
QUICHE team173c48f2019-11-19 16:34:44 -0800892 quiche::Endianness::NETWORK_BYTE_ORDER);
QUICHE teama6ef0a62019-03-07 20:34:33 -0500893 // Put N values into the buffer. Adding i to the value ensures that
894 // each value is different so we can detect if we overwrite values,
895 // or read the same value over and over.
896 for (int i = 0; i < kMultiVarCount; i++) {
897 EXPECT_TRUE(writer.WriteVarInt62(UINT64_C(0x3142f3e4d5c6b7a8) + i));
898 }
899 EXPECT_EQ(writer.length(), 8u * kMultiVarCount);
900
901 // N+1st should fail, the buffer is full.
902 EXPECT_FALSE(writer.WriteVarInt62(UINT64_C(0x3142f3e4d5c6b7a8)));
903
904 // Now we should be able to read out the N values that were
905 // successfully encoded.
QUICHE team173c48f2019-11-19 16:34:44 -0800906 QuicDataReader reader(buffer, sizeof(buffer),
907 quiche::Endianness::NETWORK_BYTE_ORDER);
QUICHE teama6ef0a62019-03-07 20:34:33 -0500908 for (int i = 0; i < kMultiVarCount; i++) {
909 EXPECT_TRUE(reader.ReadVarInt62(&test_val));
910 EXPECT_EQ(test_val, (UINT64_C(0x3142f3e4d5c6b7a8) + i));
911 }
912 // And the N+1st should fail.
913 EXPECT_FALSE(reader.ReadVarInt62(&test_val));
914}
915
916// Test writing & reading multiple 4-byte-encoded varints
917TEST_P(QuicDataWriterTest, MultiVarInt4) {
918 uint64_t test_val;
919 char buffer[4 * kMultiVarCount];
920 memset(buffer, 0, sizeof(buffer));
921 QuicDataWriter writer(sizeof(buffer), static_cast<char*>(buffer),
QUICHE team173c48f2019-11-19 16:34:44 -0800922 quiche::Endianness::NETWORK_BYTE_ORDER);
QUICHE teama6ef0a62019-03-07 20:34:33 -0500923 // Put N values into the buffer. Adding i to the value ensures that
924 // each value is different so we can detect if we overwrite values,
925 // or read the same value over and over.
926 for (int i = 0; i < kMultiVarCount; i++) {
927 EXPECT_TRUE(writer.WriteVarInt62(UINT64_C(0x3142f3e4) + i));
928 }
929 EXPECT_EQ(writer.length(), 4u * kMultiVarCount);
930
931 // N+1st should fail, the buffer is full.
932 EXPECT_FALSE(writer.WriteVarInt62(UINT64_C(0x3142f3e4)));
933
934 // Now we should be able to read out the N values that were
935 // successfully encoded.
QUICHE team173c48f2019-11-19 16:34:44 -0800936 QuicDataReader reader(buffer, sizeof(buffer),
937 quiche::Endianness::NETWORK_BYTE_ORDER);
QUICHE teama6ef0a62019-03-07 20:34:33 -0500938 for (int i = 0; i < kMultiVarCount; i++) {
939 EXPECT_TRUE(reader.ReadVarInt62(&test_val));
940 EXPECT_EQ(test_val, (UINT64_C(0x3142f3e4) + i));
941 }
942 // And the N+1st should fail.
943 EXPECT_FALSE(reader.ReadVarInt62(&test_val));
944}
945
946// Test writing & reading multiple 2-byte-encoded varints
947TEST_P(QuicDataWriterTest, MultiVarInt2) {
948 uint64_t test_val;
949 char buffer[2 * kMultiVarCount];
950 memset(buffer, 0, sizeof(buffer));
951 QuicDataWriter writer(sizeof(buffer), static_cast<char*>(buffer),
QUICHE team173c48f2019-11-19 16:34:44 -0800952 quiche::Endianness::NETWORK_BYTE_ORDER);
QUICHE teama6ef0a62019-03-07 20:34:33 -0500953 // Put N values into the buffer. Adding i to the value ensures that
954 // each value is different so we can detect if we overwrite values,
955 // or read the same value over and over.
956 for (int i = 0; i < kMultiVarCount; i++) {
957 EXPECT_TRUE(writer.WriteVarInt62(UINT64_C(0x3142) + i));
958 }
959 EXPECT_EQ(writer.length(), 2u * kMultiVarCount);
960
961 // N+1st should fail, the buffer is full.
962 EXPECT_FALSE(writer.WriteVarInt62(UINT64_C(0x3142)));
963
964 // Now we should be able to read out the N values that were
965 // successfully encoded.
QUICHE team173c48f2019-11-19 16:34:44 -0800966 QuicDataReader reader(buffer, sizeof(buffer),
967 quiche::Endianness::NETWORK_BYTE_ORDER);
QUICHE teama6ef0a62019-03-07 20:34:33 -0500968 for (int i = 0; i < kMultiVarCount; i++) {
969 EXPECT_TRUE(reader.ReadVarInt62(&test_val));
970 EXPECT_EQ(test_val, (UINT64_C(0x3142) + i));
971 }
972 // And the N+1st should fail.
973 EXPECT_FALSE(reader.ReadVarInt62(&test_val));
974}
975
976// Test writing & reading multiple 1-byte-encoded varints
977TEST_P(QuicDataWriterTest, MultiVarInt1) {
978 uint64_t test_val;
979 char buffer[1 * kMultiVarCount];
980 memset(buffer, 0, sizeof(buffer));
981 QuicDataWriter writer(sizeof(buffer), static_cast<char*>(buffer),
QUICHE team173c48f2019-11-19 16:34:44 -0800982 quiche::Endianness::NETWORK_BYTE_ORDER);
QUICHE teama6ef0a62019-03-07 20:34:33 -0500983 // Put N values into the buffer. Adding i to the value ensures that
984 // each value is different so we can detect if we overwrite values,
985 // or read the same value over and over. &0xf ensures we do not
986 // overflow the max value for single-byte encoding.
987 for (int i = 0; i < kMultiVarCount; i++) {
988 EXPECT_TRUE(writer.WriteVarInt62(UINT64_C(0x30) + (i & 0xf)));
989 }
990 EXPECT_EQ(writer.length(), 1u * kMultiVarCount);
991
992 // N+1st should fail, the buffer is full.
993 EXPECT_FALSE(writer.WriteVarInt62(UINT64_C(0x31)));
994
995 // Now we should be able to read out the N values that were
996 // successfully encoded.
QUICHE team173c48f2019-11-19 16:34:44 -0800997 QuicDataReader reader(buffer, sizeof(buffer),
998 quiche::Endianness::NETWORK_BYTE_ORDER);
QUICHE teama6ef0a62019-03-07 20:34:33 -0500999 for (int i = 0; i < kMultiVarCount; i++) {
1000 EXPECT_TRUE(reader.ReadVarInt62(&test_val));
1001 EXPECT_EQ(test_val, (UINT64_C(0x30) + (i & 0xf)));
1002 }
1003 // And the N+1st should fail.
1004 EXPECT_FALSE(reader.ReadVarInt62(&test_val));
1005}
1006
1007// Test writing varints with a forced length.
1008TEST_P(QuicDataWriterTest, VarIntFixedLength) {
1009 char buffer[90];
1010 memset(buffer, 0, sizeof(buffer));
1011 QuicDataWriter writer(sizeof(buffer), static_cast<char*>(buffer),
QUICHE team173c48f2019-11-19 16:34:44 -08001012 quiche::Endianness::NETWORK_BYTE_ORDER);
QUICHE teama6ef0a62019-03-07 20:34:33 -05001013
1014 writer.WriteVarInt62(1, VARIABLE_LENGTH_INTEGER_LENGTH_1);
1015 writer.WriteVarInt62(1, VARIABLE_LENGTH_INTEGER_LENGTH_2);
1016 writer.WriteVarInt62(1, VARIABLE_LENGTH_INTEGER_LENGTH_4);
1017 writer.WriteVarInt62(1, VARIABLE_LENGTH_INTEGER_LENGTH_8);
1018
1019 writer.WriteVarInt62(63, VARIABLE_LENGTH_INTEGER_LENGTH_1);
1020 writer.WriteVarInt62(63, VARIABLE_LENGTH_INTEGER_LENGTH_2);
1021 writer.WriteVarInt62(63, VARIABLE_LENGTH_INTEGER_LENGTH_4);
1022 writer.WriteVarInt62(63, VARIABLE_LENGTH_INTEGER_LENGTH_8);
1023
1024 writer.WriteVarInt62(64, VARIABLE_LENGTH_INTEGER_LENGTH_2);
1025 writer.WriteVarInt62(64, VARIABLE_LENGTH_INTEGER_LENGTH_4);
1026 writer.WriteVarInt62(64, VARIABLE_LENGTH_INTEGER_LENGTH_8);
1027
1028 writer.WriteVarInt62(16383, VARIABLE_LENGTH_INTEGER_LENGTH_2);
1029 writer.WriteVarInt62(16383, VARIABLE_LENGTH_INTEGER_LENGTH_4);
1030 writer.WriteVarInt62(16383, VARIABLE_LENGTH_INTEGER_LENGTH_8);
1031
1032 writer.WriteVarInt62(16384, VARIABLE_LENGTH_INTEGER_LENGTH_4);
1033 writer.WriteVarInt62(16384, VARIABLE_LENGTH_INTEGER_LENGTH_8);
1034
1035 writer.WriteVarInt62(1073741823, VARIABLE_LENGTH_INTEGER_LENGTH_4);
1036 writer.WriteVarInt62(1073741823, VARIABLE_LENGTH_INTEGER_LENGTH_8);
1037
1038 writer.WriteVarInt62(1073741824, VARIABLE_LENGTH_INTEGER_LENGTH_8);
1039
QUICHE team173c48f2019-11-19 16:34:44 -08001040 QuicDataReader reader(buffer, sizeof(buffer),
1041 quiche::Endianness::NETWORK_BYTE_ORDER);
QUICHE teama6ef0a62019-03-07 20:34:33 -05001042
1043 uint64_t test_val = 0;
1044 for (int i = 0; i < 4; ++i) {
1045 EXPECT_TRUE(reader.ReadVarInt62(&test_val));
1046 EXPECT_EQ(test_val, 1u);
1047 }
1048 for (int i = 0; i < 4; ++i) {
1049 EXPECT_TRUE(reader.ReadVarInt62(&test_val));
1050 EXPECT_EQ(test_val, 63u);
1051 }
1052
1053 for (int i = 0; i < 3; ++i) {
1054 EXPECT_TRUE(reader.ReadVarInt62(&test_val));
1055 EXPECT_EQ(test_val, 64u);
1056 }
1057 for (int i = 0; i < 3; ++i) {
1058 EXPECT_TRUE(reader.ReadVarInt62(&test_val));
1059 EXPECT_EQ(test_val, 16383u);
1060 }
1061
1062 for (int i = 0; i < 2; ++i) {
1063 EXPECT_TRUE(reader.ReadVarInt62(&test_val));
1064 EXPECT_EQ(test_val, 16384u);
1065 }
1066 for (int i = 0; i < 2; ++i) {
1067 EXPECT_TRUE(reader.ReadVarInt62(&test_val));
1068 EXPECT_EQ(test_val, 1073741823u);
1069 }
1070
1071 EXPECT_TRUE(reader.ReadVarInt62(&test_val));
1072 EXPECT_EQ(test_val, 1073741824u);
1073
1074 // We are at the end of the buffer so this should fail.
1075 EXPECT_FALSE(reader.ReadVarInt62(&test_val));
1076}
1077
1078// Test encoding/decoding stream-id values.
1079void EncodeDecodeStreamId(uint64_t value_in, bool expected_decode_result) {
1080 char buffer[1 * kMultiVarCount];
1081 memset(buffer, 0, sizeof(buffer));
1082
1083 // Encode the given Stream ID.
1084 QuicDataWriter writer(sizeof(buffer), static_cast<char*>(buffer),
QUICHE team173c48f2019-11-19 16:34:44 -08001085 quiche::Endianness::NETWORK_BYTE_ORDER);
QUICHE teama6ef0a62019-03-07 20:34:33 -05001086 EXPECT_TRUE(writer.WriteVarInt62(value_in));
1087
QUICHE team173c48f2019-11-19 16:34:44 -08001088 QuicDataReader reader(buffer, sizeof(buffer),
1089 quiche::Endianness::NETWORK_BYTE_ORDER);
QUICHE teama6ef0a62019-03-07 20:34:33 -05001090 QuicStreamId received_stream_id;
fkastenholz3c4eabf2019-04-22 07:49:59 -07001091 bool read_result = reader.ReadVarIntU32(&received_stream_id);
QUICHE teama6ef0a62019-03-07 20:34:33 -05001092 EXPECT_EQ(expected_decode_result, read_result);
1093 if (read_result) {
1094 EXPECT_EQ(value_in, received_stream_id);
1095 }
1096}
1097
1098// Test writing & reading stream-ids of various value.
1099TEST_P(QuicDataWriterTest, StreamId1) {
1100 // Check a 1-byte QuicStreamId, should work
1101 EncodeDecodeStreamId(UINT64_C(0x15), true);
1102
1103 // Check a 2-byte QuicStream ID. It should work.
1104 EncodeDecodeStreamId(UINT64_C(0x1567), true);
1105
1106 // Check a QuicStreamId that requires 4 bytes of encoding
1107 // This should work.
1108 EncodeDecodeStreamId(UINT64_C(0x34567890), true);
1109
1110 // Check a QuicStreamId that requires 8 bytes of encoding
1111 // but whose value is in the acceptable range.
1112 // This should work.
1113 EncodeDecodeStreamId(UINT64_C(0xf4567890), true);
1114
1115 // Check QuicStreamIds that require 8 bytes of encoding
1116 // and whose value is not acceptable.
1117 // This should fail.
1118 EncodeDecodeStreamId(UINT64_C(0x100000000), false);
1119 EncodeDecodeStreamId(UINT64_C(0x3fffffffffffffff), false);
1120}
1121
1122TEST_P(QuicDataWriterTest, WriteRandomBytes) {
1123 char buffer[20];
1124 char expected[20];
1125 for (size_t i = 0; i < 20; ++i) {
1126 expected[i] = 'r';
1127 }
1128 MockRandom random;
1129 QuicDataWriter writer(20, buffer, GetParam().endianness);
1130 EXPECT_FALSE(writer.WriteRandomBytes(&random, 30));
1131
1132 EXPECT_TRUE(writer.WriteRandomBytes(&random, 20));
1133 test::CompareCharArraysWithHexError("random", buffer, 20, expected, 20);
1134}
1135
1136TEST_P(QuicDataWriterTest, PeekVarInt62Length) {
1137 // In range [0, 63], variable length should be 1 byte.
1138 char buffer[20];
QUICHE team173c48f2019-11-19 16:34:44 -08001139 QuicDataWriter writer(20, buffer, quiche::NETWORK_BYTE_ORDER);
QUICHE teama6ef0a62019-03-07 20:34:33 -05001140 EXPECT_TRUE(writer.WriteVarInt62(50));
QUICHE team173c48f2019-11-19 16:34:44 -08001141 QuicDataReader reader(buffer, 20, quiche::NETWORK_BYTE_ORDER);
QUICHE teama6ef0a62019-03-07 20:34:33 -05001142 EXPECT_EQ(1, reader.PeekVarInt62Length());
1143 // In range (63-16383], variable length should be 2 byte2.
1144 char buffer2[20];
QUICHE team173c48f2019-11-19 16:34:44 -08001145 QuicDataWriter writer2(20, buffer2, quiche::NETWORK_BYTE_ORDER);
QUICHE teama6ef0a62019-03-07 20:34:33 -05001146 EXPECT_TRUE(writer2.WriteVarInt62(100));
QUICHE team173c48f2019-11-19 16:34:44 -08001147 QuicDataReader reader2(buffer2, 20, quiche::NETWORK_BYTE_ORDER);
QUICHE teama6ef0a62019-03-07 20:34:33 -05001148 EXPECT_EQ(2, reader2.PeekVarInt62Length());
1149 // In range (16383, 1073741823], variable length should be 4 bytes.
1150 char buffer3[20];
QUICHE team173c48f2019-11-19 16:34:44 -08001151 QuicDataWriter writer3(20, buffer3, quiche::NETWORK_BYTE_ORDER);
QUICHE teama6ef0a62019-03-07 20:34:33 -05001152 EXPECT_TRUE(writer3.WriteVarInt62(20000));
QUICHE team173c48f2019-11-19 16:34:44 -08001153 QuicDataReader reader3(buffer3, 20, quiche::NETWORK_BYTE_ORDER);
QUICHE teama6ef0a62019-03-07 20:34:33 -05001154 EXPECT_EQ(4, reader3.PeekVarInt62Length());
1155 // In range (1073741823, 4611686018427387903], variable length should be 8
1156 // bytes.
1157 char buffer4[20];
QUICHE team173c48f2019-11-19 16:34:44 -08001158 QuicDataWriter writer4(20, buffer4, quiche::NETWORK_BYTE_ORDER);
QUICHE teama6ef0a62019-03-07 20:34:33 -05001159 EXPECT_TRUE(writer4.WriteVarInt62(2000000000));
QUICHE team173c48f2019-11-19 16:34:44 -08001160 QuicDataReader reader4(buffer4, 20, quiche::NETWORK_BYTE_ORDER);
QUICHE teama6ef0a62019-03-07 20:34:33 -05001161 EXPECT_EQ(8, reader4.PeekVarInt62Length());
1162}
1163
QUICHE team0131a5b2019-03-20 15:23:27 -07001164TEST_P(QuicDataWriterTest, InvalidConnectionIdLengthRead) {
dschinazib953d022019-08-01 18:05:58 -07001165 static const uint8_t bad_connection_id_length = 200;
dschinazib012d212019-08-01 18:07:26 -07001166 static_assert(
1167 bad_connection_id_length > kQuicMaxConnectionIdAllVersionsLength,
1168 "bad lengths");
dschinazib953d022019-08-01 18:05:58 -07001169 char buffer[255] = {};
1170 QuicDataReader reader(buffer, sizeof(buffer));
QUICHE team0131a5b2019-03-20 15:23:27 -07001171 QuicConnectionId connection_id;
1172 bool ok;
1173 EXPECT_QUIC_BUG(
1174 ok = reader.ReadConnectionId(&connection_id, bad_connection_id_length),
1175 QuicStrCat("Attempted to read connection ID with length too high ",
1176 static_cast<int>(bad_connection_id_length)));
1177 EXPECT_FALSE(ok);
1178}
1179
fkastenholz3c4eabf2019-04-22 07:49:59 -07001180// Test that ReadVarIntU32 works properly. Tests a valid stream count
1181// (a 32 bit number) and an invalid one (a >32 bit number)
1182TEST_P(QuicDataWriterTest, ValidU32) {
1183 char buffer[1024];
1184 memset(buffer, 0, sizeof(buffer));
1185 QuicDataWriter writer(sizeof(buffer), static_cast<char*>(buffer),
QUICHE team173c48f2019-11-19 16:34:44 -08001186 quiche::Endianness::NETWORK_BYTE_ORDER);
fkastenholz3c4eabf2019-04-22 07:49:59 -07001187 QuicDataReader reader(buffer, sizeof(buffer));
1188 const QuicStreamCount write_stream_count = 0xffeeddcc;
1189 EXPECT_TRUE(writer.WriteVarInt62(write_stream_count));
1190 QuicStreamCount read_stream_count;
1191 EXPECT_TRUE(reader.ReadVarIntU32(&read_stream_count));
1192 EXPECT_EQ(write_stream_count, read_stream_count);
1193}
1194
1195TEST_P(QuicDataWriterTest, InvalidU32) {
1196 char buffer[1024];
1197 memset(buffer, 0, sizeof(buffer));
1198 QuicDataWriter writer(sizeof(buffer), static_cast<char*>(buffer),
QUICHE team173c48f2019-11-19 16:34:44 -08001199 quiche::Endianness::NETWORK_BYTE_ORDER);
fkastenholz3c4eabf2019-04-22 07:49:59 -07001200 QuicDataReader reader(buffer, sizeof(buffer));
1201 EXPECT_TRUE(writer.WriteVarInt62(UINT64_C(0x1ffeeddcc)));
1202 QuicStreamCount read_stream_count = 123456;
1203 EXPECT_FALSE(reader.ReadVarIntU32(&read_stream_count));
1204 // If the value is bad, read_stream_count ought not change.
1205 EXPECT_EQ(123456u, read_stream_count);
1206}
1207
nharper55fa6132019-05-07 19:37:21 -07001208TEST_P(QuicDataWriterTest, Seek) {
1209 char buffer[3] = {};
1210 QuicDataWriter writer(QUIC_ARRAYSIZE(buffer), buffer, GetParam().endianness);
1211 EXPECT_TRUE(writer.WriteUInt8(42));
1212 EXPECT_TRUE(writer.Seek(1));
1213 EXPECT_TRUE(writer.WriteUInt8(3));
1214
1215 char expected[] = {42, 0, 3};
1216 for (size_t i = 0; i < QUIC_ARRAYSIZE(expected); ++i) {
1217 EXPECT_EQ(buffer[i], expected[i]);
1218 }
1219}
1220
1221TEST_P(QuicDataWriterTest, SeekTooFarFails) {
1222 char buffer[20];
1223
1224 // Check that one can seek to the end of the writer, but not past.
1225 {
1226 QuicDataWriter writer(QUIC_ARRAYSIZE(buffer), buffer,
1227 GetParam().endianness);
1228 EXPECT_TRUE(writer.Seek(20));
1229 EXPECT_FALSE(writer.Seek(1));
1230 }
1231
1232 // Seeking several bytes past the end fails.
1233 {
1234 QuicDataWriter writer(QUIC_ARRAYSIZE(buffer), buffer,
1235 GetParam().endianness);
1236 EXPECT_FALSE(writer.Seek(100));
1237 }
1238
1239 // Seeking so far that arithmetic overflow could occur also fails.
1240 {
1241 QuicDataWriter writer(QUIC_ARRAYSIZE(buffer), buffer,
1242 GetParam().endianness);
1243 EXPECT_TRUE(writer.Seek(10));
1244 EXPECT_FALSE(writer.Seek(std::numeric_limits<size_t>::max()));
1245 }
1246}
1247
dschinazi4b5a68a2019-08-15 15:45:36 -07001248TEST_P(QuicDataWriterTest, PayloadReads) {
1249 char buffer[16] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16};
1250 char expected_first_read[4] = {1, 2, 3, 4};
1251 char expected_remaining[12] = {5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16};
1252 QuicDataReader reader(buffer, sizeof(buffer));
1253 char first_read_buffer[4] = {};
1254 EXPECT_TRUE(reader.ReadBytes(first_read_buffer, sizeof(first_read_buffer)));
1255 test::CompareCharArraysWithHexError(
1256 "first read", first_read_buffer, sizeof(first_read_buffer),
1257 expected_first_read, sizeof(expected_first_read));
1258 QuicStringPiece peeked_remaining_payload = reader.PeekRemainingPayload();
1259 test::CompareCharArraysWithHexError(
1260 "peeked_remaining_payload", peeked_remaining_payload.data(),
1261 peeked_remaining_payload.length(), expected_remaining,
1262 sizeof(expected_remaining));
1263 QuicStringPiece full_payload = reader.FullPayload();
1264 test::CompareCharArraysWithHexError("full_payload", full_payload.data(),
1265 full_payload.length(), buffer,
1266 sizeof(buffer));
1267 QuicStringPiece read_remaining_payload = reader.ReadRemainingPayload();
1268 test::CompareCharArraysWithHexError(
1269 "read_remaining_payload", read_remaining_payload.data(),
1270 read_remaining_payload.length(), expected_remaining,
1271 sizeof(expected_remaining));
1272 EXPECT_TRUE(reader.IsDoneReading());
1273 QuicStringPiece full_payload2 = reader.FullPayload();
1274 test::CompareCharArraysWithHexError("full_payload2", full_payload2.data(),
1275 full_payload2.length(), buffer,
1276 sizeof(buffer));
1277}
1278
QUICHE teama6ef0a62019-03-07 20:34:33 -05001279} // namespace
1280} // namespace test
1281} // namespace quic