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