xref: /aosp_15_r20/external/cronet/net/third_party/quiche/src/quiche/quic/core/quic_data_writer_test.cc (revision 6777b5387eb2ff775bb5750e3f5d96f37fb7352b)
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