xref: /aosp_15_r20/external/cronet/net/third_party/quiche/src/quiche/common/quiche_data_writer_test.cc (revision 6777b5387eb2ff775bb5750e3f5d96f37fb7352b)
1 // Copyright (c) 2020 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/common/quiche_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/common/platform/api/quiche_test.h"
14 #include "quiche/common/quiche_data_reader.h"
15 #include "quiche/common/quiche_endian.h"
16 #include "quiche/common/test_tools/quiche_test_utils.h"
17 
18 namespace quiche {
19 namespace test {
20 namespace {
21 
AsChars(unsigned char * data)22 char* AsChars(unsigned char* data) { return reinterpret_cast<char*>(data); }
23 
24 struct TestParams {
TestParamsquiche::test::__anon3eb70a620111::TestParams25   explicit TestParams(quiche::Endianness endianness) : endianness(endianness) {}
26 
27   quiche::Endianness endianness;
28 };
29 
30 // Used by ::testing::PrintToStringParamName().
PrintToString(const TestParams & p)31 std::string PrintToString(const TestParams& p) {
32   return absl::StrCat(
33       (p.endianness == quiche::NETWORK_BYTE_ORDER ? "Network" : "Host"),
34       "ByteOrder");
35 }
36 
GetTestParams()37 std::vector<TestParams> GetTestParams() {
38   std::vector<TestParams> params;
39   for (quiche::Endianness endianness :
40        {quiche::NETWORK_BYTE_ORDER, quiche::HOST_BYTE_ORDER}) {
41     params.push_back(TestParams(endianness));
42   }
43   return params;
44 }
45 
46 class QuicheDataWriterTest : public QuicheTestWithParam<TestParams> {};
47 
48 INSTANTIATE_TEST_SUITE_P(QuicheDataWriterTests, QuicheDataWriterTest,
49                          ::testing::ValuesIn(GetTestParams()),
50                          ::testing::PrintToStringParamName());
51 
TEST_P(QuicheDataWriterTest,Write16BitUnsignedIntegers)52 TEST_P(QuicheDataWriterTest, Write16BitUnsignedIntegers) {
53   char little_endian16[] = {0x22, 0x11};
54   char big_endian16[] = {0x11, 0x22};
55   char buffer16[2];
56   {
57     uint16_t in_memory16 = 0x1122;
58     QuicheDataWriter writer(2, buffer16, GetParam().endianness);
59     writer.WriteUInt16(in_memory16);
60     test::CompareCharArraysWithHexError(
61         "uint16_t", buffer16, 2,
62         GetParam().endianness == quiche::NETWORK_BYTE_ORDER ? big_endian16
63                                                             : little_endian16,
64         2);
65 
66     uint16_t read_number16;
67     QuicheDataReader reader(buffer16, 2, GetParam().endianness);
68     reader.ReadUInt16(&read_number16);
69     EXPECT_EQ(in_memory16, read_number16);
70   }
71 
72   {
73     uint64_t in_memory16 = 0x0000000000001122;
74     QuicheDataWriter writer(2, buffer16, GetParam().endianness);
75     writer.WriteBytesToUInt64(2, in_memory16);
76     test::CompareCharArraysWithHexError(
77         "uint16_t", buffer16, 2,
78         GetParam().endianness == quiche::NETWORK_BYTE_ORDER ? big_endian16
79                                                             : little_endian16,
80         2);
81 
82     uint64_t read_number16;
83     QuicheDataReader reader(buffer16, 2, GetParam().endianness);
84     reader.ReadBytesToUInt64(2, &read_number16);
85     EXPECT_EQ(in_memory16, read_number16);
86   }
87 }
88 
TEST_P(QuicheDataWriterTest,Write24BitUnsignedIntegers)89 TEST_P(QuicheDataWriterTest, Write24BitUnsignedIntegers) {
90   char little_endian24[] = {0x33, 0x22, 0x11};
91   char big_endian24[] = {0x11, 0x22, 0x33};
92   char buffer24[3];
93   uint64_t in_memory24 = 0x0000000000112233;
94   QuicheDataWriter writer(3, buffer24, GetParam().endianness);
95   writer.WriteBytesToUInt64(3, in_memory24);
96   test::CompareCharArraysWithHexError(
97       "uint24", buffer24, 3,
98       GetParam().endianness == quiche::NETWORK_BYTE_ORDER ? big_endian24
99                                                           : little_endian24,
100       3);
101 
102   uint64_t read_number24;
103   QuicheDataReader reader(buffer24, 3, GetParam().endianness);
104   reader.ReadBytesToUInt64(3, &read_number24);
105   EXPECT_EQ(in_memory24, read_number24);
106 }
107 
TEST_P(QuicheDataWriterTest,Write32BitUnsignedIntegers)108 TEST_P(QuicheDataWriterTest, Write32BitUnsignedIntegers) {
109   char little_endian32[] = {0x44, 0x33, 0x22, 0x11};
110   char big_endian32[] = {0x11, 0x22, 0x33, 0x44};
111   char buffer32[4];
112   {
113     uint32_t in_memory32 = 0x11223344;
114     QuicheDataWriter writer(4, buffer32, GetParam().endianness);
115     writer.WriteUInt32(in_memory32);
116     test::CompareCharArraysWithHexError(
117         "uint32_t", buffer32, 4,
118         GetParam().endianness == quiche::NETWORK_BYTE_ORDER ? big_endian32
119                                                             : little_endian32,
120         4);
121 
122     uint32_t read_number32;
123     QuicheDataReader reader(buffer32, 4, GetParam().endianness);
124     reader.ReadUInt32(&read_number32);
125     EXPECT_EQ(in_memory32, read_number32);
126   }
127 
128   {
129     uint64_t in_memory32 = 0x11223344;
130     QuicheDataWriter writer(4, buffer32, GetParam().endianness);
131     writer.WriteBytesToUInt64(4, in_memory32);
132     test::CompareCharArraysWithHexError(
133         "uint32_t", buffer32, 4,
134         GetParam().endianness == quiche::NETWORK_BYTE_ORDER ? big_endian32
135                                                             : little_endian32,
136         4);
137 
138     uint64_t read_number32;
139     QuicheDataReader reader(buffer32, 4, GetParam().endianness);
140     reader.ReadBytesToUInt64(4, &read_number32);
141     EXPECT_EQ(in_memory32, read_number32);
142   }
143 }
144 
TEST_P(QuicheDataWriterTest,Write40BitUnsignedIntegers)145 TEST_P(QuicheDataWriterTest, Write40BitUnsignedIntegers) {
146   uint64_t in_memory40 = 0x0000001122334455;
147   char little_endian40[] = {0x55, 0x44, 0x33, 0x22, 0x11};
148   char big_endian40[] = {0x11, 0x22, 0x33, 0x44, 0x55};
149   char buffer40[5];
150   QuicheDataWriter writer(5, buffer40, GetParam().endianness);
151   writer.WriteBytesToUInt64(5, in_memory40);
152   test::CompareCharArraysWithHexError(
153       "uint40", buffer40, 5,
154       GetParam().endianness == quiche::NETWORK_BYTE_ORDER ? big_endian40
155                                                           : little_endian40,
156       5);
157 
158   uint64_t read_number40;
159   QuicheDataReader reader(buffer40, 5, GetParam().endianness);
160   reader.ReadBytesToUInt64(5, &read_number40);
161   EXPECT_EQ(in_memory40, read_number40);
162 }
163 
TEST_P(QuicheDataWriterTest,Write48BitUnsignedIntegers)164 TEST_P(QuicheDataWriterTest, Write48BitUnsignedIntegers) {
165   uint64_t in_memory48 = 0x0000112233445566;
166   char little_endian48[] = {0x66, 0x55, 0x44, 0x33, 0x22, 0x11};
167   char big_endian48[] = {0x11, 0x22, 0x33, 0x44, 0x55, 0x66};
168   char buffer48[6];
169   QuicheDataWriter writer(6, buffer48, GetParam().endianness);
170   writer.WriteBytesToUInt64(6, in_memory48);
171   test::CompareCharArraysWithHexError(
172       "uint48", buffer48, 6,
173       GetParam().endianness == quiche::NETWORK_BYTE_ORDER ? big_endian48
174                                                           : little_endian48,
175       6);
176 
177   uint64_t read_number48;
178   QuicheDataReader reader(buffer48, 6, GetParam().endianness);
179   reader.ReadBytesToUInt64(6., &read_number48);
180   EXPECT_EQ(in_memory48, read_number48);
181 }
182 
TEST_P(QuicheDataWriterTest,Write56BitUnsignedIntegers)183 TEST_P(QuicheDataWriterTest, Write56BitUnsignedIntegers) {
184   uint64_t in_memory56 = 0x0011223344556677;
185   char little_endian56[] = {0x77, 0x66, 0x55, 0x44, 0x33, 0x22, 0x11};
186   char big_endian56[] = {0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77};
187   char buffer56[7];
188   QuicheDataWriter writer(7, buffer56, GetParam().endianness);
189   writer.WriteBytesToUInt64(7, in_memory56);
190   test::CompareCharArraysWithHexError(
191       "uint56", buffer56, 7,
192       GetParam().endianness == quiche::NETWORK_BYTE_ORDER ? big_endian56
193                                                           : little_endian56,
194       7);
195 
196   uint64_t read_number56;
197   QuicheDataReader reader(buffer56, 7, GetParam().endianness);
198   reader.ReadBytesToUInt64(7, &read_number56);
199   EXPECT_EQ(in_memory56, read_number56);
200 }
201 
TEST_P(QuicheDataWriterTest,Write64BitUnsignedIntegers)202 TEST_P(QuicheDataWriterTest, Write64BitUnsignedIntegers) {
203   uint64_t in_memory64 = 0x1122334455667788;
204   unsigned char little_endian64[] = {0x88, 0x77, 0x66, 0x55,
205                                      0x44, 0x33, 0x22, 0x11};
206   unsigned char big_endian64[] = {0x11, 0x22, 0x33, 0x44,
207                                   0x55, 0x66, 0x77, 0x88};
208   char buffer64[8];
209   QuicheDataWriter writer(8, buffer64, GetParam().endianness);
210   writer.WriteBytesToUInt64(8, in_memory64);
211   test::CompareCharArraysWithHexError(
212       "uint64_t", buffer64, 8,
213       GetParam().endianness == quiche::NETWORK_BYTE_ORDER
214           ? AsChars(big_endian64)
215           : AsChars(little_endian64),
216       8);
217 
218   uint64_t read_number64;
219   QuicheDataReader reader(buffer64, 8, GetParam().endianness);
220   reader.ReadBytesToUInt64(8, &read_number64);
221   EXPECT_EQ(in_memory64, read_number64);
222 
223   QuicheDataWriter writer2(8, buffer64, GetParam().endianness);
224   writer2.WriteUInt64(in_memory64);
225   test::CompareCharArraysWithHexError(
226       "uint64_t", buffer64, 8,
227       GetParam().endianness == quiche::NETWORK_BYTE_ORDER
228           ? AsChars(big_endian64)
229           : AsChars(little_endian64),
230       8);
231   read_number64 = 0u;
232   QuicheDataReader reader2(buffer64, 8, GetParam().endianness);
233   reader2.ReadUInt64(&read_number64);
234   EXPECT_EQ(in_memory64, read_number64);
235 }
236 
TEST_P(QuicheDataWriterTest,WriteIntegers)237 TEST_P(QuicheDataWriterTest, WriteIntegers) {
238   char buf[43];
239   uint8_t i8 = 0x01;
240   uint16_t i16 = 0x0123;
241   uint32_t i32 = 0x01234567;
242   uint64_t i64 = 0x0123456789ABCDEF;
243   QuicheDataWriter writer(46, buf, GetParam().endianness);
244   for (size_t i = 0; i < 10; ++i) {
245     switch (i) {
246       case 0u:
247         EXPECT_TRUE(writer.WriteBytesToUInt64(i, i64));
248         break;
249       case 1u:
250         EXPECT_TRUE(writer.WriteUInt8(i8));
251         EXPECT_TRUE(writer.WriteBytesToUInt64(i, i64));
252         break;
253       case 2u:
254         EXPECT_TRUE(writer.WriteUInt16(i16));
255         EXPECT_TRUE(writer.WriteBytesToUInt64(i, i64));
256         break;
257       case 3u:
258         EXPECT_TRUE(writer.WriteBytesToUInt64(i, i64));
259         break;
260       case 4u:
261         EXPECT_TRUE(writer.WriteUInt32(i32));
262         EXPECT_TRUE(writer.WriteBytesToUInt64(i, i64));
263         break;
264       case 5u:
265       case 6u:
266       case 7u:
267       case 8u:
268         EXPECT_TRUE(writer.WriteBytesToUInt64(i, i64));
269         break;
270       default:
271         EXPECT_FALSE(writer.WriteBytesToUInt64(i, i64));
272     }
273   }
274 
275   QuicheDataReader reader(buf, 46, GetParam().endianness);
276   for (size_t i = 0; i < 10; ++i) {
277     uint8_t read8;
278     uint16_t read16;
279     uint32_t read32;
280     uint64_t read64;
281     switch (i) {
282       case 0u:
283         EXPECT_TRUE(reader.ReadBytesToUInt64(i, &read64));
284         EXPECT_EQ(0u, read64);
285         break;
286       case 1u:
287         EXPECT_TRUE(reader.ReadUInt8(&read8));
288         EXPECT_TRUE(reader.ReadBytesToUInt64(i, &read64));
289         EXPECT_EQ(i8, read8);
290         EXPECT_EQ(0xEFu, read64);
291         break;
292       case 2u:
293         EXPECT_TRUE(reader.ReadUInt16(&read16));
294         EXPECT_TRUE(reader.ReadBytesToUInt64(i, &read64));
295         EXPECT_EQ(i16, read16);
296         EXPECT_EQ(0xCDEFu, read64);
297         break;
298       case 3u:
299         EXPECT_TRUE(reader.ReadBytesToUInt64(i, &read64));
300         EXPECT_EQ(0xABCDEFu, read64);
301         break;
302       case 4u:
303         EXPECT_TRUE(reader.ReadUInt32(&read32));
304         EXPECT_TRUE(reader.ReadBytesToUInt64(i, &read64));
305         EXPECT_EQ(i32, read32);
306         EXPECT_EQ(0x89ABCDEFu, read64);
307         break;
308       case 5u:
309         EXPECT_TRUE(reader.ReadBytesToUInt64(i, &read64));
310         EXPECT_EQ(0x6789ABCDEFu, read64);
311         break;
312       case 6u:
313         EXPECT_TRUE(reader.ReadBytesToUInt64(i, &read64));
314         EXPECT_EQ(0x456789ABCDEFu, read64);
315         break;
316       case 7u:
317         EXPECT_TRUE(reader.ReadBytesToUInt64(i, &read64));
318         EXPECT_EQ(0x23456789ABCDEFu, read64);
319         break;
320       case 8u:
321         EXPECT_TRUE(reader.ReadBytesToUInt64(i, &read64));
322         EXPECT_EQ(0x0123456789ABCDEFu, read64);
323         break;
324       default:
325         EXPECT_FALSE(reader.ReadBytesToUInt64(i, &read64));
326     }
327   }
328 }
329 
TEST_P(QuicheDataWriterTest,WriteBytes)330 TEST_P(QuicheDataWriterTest, WriteBytes) {
331   char bytes[] = {0, 1, 2, 3, 4, 5, 6, 7, 8};
332   char buf[ABSL_ARRAYSIZE(bytes)];
333   QuicheDataWriter writer(ABSL_ARRAYSIZE(buf), buf, GetParam().endianness);
334   EXPECT_TRUE(writer.WriteBytes(bytes, ABSL_ARRAYSIZE(bytes)));
335   for (unsigned int i = 0; i < ABSL_ARRAYSIZE(bytes); ++i) {
336     EXPECT_EQ(bytes[i], buf[i]);
337   }
338 }
339 
340 const int kVarIntBufferLength = 1024;
341 
342 // Encodes and then decodes a specified value, checks that the
343 // value that was encoded is the same as the decoded value, the length
344 // is correct, and that after decoding, all data in the buffer has
345 // been consumed..
346 // Returns true if everything works, false if not.
EncodeDecodeValue(uint64_t value_in,char * buffer,size_t size_of_buffer)347 bool EncodeDecodeValue(uint64_t value_in, char* buffer, size_t size_of_buffer) {
348   // Init the buffer to all 0, just for cleanliness. Makes for better
349   // output if, in debugging, we need to dump out the buffer.
350   memset(buffer, 0, size_of_buffer);
351   // make a writer. Note that for IETF encoding
352   // we do not care about endianness... It's always big-endian,
353   // but the c'tor expects to be told what endianness is in force...
354   QuicheDataWriter writer(size_of_buffer, buffer,
355                           quiche::Endianness::NETWORK_BYTE_ORDER);
356 
357   // Try to write the value.
358   if (writer.WriteVarInt62(value_in) != true) {
359     return false;
360   }
361   // Look at the value we encoded. Determine how much should have been
362   // used based on the value, and then check the state of the writer
363   // to see that it matches.
364   size_t expected_length = 0;
365   if (value_in <= 0x3f) {
366     expected_length = 1;
367   } else if (value_in <= 0x3fff) {
368     expected_length = 2;
369   } else if (value_in <= 0x3fffffff) {
370     expected_length = 4;
371   } else {
372     expected_length = 8;
373   }
374   if (writer.length() != expected_length) {
375     return false;
376   }
377 
378   // set up a reader, just the length we've used, no more, no less.
379   QuicheDataReader reader(buffer, expected_length,
380                           quiche::Endianness::NETWORK_BYTE_ORDER);
381   uint64_t value_out;
382 
383   if (reader.ReadVarInt62(&value_out) == false) {
384     return false;
385   }
386   if (value_in != value_out) {
387     return false;
388   }
389   // We only write one value so there had better be nothing left to read
390   return reader.IsDoneReading();
391 }
392 
393 // Test that 8-byte-encoded Variable Length Integers are properly laid
394 // out in the buffer.
TEST_P(QuicheDataWriterTest,VarInt8Layout)395 TEST_P(QuicheDataWriterTest, VarInt8Layout) {
396   char buffer[1024];
397 
398   // Check that the layout of bytes in the buffer is correct. Bytes
399   // are always encoded big endian...
400   memset(buffer, 0, sizeof(buffer));
401   QuicheDataWriter writer(sizeof(buffer), static_cast<char*>(buffer),
402                           quiche::Endianness::NETWORK_BYTE_ORDER);
403   EXPECT_TRUE(writer.WriteVarInt62(UINT64_C(0x3142f3e4d5c6b7a8)));
404   EXPECT_EQ(static_cast<unsigned char>(*(writer.data() + 0)),
405             (0x31 + 0xc0));  // 0xc0 for encoding
406   EXPECT_EQ(static_cast<unsigned char>(*(writer.data() + 1)), 0x42);
407   EXPECT_EQ(static_cast<unsigned char>(*(writer.data() + 2)), 0xf3);
408   EXPECT_EQ(static_cast<unsigned char>(*(writer.data() + 3)), 0xe4);
409   EXPECT_EQ(static_cast<unsigned char>(*(writer.data() + 4)), 0xd5);
410   EXPECT_EQ(static_cast<unsigned char>(*(writer.data() + 5)), 0xc6);
411   EXPECT_EQ(static_cast<unsigned char>(*(writer.data() + 6)), 0xb7);
412   EXPECT_EQ(static_cast<unsigned char>(*(writer.data() + 7)), 0xa8);
413 }
414 
415 // Test that 4-byte-encoded Variable Length Integers are properly laid
416 // out in the buffer.
TEST_P(QuicheDataWriterTest,VarInt4Layout)417 TEST_P(QuicheDataWriterTest, VarInt4Layout) {
418   char buffer[1024];
419 
420   // Check that the layout of bytes in the buffer is correct. Bytes
421   // are always encoded big endian...
422   memset(buffer, 0, sizeof(buffer));
423   QuicheDataWriter writer(sizeof(buffer), static_cast<char*>(buffer),
424                           quiche::Endianness::NETWORK_BYTE_ORDER);
425   EXPECT_TRUE(writer.WriteVarInt62(0x3243f4e5));
426   EXPECT_EQ(static_cast<unsigned char>(*(writer.data() + 0)),
427             (0x32 + 0x80));  // 0x80 for encoding
428   EXPECT_EQ(static_cast<unsigned char>(*(writer.data() + 1)), 0x43);
429   EXPECT_EQ(static_cast<unsigned char>(*(writer.data() + 2)), 0xf4);
430   EXPECT_EQ(static_cast<unsigned char>(*(writer.data() + 3)), 0xe5);
431 }
432 
433 // Test that 2-byte-encoded Variable Length Integers are properly laid
434 // out in the buffer.
TEST_P(QuicheDataWriterTest,VarInt2Layout)435 TEST_P(QuicheDataWriterTest, VarInt2Layout) {
436   char buffer[1024];
437 
438   // Check that the layout of bytes in the buffer is correct. Bytes
439   // are always encoded big endian...
440   memset(buffer, 0, sizeof(buffer));
441   QuicheDataWriter writer(sizeof(buffer), static_cast<char*>(buffer),
442                           quiche::Endianness::NETWORK_BYTE_ORDER);
443   EXPECT_TRUE(writer.WriteVarInt62(0x3647));
444   EXPECT_EQ(static_cast<unsigned char>(*(writer.data() + 0)),
445             (0x36 + 0x40));  // 0x40 for encoding
446   EXPECT_EQ(static_cast<unsigned char>(*(writer.data() + 1)), 0x47);
447 }
448 
449 // Test that 1-byte-encoded Variable Length Integers are properly laid
450 // out in the buffer.
TEST_P(QuicheDataWriterTest,VarInt1Layout)451 TEST_P(QuicheDataWriterTest, VarInt1Layout) {
452   char buffer[1024];
453 
454   // Check that the layout of bytes in the buffer
455   // is correct. Bytes are always encoded big endian...
456   memset(buffer, 0, sizeof(buffer));
457   QuicheDataWriter writer(sizeof(buffer), static_cast<char*>(buffer),
458                           quiche::Endianness::NETWORK_BYTE_ORDER);
459   EXPECT_TRUE(writer.WriteVarInt62(0x3f));
460   EXPECT_EQ(static_cast<unsigned char>(*(writer.data() + 0)), 0x3f);
461 }
462 
463 // Test certain, targeted, values that are expected to succeed:
464 // 0, 1,
465 // 0x3e, 0x3f, 0x40, 0x41 (around the 1-2 byte transitions)
466 // 0x3ffe, 0x3fff, 0x4000, 0x4001 (the 2-4 byte transition)
467 // 0x3ffffffe, 0x3fffffff, 0x40000000, 0x40000001 (the 4-8 byte
468 //                          transition)
469 // 0x3ffffffffffffffe, 0x3fffffffffffffff,  (the highest valid values)
470 // 0xfe, 0xff, 0x100, 0x101,
471 // 0xfffe, 0xffff, 0x10000, 0x10001,
472 // 0xfffffe, 0xffffff, 0x1000000, 0x1000001,
473 // 0xfffffffe, 0xffffffff, 0x100000000, 0x100000001,
474 // 0xfffffffffe, 0xffffffffff, 0x10000000000, 0x10000000001,
475 // 0xfffffffffffe, 0xffffffffffff, 0x1000000000000, 0x1000000000001,
476 // 0xfffffffffffffe, 0xffffffffffffff, 0x100000000000000, 0x100000000000001,
TEST_P(QuicheDataWriterTest,VarIntGoodTargetedValues)477 TEST_P(QuicheDataWriterTest, VarIntGoodTargetedValues) {
478   char buffer[kVarIntBufferLength];
479   uint64_t passing_values[] = {
480       0,
481       1,
482       0x3e,
483       0x3f,
484       0x40,
485       0x41,
486       0x3ffe,
487       0x3fff,
488       0x4000,
489       0x4001,
490       0x3ffffffe,
491       0x3fffffff,
492       0x40000000,
493       0x40000001,
494       0x3ffffffffffffffe,
495       0x3fffffffffffffff,
496       0xfe,
497       0xff,
498       0x100,
499       0x101,
500       0xfffe,
501       0xffff,
502       0x10000,
503       0x10001,
504       0xfffffe,
505       0xffffff,
506       0x1000000,
507       0x1000001,
508       0xfffffffe,
509       0xffffffff,
510       0x100000000,
511       0x100000001,
512       0xfffffffffe,
513       0xffffffffff,
514       0x10000000000,
515       0x10000000001,
516       0xfffffffffffe,
517       0xffffffffffff,
518       0x1000000000000,
519       0x1000000000001,
520       0xfffffffffffffe,
521       0xffffffffffffff,
522       0x100000000000000,
523       0x100000000000001,
524   };
525   for (uint64_t test_val : passing_values) {
526     EXPECT_TRUE(
527         EncodeDecodeValue(test_val, static_cast<char*>(buffer), sizeof(buffer)))
528         << " encode/decode of " << test_val << " failed";
529   }
530 }
531 //
532 // Test certain, targeted, values where failure is expected (the
533 // values are invalid w.r.t. IETF VarInt encoding):
534 // 0x4000000000000000, 0x4000000000000001,  ( Just above max allowed value)
535 // 0xfffffffffffffffe, 0xffffffffffffffff,  (should fail)
TEST_P(QuicheDataWriterTest,VarIntBadTargetedValues)536 TEST_P(QuicheDataWriterTest, VarIntBadTargetedValues) {
537   char buffer[kVarIntBufferLength];
538   uint64_t failing_values[] = {
539       0x4000000000000000,
540       0x4000000000000001,
541       0xfffffffffffffffe,
542       0xffffffffffffffff,
543   };
544   for (uint64_t test_val : failing_values) {
545     EXPECT_FALSE(
546         EncodeDecodeValue(test_val, static_cast<char*>(buffer), sizeof(buffer)))
547         << " encode/decode of " << test_val << " succeeded, but was an "
548         << "invalid value";
549   }
550 }
551 // Test writing varints with a forced length.
TEST_P(QuicheDataWriterTest,WriteVarInt62WithForcedLength)552 TEST_P(QuicheDataWriterTest, WriteVarInt62WithForcedLength) {
553   char buffer[90];
554   memset(buffer, 0, sizeof(buffer));
555   QuicheDataWriter writer(sizeof(buffer), static_cast<char*>(buffer));
556 
557   writer.WriteVarInt62WithForcedLength(1, VARIABLE_LENGTH_INTEGER_LENGTH_1);
558   writer.WriteVarInt62WithForcedLength(1, VARIABLE_LENGTH_INTEGER_LENGTH_2);
559   writer.WriteVarInt62WithForcedLength(1, VARIABLE_LENGTH_INTEGER_LENGTH_4);
560   writer.WriteVarInt62WithForcedLength(1, VARIABLE_LENGTH_INTEGER_LENGTH_8);
561 
562   writer.WriteVarInt62WithForcedLength(63, VARIABLE_LENGTH_INTEGER_LENGTH_1);
563   writer.WriteVarInt62WithForcedLength(63, VARIABLE_LENGTH_INTEGER_LENGTH_2);
564   writer.WriteVarInt62WithForcedLength(63, VARIABLE_LENGTH_INTEGER_LENGTH_4);
565   writer.WriteVarInt62WithForcedLength(63, VARIABLE_LENGTH_INTEGER_LENGTH_8);
566 
567   writer.WriteVarInt62WithForcedLength(64, VARIABLE_LENGTH_INTEGER_LENGTH_2);
568   writer.WriteVarInt62WithForcedLength(64, VARIABLE_LENGTH_INTEGER_LENGTH_4);
569   writer.WriteVarInt62WithForcedLength(64, VARIABLE_LENGTH_INTEGER_LENGTH_8);
570 
571   writer.WriteVarInt62WithForcedLength(16383, VARIABLE_LENGTH_INTEGER_LENGTH_2);
572   writer.WriteVarInt62WithForcedLength(16383, VARIABLE_LENGTH_INTEGER_LENGTH_4);
573   writer.WriteVarInt62WithForcedLength(16383, VARIABLE_LENGTH_INTEGER_LENGTH_8);
574 
575   writer.WriteVarInt62WithForcedLength(16384, VARIABLE_LENGTH_INTEGER_LENGTH_4);
576   writer.WriteVarInt62WithForcedLength(16384, VARIABLE_LENGTH_INTEGER_LENGTH_8);
577 
578   writer.WriteVarInt62WithForcedLength(1073741823,
579                                        VARIABLE_LENGTH_INTEGER_LENGTH_4);
580   writer.WriteVarInt62WithForcedLength(1073741823,
581                                        VARIABLE_LENGTH_INTEGER_LENGTH_8);
582 
583   writer.WriteVarInt62WithForcedLength(1073741824,
584                                        VARIABLE_LENGTH_INTEGER_LENGTH_8);
585 
586   QuicheDataReader reader(buffer, sizeof(buffer));
587 
588   uint64_t test_val = 0;
589   for (int i = 0; i < 4; ++i) {
590     EXPECT_TRUE(reader.ReadVarInt62(&test_val));
591     EXPECT_EQ(test_val, 1u);
592   }
593   for (int i = 0; i < 4; ++i) {
594     EXPECT_TRUE(reader.ReadVarInt62(&test_val));
595     EXPECT_EQ(test_val, 63u);
596   }
597 
598   for (int i = 0; i < 3; ++i) {
599     EXPECT_TRUE(reader.ReadVarInt62(&test_val));
600     EXPECT_EQ(test_val, 64u);
601   }
602   for (int i = 0; i < 3; ++i) {
603     EXPECT_TRUE(reader.ReadVarInt62(&test_val));
604     EXPECT_EQ(test_val, 16383u);
605   }
606 
607   for (int i = 0; i < 2; ++i) {
608     EXPECT_TRUE(reader.ReadVarInt62(&test_val));
609     EXPECT_EQ(test_val, 16384u);
610   }
611   for (int i = 0; i < 2; ++i) {
612     EXPECT_TRUE(reader.ReadVarInt62(&test_val));
613     EXPECT_EQ(test_val, 1073741823u);
614   }
615 
616   EXPECT_TRUE(reader.ReadVarInt62(&test_val));
617   EXPECT_EQ(test_val, 1073741824u);
618 
619   // We are at the end of the buffer so this should fail.
620   EXPECT_FALSE(reader.ReadVarInt62(&test_val));
621 }
622 
623 // Following tests all try to fill the buffer with multiple values,
624 // go one value more than the buffer can accommodate, then read
625 // the successfully encoded values, and try to read the unsuccessfully
626 // encoded value. The following is the number of values to encode.
627 const int kMultiVarCount = 1000;
628 
629 // Test writing & reading multiple 8-byte-encoded varints
TEST_P(QuicheDataWriterTest,MultiVarInt8)630 TEST_P(QuicheDataWriterTest, MultiVarInt8) {
631   uint64_t test_val;
632   char buffer[8 * kMultiVarCount];
633   memset(buffer, 0, sizeof(buffer));
634   QuicheDataWriter writer(sizeof(buffer), static_cast<char*>(buffer),
635                           quiche::Endianness::NETWORK_BYTE_ORDER);
636   // Put N values into the buffer. Adding i to the value ensures that
637   // each value is different so we can detect if we overwrite values,
638   // or read the same value over and over.
639   for (int i = 0; i < kMultiVarCount; i++) {
640     EXPECT_TRUE(writer.WriteVarInt62(UINT64_C(0x3142f3e4d5c6b7a8) + i));
641   }
642   EXPECT_EQ(writer.length(), 8u * kMultiVarCount);
643 
644   // N+1st should fail, the buffer is full.
645   EXPECT_FALSE(writer.WriteVarInt62(UINT64_C(0x3142f3e4d5c6b7a8)));
646 
647   // Now we should be able to read out the N values that were
648   // successfully encoded.
649   QuicheDataReader reader(buffer, sizeof(buffer),
650                           quiche::Endianness::NETWORK_BYTE_ORDER);
651   for (int i = 0; i < kMultiVarCount; i++) {
652     EXPECT_TRUE(reader.ReadVarInt62(&test_val));
653     EXPECT_EQ(test_val, (UINT64_C(0x3142f3e4d5c6b7a8) + i));
654   }
655   // And the N+1st should fail.
656   EXPECT_FALSE(reader.ReadVarInt62(&test_val));
657 }
658 
659 // Test writing & reading multiple 4-byte-encoded varints
TEST_P(QuicheDataWriterTest,MultiVarInt4)660 TEST_P(QuicheDataWriterTest, MultiVarInt4) {
661   uint64_t test_val;
662   char buffer[4 * kMultiVarCount];
663   memset(buffer, 0, sizeof(buffer));
664   QuicheDataWriter writer(sizeof(buffer), static_cast<char*>(buffer),
665                           quiche::Endianness::NETWORK_BYTE_ORDER);
666   // Put N values into the buffer. Adding i to the value ensures that
667   // each value is different so we can detect if we overwrite values,
668   // or read the same value over and over.
669   for (int i = 0; i < kMultiVarCount; i++) {
670     EXPECT_TRUE(writer.WriteVarInt62(UINT64_C(0x3142f3e4) + i));
671   }
672   EXPECT_EQ(writer.length(), 4u * kMultiVarCount);
673 
674   // N+1st should fail, the buffer is full.
675   EXPECT_FALSE(writer.WriteVarInt62(UINT64_C(0x3142f3e4)));
676 
677   // Now we should be able to read out the N values that were
678   // successfully encoded.
679   QuicheDataReader reader(buffer, sizeof(buffer),
680                           quiche::Endianness::NETWORK_BYTE_ORDER);
681   for (int i = 0; i < kMultiVarCount; i++) {
682     EXPECT_TRUE(reader.ReadVarInt62(&test_val));
683     EXPECT_EQ(test_val, (UINT64_C(0x3142f3e4) + i));
684   }
685   // And the N+1st should fail.
686   EXPECT_FALSE(reader.ReadVarInt62(&test_val));
687 }
688 
689 // Test writing & reading multiple 2-byte-encoded varints
TEST_P(QuicheDataWriterTest,MultiVarInt2)690 TEST_P(QuicheDataWriterTest, MultiVarInt2) {
691   uint64_t test_val;
692   char buffer[2 * kMultiVarCount];
693   memset(buffer, 0, sizeof(buffer));
694   QuicheDataWriter writer(sizeof(buffer), static_cast<char*>(buffer),
695                           quiche::Endianness::NETWORK_BYTE_ORDER);
696   // Put N values into the buffer. Adding i to the value ensures that
697   // each value is different so we can detect if we overwrite values,
698   // or read the same value over and over.
699   for (int i = 0; i < kMultiVarCount; i++) {
700     EXPECT_TRUE(writer.WriteVarInt62(UINT64_C(0x3142) + i));
701   }
702   EXPECT_EQ(writer.length(), 2u * kMultiVarCount);
703 
704   // N+1st should fail, the buffer is full.
705   EXPECT_FALSE(writer.WriteVarInt62(UINT64_C(0x3142)));
706 
707   // Now we should be able to read out the N values that were
708   // successfully encoded.
709   QuicheDataReader reader(buffer, sizeof(buffer),
710                           quiche::Endianness::NETWORK_BYTE_ORDER);
711   for (int i = 0; i < kMultiVarCount; i++) {
712     EXPECT_TRUE(reader.ReadVarInt62(&test_val));
713     EXPECT_EQ(test_val, (UINT64_C(0x3142) + i));
714   }
715   // And the N+1st should fail.
716   EXPECT_FALSE(reader.ReadVarInt62(&test_val));
717 }
718 
719 // Test writing & reading multiple 1-byte-encoded varints
TEST_P(QuicheDataWriterTest,MultiVarInt1)720 TEST_P(QuicheDataWriterTest, MultiVarInt1) {
721   uint64_t test_val;
722   char buffer[1 * kMultiVarCount];
723   memset(buffer, 0, sizeof(buffer));
724   QuicheDataWriter writer(sizeof(buffer), static_cast<char*>(buffer),
725                           quiche::Endianness::NETWORK_BYTE_ORDER);
726   // Put N values into the buffer. Adding i to the value ensures that
727   // each value is different so we can detect if we overwrite values,
728   // or read the same value over and over. &0xf ensures we do not
729   // overflow the max value for single-byte encoding.
730   for (int i = 0; i < kMultiVarCount; i++) {
731     EXPECT_TRUE(writer.WriteVarInt62(UINT64_C(0x30) + (i & 0xf)));
732   }
733   EXPECT_EQ(writer.length(), 1u * kMultiVarCount);
734 
735   // N+1st should fail, the buffer is full.
736   EXPECT_FALSE(writer.WriteVarInt62(UINT64_C(0x31)));
737 
738   // Now we should be able to read out the N values that were
739   // successfully encoded.
740   QuicheDataReader reader(buffer, sizeof(buffer),
741                           quiche::Endianness::NETWORK_BYTE_ORDER);
742   for (int i = 0; i < kMultiVarCount; i++) {
743     EXPECT_TRUE(reader.ReadVarInt62(&test_val));
744     EXPECT_EQ(test_val, (UINT64_C(0x30) + (i & 0xf)));
745   }
746   // And the N+1st should fail.
747   EXPECT_FALSE(reader.ReadVarInt62(&test_val));
748 }
749 
TEST_P(QuicheDataWriterTest,Seek)750 TEST_P(QuicheDataWriterTest, Seek) {
751   char buffer[3] = {};
752   QuicheDataWriter writer(ABSL_ARRAYSIZE(buffer), buffer,
753                           GetParam().endianness);
754   EXPECT_TRUE(writer.WriteUInt8(42));
755   EXPECT_TRUE(writer.Seek(1));
756   EXPECT_TRUE(writer.WriteUInt8(3));
757 
758   char expected[] = {42, 0, 3};
759   for (size_t i = 0; i < ABSL_ARRAYSIZE(expected); ++i) {
760     EXPECT_EQ(buffer[i], expected[i]);
761   }
762 }
763 
TEST_P(QuicheDataWriterTest,SeekTooFarFails)764 TEST_P(QuicheDataWriterTest, SeekTooFarFails) {
765   char buffer[20];
766 
767   // Check that one can seek to the end of the writer, but not past.
768   {
769     QuicheDataWriter writer(ABSL_ARRAYSIZE(buffer), buffer,
770                             GetParam().endianness);
771     EXPECT_TRUE(writer.Seek(20));
772     EXPECT_FALSE(writer.Seek(1));
773   }
774 
775   // Seeking several bytes past the end fails.
776   {
777     QuicheDataWriter writer(ABSL_ARRAYSIZE(buffer), buffer,
778                             GetParam().endianness);
779     EXPECT_FALSE(writer.Seek(100));
780   }
781 
782   // Seeking so far that arithmetic overflow could occur also fails.
783   {
784     QuicheDataWriter writer(ABSL_ARRAYSIZE(buffer), buffer,
785                             GetParam().endianness);
786     EXPECT_TRUE(writer.Seek(10));
787     EXPECT_FALSE(writer.Seek(std::numeric_limits<size_t>::max()));
788   }
789 }
790 
TEST_P(QuicheDataWriterTest,PayloadReads)791 TEST_P(QuicheDataWriterTest, PayloadReads) {
792   char buffer[16] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16};
793   char expected_first_read[4] = {1, 2, 3, 4};
794   char expected_remaining[12] = {5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16};
795   QuicheDataReader reader(buffer, sizeof(buffer));
796   absl::string_view previously_read_payload1 = reader.PreviouslyReadPayload();
797   EXPECT_TRUE(previously_read_payload1.empty());
798   char first_read_buffer[4] = {};
799   EXPECT_TRUE(reader.ReadBytes(first_read_buffer, sizeof(first_read_buffer)));
800   test::CompareCharArraysWithHexError(
801       "first read", first_read_buffer, sizeof(first_read_buffer),
802       expected_first_read, sizeof(expected_first_read));
803   absl::string_view peeked_remaining_payload = reader.PeekRemainingPayload();
804   test::CompareCharArraysWithHexError(
805       "peeked_remaining_payload", peeked_remaining_payload.data(),
806       peeked_remaining_payload.length(), expected_remaining,
807       sizeof(expected_remaining));
808   absl::string_view full_payload = reader.FullPayload();
809   test::CompareCharArraysWithHexError("full_payload", full_payload.data(),
810                                       full_payload.length(), buffer,
811                                       sizeof(buffer));
812   absl::string_view previously_read_payload2 = reader.PreviouslyReadPayload();
813   test::CompareCharArraysWithHexError(
814       "previously_read_payload2", previously_read_payload2.data(),
815       previously_read_payload2.length(), first_read_buffer,
816       sizeof(first_read_buffer));
817   absl::string_view read_remaining_payload = reader.ReadRemainingPayload();
818   test::CompareCharArraysWithHexError(
819       "read_remaining_payload", read_remaining_payload.data(),
820       read_remaining_payload.length(), expected_remaining,
821       sizeof(expected_remaining));
822   EXPECT_TRUE(reader.IsDoneReading());
823   absl::string_view full_payload2 = reader.FullPayload();
824   test::CompareCharArraysWithHexError("full_payload2", full_payload2.data(),
825                                       full_payload2.length(), buffer,
826                                       sizeof(buffer));
827   absl::string_view previously_read_payload3 = reader.PreviouslyReadPayload();
828   test::CompareCharArraysWithHexError(
829       "previously_read_payload3", previously_read_payload3.data(),
830       previously_read_payload3.length(), buffer, sizeof(buffer));
831 }
832 
833 }  // namespace
834 }  // namespace test
835 }  // namespace quiche
836