1 // 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 "quiche/quic/core/quic_data_writer.h"
6
7 #include <cstdint>
8 #include <cstring>
9
10 #include "absl/base/macros.h"
11 #include "absl/strings/str_cat.h"
12 #include "absl/strings/string_view.h"
13 #include "quiche/quic/core/quic_connection_id.h"
14 #include "quiche/quic/core/quic_data_reader.h"
15 #include "quiche/quic/core/quic_types.h"
16 #include "quiche/quic/core/quic_utils.h"
17 #include "quiche/quic/platform/api/quic_expect_bug.h"
18 #include "quiche/quic/platform/api/quic_flags.h"
19 #include "quiche/quic/platform/api/quic_test.h"
20 #include "quiche/quic/test_tools/quic_test_utils.h"
21 #include "quiche/common/quiche_endian.h"
22 #include "quiche/common/test_tools/quiche_test_utils.h"
23
24 namespace quic {
25 namespace test {
26 namespace {
27
AsChars(unsigned char * data)28 char* AsChars(unsigned char* data) { return reinterpret_cast<char*>(data); }
29
30 struct TestParams {
TestParamsquic::test::__anonea00e1560111::TestParams31 explicit TestParams(quiche::Endianness endianness) : endianness(endianness) {}
32
33 quiche::Endianness endianness;
34 };
35
36 // Used by ::testing::PrintToStringParamName().
PrintToString(const TestParams & p)37 std::string PrintToString(const TestParams& p) {
38 return absl::StrCat(
39 (p.endianness == quiche::NETWORK_BYTE_ORDER ? "Network" : "Host"),
40 "ByteOrder");
41 }
42
GetTestParams()43 std::vector<TestParams> GetTestParams() {
44 std::vector<TestParams> params;
45 for (quiche::Endianness endianness :
46 {quiche::NETWORK_BYTE_ORDER, quiche::HOST_BYTE_ORDER}) {
47 params.push_back(TestParams(endianness));
48 }
49 return params;
50 }
51
52 class QuicDataWriterTest : public QuicTestWithParam<TestParams> {};
53
54 INSTANTIATE_TEST_SUITE_P(QuicDataWriterTests, QuicDataWriterTest,
55 ::testing::ValuesIn(GetTestParams()),
56 ::testing::PrintToStringParamName());
57
TEST_P(QuicDataWriterTest,SanityCheckUFloat16Consts)58 TEST_P(QuicDataWriterTest, SanityCheckUFloat16Consts) {
59 // Check the arithmetic on the constants - otherwise the values below make
60 // no sense.
61 EXPECT_EQ(30, kUFloat16MaxExponent);
62 EXPECT_EQ(11, kUFloat16MantissaBits);
63 EXPECT_EQ(12, kUFloat16MantissaEffectiveBits);
64 EXPECT_EQ(UINT64_C(0x3FFC0000000), kUFloat16MaxValue);
65 }
66
TEST_P(QuicDataWriterTest,WriteUFloat16)67 TEST_P(QuicDataWriterTest, WriteUFloat16) {
68 struct TestCase {
69 uint64_t decoded;
70 uint16_t encoded;
71 };
72 TestCase test_cases[] = {
73 // Small numbers represent themselves.
74 {0, 0},
75 {1, 1},
76 {2, 2},
77 {3, 3},
78 {4, 4},
79 {5, 5},
80 {6, 6},
81 {7, 7},
82 {15, 15},
83 {31, 31},
84 {42, 42},
85 {123, 123},
86 {1234, 1234},
87 // Check transition through 2^11.
88 {2046, 2046},
89 {2047, 2047},
90 {2048, 2048},
91 {2049, 2049},
92 // Running out of mantissa at 2^12.
93 {4094, 4094},
94 {4095, 4095},
95 {4096, 4096},
96 {4097, 4096},
97 {4098, 4097},
98 {4099, 4097},
99 {4100, 4098},
100 {4101, 4098},
101 // Check transition through 2^13.
102 {8190, 6143},
103 {8191, 6143},
104 {8192, 6144},
105 {8193, 6144},
106 {8194, 6144},
107 {8195, 6144},
108 {8196, 6145},
109 {8197, 6145},
110 // Half-way through the exponents.
111 {0x7FF8000, 0x87FF},
112 {0x7FFFFFF, 0x87FF},
113 {0x8000000, 0x8800},
114 {0xFFF0000, 0x8FFF},
115 {0xFFFFFFF, 0x8FFF},
116 {0x10000000, 0x9000},
117 // Transition into the largest exponent.
118 {0x1FFFFFFFFFE, 0xF7FF},
119 {0x1FFFFFFFFFF, 0xF7FF},
120 {0x20000000000, 0xF800},
121 {0x20000000001, 0xF800},
122 {0x2003FFFFFFE, 0xF800},
123 {0x2003FFFFFFF, 0xF800},
124 {0x20040000000, 0xF801},
125 {0x20040000001, 0xF801},
126 // Transition into the max value and clamping.
127 {0x3FF80000000, 0xFFFE},
128 {0x3FFBFFFFFFF, 0xFFFE},
129 {0x3FFC0000000, 0xFFFF},
130 {0x3FFC0000001, 0xFFFF},
131 {0x3FFFFFFFFFF, 0xFFFF},
132 {0x40000000000, 0xFFFF},
133 {0xFFFFFFFFFFFFFFFF, 0xFFFF},
134 };
135 int num_test_cases = sizeof(test_cases) / sizeof(test_cases[0]);
136
137 for (int i = 0; i < num_test_cases; ++i) {
138 char buffer[2];
139 QuicDataWriter writer(2, buffer, GetParam().endianness);
140 EXPECT_TRUE(writer.WriteUFloat16(test_cases[i].decoded));
141 uint16_t result = *reinterpret_cast<uint16_t*>(writer.data());
142 if (GetParam().endianness == quiche::NETWORK_BYTE_ORDER) {
143 result = quiche::QuicheEndian::HostToNet16(result);
144 }
145 EXPECT_EQ(test_cases[i].encoded, result);
146 }
147 }
148
TEST_P(QuicDataWriterTest,ReadUFloat16)149 TEST_P(QuicDataWriterTest, ReadUFloat16) {
150 struct TestCase {
151 uint64_t decoded;
152 uint16_t encoded;
153 };
154 TestCase test_cases[] = {
155 // There are fewer decoding test cases because encoding truncates, and
156 // decoding returns the smallest expansion.
157 // Small numbers represent themselves.
158 {0, 0},
159 {1, 1},
160 {2, 2},
161 {3, 3},
162 {4, 4},
163 {5, 5},
164 {6, 6},
165 {7, 7},
166 {15, 15},
167 {31, 31},
168 {42, 42},
169 {123, 123},
170 {1234, 1234},
171 // Check transition through 2^11.
172 {2046, 2046},
173 {2047, 2047},
174 {2048, 2048},
175 {2049, 2049},
176 // Running out of mantissa at 2^12.
177 {4094, 4094},
178 {4095, 4095},
179 {4096, 4096},
180 {4098, 4097},
181 {4100, 4098},
182 // Check transition through 2^13.
183 {8190, 6143},
184 {8192, 6144},
185 {8196, 6145},
186 // Half-way through the exponents.
187 {0x7FF8000, 0x87FF},
188 {0x8000000, 0x8800},
189 {0xFFF0000, 0x8FFF},
190 {0x10000000, 0x9000},
191 // Transition into the largest exponent.
192 {0x1FFE0000000, 0xF7FF},
193 {0x20000000000, 0xF800},
194 {0x20040000000, 0xF801},
195 // Transition into the max value.
196 {0x3FF80000000, 0xFFFE},
197 {0x3FFC0000000, 0xFFFF},
198 };
199 int num_test_cases = sizeof(test_cases) / sizeof(test_cases[0]);
200
201 for (int i = 0; i < num_test_cases; ++i) {
202 uint16_t encoded_ufloat = test_cases[i].encoded;
203 if (GetParam().endianness == quiche::NETWORK_BYTE_ORDER) {
204 encoded_ufloat = quiche::QuicheEndian::HostToNet16(encoded_ufloat);
205 }
206 QuicDataReader reader(reinterpret_cast<char*>(&encoded_ufloat), 2,
207 GetParam().endianness);
208 uint64_t value;
209 EXPECT_TRUE(reader.ReadUFloat16(&value));
210 EXPECT_EQ(test_cases[i].decoded, value);
211 }
212 }
213
TEST_P(QuicDataWriterTest,RoundTripUFloat16)214 TEST_P(QuicDataWriterTest, RoundTripUFloat16) {
215 // Just test all 16-bit encoded values. 0 and max already tested above.
216 uint64_t previous_value = 0;
217 for (uint16_t i = 1; i < 0xFFFF; ++i) {
218 // Read the two bytes.
219 uint16_t read_number = i;
220 if (GetParam().endianness == quiche::NETWORK_BYTE_ORDER) {
221 read_number = quiche::QuicheEndian::HostToNet16(read_number);
222 }
223 QuicDataReader reader(reinterpret_cast<char*>(&read_number), 2,
224 GetParam().endianness);
225 uint64_t value;
226 // All values must be decodable.
227 EXPECT_TRUE(reader.ReadUFloat16(&value));
228 // Check that small numbers represent themselves
229 if (i < 4097) {
230 EXPECT_EQ(i, value);
231 }
232 // Check there's monotonic growth.
233 EXPECT_LT(previous_value, value);
234 // Check that precision is within 0.5% away from the denormals.
235 if (i > 2000) {
236 EXPECT_GT(previous_value * 1005, value * 1000);
237 }
238 // Check we're always within the promised range.
239 EXPECT_LT(value, UINT64_C(0x3FFC0000000));
240 previous_value = value;
241 char buffer[6];
242 QuicDataWriter writer(6, buffer, GetParam().endianness);
243 EXPECT_TRUE(writer.WriteUFloat16(value - 1));
244 EXPECT_TRUE(writer.WriteUFloat16(value));
245 EXPECT_TRUE(writer.WriteUFloat16(value + 1));
246 // Check minimal decoding (previous decoding has previous encoding).
247 uint16_t encoded1 = *reinterpret_cast<uint16_t*>(writer.data());
248 uint16_t encoded2 = *reinterpret_cast<uint16_t*>(writer.data() + 2);
249 uint16_t encoded3 = *reinterpret_cast<uint16_t*>(writer.data() + 4);
250 if (GetParam().endianness == quiche::NETWORK_BYTE_ORDER) {
251 encoded1 = quiche::QuicheEndian::NetToHost16(encoded1);
252 encoded2 = quiche::QuicheEndian::NetToHost16(encoded2);
253 encoded3 = quiche::QuicheEndian::NetToHost16(encoded3);
254 }
255 EXPECT_EQ(i - 1, encoded1);
256 // Check roundtrip.
257 EXPECT_EQ(i, encoded2);
258 // Check next decoding.
259 EXPECT_EQ(i < 4096 ? i + 1 : i, encoded3);
260 }
261 }
262
TEST_P(QuicDataWriterTest,WriteConnectionId)263 TEST_P(QuicDataWriterTest, WriteConnectionId) {
264 QuicConnectionId connection_id =
265 TestConnectionId(UINT64_C(0x0011223344556677));
266 char big_endian[] = {
267 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77,
268 };
269 EXPECT_EQ(connection_id.length(), ABSL_ARRAYSIZE(big_endian));
270 ASSERT_LE(connection_id.length(), 255);
271 char buffer[255];
272 QuicDataWriter writer(connection_id.length(), buffer, GetParam().endianness);
273 EXPECT_TRUE(writer.WriteConnectionId(connection_id));
274 quiche::test::CompareCharArraysWithHexError(
275 "connection_id", buffer, connection_id.length(), big_endian,
276 connection_id.length());
277
278 QuicConnectionId read_connection_id;
279 QuicDataReader reader(buffer, connection_id.length(), GetParam().endianness);
280 EXPECT_TRUE(
281 reader.ReadConnectionId(&read_connection_id, ABSL_ARRAYSIZE(big_endian)));
282 EXPECT_EQ(connection_id, read_connection_id);
283 }
284
TEST_P(QuicDataWriterTest,LengthPrefixedConnectionId)285 TEST_P(QuicDataWriterTest, LengthPrefixedConnectionId) {
286 QuicConnectionId connection_id =
287 TestConnectionId(UINT64_C(0x0011223344556677));
288 char length_prefixed_connection_id[] = {
289 0x08, 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77,
290 };
291 EXPECT_EQ(ABSL_ARRAYSIZE(length_prefixed_connection_id),
292 kConnectionIdLengthSize + connection_id.length());
293 char buffer[kConnectionIdLengthSize + 255] = {};
294 QuicDataWriter writer(ABSL_ARRAYSIZE(buffer), buffer);
295 EXPECT_TRUE(writer.WriteLengthPrefixedConnectionId(connection_id));
296 quiche::test::CompareCharArraysWithHexError(
297 "WriteLengthPrefixedConnectionId", buffer, writer.length(),
298 length_prefixed_connection_id,
299 ABSL_ARRAYSIZE(length_prefixed_connection_id));
300
301 // Verify that writing length then connection ID produces the same output.
302 memset(buffer, 0, ABSL_ARRAYSIZE(buffer));
303 QuicDataWriter writer2(ABSL_ARRAYSIZE(buffer), buffer);
304 EXPECT_TRUE(writer2.WriteUInt8(connection_id.length()));
305 EXPECT_TRUE(writer2.WriteConnectionId(connection_id));
306 quiche::test::CompareCharArraysWithHexError(
307 "Write length then ConnectionId", buffer, writer2.length(),
308 length_prefixed_connection_id,
309 ABSL_ARRAYSIZE(length_prefixed_connection_id));
310
311 QuicConnectionId read_connection_id;
312 QuicDataReader reader(buffer, ABSL_ARRAYSIZE(buffer));
313 EXPECT_TRUE(reader.ReadLengthPrefixedConnectionId(&read_connection_id));
314 EXPECT_EQ(connection_id, read_connection_id);
315
316 // Verify that reading length then connection ID produces the same output.
317 uint8_t read_connection_id_length2 = 33;
318 QuicConnectionId read_connection_id2;
319 QuicDataReader reader2(buffer, ABSL_ARRAYSIZE(buffer));
320 ASSERT_TRUE(reader2.ReadUInt8(&read_connection_id_length2));
321 EXPECT_EQ(connection_id.length(), read_connection_id_length2);
322 EXPECT_TRUE(reader2.ReadConnectionId(&read_connection_id2,
323 read_connection_id_length2));
324 EXPECT_EQ(connection_id, read_connection_id2);
325 }
326
TEST_P(QuicDataWriterTest,EmptyConnectionIds)327 TEST_P(QuicDataWriterTest, EmptyConnectionIds) {
328 QuicConnectionId empty_connection_id = EmptyQuicConnectionId();
329 char buffer[2];
330 QuicDataWriter writer(ABSL_ARRAYSIZE(buffer), buffer, GetParam().endianness);
331 EXPECT_TRUE(writer.WriteConnectionId(empty_connection_id));
332 EXPECT_TRUE(writer.WriteUInt8(1));
333 EXPECT_TRUE(writer.WriteConnectionId(empty_connection_id));
334 EXPECT_TRUE(writer.WriteUInt8(2));
335 EXPECT_TRUE(writer.WriteConnectionId(empty_connection_id));
336 EXPECT_FALSE(writer.WriteUInt8(3));
337
338 EXPECT_EQ(buffer[0], 1);
339 EXPECT_EQ(buffer[1], 2);
340
341 QuicConnectionId read_connection_id = TestConnectionId();
342 uint8_t read_byte;
343 QuicDataReader reader(buffer, ABSL_ARRAYSIZE(buffer), GetParam().endianness);
344 EXPECT_TRUE(reader.ReadConnectionId(&read_connection_id, 0));
345 EXPECT_EQ(read_connection_id, empty_connection_id);
346 EXPECT_TRUE(reader.ReadUInt8(&read_byte));
347 EXPECT_EQ(read_byte, 1);
348 // Reset read_connection_id to something else to verify that
349 // ReadConnectionId properly sets it back to empty.
350 read_connection_id = TestConnectionId();
351 EXPECT_TRUE(reader.ReadConnectionId(&read_connection_id, 0));
352 EXPECT_EQ(read_connection_id, empty_connection_id);
353 EXPECT_TRUE(reader.ReadUInt8(&read_byte));
354 EXPECT_EQ(read_byte, 2);
355 read_connection_id = TestConnectionId();
356 EXPECT_TRUE(reader.ReadConnectionId(&read_connection_id, 0));
357 EXPECT_EQ(read_connection_id, empty_connection_id);
358 EXPECT_FALSE(reader.ReadUInt8(&read_byte));
359 }
360
TEST_P(QuicDataWriterTest,WriteTag)361 TEST_P(QuicDataWriterTest, WriteTag) {
362 char CHLO[] = {
363 'C',
364 'H',
365 'L',
366 'O',
367 };
368 const int kBufferLength = sizeof(QuicTag);
369 char buffer[kBufferLength];
370 QuicDataWriter writer(kBufferLength, buffer, GetParam().endianness);
371 writer.WriteTag(kCHLO);
372 quiche::test::CompareCharArraysWithHexError("CHLO", buffer, kBufferLength,
373 CHLO, kBufferLength);
374
375 QuicTag read_chlo;
376 QuicDataReader reader(buffer, kBufferLength, GetParam().endianness);
377 reader.ReadTag(&read_chlo);
378 EXPECT_EQ(kCHLO, read_chlo);
379 }
380
TEST_P(QuicDataWriterTest,Write16BitUnsignedIntegers)381 TEST_P(QuicDataWriterTest, Write16BitUnsignedIntegers) {
382 char little_endian16[] = {0x22, 0x11};
383 char big_endian16[] = {0x11, 0x22};
384 char buffer16[2];
385 {
386 uint16_t in_memory16 = 0x1122;
387 QuicDataWriter writer(2, buffer16, GetParam().endianness);
388 writer.WriteUInt16(in_memory16);
389 quiche::test::CompareCharArraysWithHexError(
390 "uint16_t", buffer16, 2,
391 GetParam().endianness == quiche::NETWORK_BYTE_ORDER ? big_endian16
392 : little_endian16,
393 2);
394
395 uint16_t read_number16;
396 QuicDataReader reader(buffer16, 2, GetParam().endianness);
397 reader.ReadUInt16(&read_number16);
398 EXPECT_EQ(in_memory16, read_number16);
399 }
400
401 {
402 uint64_t in_memory16 = 0x0000000000001122;
403 QuicDataWriter writer(2, buffer16, GetParam().endianness);
404 writer.WriteBytesToUInt64(2, in_memory16);
405 quiche::test::CompareCharArraysWithHexError(
406 "uint16_t", buffer16, 2,
407 GetParam().endianness == quiche::NETWORK_BYTE_ORDER ? big_endian16
408 : little_endian16,
409 2);
410
411 uint64_t read_number16;
412 QuicDataReader reader(buffer16, 2, GetParam().endianness);
413 reader.ReadBytesToUInt64(2, &read_number16);
414 EXPECT_EQ(in_memory16, read_number16);
415 }
416 }
417
TEST_P(QuicDataWriterTest,Write24BitUnsignedIntegers)418 TEST_P(QuicDataWriterTest, Write24BitUnsignedIntegers) {
419 char little_endian24[] = {0x33, 0x22, 0x11};
420 char big_endian24[] = {0x11, 0x22, 0x33};
421 char buffer24[3];
422 uint64_t in_memory24 = 0x0000000000112233;
423 QuicDataWriter writer(3, buffer24, GetParam().endianness);
424 writer.WriteBytesToUInt64(3, in_memory24);
425 quiche::test::CompareCharArraysWithHexError(
426 "uint24", buffer24, 3,
427 GetParam().endianness == quiche::NETWORK_BYTE_ORDER ? big_endian24
428 : little_endian24,
429 3);
430
431 uint64_t read_number24;
432 QuicDataReader reader(buffer24, 3, GetParam().endianness);
433 reader.ReadBytesToUInt64(3, &read_number24);
434 EXPECT_EQ(in_memory24, read_number24);
435 }
436
TEST_P(QuicDataWriterTest,Write32BitUnsignedIntegers)437 TEST_P(QuicDataWriterTest, Write32BitUnsignedIntegers) {
438 char little_endian32[] = {0x44, 0x33, 0x22, 0x11};
439 char big_endian32[] = {0x11, 0x22, 0x33, 0x44};
440 char buffer32[4];
441 {
442 uint32_t in_memory32 = 0x11223344;
443 QuicDataWriter writer(4, buffer32, GetParam().endianness);
444 writer.WriteUInt32(in_memory32);
445 quiche::test::CompareCharArraysWithHexError(
446 "uint32_t", buffer32, 4,
447 GetParam().endianness == quiche::NETWORK_BYTE_ORDER ? big_endian32
448 : little_endian32,
449 4);
450
451 uint32_t read_number32;
452 QuicDataReader reader(buffer32, 4, GetParam().endianness);
453 reader.ReadUInt32(&read_number32);
454 EXPECT_EQ(in_memory32, read_number32);
455 }
456
457 {
458 uint64_t in_memory32 = 0x11223344;
459 QuicDataWriter writer(4, buffer32, GetParam().endianness);
460 writer.WriteBytesToUInt64(4, in_memory32);
461 quiche::test::CompareCharArraysWithHexError(
462 "uint32_t", buffer32, 4,
463 GetParam().endianness == quiche::NETWORK_BYTE_ORDER ? big_endian32
464 : little_endian32,
465 4);
466
467 uint64_t read_number32;
468 QuicDataReader reader(buffer32, 4, GetParam().endianness);
469 reader.ReadBytesToUInt64(4, &read_number32);
470 EXPECT_EQ(in_memory32, read_number32);
471 }
472 }
473
TEST_P(QuicDataWriterTest,Write40BitUnsignedIntegers)474 TEST_P(QuicDataWriterTest, Write40BitUnsignedIntegers) {
475 uint64_t in_memory40 = 0x0000001122334455;
476 char little_endian40[] = {0x55, 0x44, 0x33, 0x22, 0x11};
477 char big_endian40[] = {0x11, 0x22, 0x33, 0x44, 0x55};
478 char buffer40[5];
479 QuicDataWriter writer(5, buffer40, GetParam().endianness);
480 writer.WriteBytesToUInt64(5, in_memory40);
481 quiche::test::CompareCharArraysWithHexError(
482 "uint40", buffer40, 5,
483 GetParam().endianness == quiche::NETWORK_BYTE_ORDER ? big_endian40
484 : little_endian40,
485 5);
486
487 uint64_t read_number40;
488 QuicDataReader reader(buffer40, 5, GetParam().endianness);
489 reader.ReadBytesToUInt64(5, &read_number40);
490 EXPECT_EQ(in_memory40, read_number40);
491 }
492
TEST_P(QuicDataWriterTest,Write48BitUnsignedIntegers)493 TEST_P(QuicDataWriterTest, Write48BitUnsignedIntegers) {
494 uint64_t in_memory48 = 0x0000112233445566;
495 char little_endian48[] = {0x66, 0x55, 0x44, 0x33, 0x22, 0x11};
496 char big_endian48[] = {0x11, 0x22, 0x33, 0x44, 0x55, 0x66};
497 char buffer48[6];
498 QuicDataWriter writer(6, buffer48, GetParam().endianness);
499 writer.WriteBytesToUInt64(6, in_memory48);
500 quiche::test::CompareCharArraysWithHexError(
501 "uint48", buffer48, 6,
502 GetParam().endianness == quiche::NETWORK_BYTE_ORDER ? big_endian48
503 : little_endian48,
504 6);
505
506 uint64_t read_number48;
507 QuicDataReader reader(buffer48, 6, GetParam().endianness);
508 reader.ReadBytesToUInt64(6., &read_number48);
509 EXPECT_EQ(in_memory48, read_number48);
510 }
511
TEST_P(QuicDataWriterTest,Write56BitUnsignedIntegers)512 TEST_P(QuicDataWriterTest, Write56BitUnsignedIntegers) {
513 uint64_t in_memory56 = 0x0011223344556677;
514 char little_endian56[] = {0x77, 0x66, 0x55, 0x44, 0x33, 0x22, 0x11};
515 char big_endian56[] = {0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77};
516 char buffer56[7];
517 QuicDataWriter writer(7, buffer56, GetParam().endianness);
518 writer.WriteBytesToUInt64(7, in_memory56);
519 quiche::test::CompareCharArraysWithHexError(
520 "uint56", buffer56, 7,
521 GetParam().endianness == quiche::NETWORK_BYTE_ORDER ? big_endian56
522 : little_endian56,
523 7);
524
525 uint64_t read_number56;
526 QuicDataReader reader(buffer56, 7, GetParam().endianness);
527 reader.ReadBytesToUInt64(7, &read_number56);
528 EXPECT_EQ(in_memory56, read_number56);
529 }
530
TEST_P(QuicDataWriterTest,Write64BitUnsignedIntegers)531 TEST_P(QuicDataWriterTest, Write64BitUnsignedIntegers) {
532 uint64_t in_memory64 = 0x1122334455667788;
533 unsigned char little_endian64[] = {0x88, 0x77, 0x66, 0x55,
534 0x44, 0x33, 0x22, 0x11};
535 unsigned char big_endian64[] = {0x11, 0x22, 0x33, 0x44,
536 0x55, 0x66, 0x77, 0x88};
537 char buffer64[8];
538 QuicDataWriter writer(8, buffer64, GetParam().endianness);
539 writer.WriteBytesToUInt64(8, in_memory64);
540 quiche::test::CompareCharArraysWithHexError(
541 "uint64_t", buffer64, 8,
542 GetParam().endianness == quiche::NETWORK_BYTE_ORDER
543 ? AsChars(big_endian64)
544 : AsChars(little_endian64),
545 8);
546
547 uint64_t read_number64;
548 QuicDataReader reader(buffer64, 8, GetParam().endianness);
549 reader.ReadBytesToUInt64(8, &read_number64);
550 EXPECT_EQ(in_memory64, read_number64);
551
552 QuicDataWriter writer2(8, buffer64, GetParam().endianness);
553 writer2.WriteUInt64(in_memory64);
554 quiche::test::CompareCharArraysWithHexError(
555 "uint64_t", buffer64, 8,
556 GetParam().endianness == quiche::NETWORK_BYTE_ORDER
557 ? AsChars(big_endian64)
558 : AsChars(little_endian64),
559 8);
560 read_number64 = 0u;
561 QuicDataReader reader2(buffer64, 8, GetParam().endianness);
562 reader2.ReadUInt64(&read_number64);
563 EXPECT_EQ(in_memory64, read_number64);
564 }
565
TEST_P(QuicDataWriterTest,WriteIntegers)566 TEST_P(QuicDataWriterTest, WriteIntegers) {
567 char buf[43];
568 uint8_t i8 = 0x01;
569 uint16_t i16 = 0x0123;
570 uint32_t i32 = 0x01234567;
571 uint64_t i64 = 0x0123456789ABCDEF;
572 QuicDataWriter writer(46, buf, GetParam().endianness);
573 for (size_t i = 0; i < 10; ++i) {
574 switch (i) {
575 case 0u:
576 EXPECT_TRUE(writer.WriteBytesToUInt64(i, i64));
577 break;
578 case 1u:
579 EXPECT_TRUE(writer.WriteUInt8(i8));
580 EXPECT_TRUE(writer.WriteBytesToUInt64(i, i64));
581 break;
582 case 2u:
583 EXPECT_TRUE(writer.WriteUInt16(i16));
584 EXPECT_TRUE(writer.WriteBytesToUInt64(i, i64));
585 break;
586 case 3u:
587 EXPECT_TRUE(writer.WriteBytesToUInt64(i, i64));
588 break;
589 case 4u:
590 EXPECT_TRUE(writer.WriteUInt32(i32));
591 EXPECT_TRUE(writer.WriteBytesToUInt64(i, i64));
592 break;
593 case 5u:
594 case 6u:
595 case 7u:
596 case 8u:
597 EXPECT_TRUE(writer.WriteBytesToUInt64(i, i64));
598 break;
599 default:
600 EXPECT_FALSE(writer.WriteBytesToUInt64(i, i64));
601 }
602 }
603
604 QuicDataReader reader(buf, 46, GetParam().endianness);
605 for (size_t i = 0; i < 10; ++i) {
606 uint8_t read8;
607 uint16_t read16;
608 uint32_t read32;
609 uint64_t read64;
610 switch (i) {
611 case 0u:
612 EXPECT_TRUE(reader.ReadBytesToUInt64(i, &read64));
613 EXPECT_EQ(0u, read64);
614 break;
615 case 1u:
616 EXPECT_TRUE(reader.ReadUInt8(&read8));
617 EXPECT_TRUE(reader.ReadBytesToUInt64(i, &read64));
618 EXPECT_EQ(i8, read8);
619 EXPECT_EQ(0xEFu, read64);
620 break;
621 case 2u:
622 EXPECT_TRUE(reader.ReadUInt16(&read16));
623 EXPECT_TRUE(reader.ReadBytesToUInt64(i, &read64));
624 EXPECT_EQ(i16, read16);
625 EXPECT_EQ(0xCDEFu, read64);
626 break;
627 case 3u:
628 EXPECT_TRUE(reader.ReadBytesToUInt64(i, &read64));
629 EXPECT_EQ(0xABCDEFu, read64);
630 break;
631 case 4u:
632 EXPECT_TRUE(reader.ReadUInt32(&read32));
633 EXPECT_TRUE(reader.ReadBytesToUInt64(i, &read64));
634 EXPECT_EQ(i32, read32);
635 EXPECT_EQ(0x89ABCDEFu, read64);
636 break;
637 case 5u:
638 EXPECT_TRUE(reader.ReadBytesToUInt64(i, &read64));
639 EXPECT_EQ(0x6789ABCDEFu, read64);
640 break;
641 case 6u:
642 EXPECT_TRUE(reader.ReadBytesToUInt64(i, &read64));
643 EXPECT_EQ(0x456789ABCDEFu, read64);
644 break;
645 case 7u:
646 EXPECT_TRUE(reader.ReadBytesToUInt64(i, &read64));
647 EXPECT_EQ(0x23456789ABCDEFu, read64);
648 break;
649 case 8u:
650 EXPECT_TRUE(reader.ReadBytesToUInt64(i, &read64));
651 EXPECT_EQ(0x0123456789ABCDEFu, read64);
652 break;
653 default:
654 EXPECT_FALSE(reader.ReadBytesToUInt64(i, &read64));
655 }
656 }
657 }
658
TEST_P(QuicDataWriterTest,WriteBytes)659 TEST_P(QuicDataWriterTest, WriteBytes) {
660 char bytes[] = {0, 1, 2, 3, 4, 5, 6, 7, 8};
661 char buf[ABSL_ARRAYSIZE(bytes)];
662 QuicDataWriter writer(ABSL_ARRAYSIZE(buf), buf, GetParam().endianness);
663 EXPECT_TRUE(writer.WriteBytes(bytes, ABSL_ARRAYSIZE(bytes)));
664 for (unsigned int i = 0; i < ABSL_ARRAYSIZE(bytes); ++i) {
665 EXPECT_EQ(bytes[i], buf[i]);
666 }
667 }
668
669 // Following tests all try to fill the buffer with multiple values,
670 // go one value more than the buffer can accommodate, then read
671 // the successfully encoded values, and try to read the unsuccessfully
672 // encoded value. The following is the number of values to encode.
673 const int kMultiVarCount = 1000;
674
675 // Test encoding/decoding stream-id values.
EncodeDecodeStreamId(uint64_t value_in)676 void EncodeDecodeStreamId(uint64_t value_in) {
677 char buffer[1 * kMultiVarCount];
678 memset(buffer, 0, sizeof(buffer));
679
680 // Encode the given Stream ID.
681 QuicDataWriter writer(sizeof(buffer), static_cast<char*>(buffer),
682 quiche::Endianness::NETWORK_BYTE_ORDER);
683 EXPECT_TRUE(writer.WriteVarInt62(value_in));
684
685 QuicDataReader reader(buffer, sizeof(buffer),
686 quiche::Endianness::NETWORK_BYTE_ORDER);
687 QuicStreamId received_stream_id;
688 uint64_t temp;
689 EXPECT_TRUE(reader.ReadVarInt62(&temp));
690 received_stream_id = static_cast<QuicStreamId>(temp);
691 EXPECT_EQ(value_in, received_stream_id);
692 }
693
694 // Test writing & reading stream-ids of various value.
TEST_P(QuicDataWriterTest,StreamId1)695 TEST_P(QuicDataWriterTest, StreamId1) {
696 // Check a 1-byte QuicStreamId, should work
697 EncodeDecodeStreamId(UINT64_C(0x15));
698
699 // Check a 2-byte QuicStream ID. It should work.
700 EncodeDecodeStreamId(UINT64_C(0x1567));
701
702 // Check a QuicStreamId that requires 4 bytes of encoding
703 // This should work.
704 EncodeDecodeStreamId(UINT64_C(0x34567890));
705
706 // Check a QuicStreamId that requires 8 bytes of encoding
707 // but whose value is in the acceptable range.
708 // This should work.
709 EncodeDecodeStreamId(UINT64_C(0xf4567890));
710 }
711
TEST_P(QuicDataWriterTest,WriteRandomBytes)712 TEST_P(QuicDataWriterTest, WriteRandomBytes) {
713 char buffer[20];
714 char expected[20];
715 for (size_t i = 0; i < 20; ++i) {
716 expected[i] = 'r';
717 }
718 MockRandom random;
719 QuicDataWriter writer(20, buffer, GetParam().endianness);
720 EXPECT_FALSE(writer.WriteRandomBytes(&random, 30));
721
722 EXPECT_TRUE(writer.WriteRandomBytes(&random, 20));
723 quiche::test::CompareCharArraysWithHexError("random", buffer, 20, expected,
724 20);
725 }
726
TEST_P(QuicDataWriterTest,WriteInsecureRandomBytes)727 TEST_P(QuicDataWriterTest, WriteInsecureRandomBytes) {
728 char buffer[20];
729 char expected[20];
730 for (size_t i = 0; i < 20; ++i) {
731 expected[i] = 'r';
732 }
733 MockRandom random;
734 QuicDataWriter writer(20, buffer, GetParam().endianness);
735 EXPECT_FALSE(writer.WriteInsecureRandomBytes(&random, 30));
736
737 EXPECT_TRUE(writer.WriteInsecureRandomBytes(&random, 20));
738 quiche::test::CompareCharArraysWithHexError("random", buffer, 20, expected,
739 20);
740 }
741
TEST_P(QuicDataWriterTest,PeekVarInt62Length)742 TEST_P(QuicDataWriterTest, PeekVarInt62Length) {
743 // In range [0, 63], variable length should be 1 byte.
744 char buffer[20];
745 QuicDataWriter writer(20, buffer, quiche::NETWORK_BYTE_ORDER);
746 EXPECT_TRUE(writer.WriteVarInt62(50));
747 QuicDataReader reader(buffer, 20, quiche::NETWORK_BYTE_ORDER);
748 EXPECT_EQ(1, reader.PeekVarInt62Length());
749 // In range (63-16383], variable length should be 2 byte2.
750 char buffer2[20];
751 QuicDataWriter writer2(20, buffer2, quiche::NETWORK_BYTE_ORDER);
752 EXPECT_TRUE(writer2.WriteVarInt62(100));
753 QuicDataReader reader2(buffer2, 20, quiche::NETWORK_BYTE_ORDER);
754 EXPECT_EQ(2, reader2.PeekVarInt62Length());
755 // In range (16383, 1073741823], variable length should be 4 bytes.
756 char buffer3[20];
757 QuicDataWriter writer3(20, buffer3, quiche::NETWORK_BYTE_ORDER);
758 EXPECT_TRUE(writer3.WriteVarInt62(20000));
759 QuicDataReader reader3(buffer3, 20, quiche::NETWORK_BYTE_ORDER);
760 EXPECT_EQ(4, reader3.PeekVarInt62Length());
761 // In range (1073741823, 4611686018427387903], variable length should be 8
762 // bytes.
763 char buffer4[20];
764 QuicDataWriter writer4(20, buffer4, quiche::NETWORK_BYTE_ORDER);
765 EXPECT_TRUE(writer4.WriteVarInt62(2000000000));
766 QuicDataReader reader4(buffer4, 20, quiche::NETWORK_BYTE_ORDER);
767 EXPECT_EQ(8, reader4.PeekVarInt62Length());
768 }
769
TEST_P(QuicDataWriterTest,ValidStreamCount)770 TEST_P(QuicDataWriterTest, ValidStreamCount) {
771 char buffer[1024];
772 memset(buffer, 0, sizeof(buffer));
773 QuicDataWriter writer(sizeof(buffer), static_cast<char*>(buffer),
774 quiche::Endianness::NETWORK_BYTE_ORDER);
775 QuicDataReader reader(buffer, sizeof(buffer));
776 const QuicStreamCount write_stream_count = 0xffeeddcc;
777 EXPECT_TRUE(writer.WriteVarInt62(write_stream_count));
778 QuicStreamCount read_stream_count;
779 uint64_t temp;
780 EXPECT_TRUE(reader.ReadVarInt62(&temp));
781 read_stream_count = static_cast<QuicStreamId>(temp);
782 EXPECT_EQ(write_stream_count, read_stream_count);
783 }
784
TEST_P(QuicDataWriterTest,Seek)785 TEST_P(QuicDataWriterTest, Seek) {
786 char buffer[3] = {};
787 QuicDataWriter writer(ABSL_ARRAYSIZE(buffer), buffer, GetParam().endianness);
788 EXPECT_TRUE(writer.WriteUInt8(42));
789 EXPECT_TRUE(writer.Seek(1));
790 EXPECT_TRUE(writer.WriteUInt8(3));
791
792 char expected[] = {42, 0, 3};
793 for (size_t i = 0; i < ABSL_ARRAYSIZE(expected); ++i) {
794 EXPECT_EQ(buffer[i], expected[i]);
795 }
796 }
797
TEST_P(QuicDataWriterTest,SeekTooFarFails)798 TEST_P(QuicDataWriterTest, SeekTooFarFails) {
799 char buffer[20];
800
801 // Check that one can seek to the end of the writer, but not past.
802 {
803 QuicDataWriter writer(ABSL_ARRAYSIZE(buffer), buffer,
804 GetParam().endianness);
805 EXPECT_TRUE(writer.Seek(20));
806 EXPECT_FALSE(writer.Seek(1));
807 }
808
809 // Seeking several bytes past the end fails.
810 {
811 QuicDataWriter writer(ABSL_ARRAYSIZE(buffer), buffer,
812 GetParam().endianness);
813 EXPECT_FALSE(writer.Seek(100));
814 }
815
816 // Seeking so far that arithmetic overflow could occur also fails.
817 {
818 QuicDataWriter writer(ABSL_ARRAYSIZE(buffer), buffer,
819 GetParam().endianness);
820 EXPECT_TRUE(writer.Seek(10));
821 EXPECT_FALSE(writer.Seek(std::numeric_limits<size_t>::max()));
822 }
823 }
824
TEST_P(QuicDataWriterTest,PayloadReads)825 TEST_P(QuicDataWriterTest, PayloadReads) {
826 char buffer[16] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16};
827 char expected_first_read[4] = {1, 2, 3, 4};
828 char expected_remaining[12] = {5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16};
829 QuicDataReader reader(buffer, sizeof(buffer));
830 char first_read_buffer[4] = {};
831 EXPECT_TRUE(reader.ReadBytes(first_read_buffer, sizeof(first_read_buffer)));
832 quiche::test::CompareCharArraysWithHexError(
833 "first read", first_read_buffer, sizeof(first_read_buffer),
834 expected_first_read, sizeof(expected_first_read));
835 absl::string_view peeked_remaining_payload = reader.PeekRemainingPayload();
836 quiche::test::CompareCharArraysWithHexError(
837 "peeked_remaining_payload", peeked_remaining_payload.data(),
838 peeked_remaining_payload.length(), expected_remaining,
839 sizeof(expected_remaining));
840 absl::string_view full_payload = reader.FullPayload();
841 quiche::test::CompareCharArraysWithHexError(
842 "full_payload", full_payload.data(), full_payload.length(), buffer,
843 sizeof(buffer));
844 absl::string_view read_remaining_payload = reader.ReadRemainingPayload();
845 quiche::test::CompareCharArraysWithHexError(
846 "read_remaining_payload", read_remaining_payload.data(),
847 read_remaining_payload.length(), expected_remaining,
848 sizeof(expected_remaining));
849 EXPECT_TRUE(reader.IsDoneReading());
850 absl::string_view full_payload2 = reader.FullPayload();
851 quiche::test::CompareCharArraysWithHexError(
852 "full_payload2", full_payload2.data(), full_payload2.length(), buffer,
853 sizeof(buffer));
854 }
855
TEST_P(QuicDataWriterTest,StringPieceVarInt62)856 TEST_P(QuicDataWriterTest, StringPieceVarInt62) {
857 char inner_buffer[16] = {1, 2, 3, 4, 5, 6, 7, 8,
858 9, 10, 11, 12, 13, 14, 15, 16};
859 absl::string_view inner_payload_write(inner_buffer, sizeof(inner_buffer));
860 char buffer[sizeof(inner_buffer) + sizeof(uint8_t)] = {};
861 QuicDataWriter writer(sizeof(buffer), buffer);
862 EXPECT_TRUE(writer.WriteStringPieceVarInt62(inner_payload_write));
863 EXPECT_EQ(0u, writer.remaining());
864 QuicDataReader reader(buffer, sizeof(buffer));
865 absl::string_view inner_payload_read;
866 EXPECT_TRUE(reader.ReadStringPieceVarInt62(&inner_payload_read));
867 quiche::test::CompareCharArraysWithHexError(
868 "inner_payload", inner_payload_write.data(), inner_payload_write.length(),
869 inner_payload_read.data(), inner_payload_read.length());
870 }
871
872 } // namespace
873 } // namespace test
874 } // namespace quic
875