Pin Chrome's shortcut to the Win10 Start menu on install and OS upgrade.
[chromium-blink-merge.git] / net / spdy / spdy_alt_svc_wire_format_test.cc
blob9113c3b80d3a4aa27c1fff192bb08b6e3b6936eb
1 // Copyright (c) 2015 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.
5 #include "net/spdy/spdy_alt_svc_wire_format.h"
7 #include "base/logging.h"
8 #include "testing/gmock/include/gmock/gmock.h"
9 #include "testing/platform_test.h"
11 using ::testing::_;
13 namespace net {
15 namespace test {
17 // Expose all private methods of class SpdyAltSvcWireFormat.
18 class SpdyAltSvcWireFormatPeer {
19 public:
20 static void SkipWhiteSpace(StringPiece::const_iterator* c,
21 StringPiece::const_iterator end) {
22 SpdyAltSvcWireFormat::SkipWhiteSpace(c, end);
24 static bool PercentDecode(StringPiece::const_iterator c,
25 StringPiece::const_iterator end,
26 std::string* output) {
27 return SpdyAltSvcWireFormat::PercentDecode(c, end, output);
29 static bool ParseAltAuthority(StringPiece::const_iterator c,
30 StringPiece::const_iterator end,
31 std::string* host,
32 uint16* port) {
33 return SpdyAltSvcWireFormat::ParseAltAuthority(c, end, host, port);
35 static bool ParsePositiveInteger16(StringPiece::const_iterator c,
36 StringPiece::const_iterator end,
37 uint16* max_age) {
38 return SpdyAltSvcWireFormat::ParsePositiveInteger16(c, end, max_age);
40 static bool ParsePositiveInteger32(StringPiece::const_iterator c,
41 StringPiece::const_iterator end,
42 uint32* max_age) {
43 return SpdyAltSvcWireFormat::ParsePositiveInteger32(c, end, max_age);
45 static bool ParseProbability(StringPiece::const_iterator c,
46 StringPiece::const_iterator end,
47 double* p) {
48 return SpdyAltSvcWireFormat::ParseProbability(c, end, p);
52 } // namespace test
54 namespace {
56 void FuzzHeaderFieldValue(
57 int i,
58 std::string* header_field_value,
59 SpdyAltSvcWireFormat::AlternativeService* expected_altsvc) {
60 if (!header_field_value->empty()) {
61 header_field_value->push_back(',');
63 expected_altsvc->protocol_id = "a=b%c";
64 header_field_value->append("a%3Db%25c=\"");
65 expected_altsvc->host = "";
66 if (i & 1 << 0) {
67 expected_altsvc->host = "foo\"bar\\baz";
68 header_field_value->append("foo\\\"bar\\\\baz");
70 expected_altsvc->port = 42;
71 header_field_value->append(":42\"");
72 if (i & 1 << 1) {
73 header_field_value->append(" ");
75 expected_altsvc->max_age = 86400;
76 if (i & 3 << 2) {
77 expected_altsvc->max_age = 1111;
78 header_field_value->append(";");
79 if (i & 1 << 2) {
80 header_field_value->append(" ");
82 header_field_value->append("mA=1111");
83 if (i & 2 << 2) {
84 header_field_value->append(" ");
87 if (i & 1 << 4) {
88 header_field_value->append("; J=s");
90 expected_altsvc->p = 1.0;
91 if (i & 1 << 5) {
92 expected_altsvc->p = 0.33;
93 header_field_value->append("; P=.33");
95 if (i & 1 << 6) {
96 expected_altsvc->p = 0.0;
97 header_field_value->append("; p=0");
99 if (i & 1 << 7) {
100 expected_altsvc->max_age = 999999999;
101 header_field_value->append("; Ma=999999999");
103 if (i & 1 << 8) {
104 expected_altsvc->p = 0.0;
105 header_field_value->append("; P=0.");
107 if (i & 1 << 9) {
108 header_field_value->append(";");
110 if (i & 1 << 10) {
111 header_field_value->append(" ");
113 if (i & 1 << 11) {
114 header_field_value->append(",");
116 if (i & 1 << 12) {
117 header_field_value->append(" ");
121 void FuzzAlternativeService(int i,
122 SpdyAltSvcWireFormat::AlternativeService* altsvc,
123 std::string* expected_header_field_value) {
124 if (!expected_header_field_value->empty()) {
125 expected_header_field_value->push_back(',');
127 altsvc->protocol_id = "a=b%c";
128 altsvc->port = 42;
129 expected_header_field_value->append("a%3Db%25c=\"");
130 if (i & 1 << 0) {
131 altsvc->host = "foo\"bar\\baz";
132 expected_header_field_value->append("foo\\\"bar\\\\baz");
134 expected_header_field_value->append(":42\"");
135 altsvc->max_age = 86400;
136 if (i & 1 << 1) {
137 altsvc->max_age = 1111;
138 expected_header_field_value->append("; ma=1111");
140 altsvc->p = 1.0;
141 if (i & 1 << 2) {
142 altsvc->p = 0.33;
143 expected_header_field_value->append("; p=0.33");
147 class SpdyAltSvcWireFormatTest : public ::testing::Test {};
149 // Tests of public API.
151 TEST(SpdyAltSvcWireFormatTest, ParseEmptyHeaderFieldValue) {
152 SpdyAltSvcWireFormat::AlternativeServiceVector altsvc_vector;
153 ASSERT_TRUE(SpdyAltSvcWireFormat::ParseHeaderFieldValue("", &altsvc_vector));
154 EXPECT_EQ(0u, altsvc_vector.size());
157 // Fuzz test of ParseHeaderFieldValue() with optional whitespaces, ignored
158 // parameters, duplicate parameters, trailing space, trailing alternate service
159 // separator, etc. Single alternative service at a time.
160 TEST(SpdyAltSvcWireFormatTest, ParseHeaderFieldValue) {
161 for (int i = 0; i < 1 << 13; ++i) {
162 std::string header_field_value;
163 SpdyAltSvcWireFormat::AlternativeService expected_altsvc;
164 FuzzHeaderFieldValue(i, &header_field_value, &expected_altsvc);
165 SpdyAltSvcWireFormat::AlternativeServiceVector altsvc_vector;
166 ASSERT_TRUE(SpdyAltSvcWireFormat::ParseHeaderFieldValue(header_field_value,
167 &altsvc_vector));
168 ASSERT_EQ(1u, altsvc_vector.size());
169 EXPECT_EQ(expected_altsvc.protocol_id, altsvc_vector[0].protocol_id);
170 EXPECT_EQ(expected_altsvc.host, altsvc_vector[0].host);
171 EXPECT_EQ(expected_altsvc.port, altsvc_vector[0].port);
172 EXPECT_EQ(expected_altsvc.max_age, altsvc_vector[0].max_age);
173 EXPECT_DOUBLE_EQ(expected_altsvc.p, altsvc_vector[0].p);
177 // Fuzz test of ParseHeaderFieldValue() with optional whitespaces, ignored
178 // parameters, duplicate parameters, trailing space, trailing alternate service
179 // separator, etc. Possibly multiple alternative service at a time.
180 TEST(SpdyAltSvcWireFormatTest, ParseHeaderFieldValueMultiple) {
181 for (int i = 0; i < 1 << 13;) {
182 std::string header_field_value;
183 SpdyAltSvcWireFormat::AlternativeServiceVector expected_altsvc_vector;
184 // This will generate almost two hundred header field values with two,
185 // three, four, five, six, and seven alternative services each, and
186 // thousands with a single one.
187 do {
188 SpdyAltSvcWireFormat::AlternativeService expected_altsvc;
189 FuzzHeaderFieldValue(i, &header_field_value, &expected_altsvc);
190 expected_altsvc_vector.push_back(expected_altsvc);
191 ++i;
192 } while ((i < 1 << 13) && (i % 6 < i % 7));
193 SpdyAltSvcWireFormat::AlternativeServiceVector altsvc_vector;
194 ASSERT_TRUE(SpdyAltSvcWireFormat::ParseHeaderFieldValue(header_field_value,
195 &altsvc_vector));
196 ASSERT_EQ(expected_altsvc_vector.size(), altsvc_vector.size());
197 for (unsigned int j = 0; j < altsvc_vector.size(); ++j) {
198 EXPECT_EQ(expected_altsvc_vector[j].protocol_id,
199 altsvc_vector[j].protocol_id);
200 EXPECT_EQ(expected_altsvc_vector[j].host, altsvc_vector[j].host);
201 EXPECT_EQ(expected_altsvc_vector[j].port, altsvc_vector[j].port);
202 EXPECT_EQ(expected_altsvc_vector[j].max_age, altsvc_vector[j].max_age);
203 EXPECT_DOUBLE_EQ(expected_altsvc_vector[j].p, altsvc_vector[j].p);
208 TEST(SpdyAltSvcWireFormatTest, SerializeEmptyHeaderFieldValue) {
209 SpdyAltSvcWireFormat::AlternativeServiceVector altsvc_vector;
210 EXPECT_EQ("", SpdyAltSvcWireFormat::SerializeHeaderFieldValue(altsvc_vector));
213 // Test SerializeHeaderFieldValue() with and without hostname and each
214 // parameter. Single alternative service at a time.
215 TEST(SpdyAltSvcWireFormatTest, SerializeHeaderFieldValue) {
216 for (int i = 0; i < 1 << 3; ++i) {
217 SpdyAltSvcWireFormat::AlternativeService altsvc;
218 std::string expected_header_field_value;
219 FuzzAlternativeService(i, &altsvc, &expected_header_field_value);
220 SpdyAltSvcWireFormat::AlternativeServiceVector altsvc_vector;
221 altsvc_vector.push_back(altsvc);
222 EXPECT_EQ(expected_header_field_value,
223 SpdyAltSvcWireFormat::SerializeHeaderFieldValue(altsvc_vector));
227 // Test SerializeHeaderFieldValue() with and without hostname and each
228 // parameter. Multiple alternative services at a time.
229 TEST(SpdyAltSvcWireFormatTest, SerializeHeaderFieldValueMultiple) {
230 SpdyAltSvcWireFormat::AlternativeServiceVector altsvc_vector;
231 std::string expected_header_field_value;
232 for (int i = 0; i < 1 << 3; ++i) {
233 SpdyAltSvcWireFormat::AlternativeService altsvc;
234 FuzzAlternativeService(i, &altsvc, &expected_header_field_value);
235 altsvc_vector.push_back(altsvc);
237 EXPECT_EQ(expected_header_field_value,
238 SpdyAltSvcWireFormat::SerializeHeaderFieldValue(altsvc_vector));
241 // ParseHeaderFieldValue() should return false on malformed field values:
242 // invalid percent encoding, unmatched quotation mark, empty port, non-numeric
243 // characters in numeric fields, negative or larger than 1.0 probability.
244 TEST(SpdyAltSvcWireFormatTest, ParseHeaderFieldValueInvalid) {
245 SpdyAltSvcWireFormat::AlternativeServiceVector altsvc_vector;
246 const char* invalid_field_value_array[] = {"a%", "a%x", "a%b", "a%9z",
247 "a=", "a=\"", "a=\"b\"", "a=\":\"", "a=\"c:\"", "a=\"c:foo\"",
248 "a=\"c:42foo\"", "a=\"b:42\"bar", "a=\"b:42\" ; m",
249 "a=\"b:42\" ; min-age", "a=\"b:42\" ; ma", "a=\"b:42\" ; ma=",
250 "a=\"b:42\" ; ma=ma", "a=\"b:42\" ; ma=123bar", "a=\"b:42\" ; p=-2",
251 "a=\"b:42\" ; p=..", "a=\"b:42\" ; p=1.05"};
252 for (const char* invalid_field_value : invalid_field_value_array) {
253 EXPECT_FALSE(SpdyAltSvcWireFormat::ParseHeaderFieldValue(
254 invalid_field_value, &altsvc_vector))
255 << invalid_field_value;
259 // ParseHeaderFieldValue() should return false on a field values truncated
260 // before closing quotation mark, without trying to access memory beyond the end
261 // of the input.
262 TEST(SpdyAltSvcWireFormatTest, ParseTruncatedHeaderFieldValue) {
263 SpdyAltSvcWireFormat::AlternativeServiceVector altsvc_vector;
264 const char* field_value_array[] = {
265 "p=\":137\"", "p=\"foo:137\"", "p%25=\"foo\\\"bar\\\\baz:137\""};
266 for (std::string field_value : field_value_array) {
267 for (size_t len = 1; len < field_value.size(); ++len) {
268 EXPECT_FALSE(SpdyAltSvcWireFormat::ParseHeaderFieldValue(
269 field_value.substr(0, len), &altsvc_vector))
270 << len;
275 // Tests of private methods.
277 // Test SkipWhiteSpace().
278 TEST(SpdyAltSvcWireFormatTest, SkipWhiteSpace) {
279 StringPiece input("a \tb ");
280 StringPiece::const_iterator c = input.begin();
281 test::SpdyAltSvcWireFormatPeer::SkipWhiteSpace(&c, input.end());
282 ASSERT_EQ(input.begin(), c);
283 ++c;
284 test::SpdyAltSvcWireFormatPeer::SkipWhiteSpace(&c, input.end());
285 ASSERT_EQ(input.begin() + 3, c);
286 ++c;
287 test::SpdyAltSvcWireFormatPeer::SkipWhiteSpace(&c, input.end());
288 ASSERT_EQ(input.end(), c);
291 // Test PercentDecode() on valid input.
292 TEST(SpdyAltSvcWireFormatTest, PercentDecodeValid) {
293 StringPiece input("");
294 std::string output;
295 ASSERT_TRUE(test::SpdyAltSvcWireFormatPeer::PercentDecode(
296 input.begin(), input.end(), &output));
297 EXPECT_EQ("", output);
299 input = StringPiece("foo");
300 output.clear();
301 ASSERT_TRUE(test::SpdyAltSvcWireFormatPeer::PercentDecode(
302 input.begin(), input.end(), &output));
303 EXPECT_EQ("foo", output);
305 input = StringPiece("%2ca%5Cb");
306 output.clear();
307 ASSERT_TRUE(test::SpdyAltSvcWireFormatPeer::PercentDecode(
308 input.begin(), input.end(), &output));
309 EXPECT_EQ(",a\\b", output);
312 // Test PercentDecode() on invalid input.
313 TEST(SpdyAltSvcWireFormatTest, PercentDecodeInvalid) {
314 const char* invalid_input_array[] = {"a%", "a%x", "a%b", "%J22", "%9z"};
315 for (const char* invalid_input : invalid_input_array) {
316 StringPiece input(invalid_input);
317 std::string output;
318 EXPECT_FALSE(test::SpdyAltSvcWireFormatPeer::PercentDecode(
319 input.begin(), input.end(), &output))
320 << input;
324 // Test ParseAltAuthority() on valid input.
325 TEST(SpdyAltSvcWireFormatTest, ParseAltAuthorityValid) {
326 StringPiece input(":42");
327 std::string host;
328 uint16 port;
329 ASSERT_TRUE(test::SpdyAltSvcWireFormatPeer::ParseAltAuthority(
330 input.begin(), input.end(), &host, &port));
331 EXPECT_TRUE(host.empty());
332 EXPECT_EQ(42, port);
334 input = StringPiece("foo:137");
335 ASSERT_TRUE(test::SpdyAltSvcWireFormatPeer::ParseAltAuthority(
336 input.begin(), input.end(), &host, &port));
337 EXPECT_EQ("foo", host);
338 EXPECT_EQ(137, port);
341 // Test ParseAltAuthority() on invalid input: empty string, no port, zero port,
342 // non-digit characters following port.
343 TEST(SpdyAltSvcWireFormatTest, ParseAltAuthorityInvalid) {
344 const char* invalid_input_array[] = {"", ":", "foo:", ":bar", ":0", "foo:0",
345 ":12bar", "foo:23bar", " ", ":12 ", "foo:12 "};
346 for (const char* invalid_input : invalid_input_array) {
347 StringPiece input(invalid_input);
348 std::string host;
349 uint16 port;
350 EXPECT_FALSE(test::SpdyAltSvcWireFormatPeer::ParseAltAuthority(
351 input.begin(), input.end(), &host, &port))
352 << input;
356 // Test ParseInteger() on valid input.
357 TEST(SpdyAltSvcWireFormatTest, ParseIntegerValid) {
358 StringPiece input("3");
359 uint16 value;
360 ASSERT_TRUE(test::SpdyAltSvcWireFormatPeer::ParsePositiveInteger16(
361 input.begin(), input.end(), &value));
362 EXPECT_EQ(3, value);
364 input = StringPiece("1337");
365 ASSERT_TRUE(test::SpdyAltSvcWireFormatPeer::ParsePositiveInteger16(
366 input.begin(), input.end(), &value));
367 EXPECT_EQ(1337, value);
370 // Test ParseIntegerValid() on invalid input: empty, zero, non-numeric, trailing
371 // non-numeric characters.
372 TEST(SpdyAltSvcWireFormatTest, ParseIntegerInvalid) {
373 const char* invalid_input_array[] = {"", " ", "a", "0", "00", "1 ", "12b"};
374 for (const char* invalid_input : invalid_input_array) {
375 StringPiece input(invalid_input);
376 uint16 value;
377 EXPECT_FALSE(test::SpdyAltSvcWireFormatPeer::ParsePositiveInteger16(
378 input.begin(), input.end(), &value))
379 << input;
383 // Test ParseIntegerValid() around overflow limit.
384 TEST(SpdyAltSvcWireFormatTest, ParseIntegerOverflow) {
385 // Largest possible uint16 value.
386 StringPiece input("65535");
387 uint16 value16;
388 ASSERT_TRUE(test::SpdyAltSvcWireFormatPeer::ParsePositiveInteger16(
389 input.begin(), input.end(), &value16));
390 EXPECT_EQ(65535, value16);
392 // Overflow uint16, ParsePositiveInteger16() should return false.
393 input = StringPiece("65536");
394 ASSERT_FALSE(test::SpdyAltSvcWireFormatPeer::ParsePositiveInteger16(
395 input.begin(), input.end(), &value16));
397 // However, even if overflow is not checked for, 65536 overflows to 0, which
398 // returns false anyway. Check for a larger number which overflows to 1.
399 input = StringPiece("65537");
400 ASSERT_FALSE(test::SpdyAltSvcWireFormatPeer::ParsePositiveInteger16(
401 input.begin(), input.end(), &value16));
403 // Largest possible uint32 value.
404 input = StringPiece("4294967295");
405 uint32 value32;
406 ASSERT_TRUE(test::SpdyAltSvcWireFormatPeer::ParsePositiveInteger32(
407 input.begin(), input.end(), &value32));
408 EXPECT_EQ(4294967295, value32);
410 // Overflow uint32, ParsePositiveInteger32() should return false.
411 input = StringPiece("4294967296");
412 ASSERT_FALSE(test::SpdyAltSvcWireFormatPeer::ParsePositiveInteger32(
413 input.begin(), input.end(), &value32));
415 // However, even if overflow is not checked for, 4294967296 overflows to 0,
416 // which returns false anyway. Check for a larger number which overflows to
417 // 1.
418 input = StringPiece("4294967297");
419 ASSERT_FALSE(test::SpdyAltSvcWireFormatPeer::ParsePositiveInteger32(
420 input.begin(), input.end(), &value32));
423 // Test ParseProbability() on valid input.
424 TEST(SpdyAltSvcWireFormatTest, ParseProbabilityValid) {
425 StringPiece input("0");
426 double probability = -2.0;
427 ASSERT_TRUE(test::SpdyAltSvcWireFormatPeer::ParseProbability(
428 input.begin(), input.end(), &probability));
429 EXPECT_DOUBLE_EQ(0.0, probability);
431 input = StringPiece("0.");
432 probability = -2.0;
433 ASSERT_TRUE(test::SpdyAltSvcWireFormatPeer::ParseProbability(
434 input.begin(), input.end(), &probability));
435 EXPECT_DOUBLE_EQ(0.0, probability);
437 input = StringPiece("0.0");
438 probability = -2.0;
439 ASSERT_TRUE(test::SpdyAltSvcWireFormatPeer::ParseProbability(
440 input.begin(), input.end(), &probability));
441 EXPECT_DOUBLE_EQ(0.0, probability);
443 input = StringPiece("1");
444 probability = -2.0;
445 ASSERT_TRUE(test::SpdyAltSvcWireFormatPeer::ParseProbability(
446 input.begin(), input.end(), &probability));
447 EXPECT_DOUBLE_EQ(1.0, probability);
449 input = StringPiece("1.");
450 probability = -2.0;
451 ASSERT_TRUE(test::SpdyAltSvcWireFormatPeer::ParseProbability(
452 input.begin(), input.end(), &probability));
453 EXPECT_DOUBLE_EQ(1.0, probability);
455 input = StringPiece("1.0");
456 probability = -2.0;
457 ASSERT_TRUE(test::SpdyAltSvcWireFormatPeer::ParseProbability(
458 input.begin(), input.end(), &probability));
459 EXPECT_DOUBLE_EQ(1.0, probability);
461 input = StringPiece("0.37");
462 probability = -2.0;
463 ASSERT_TRUE(test::SpdyAltSvcWireFormatPeer::ParseProbability(
464 input.begin(), input.end(), &probability));
465 EXPECT_DOUBLE_EQ(0.37, probability);
467 input = StringPiece("0.72");
468 probability = -2.0;
469 ASSERT_TRUE(test::SpdyAltSvcWireFormatPeer::ParseProbability(
470 input.begin(), input.end(), &probability));
471 EXPECT_DOUBLE_EQ(0.72, probability);
474 // Test ParseProbability() on invalid input: empty string, non-digit characters,
475 // negative input, larger than 1.0.
476 TEST(SpdyAltSvcWireFormatTest, ParseProbabilityInvalid) {
477 const char* invalid_input_array[] = {"", " ", ".", "a", "-2", "-0", "0a",
478 "1b ", "0.9z2", "0.33 ", "0.98x", "2.0", "1.0001", "1.00001",
479 "1.000001"};
480 for (const char* invalid_input : invalid_input_array) {
481 StringPiece input(invalid_input);
482 double probability;
483 EXPECT_FALSE(test::SpdyAltSvcWireFormatPeer::ParseProbability(
484 input.begin(), input.end(), &probability));
488 } // namespace
490 } // namespace net