blob: e05af218994d607dca99e59e74b187d64dea800d [file] [log] [blame]
QUICHE teama6ef0a62019-03-07 20:34:33 -05001// Copyright (c) 2012 The Chromium Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#include "net/third_party/quiche/src/quic/core/quic_data_writer.h"
6
7#include <cstdint>
dschinazicf5b1e22019-07-17 18:35:17 -07008#include <cstring>
QUICHE teama6ef0a62019-03-07 20:34:33 -05009
10#include "net/third_party/quiche/src/quic/core/quic_connection_id.h"
11#include "net/third_party/quiche/src/quic/core/quic_data_reader.h"
renjietangd077f8c2020-03-23 17:22:09 -070012#include "net/third_party/quiche/src/quic/core/quic_types.h"
QUICHE teama6ef0a62019-03-07 20:34:33 -050013#include "net/third_party/quiche/src/quic/core/quic_utils.h"
QUICHE team0131a5b2019-03-20 15:23:27 -070014#include "net/third_party/quiche/src/quic/platform/api/quic_expect_bug.h"
QUICHE teama6ef0a62019-03-07 20:34:33 -050015#include "net/third_party/quiche/src/quic/platform/api/quic_flags.h"
16#include "net/third_party/quiche/src/quic/platform/api/quic_test.h"
17#include "net/third_party/quiche/src/quic/test_tools/quic_test_utils.h"
bnc4e9283d2019-12-17 07:08:57 -080018#include "net/third_party/quiche/src/common/platform/api/quiche_arraysize.h"
QUICHE team173c48f2019-11-19 16:34:44 -080019#include "net/third_party/quiche/src/common/platform/api/quiche_endian.h"
dmcardlecf0bfcf2019-12-13 08:08:21 -080020#include "net/third_party/quiche/src/common/platform/api/quiche_str_cat.h"
21#include "net/third_party/quiche/src/common/platform/api/quiche_string_piece.h"
dmcardle8f7df532020-01-07 13:28:57 -080022#include "net/third_party/quiche/src/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) {
dmcardlecf0bfcf2019-12-13 08:08:21 -080040 return quiche::QuicheStrCat(
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 };
bnc4e9283d2019-12-17 07:08:57 -0800272 EXPECT_EQ(connection_id.length(), QUICHE_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);
bnc4e9283d2019-12-17 07:08:57 -0800283 EXPECT_TRUE(reader.ReadConnectionId(&read_connection_id,
284 QUICHE_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 };
bnc4e9283d2019-12-17 07:08:57 -0800294 EXPECT_EQ(QUICHE_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] = {};
bnc4e9283d2019-12-17 07:08:57 -0800297 QuicDataWriter writer(QUICHE_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,
bnc4e9283d2019-12-17 07:08:57 -0800302 QUICHE_ARRAYSIZE(length_prefixed_connection_id));
dschinazicf5b1e22019-07-17 18:35:17 -0700303
304 // Verify that writing length then connection ID produces the same output.
bnc4e9283d2019-12-17 07:08:57 -0800305 memset(buffer, 0, QUICHE_ARRAYSIZE(buffer));
306 QuicDataWriter writer2(QUICHE_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,
bnc4e9283d2019-12-17 07:08:57 -0800312 QUICHE_ARRAYSIZE(length_prefixed_connection_id));
dschinazicf5b1e22019-07-17 18:35:17 -0700313
314 QuicConnectionId read_connection_id;
bnc4e9283d2019-12-17 07:08:57 -0800315 QuicDataReader reader(buffer, QUICHE_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;
bnc4e9283d2019-12-17 07:08:57 -0800322 QuicDataReader reader2(buffer, QUICHE_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];
bnc4e9283d2019-12-17 07:08:57 -0800333 QuicDataWriter writer(QUICHE_ARRAYSIZE(buffer), buffer,
334 GetParam().endianness);
QUICHE teama6ef0a62019-03-07 20:34:33 -0500335 EXPECT_TRUE(writer.WriteConnectionId(empty_connection_id));
336 EXPECT_TRUE(writer.WriteUInt8(1));
337 EXPECT_TRUE(writer.WriteConnectionId(empty_connection_id));
338 EXPECT_TRUE(writer.WriteUInt8(2));
339 EXPECT_TRUE(writer.WriteConnectionId(empty_connection_id));
340 EXPECT_FALSE(writer.WriteUInt8(3));
341
342 EXPECT_EQ(buffer[0], 1);
343 EXPECT_EQ(buffer[1], 2);
344
345 QuicConnectionId read_connection_id = TestConnectionId();
346 uint8_t read_byte;
bnc4e9283d2019-12-17 07:08:57 -0800347 QuicDataReader reader(buffer, QUICHE_ARRAYSIZE(buffer),
348 GetParam().endianness);
QUICHE teama6ef0a62019-03-07 20:34:33 -0500349 EXPECT_TRUE(reader.ReadConnectionId(&read_connection_id, 0));
350 EXPECT_EQ(read_connection_id, empty_connection_id);
351 EXPECT_TRUE(reader.ReadUInt8(&read_byte));
352 EXPECT_EQ(read_byte, 1);
353 // Reset read_connection_id to something else to verify that
354 // ReadConnectionId properly sets it back to empty.
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_TRUE(reader.ReadUInt8(&read_byte));
359 EXPECT_EQ(read_byte, 2);
360 read_connection_id = TestConnectionId();
361 EXPECT_TRUE(reader.ReadConnectionId(&read_connection_id, 0));
362 EXPECT_EQ(read_connection_id, empty_connection_id);
363 EXPECT_FALSE(reader.ReadUInt8(&read_byte));
364}
365
366TEST_P(QuicDataWriterTest, WriteTag) {
367 char CHLO[] = {
368 'C',
369 'H',
370 'L',
371 'O',
372 };
373 const int kBufferLength = sizeof(QuicTag);
374 char buffer[kBufferLength];
375 QuicDataWriter writer(kBufferLength, buffer, GetParam().endianness);
376 writer.WriteTag(kCHLO);
dmcardle8f7df532020-01-07 13:28:57 -0800377 quiche::test::CompareCharArraysWithHexError("CHLO", buffer, kBufferLength,
378 CHLO, kBufferLength);
QUICHE teama6ef0a62019-03-07 20:34:33 -0500379
380 QuicTag read_chlo;
381 QuicDataReader reader(buffer, kBufferLength, GetParam().endianness);
382 reader.ReadTag(&read_chlo);
383 EXPECT_EQ(kCHLO, read_chlo);
384}
385
386TEST_P(QuicDataWriterTest, Write16BitUnsignedIntegers) {
387 char little_endian16[] = {0x22, 0x11};
388 char big_endian16[] = {0x11, 0x22};
389 char buffer16[2];
390 {
391 uint16_t in_memory16 = 0x1122;
392 QuicDataWriter writer(2, buffer16, GetParam().endianness);
393 writer.WriteUInt16(in_memory16);
dmcardle8f7df532020-01-07 13:28:57 -0800394 quiche::test::CompareCharArraysWithHexError(
QUICHE teama6ef0a62019-03-07 20:34:33 -0500395 "uint16_t", buffer16, 2,
QUICHE team173c48f2019-11-19 16:34:44 -0800396 GetParam().endianness == quiche::NETWORK_BYTE_ORDER ? big_endian16
397 : little_endian16,
QUICHE teama6ef0a62019-03-07 20:34:33 -0500398 2);
399
400 uint16_t read_number16;
401 QuicDataReader reader(buffer16, 2, GetParam().endianness);
402 reader.ReadUInt16(&read_number16);
403 EXPECT_EQ(in_memory16, read_number16);
404 }
405
406 {
407 uint64_t in_memory16 = 0x0000000000001122;
408 QuicDataWriter writer(2, buffer16, GetParam().endianness);
409 writer.WriteBytesToUInt64(2, in_memory16);
dmcardle8f7df532020-01-07 13:28:57 -0800410 quiche::test::CompareCharArraysWithHexError(
QUICHE teama6ef0a62019-03-07 20:34:33 -0500411 "uint16_t", buffer16, 2,
QUICHE team173c48f2019-11-19 16:34:44 -0800412 GetParam().endianness == quiche::NETWORK_BYTE_ORDER ? big_endian16
413 : little_endian16,
QUICHE teama6ef0a62019-03-07 20:34:33 -0500414 2);
415
416 uint64_t read_number16;
417 QuicDataReader reader(buffer16, 2, GetParam().endianness);
418 reader.ReadBytesToUInt64(2, &read_number16);
419 EXPECT_EQ(in_memory16, read_number16);
420 }
421}
422
423TEST_P(QuicDataWriterTest, Write24BitUnsignedIntegers) {
424 char little_endian24[] = {0x33, 0x22, 0x11};
425 char big_endian24[] = {0x11, 0x22, 0x33};
426 char buffer24[3];
427 uint64_t in_memory24 = 0x0000000000112233;
428 QuicDataWriter writer(3, buffer24, GetParam().endianness);
429 writer.WriteBytesToUInt64(3, in_memory24);
dmcardle8f7df532020-01-07 13:28:57 -0800430 quiche::test::CompareCharArraysWithHexError(
QUICHE teama6ef0a62019-03-07 20:34:33 -0500431 "uint24", buffer24, 3,
QUICHE team173c48f2019-11-19 16:34:44 -0800432 GetParam().endianness == quiche::NETWORK_BYTE_ORDER ? big_endian24
433 : little_endian24,
QUICHE teama6ef0a62019-03-07 20:34:33 -0500434 3);
435
436 uint64_t read_number24;
437 QuicDataReader reader(buffer24, 3, GetParam().endianness);
438 reader.ReadBytesToUInt64(3, &read_number24);
439 EXPECT_EQ(in_memory24, read_number24);
440}
441
442TEST_P(QuicDataWriterTest, Write32BitUnsignedIntegers) {
443 char little_endian32[] = {0x44, 0x33, 0x22, 0x11};
444 char big_endian32[] = {0x11, 0x22, 0x33, 0x44};
445 char buffer32[4];
446 {
447 uint32_t in_memory32 = 0x11223344;
448 QuicDataWriter writer(4, buffer32, GetParam().endianness);
449 writer.WriteUInt32(in_memory32);
dmcardle8f7df532020-01-07 13:28:57 -0800450 quiche::test::CompareCharArraysWithHexError(
QUICHE teama6ef0a62019-03-07 20:34:33 -0500451 "uint32_t", buffer32, 4,
QUICHE team173c48f2019-11-19 16:34:44 -0800452 GetParam().endianness == quiche::NETWORK_BYTE_ORDER ? big_endian32
453 : little_endian32,
QUICHE teama6ef0a62019-03-07 20:34:33 -0500454 4);
455
456 uint32_t read_number32;
457 QuicDataReader reader(buffer32, 4, GetParam().endianness);
458 reader.ReadUInt32(&read_number32);
459 EXPECT_EQ(in_memory32, read_number32);
460 }
461
462 {
463 uint64_t in_memory32 = 0x11223344;
464 QuicDataWriter writer(4, buffer32, GetParam().endianness);
465 writer.WriteBytesToUInt64(4, in_memory32);
dmcardle8f7df532020-01-07 13:28:57 -0800466 quiche::test::CompareCharArraysWithHexError(
QUICHE teama6ef0a62019-03-07 20:34:33 -0500467 "uint32_t", buffer32, 4,
QUICHE team173c48f2019-11-19 16:34:44 -0800468 GetParam().endianness == quiche::NETWORK_BYTE_ORDER ? big_endian32
469 : little_endian32,
QUICHE teama6ef0a62019-03-07 20:34:33 -0500470 4);
471
472 uint64_t read_number32;
473 QuicDataReader reader(buffer32, 4, GetParam().endianness);
474 reader.ReadBytesToUInt64(4, &read_number32);
475 EXPECT_EQ(in_memory32, read_number32);
476 }
477}
478
479TEST_P(QuicDataWriterTest, Write40BitUnsignedIntegers) {
480 uint64_t in_memory40 = 0x0000001122334455;
481 char little_endian40[] = {0x55, 0x44, 0x33, 0x22, 0x11};
482 char big_endian40[] = {0x11, 0x22, 0x33, 0x44, 0x55};
483 char buffer40[5];
484 QuicDataWriter writer(5, buffer40, GetParam().endianness);
485 writer.WriteBytesToUInt64(5, in_memory40);
dmcardle8f7df532020-01-07 13:28:57 -0800486 quiche::test::CompareCharArraysWithHexError(
QUICHE teama6ef0a62019-03-07 20:34:33 -0500487 "uint40", buffer40, 5,
QUICHE team173c48f2019-11-19 16:34:44 -0800488 GetParam().endianness == quiche::NETWORK_BYTE_ORDER ? big_endian40
489 : little_endian40,
QUICHE teama6ef0a62019-03-07 20:34:33 -0500490 5);
491
492 uint64_t read_number40;
493 QuicDataReader reader(buffer40, 5, GetParam().endianness);
494 reader.ReadBytesToUInt64(5, &read_number40);
495 EXPECT_EQ(in_memory40, read_number40);
496}
497
498TEST_P(QuicDataWriterTest, Write48BitUnsignedIntegers) {
499 uint64_t in_memory48 = 0x0000112233445566;
500 char little_endian48[] = {0x66, 0x55, 0x44, 0x33, 0x22, 0x11};
501 char big_endian48[] = {0x11, 0x22, 0x33, 0x44, 0x55, 0x66};
502 char buffer48[6];
503 QuicDataWriter writer(6, buffer48, GetParam().endianness);
504 writer.WriteBytesToUInt64(6, in_memory48);
dmcardle8f7df532020-01-07 13:28:57 -0800505 quiche::test::CompareCharArraysWithHexError(
QUICHE teama6ef0a62019-03-07 20:34:33 -0500506 "uint48", buffer48, 6,
QUICHE team173c48f2019-11-19 16:34:44 -0800507 GetParam().endianness == quiche::NETWORK_BYTE_ORDER ? big_endian48
508 : little_endian48,
QUICHE teama6ef0a62019-03-07 20:34:33 -0500509 6);
510
511 uint64_t read_number48;
512 QuicDataReader reader(buffer48, 6, GetParam().endianness);
513 reader.ReadBytesToUInt64(6., &read_number48);
514 EXPECT_EQ(in_memory48, read_number48);
515}
516
517TEST_P(QuicDataWriterTest, Write56BitUnsignedIntegers) {
518 uint64_t in_memory56 = 0x0011223344556677;
519 char little_endian56[] = {0x77, 0x66, 0x55, 0x44, 0x33, 0x22, 0x11};
520 char big_endian56[] = {0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77};
521 char buffer56[7];
522 QuicDataWriter writer(7, buffer56, GetParam().endianness);
523 writer.WriteBytesToUInt64(7, in_memory56);
dmcardle8f7df532020-01-07 13:28:57 -0800524 quiche::test::CompareCharArraysWithHexError(
QUICHE teama6ef0a62019-03-07 20:34:33 -0500525 "uint56", buffer56, 7,
QUICHE team173c48f2019-11-19 16:34:44 -0800526 GetParam().endianness == quiche::NETWORK_BYTE_ORDER ? big_endian56
527 : little_endian56,
QUICHE teama6ef0a62019-03-07 20:34:33 -0500528 7);
529
530 uint64_t read_number56;
531 QuicDataReader reader(buffer56, 7, GetParam().endianness);
532 reader.ReadBytesToUInt64(7, &read_number56);
533 EXPECT_EQ(in_memory56, read_number56);
534}
535
536TEST_P(QuicDataWriterTest, Write64BitUnsignedIntegers) {
537 uint64_t in_memory64 = 0x1122334455667788;
538 unsigned char little_endian64[] = {0x88, 0x77, 0x66, 0x55,
539 0x44, 0x33, 0x22, 0x11};
540 unsigned char big_endian64[] = {0x11, 0x22, 0x33, 0x44,
541 0x55, 0x66, 0x77, 0x88};
542 char buffer64[8];
543 QuicDataWriter writer(8, buffer64, GetParam().endianness);
544 writer.WriteBytesToUInt64(8, in_memory64);
dmcardle8f7df532020-01-07 13:28:57 -0800545 quiche::test::CompareCharArraysWithHexError(
QUICHE teama6ef0a62019-03-07 20:34:33 -0500546 "uint64_t", buffer64, 8,
QUICHE team173c48f2019-11-19 16:34:44 -0800547 GetParam().endianness == quiche::NETWORK_BYTE_ORDER
548 ? AsChars(big_endian64)
549 : AsChars(little_endian64),
QUICHE teama6ef0a62019-03-07 20:34:33 -0500550 8);
551
552 uint64_t read_number64;
553 QuicDataReader reader(buffer64, 8, GetParam().endianness);
554 reader.ReadBytesToUInt64(8, &read_number64);
555 EXPECT_EQ(in_memory64, read_number64);
556
557 QuicDataWriter writer2(8, buffer64, GetParam().endianness);
558 writer2.WriteUInt64(in_memory64);
dmcardle8f7df532020-01-07 13:28:57 -0800559 quiche::test::CompareCharArraysWithHexError(
QUICHE teama6ef0a62019-03-07 20:34:33 -0500560 "uint64_t", buffer64, 8,
QUICHE team173c48f2019-11-19 16:34:44 -0800561 GetParam().endianness == quiche::NETWORK_BYTE_ORDER
562 ? AsChars(big_endian64)
563 : AsChars(little_endian64),
QUICHE teama6ef0a62019-03-07 20:34:33 -0500564 8);
565 read_number64 = 0u;
566 QuicDataReader reader2(buffer64, 8, GetParam().endianness);
567 reader2.ReadUInt64(&read_number64);
568 EXPECT_EQ(in_memory64, read_number64);
569}
570
571TEST_P(QuicDataWriterTest, WriteIntegers) {
572 char buf[43];
573 uint8_t i8 = 0x01;
574 uint16_t i16 = 0x0123;
575 uint32_t i32 = 0x01234567;
576 uint64_t i64 = 0x0123456789ABCDEF;
577 QuicDataWriter writer(46, buf, GetParam().endianness);
578 for (size_t i = 0; i < 10; ++i) {
579 switch (i) {
580 case 0u:
581 EXPECT_TRUE(writer.WriteBytesToUInt64(i, i64));
582 break;
583 case 1u:
584 EXPECT_TRUE(writer.WriteUInt8(i8));
585 EXPECT_TRUE(writer.WriteBytesToUInt64(i, i64));
586 break;
587 case 2u:
588 EXPECT_TRUE(writer.WriteUInt16(i16));
589 EXPECT_TRUE(writer.WriteBytesToUInt64(i, i64));
590 break;
591 case 3u:
592 EXPECT_TRUE(writer.WriteBytesToUInt64(i, i64));
593 break;
594 case 4u:
595 EXPECT_TRUE(writer.WriteUInt32(i32));
596 EXPECT_TRUE(writer.WriteBytesToUInt64(i, i64));
597 break;
598 case 5u:
599 case 6u:
600 case 7u:
601 case 8u:
602 EXPECT_TRUE(writer.WriteBytesToUInt64(i, i64));
603 break;
604 default:
605 EXPECT_FALSE(writer.WriteBytesToUInt64(i, i64));
606 }
607 }
608
609 QuicDataReader reader(buf, 46, GetParam().endianness);
610 for (size_t i = 0; i < 10; ++i) {
611 uint8_t read8;
612 uint16_t read16;
613 uint32_t read32;
614 uint64_t read64;
615 switch (i) {
616 case 0u:
617 EXPECT_TRUE(reader.ReadBytesToUInt64(i, &read64));
618 EXPECT_EQ(0u, read64);
619 break;
620 case 1u:
621 EXPECT_TRUE(reader.ReadUInt8(&read8));
622 EXPECT_TRUE(reader.ReadBytesToUInt64(i, &read64));
623 EXPECT_EQ(i8, read8);
624 EXPECT_EQ(0xEFu, read64);
625 break;
626 case 2u:
627 EXPECT_TRUE(reader.ReadUInt16(&read16));
628 EXPECT_TRUE(reader.ReadBytesToUInt64(i, &read64));
629 EXPECT_EQ(i16, read16);
630 EXPECT_EQ(0xCDEFu, read64);
631 break;
632 case 3u:
633 EXPECT_TRUE(reader.ReadBytesToUInt64(i, &read64));
634 EXPECT_EQ(0xABCDEFu, read64);
635 break;
636 case 4u:
637 EXPECT_TRUE(reader.ReadUInt32(&read32));
638 EXPECT_TRUE(reader.ReadBytesToUInt64(i, &read64));
639 EXPECT_EQ(i32, read32);
640 EXPECT_EQ(0x89ABCDEFu, read64);
641 break;
642 case 5u:
643 EXPECT_TRUE(reader.ReadBytesToUInt64(i, &read64));
644 EXPECT_EQ(0x6789ABCDEFu, read64);
645 break;
646 case 6u:
647 EXPECT_TRUE(reader.ReadBytesToUInt64(i, &read64));
648 EXPECT_EQ(0x456789ABCDEFu, read64);
649 break;
650 case 7u:
651 EXPECT_TRUE(reader.ReadBytesToUInt64(i, &read64));
652 EXPECT_EQ(0x23456789ABCDEFu, read64);
653 break;
654 case 8u:
655 EXPECT_TRUE(reader.ReadBytesToUInt64(i, &read64));
656 EXPECT_EQ(0x0123456789ABCDEFu, read64);
657 break;
658 default:
659 EXPECT_FALSE(reader.ReadBytesToUInt64(i, &read64));
660 }
661 }
662}
663
664TEST_P(QuicDataWriterTest, WriteBytes) {
665 char bytes[] = {0, 1, 2, 3, 4, 5, 6, 7, 8};
bnc4e9283d2019-12-17 07:08:57 -0800666 char buf[QUICHE_ARRAYSIZE(bytes)];
667 QuicDataWriter writer(QUICHE_ARRAYSIZE(buf), buf, GetParam().endianness);
668 EXPECT_TRUE(writer.WriteBytes(bytes, QUICHE_ARRAYSIZE(bytes)));
669 for (unsigned int i = 0; i < QUICHE_ARRAYSIZE(bytes); ++i) {
QUICHE teama6ef0a62019-03-07 20:34:33 -0500670 EXPECT_EQ(bytes[i], buf[i]);
671 }
672}
673
674const int kVarIntBufferLength = 1024;
675
676// Encodes and then decodes a specified value, checks that the
677// value that was encoded is the same as the decoded value, the length
678// is correct, and that after decoding, all data in the buffer has
679// been consumed..
680// Returns true if everything works, false if not.
681bool EncodeDecodeValue(uint64_t value_in, char* buffer, size_t size_of_buffer) {
682 // Init the buffer to all 0, just for cleanliness. Makes for better
683 // output if, in debugging, we need to dump out the buffer.
684 memset(buffer, 0, size_of_buffer);
685 // make a writer. Note that for IETF encoding
686 // we do not care about endianness... It's always big-endian,
687 // but the c'tor expects to be told what endianness is in force...
QUICHE team173c48f2019-11-19 16:34:44 -0800688 QuicDataWriter writer(size_of_buffer, buffer,
689 quiche::Endianness::NETWORK_BYTE_ORDER);
QUICHE teama6ef0a62019-03-07 20:34:33 -0500690
691 // Try to write the value.
692 if (writer.WriteVarInt62(value_in) != true) {
693 return false;
694 }
695 // Look at the value we encoded. Determine how much should have been
696 // used based on the value, and then check the state of the writer
697 // to see that it matches.
698 size_t expected_length = 0;
699 if (value_in <= 0x3f) {
700 expected_length = 1;
701 } else if (value_in <= 0x3fff) {
702 expected_length = 2;
703 } else if (value_in <= 0x3fffffff) {
704 expected_length = 4;
705 } else {
706 expected_length = 8;
707 }
708 if (writer.length() != expected_length) {
709 return false;
710 }
711
712 // set up a reader, just the length we've used, no more, no less.
713 QuicDataReader reader(buffer, expected_length,
QUICHE team173c48f2019-11-19 16:34:44 -0800714 quiche::Endianness::NETWORK_BYTE_ORDER);
QUICHE teama6ef0a62019-03-07 20:34:33 -0500715 uint64_t value_out;
716
717 if (reader.ReadVarInt62(&value_out) == false) {
718 return false;
719 }
720 if (value_in != value_out) {
721 return false;
722 }
723 // We only write one value so there had better be nothing left to read
724 return reader.IsDoneReading();
725}
726
727// Test that 8-byte-encoded Variable Length Integers are properly laid
728// out in the buffer.
729TEST_P(QuicDataWriterTest, VarInt8Layout) {
730 char buffer[1024];
731
732 // Check that the layout of bytes in the buffer is correct. Bytes
733 // are always encoded big endian...
734 memset(buffer, 0, sizeof(buffer));
735 QuicDataWriter writer(sizeof(buffer), static_cast<char*>(buffer),
QUICHE team173c48f2019-11-19 16:34:44 -0800736 quiche::Endianness::NETWORK_BYTE_ORDER);
QUICHE teama6ef0a62019-03-07 20:34:33 -0500737 EXPECT_TRUE(writer.WriteVarInt62(UINT64_C(0x3142f3e4d5c6b7a8)));
738 EXPECT_EQ(static_cast<unsigned char>(*(writer.data() + 0)),
739 (0x31 + 0xc0)); // 0xc0 for encoding
740 EXPECT_EQ(static_cast<unsigned char>(*(writer.data() + 1)), 0x42);
741 EXPECT_EQ(static_cast<unsigned char>(*(writer.data() + 2)), 0xf3);
742 EXPECT_EQ(static_cast<unsigned char>(*(writer.data() + 3)), 0xe4);
743 EXPECT_EQ(static_cast<unsigned char>(*(writer.data() + 4)), 0xd5);
744 EXPECT_EQ(static_cast<unsigned char>(*(writer.data() + 5)), 0xc6);
745 EXPECT_EQ(static_cast<unsigned char>(*(writer.data() + 6)), 0xb7);
746 EXPECT_EQ(static_cast<unsigned char>(*(writer.data() + 7)), 0xa8);
747}
748
749// Test that 4-byte-encoded Variable Length Integers are properly laid
750// out in the buffer.
751TEST_P(QuicDataWriterTest, VarInt4Layout) {
752 char buffer[1024];
753
754 // Check that the layout of bytes in the buffer is correct. Bytes
755 // are always encoded big endian...
756 memset(buffer, 0, sizeof(buffer));
757 QuicDataWriter writer(sizeof(buffer), static_cast<char*>(buffer),
QUICHE team173c48f2019-11-19 16:34:44 -0800758 quiche::Endianness::NETWORK_BYTE_ORDER);
QUICHE teama6ef0a62019-03-07 20:34:33 -0500759 EXPECT_TRUE(writer.WriteVarInt62(0x3243f4e5));
760 EXPECT_EQ(static_cast<unsigned char>(*(writer.data() + 0)),
761 (0x32 + 0x80)); // 0x80 for encoding
762 EXPECT_EQ(static_cast<unsigned char>(*(writer.data() + 1)), 0x43);
763 EXPECT_EQ(static_cast<unsigned char>(*(writer.data() + 2)), 0xf4);
764 EXPECT_EQ(static_cast<unsigned char>(*(writer.data() + 3)), 0xe5);
765}
766
767// Test that 2-byte-encoded Variable Length Integers are properly laid
768// out in the buffer.
769TEST_P(QuicDataWriterTest, VarInt2Layout) {
770 char buffer[1024];
771
772 // Check that the layout of bytes in the buffer is correct. Bytes
773 // are always encoded big endian...
774 memset(buffer, 0, sizeof(buffer));
775 QuicDataWriter writer(sizeof(buffer), static_cast<char*>(buffer),
QUICHE team173c48f2019-11-19 16:34:44 -0800776 quiche::Endianness::NETWORK_BYTE_ORDER);
QUICHE teama6ef0a62019-03-07 20:34:33 -0500777 EXPECT_TRUE(writer.WriteVarInt62(0x3647));
778 EXPECT_EQ(static_cast<unsigned char>(*(writer.data() + 0)),
779 (0x36 + 0x40)); // 0x40 for encoding
780 EXPECT_EQ(static_cast<unsigned char>(*(writer.data() + 1)), 0x47);
781}
782
783// Test that 1-byte-encoded Variable Length Integers are properly laid
784// out in the buffer.
785TEST_P(QuicDataWriterTest, VarInt1Layout) {
786 char buffer[1024];
787
788 // Check that the layout of bytes in the buffer
789 // is correct. Bytes are always encoded big endian...
790 memset(buffer, 0, sizeof(buffer));
791 QuicDataWriter writer(sizeof(buffer), static_cast<char*>(buffer),
QUICHE team173c48f2019-11-19 16:34:44 -0800792 quiche::Endianness::NETWORK_BYTE_ORDER);
QUICHE teama6ef0a62019-03-07 20:34:33 -0500793 EXPECT_TRUE(writer.WriteVarInt62(0x3f));
794 EXPECT_EQ(static_cast<unsigned char>(*(writer.data() + 0)), 0x3f);
795}
796
797// Test certain, targeted, values that are expected to succeed:
798// 0, 1,
799// 0x3e, 0x3f, 0x40, 0x41 (around the 1-2 byte transitions)
800// 0x3ffe, 0x3fff, 0x4000, 0x4001 (the 2-4 byte transition)
801// 0x3ffffffe, 0x3fffffff, 0x40000000, 0x40000001 (the 4-8 byte
802// transition)
803// 0x3ffffffffffffffe, 0x3fffffffffffffff, (the highest valid values)
804// 0xfe, 0xff, 0x100, 0x101,
805// 0xfffe, 0xffff, 0x10000, 0x10001,
806// 0xfffffe, 0xffffff, 0x1000000, 0x1000001,
807// 0xfffffffe, 0xffffffff, 0x100000000, 0x100000001,
808// 0xfffffffffe, 0xffffffffff, 0x10000000000, 0x10000000001,
809// 0xfffffffffffe, 0xffffffffffff, 0x1000000000000, 0x1000000000001,
810// 0xfffffffffffffe, 0xffffffffffffff, 0x100000000000000, 0x100000000000001,
811TEST_P(QuicDataWriterTest, VarIntGoodTargetedValues) {
812 char buffer[kVarIntBufferLength];
813 uint64_t passing_values[] = {
814 0,
815 1,
816 0x3e,
817 0x3f,
818 0x40,
819 0x41,
820 0x3ffe,
821 0x3fff,
822 0x4000,
823 0x4001,
824 0x3ffffffe,
825 0x3fffffff,
826 0x40000000,
827 0x40000001,
828 0x3ffffffffffffffe,
829 0x3fffffffffffffff,
830 0xfe,
831 0xff,
832 0x100,
833 0x101,
834 0xfffe,
835 0xffff,
836 0x10000,
837 0x10001,
838 0xfffffe,
839 0xffffff,
840 0x1000000,
841 0x1000001,
842 0xfffffffe,
843 0xffffffff,
844 0x100000000,
845 0x100000001,
846 0xfffffffffe,
847 0xffffffffff,
848 0x10000000000,
849 0x10000000001,
850 0xfffffffffffe,
851 0xffffffffffff,
852 0x1000000000000,
853 0x1000000000001,
854 0xfffffffffffffe,
855 0xffffffffffffff,
856 0x100000000000000,
857 0x100000000000001,
858 };
859 for (uint64_t test_val : passing_values) {
860 EXPECT_TRUE(
861 EncodeDecodeValue(test_val, static_cast<char*>(buffer), sizeof(buffer)))
862 << " encode/decode of " << test_val << " failed";
863 }
864}
865//
866// Test certain, targeted, values where failure is expected (the
867// values are invalid w.r.t. IETF VarInt encoding):
868// 0x4000000000000000, 0x4000000000000001, ( Just above max allowed value)
869// 0xfffffffffffffffe, 0xffffffffffffffff, (should fail)
870TEST_P(QuicDataWriterTest, VarIntBadTargetedValues) {
871 char buffer[kVarIntBufferLength];
872 uint64_t failing_values[] = {
873 0x4000000000000000,
874 0x4000000000000001,
875 0xfffffffffffffffe,
876 0xffffffffffffffff,
877 };
878 for (uint64_t test_val : failing_values) {
879 EXPECT_FALSE(
880 EncodeDecodeValue(test_val, static_cast<char*>(buffer), sizeof(buffer)))
881 << " encode/decode of " << test_val << " succeeded, but was an "
882 << "invalid value";
883 }
884}
885
886// Following tests all try to fill the buffer with multiple values,
887// go one value more than the buffer can accommodate, then read
888// the successfully encoded values, and try to read the unsuccessfully
889// encoded value. The following is the number of values to encode.
890const int kMultiVarCount = 1000;
891
892// Test writing & reading multiple 8-byte-encoded varints
893TEST_P(QuicDataWriterTest, MultiVarInt8) {
894 uint64_t test_val;
895 char buffer[8 * kMultiVarCount];
896 memset(buffer, 0, sizeof(buffer));
897 QuicDataWriter writer(sizeof(buffer), static_cast<char*>(buffer),
QUICHE team173c48f2019-11-19 16:34:44 -0800898 quiche::Endianness::NETWORK_BYTE_ORDER);
QUICHE teama6ef0a62019-03-07 20:34:33 -0500899 // Put N values into the buffer. Adding i to the value ensures that
900 // each value is different so we can detect if we overwrite values,
901 // or read the same value over and over.
902 for (int i = 0; i < kMultiVarCount; i++) {
903 EXPECT_TRUE(writer.WriteVarInt62(UINT64_C(0x3142f3e4d5c6b7a8) + i));
904 }
905 EXPECT_EQ(writer.length(), 8u * kMultiVarCount);
906
907 // N+1st should fail, the buffer is full.
908 EXPECT_FALSE(writer.WriteVarInt62(UINT64_C(0x3142f3e4d5c6b7a8)));
909
910 // Now we should be able to read out the N values that were
911 // successfully encoded.
QUICHE team173c48f2019-11-19 16:34:44 -0800912 QuicDataReader reader(buffer, sizeof(buffer),
913 quiche::Endianness::NETWORK_BYTE_ORDER);
QUICHE teama6ef0a62019-03-07 20:34:33 -0500914 for (int i = 0; i < kMultiVarCount; i++) {
915 EXPECT_TRUE(reader.ReadVarInt62(&test_val));
916 EXPECT_EQ(test_val, (UINT64_C(0x3142f3e4d5c6b7a8) + i));
917 }
918 // And the N+1st should fail.
919 EXPECT_FALSE(reader.ReadVarInt62(&test_val));
920}
921
922// Test writing & reading multiple 4-byte-encoded varints
923TEST_P(QuicDataWriterTest, MultiVarInt4) {
924 uint64_t test_val;
925 char buffer[4 * kMultiVarCount];
926 memset(buffer, 0, sizeof(buffer));
927 QuicDataWriter writer(sizeof(buffer), static_cast<char*>(buffer),
QUICHE team173c48f2019-11-19 16:34:44 -0800928 quiche::Endianness::NETWORK_BYTE_ORDER);
QUICHE teama6ef0a62019-03-07 20:34:33 -0500929 // Put N values into the buffer. Adding i to the value ensures that
930 // each value is different so we can detect if we overwrite values,
931 // or read the same value over and over.
932 for (int i = 0; i < kMultiVarCount; i++) {
933 EXPECT_TRUE(writer.WriteVarInt62(UINT64_C(0x3142f3e4) + i));
934 }
935 EXPECT_EQ(writer.length(), 4u * kMultiVarCount);
936
937 // N+1st should fail, the buffer is full.
938 EXPECT_FALSE(writer.WriteVarInt62(UINT64_C(0x3142f3e4)));
939
940 // Now we should be able to read out the N values that were
941 // successfully encoded.
QUICHE team173c48f2019-11-19 16:34:44 -0800942 QuicDataReader reader(buffer, sizeof(buffer),
943 quiche::Endianness::NETWORK_BYTE_ORDER);
QUICHE teama6ef0a62019-03-07 20:34:33 -0500944 for (int i = 0; i < kMultiVarCount; i++) {
945 EXPECT_TRUE(reader.ReadVarInt62(&test_val));
946 EXPECT_EQ(test_val, (UINT64_C(0x3142f3e4) + i));
947 }
948 // And the N+1st should fail.
949 EXPECT_FALSE(reader.ReadVarInt62(&test_val));
950}
951
952// Test writing & reading multiple 2-byte-encoded varints
953TEST_P(QuicDataWriterTest, MultiVarInt2) {
954 uint64_t test_val;
955 char buffer[2 * kMultiVarCount];
956 memset(buffer, 0, sizeof(buffer));
957 QuicDataWriter writer(sizeof(buffer), static_cast<char*>(buffer),
QUICHE team173c48f2019-11-19 16:34:44 -0800958 quiche::Endianness::NETWORK_BYTE_ORDER);
QUICHE teama6ef0a62019-03-07 20:34:33 -0500959 // Put N values into the buffer. Adding i to the value ensures that
960 // each value is different so we can detect if we overwrite values,
961 // or read the same value over and over.
962 for (int i = 0; i < kMultiVarCount; i++) {
963 EXPECT_TRUE(writer.WriteVarInt62(UINT64_C(0x3142) + i));
964 }
965 EXPECT_EQ(writer.length(), 2u * kMultiVarCount);
966
967 // N+1st should fail, the buffer is full.
968 EXPECT_FALSE(writer.WriteVarInt62(UINT64_C(0x3142)));
969
970 // Now we should be able to read out the N values that were
971 // successfully encoded.
QUICHE team173c48f2019-11-19 16:34:44 -0800972 QuicDataReader reader(buffer, sizeof(buffer),
973 quiche::Endianness::NETWORK_BYTE_ORDER);
QUICHE teama6ef0a62019-03-07 20:34:33 -0500974 for (int i = 0; i < kMultiVarCount; i++) {
975 EXPECT_TRUE(reader.ReadVarInt62(&test_val));
976 EXPECT_EQ(test_val, (UINT64_C(0x3142) + i));
977 }
978 // And the N+1st should fail.
979 EXPECT_FALSE(reader.ReadVarInt62(&test_val));
980}
981
982// Test writing & reading multiple 1-byte-encoded varints
983TEST_P(QuicDataWriterTest, MultiVarInt1) {
984 uint64_t test_val;
985 char buffer[1 * kMultiVarCount];
986 memset(buffer, 0, sizeof(buffer));
987 QuicDataWriter writer(sizeof(buffer), static_cast<char*>(buffer),
QUICHE team173c48f2019-11-19 16:34:44 -0800988 quiche::Endianness::NETWORK_BYTE_ORDER);
QUICHE teama6ef0a62019-03-07 20:34:33 -0500989 // Put N values into the buffer. Adding i to the value ensures that
990 // each value is different so we can detect if we overwrite values,
991 // or read the same value over and over. &0xf ensures we do not
992 // overflow the max value for single-byte encoding.
993 for (int i = 0; i < kMultiVarCount; i++) {
994 EXPECT_TRUE(writer.WriteVarInt62(UINT64_C(0x30) + (i & 0xf)));
995 }
996 EXPECT_EQ(writer.length(), 1u * kMultiVarCount);
997
998 // N+1st should fail, the buffer is full.
999 EXPECT_FALSE(writer.WriteVarInt62(UINT64_C(0x31)));
1000
1001 // Now we should be able to read out the N values that were
1002 // successfully encoded.
QUICHE team173c48f2019-11-19 16:34:44 -08001003 QuicDataReader reader(buffer, sizeof(buffer),
1004 quiche::Endianness::NETWORK_BYTE_ORDER);
QUICHE teama6ef0a62019-03-07 20:34:33 -05001005 for (int i = 0; i < kMultiVarCount; i++) {
1006 EXPECT_TRUE(reader.ReadVarInt62(&test_val));
1007 EXPECT_EQ(test_val, (UINT64_C(0x30) + (i & 0xf)));
1008 }
1009 // And the N+1st should fail.
1010 EXPECT_FALSE(reader.ReadVarInt62(&test_val));
1011}
1012
1013// Test writing varints with a forced length.
1014TEST_P(QuicDataWriterTest, VarIntFixedLength) {
1015 char buffer[90];
1016 memset(buffer, 0, sizeof(buffer));
1017 QuicDataWriter writer(sizeof(buffer), static_cast<char*>(buffer),
QUICHE team173c48f2019-11-19 16:34:44 -08001018 quiche::Endianness::NETWORK_BYTE_ORDER);
QUICHE teama6ef0a62019-03-07 20:34:33 -05001019
1020 writer.WriteVarInt62(1, VARIABLE_LENGTH_INTEGER_LENGTH_1);
1021 writer.WriteVarInt62(1, VARIABLE_LENGTH_INTEGER_LENGTH_2);
1022 writer.WriteVarInt62(1, VARIABLE_LENGTH_INTEGER_LENGTH_4);
1023 writer.WriteVarInt62(1, VARIABLE_LENGTH_INTEGER_LENGTH_8);
1024
1025 writer.WriteVarInt62(63, VARIABLE_LENGTH_INTEGER_LENGTH_1);
1026 writer.WriteVarInt62(63, VARIABLE_LENGTH_INTEGER_LENGTH_2);
1027 writer.WriteVarInt62(63, VARIABLE_LENGTH_INTEGER_LENGTH_4);
1028 writer.WriteVarInt62(63, VARIABLE_LENGTH_INTEGER_LENGTH_8);
1029
1030 writer.WriteVarInt62(64, VARIABLE_LENGTH_INTEGER_LENGTH_2);
1031 writer.WriteVarInt62(64, VARIABLE_LENGTH_INTEGER_LENGTH_4);
1032 writer.WriteVarInt62(64, VARIABLE_LENGTH_INTEGER_LENGTH_8);
1033
1034 writer.WriteVarInt62(16383, VARIABLE_LENGTH_INTEGER_LENGTH_2);
1035 writer.WriteVarInt62(16383, VARIABLE_LENGTH_INTEGER_LENGTH_4);
1036 writer.WriteVarInt62(16383, VARIABLE_LENGTH_INTEGER_LENGTH_8);
1037
1038 writer.WriteVarInt62(16384, VARIABLE_LENGTH_INTEGER_LENGTH_4);
1039 writer.WriteVarInt62(16384, VARIABLE_LENGTH_INTEGER_LENGTH_8);
1040
1041 writer.WriteVarInt62(1073741823, VARIABLE_LENGTH_INTEGER_LENGTH_4);
1042 writer.WriteVarInt62(1073741823, VARIABLE_LENGTH_INTEGER_LENGTH_8);
1043
1044 writer.WriteVarInt62(1073741824, VARIABLE_LENGTH_INTEGER_LENGTH_8);
1045
QUICHE team173c48f2019-11-19 16:34:44 -08001046 QuicDataReader reader(buffer, sizeof(buffer),
1047 quiche::Endianness::NETWORK_BYTE_ORDER);
QUICHE teama6ef0a62019-03-07 20:34:33 -05001048
1049 uint64_t test_val = 0;
1050 for (int i = 0; i < 4; ++i) {
1051 EXPECT_TRUE(reader.ReadVarInt62(&test_val));
1052 EXPECT_EQ(test_val, 1u);
1053 }
1054 for (int i = 0; i < 4; ++i) {
1055 EXPECT_TRUE(reader.ReadVarInt62(&test_val));
1056 EXPECT_EQ(test_val, 63u);
1057 }
1058
1059 for (int i = 0; i < 3; ++i) {
1060 EXPECT_TRUE(reader.ReadVarInt62(&test_val));
1061 EXPECT_EQ(test_val, 64u);
1062 }
1063 for (int i = 0; i < 3; ++i) {
1064 EXPECT_TRUE(reader.ReadVarInt62(&test_val));
1065 EXPECT_EQ(test_val, 16383u);
1066 }
1067
1068 for (int i = 0; i < 2; ++i) {
1069 EXPECT_TRUE(reader.ReadVarInt62(&test_val));
1070 EXPECT_EQ(test_val, 16384u);
1071 }
1072 for (int i = 0; i < 2; ++i) {
1073 EXPECT_TRUE(reader.ReadVarInt62(&test_val));
1074 EXPECT_EQ(test_val, 1073741823u);
1075 }
1076
1077 EXPECT_TRUE(reader.ReadVarInt62(&test_val));
1078 EXPECT_EQ(test_val, 1073741824u);
1079
1080 // We are at the end of the buffer so this should fail.
1081 EXPECT_FALSE(reader.ReadVarInt62(&test_val));
1082}
1083
1084// Test encoding/decoding stream-id values.
renjietangd077f8c2020-03-23 17:22:09 -07001085void EncodeDecodeStreamId(uint64_t value_in) {
QUICHE teama6ef0a62019-03-07 20:34:33 -05001086 char buffer[1 * kMultiVarCount];
1087 memset(buffer, 0, sizeof(buffer));
1088
1089 // Encode the given Stream ID.
1090 QuicDataWriter writer(sizeof(buffer), static_cast<char*>(buffer),
QUICHE team173c48f2019-11-19 16:34:44 -08001091 quiche::Endianness::NETWORK_BYTE_ORDER);
QUICHE teama6ef0a62019-03-07 20:34:33 -05001092 EXPECT_TRUE(writer.WriteVarInt62(value_in));
1093
QUICHE team173c48f2019-11-19 16:34:44 -08001094 QuicDataReader reader(buffer, sizeof(buffer),
1095 quiche::Endianness::NETWORK_BYTE_ORDER);
QUICHE teama6ef0a62019-03-07 20:34:33 -05001096 QuicStreamId received_stream_id;
renjietangd077f8c2020-03-23 17:22:09 -07001097 uint64_t temp;
1098 EXPECT_TRUE(reader.ReadVarInt62(&temp));
1099 received_stream_id = static_cast<QuicStreamId>(temp);
1100 EXPECT_EQ(value_in, received_stream_id);
QUICHE teama6ef0a62019-03-07 20:34:33 -05001101}
1102
1103// Test writing & reading stream-ids of various value.
1104TEST_P(QuicDataWriterTest, StreamId1) {
1105 // Check a 1-byte QuicStreamId, should work
renjietangd077f8c2020-03-23 17:22:09 -07001106 EncodeDecodeStreamId(UINT64_C(0x15));
QUICHE teama6ef0a62019-03-07 20:34:33 -05001107
1108 // Check a 2-byte QuicStream ID. It should work.
renjietangd077f8c2020-03-23 17:22:09 -07001109 EncodeDecodeStreamId(UINT64_C(0x1567));
QUICHE teama6ef0a62019-03-07 20:34:33 -05001110
1111 // Check a QuicStreamId that requires 4 bytes of encoding
1112 // This should work.
renjietangd077f8c2020-03-23 17:22:09 -07001113 EncodeDecodeStreamId(UINT64_C(0x34567890));
QUICHE teama6ef0a62019-03-07 20:34:33 -05001114
1115 // Check a QuicStreamId that requires 8 bytes of encoding
1116 // but whose value is in the acceptable range.
1117 // This should work.
renjietangd077f8c2020-03-23 17:22:09 -07001118 EncodeDecodeStreamId(UINT64_C(0xf4567890));
QUICHE teama6ef0a62019-03-07 20:34:33 -05001119}
1120
1121TEST_P(QuicDataWriterTest, WriteRandomBytes) {
1122 char buffer[20];
1123 char expected[20];
1124 for (size_t i = 0; i < 20; ++i) {
1125 expected[i] = 'r';
1126 }
1127 MockRandom random;
1128 QuicDataWriter writer(20, buffer, GetParam().endianness);
1129 EXPECT_FALSE(writer.WriteRandomBytes(&random, 30));
1130
1131 EXPECT_TRUE(writer.WriteRandomBytes(&random, 20));
dmcardle8f7df532020-01-07 13:28:57 -08001132 quiche::test::CompareCharArraysWithHexError("random", buffer, 20, expected,
1133 20);
QUICHE teama6ef0a62019-03-07 20:34:33 -05001134}
1135
1136TEST_P(QuicDataWriterTest, PeekVarInt62Length) {
1137 // In range [0, 63], variable length should be 1 byte.
1138 char buffer[20];
QUICHE team173c48f2019-11-19 16:34:44 -08001139 QuicDataWriter writer(20, buffer, quiche::NETWORK_BYTE_ORDER);
QUICHE teama6ef0a62019-03-07 20:34:33 -05001140 EXPECT_TRUE(writer.WriteVarInt62(50));
QUICHE team173c48f2019-11-19 16:34:44 -08001141 QuicDataReader reader(buffer, 20, quiche::NETWORK_BYTE_ORDER);
QUICHE teama6ef0a62019-03-07 20:34:33 -05001142 EXPECT_EQ(1, reader.PeekVarInt62Length());
1143 // In range (63-16383], variable length should be 2 byte2.
1144 char buffer2[20];
QUICHE team173c48f2019-11-19 16:34:44 -08001145 QuicDataWriter writer2(20, buffer2, quiche::NETWORK_BYTE_ORDER);
QUICHE teama6ef0a62019-03-07 20:34:33 -05001146 EXPECT_TRUE(writer2.WriteVarInt62(100));
QUICHE team173c48f2019-11-19 16:34:44 -08001147 QuicDataReader reader2(buffer2, 20, quiche::NETWORK_BYTE_ORDER);
QUICHE teama6ef0a62019-03-07 20:34:33 -05001148 EXPECT_EQ(2, reader2.PeekVarInt62Length());
1149 // In range (16383, 1073741823], variable length should be 4 bytes.
1150 char buffer3[20];
QUICHE team173c48f2019-11-19 16:34:44 -08001151 QuicDataWriter writer3(20, buffer3, quiche::NETWORK_BYTE_ORDER);
QUICHE teama6ef0a62019-03-07 20:34:33 -05001152 EXPECT_TRUE(writer3.WriteVarInt62(20000));
QUICHE team173c48f2019-11-19 16:34:44 -08001153 QuicDataReader reader3(buffer3, 20, quiche::NETWORK_BYTE_ORDER);
QUICHE teama6ef0a62019-03-07 20:34:33 -05001154 EXPECT_EQ(4, reader3.PeekVarInt62Length());
1155 // In range (1073741823, 4611686018427387903], variable length should be 8
1156 // bytes.
1157 char buffer4[20];
QUICHE team173c48f2019-11-19 16:34:44 -08001158 QuicDataWriter writer4(20, buffer4, quiche::NETWORK_BYTE_ORDER);
QUICHE teama6ef0a62019-03-07 20:34:33 -05001159 EXPECT_TRUE(writer4.WriteVarInt62(2000000000));
QUICHE team173c48f2019-11-19 16:34:44 -08001160 QuicDataReader reader4(buffer4, 20, quiche::NETWORK_BYTE_ORDER);
QUICHE teama6ef0a62019-03-07 20:34:33 -05001161 EXPECT_EQ(8, reader4.PeekVarInt62Length());
1162}
1163
renjietangd077f8c2020-03-23 17:22:09 -07001164TEST_P(QuicDataWriterTest, ValidStreamCount) {
fkastenholz3c4eabf2019-04-22 07:49:59 -07001165 char buffer[1024];
1166 memset(buffer, 0, sizeof(buffer));
1167 QuicDataWriter writer(sizeof(buffer), static_cast<char*>(buffer),
QUICHE team173c48f2019-11-19 16:34:44 -08001168 quiche::Endianness::NETWORK_BYTE_ORDER);
fkastenholz3c4eabf2019-04-22 07:49:59 -07001169 QuicDataReader reader(buffer, sizeof(buffer));
1170 const QuicStreamCount write_stream_count = 0xffeeddcc;
1171 EXPECT_TRUE(writer.WriteVarInt62(write_stream_count));
1172 QuicStreamCount read_stream_count;
renjietangd077f8c2020-03-23 17:22:09 -07001173 uint64_t temp;
1174 EXPECT_TRUE(reader.ReadVarInt62(&temp));
1175 read_stream_count = static_cast<QuicStreamId>(temp);
fkastenholz3c4eabf2019-04-22 07:49:59 -07001176 EXPECT_EQ(write_stream_count, read_stream_count);
1177}
1178
nharper55fa6132019-05-07 19:37:21 -07001179TEST_P(QuicDataWriterTest, Seek) {
1180 char buffer[3] = {};
bnc4e9283d2019-12-17 07:08:57 -08001181 QuicDataWriter writer(QUICHE_ARRAYSIZE(buffer), buffer,
1182 GetParam().endianness);
nharper55fa6132019-05-07 19:37:21 -07001183 EXPECT_TRUE(writer.WriteUInt8(42));
1184 EXPECT_TRUE(writer.Seek(1));
1185 EXPECT_TRUE(writer.WriteUInt8(3));
1186
1187 char expected[] = {42, 0, 3};
bnc4e9283d2019-12-17 07:08:57 -08001188 for (size_t i = 0; i < QUICHE_ARRAYSIZE(expected); ++i) {
nharper55fa6132019-05-07 19:37:21 -07001189 EXPECT_EQ(buffer[i], expected[i]);
1190 }
1191}
1192
1193TEST_P(QuicDataWriterTest, SeekTooFarFails) {
1194 char buffer[20];
1195
1196 // Check that one can seek to the end of the writer, but not past.
1197 {
bnc4e9283d2019-12-17 07:08:57 -08001198 QuicDataWriter writer(QUICHE_ARRAYSIZE(buffer), buffer,
nharper55fa6132019-05-07 19:37:21 -07001199 GetParam().endianness);
1200 EXPECT_TRUE(writer.Seek(20));
1201 EXPECT_FALSE(writer.Seek(1));
1202 }
1203
1204 // Seeking several bytes past the end fails.
1205 {
bnc4e9283d2019-12-17 07:08:57 -08001206 QuicDataWriter writer(QUICHE_ARRAYSIZE(buffer), buffer,
nharper55fa6132019-05-07 19:37:21 -07001207 GetParam().endianness);
1208 EXPECT_FALSE(writer.Seek(100));
1209 }
1210
1211 // Seeking so far that arithmetic overflow could occur also fails.
1212 {
bnc4e9283d2019-12-17 07:08:57 -08001213 QuicDataWriter writer(QUICHE_ARRAYSIZE(buffer), buffer,
nharper55fa6132019-05-07 19:37:21 -07001214 GetParam().endianness);
1215 EXPECT_TRUE(writer.Seek(10));
1216 EXPECT_FALSE(writer.Seek(std::numeric_limits<size_t>::max()));
1217 }
1218}
1219
dschinazi4b5a68a2019-08-15 15:45:36 -07001220TEST_P(QuicDataWriterTest, PayloadReads) {
1221 char buffer[16] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16};
1222 char expected_first_read[4] = {1, 2, 3, 4};
1223 char expected_remaining[12] = {5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16};
1224 QuicDataReader reader(buffer, sizeof(buffer));
1225 char first_read_buffer[4] = {};
1226 EXPECT_TRUE(reader.ReadBytes(first_read_buffer, sizeof(first_read_buffer)));
dmcardle8f7df532020-01-07 13:28:57 -08001227 quiche::test::CompareCharArraysWithHexError(
dschinazi4b5a68a2019-08-15 15:45:36 -07001228 "first read", first_read_buffer, sizeof(first_read_buffer),
1229 expected_first_read, sizeof(expected_first_read));
dmcardlecf0bfcf2019-12-13 08:08:21 -08001230 quiche::QuicheStringPiece peeked_remaining_payload =
1231 reader.PeekRemainingPayload();
dmcardle8f7df532020-01-07 13:28:57 -08001232 quiche::test::CompareCharArraysWithHexError(
dschinazi4b5a68a2019-08-15 15:45:36 -07001233 "peeked_remaining_payload", peeked_remaining_payload.data(),
1234 peeked_remaining_payload.length(), expected_remaining,
1235 sizeof(expected_remaining));
dmcardlecf0bfcf2019-12-13 08:08:21 -08001236 quiche::QuicheStringPiece full_payload = reader.FullPayload();
dmcardle8f7df532020-01-07 13:28:57 -08001237 quiche::test::CompareCharArraysWithHexError(
1238 "full_payload", full_payload.data(), full_payload.length(), buffer,
1239 sizeof(buffer));
dmcardlecf0bfcf2019-12-13 08:08:21 -08001240 quiche::QuicheStringPiece read_remaining_payload =
1241 reader.ReadRemainingPayload();
dmcardle8f7df532020-01-07 13:28:57 -08001242 quiche::test::CompareCharArraysWithHexError(
dschinazi4b5a68a2019-08-15 15:45:36 -07001243 "read_remaining_payload", read_remaining_payload.data(),
1244 read_remaining_payload.length(), expected_remaining,
1245 sizeof(expected_remaining));
1246 EXPECT_TRUE(reader.IsDoneReading());
dmcardlecf0bfcf2019-12-13 08:08:21 -08001247 quiche::QuicheStringPiece full_payload2 = reader.FullPayload();
dmcardle8f7df532020-01-07 13:28:57 -08001248 quiche::test::CompareCharArraysWithHexError(
1249 "full_payload2", full_payload2.data(), full_payload2.length(), buffer,
1250 sizeof(buffer));
dschinazi4b5a68a2019-08-15 15:45:36 -07001251}
1252
dschinazi7b8f0c72020-03-02 13:17:57 -08001253TEST_P(QuicDataWriterTest, StringPieceVarInt62) {
1254 char inner_buffer[16] = {1, 2, 3, 4, 5, 6, 7, 8,
1255 9, 10, 11, 12, 13, 14, 15, 16};
1256 quiche::QuicheStringPiece inner_payload_write(inner_buffer,
1257 sizeof(inner_buffer));
1258 char buffer[sizeof(inner_buffer) + sizeof(uint8_t)] = {};
1259 QuicDataWriter writer(sizeof(buffer), buffer);
1260 EXPECT_TRUE(writer.WriteStringPieceVarInt62(inner_payload_write));
1261 EXPECT_EQ(0u, writer.remaining());
1262 QuicDataReader reader(buffer, sizeof(buffer));
1263 quiche::QuicheStringPiece inner_payload_read;
1264 EXPECT_TRUE(reader.ReadStringPieceVarInt62(&inner_payload_read));
1265 quiche::test::CompareCharArraysWithHexError(
1266 "inner_payload", inner_payload_write.data(), inner_payload_write.length(),
1267 inner_payload_read.data(), inner_payload_read.length());
1268}
1269
QUICHE teama6ef0a62019-03-07 20:34:33 -05001270} // namespace
1271} // namespace test
1272} // namespace quic