Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1224)

Unified Diff: net/spdy/spdy_alt_svc_wire_format_test.cc

Issue 1130053007: Update HTTP/2 ALTSVC wireformat from draft-04 to draft-06. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Hack around win_chromium_compile_dbg_ng linker errors. Created 5 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « net/spdy/spdy_alt_svc_wire_format.cc ('k') | net/spdy/spdy_framer.h » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: net/spdy/spdy_alt_svc_wire_format_test.cc
diff --git a/net/spdy/spdy_alt_svc_wire_format_test.cc b/net/spdy/spdy_alt_svc_wire_format_test.cc
new file mode 100644
index 0000000000000000000000000000000000000000..1ecd53b6065ba31025ababe9da6f0a7fa817ac16
--- /dev/null
+++ b/net/spdy/spdy_alt_svc_wire_format_test.cc
@@ -0,0 +1,420 @@
+// Copyright (c) 2015 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "net/spdy/spdy_alt_svc_wire_format.h"
+
+#include "base/logging.h"
+#include "testing/gmock/include/gmock/gmock.h"
+#include "testing/platform_test.h"
+
+using ::testing::_;
+
+namespace net {
+
+namespace test {
+
+// Expose all private methods of class SpdyAltSvcWireFormat.
+class SpdyAltSvcWireFormatPeer {
+ public:
+ static void SkipWhiteSpace(StringPiece::const_iterator* c,
+ StringPiece::const_iterator end) {
+ SpdyAltSvcWireFormat::SkipWhiteSpace(c, end);
+ }
+ static bool PercentDecode(StringPiece::const_iterator c,
+ StringPiece::const_iterator end,
+ std::string* output) {
+ return SpdyAltSvcWireFormat::PercentDecode(c, end, output);
+ }
+ static bool ParseAltAuthority(StringPiece::const_iterator c,
+ StringPiece::const_iterator end,
+ std::string* host,
+ uint16* port) {
+ return SpdyAltSvcWireFormat::ParseAltAuthority(c, end, host, port);
+ }
+ static bool ParsePositiveInteger16(StringPiece::const_iterator c,
+ StringPiece::const_iterator end,
+ uint16* max_age) {
+ return SpdyAltSvcWireFormat::ParsePositiveInteger16(c, end, max_age);
+ }
+ static bool ParsePositiveInteger32(StringPiece::const_iterator c,
+ StringPiece::const_iterator end,
+ uint32* max_age) {
+ return SpdyAltSvcWireFormat::ParsePositiveInteger32(c, end, max_age);
+ }
+ static bool ParseProbability(StringPiece::const_iterator c,
+ StringPiece::const_iterator end,
+ double* p) {
+ return SpdyAltSvcWireFormat::ParseProbability(c, end, p);
+ }
+};
+
+} // namespace test
+
+namespace {
+
+class SpdyAltSvcWireFormatTest : public ::testing::Test {};
+
+// Tests of public API.
+
+// Fuzz test of ParseHeaderFieldValue() with optional whitespaces, ignored
+// parameters, duplicate parameters, trailing space, trailing alternate service
+// separator, etc.
+TEST(SpdyAltSvcWireFormatTest, ParseHeaderFieldValue) {
+ for (int i = 0; i < 1 << 13; ++i) {
+ std::string header_field_value = "a%3Db%25c=\"";
+ std::string expected_host;
+ if (i & 1 << 0) {
+ expected_host = "foo\"bar\\baz";
+ header_field_value.append("foo\\\"bar\\\\baz");
+ }
+ header_field_value.append(":42\"");
+ if (i & 1 << 1) {
+ header_field_value.append(" ");
+ }
+ uint32 expected_max_age = 86400;
+ if (i & 3 << 2) {
+ expected_max_age = 1111;
+ header_field_value.append(";");
+ if (i & 1 << 2) {
+ header_field_value.append(" ");
+ }
+ header_field_value.append("mA=1111");
+ if (i & 2 << 2) {
+ header_field_value.append(" ");
+ }
+ }
+ if (i & 1 << 4) {
+ header_field_value.append("; J=s");
+ }
+ double expected_p = 1.0;
+ if (i & 1 << 5) {
+ expected_p = 0.33;
+ header_field_value.append("; P=.33");
+ }
+ if (i & 1 << 6) {
+ expected_p = 0.0;
+ header_field_value.append("; p=0");
+ }
+ if (i & 1 << 7) {
+ expected_max_age = 999999999;
+ header_field_value.append("; Ma=999999999");
+ }
+ if (i & 1 << 8) {
+ expected_p = 0.0;
+ header_field_value.append("; P=0.");
+ }
+ if (i & 1 << 9) {
+ header_field_value.append(";");
+ }
+ if (i & 1 << 10) {
+ header_field_value.append(" ");
+ }
+ if (i & 1 << 11) {
+ header_field_value.append(",");
+ }
+ if (i & 1 << 12) {
+ header_field_value.append(" ");
+ }
+
+ std::string protocol_id;
+ std::string host;
+ uint16 port = 0;
+ uint32 max_age = 0;
+ double p = 0.0;
+
+ ASSERT_TRUE(SpdyAltSvcWireFormat::ParseHeaderFieldValue(
+ header_field_value, &protocol_id, &host, &port, &max_age, &p));
+ EXPECT_EQ("a=b%c", protocol_id);
+ EXPECT_EQ(expected_host, host);
+ EXPECT_EQ(42, port);
+ EXPECT_EQ(expected_max_age, max_age);
+ EXPECT_DOUBLE_EQ(expected_p, p);
+ }
+}
+
+// Test SerializeHeaderFieldValue() with and without hostname and each
+// parameter.
+TEST(SpdyAltSvcWireFormatTest, SerializeHeaderFieldValue) {
+ for (int i = 0; i < 1 << 3; ++i) {
+ std::string expected_header_field_value = "a%3Db%25c=\"";
+ std::string host;
+ if (i & 1 << 0) {
+ host = "foo\"bar\\baz";
+ expected_header_field_value.append("foo\\\"bar\\\\baz");
+ }
+ expected_header_field_value.append(":42\"");
+ int max_age = 86400;
+ if (i & 1 << 1) {
+ max_age = 1111;
+ expected_header_field_value.append("; ma=1111");
+ }
+ double p = 1.0;
+ if (i & 1 << 2) {
+ p = 0.33;
+ expected_header_field_value.append("; p=0.33");
+ }
+ EXPECT_EQ(expected_header_field_value,
+ SpdyAltSvcWireFormat::SerializeHeaderFieldValue("a=b%c", host, 42,
+ max_age, p));
+ }
+}
+
+// ParseHeaderFieldValue() should return false on malformed field values:
+// invalid percent encoding, unmatched quotation mark, empty port, non-numeric
+// characters in numeric fields, negative or larger than 1.0 probability.
+TEST(SpdyAltSvcWireFormatTest, ParseHeaderFieldValueInvalid) {
+ std::string protocol_id;
+ std::string host;
+ uint16 port;
+ uint32 max_age;
+ double p;
+ const char* invalid_field_value_array[] = {"", "a%", "a%x", "a%b", "a%9z",
+ "a=", "a=\"", "a=\"b\"", "a=\":\"", "a=\"c:\"", "a=\"c:foo\"",
+ "a=\"c:42foo\"", "a=\"b:42\"bar", "a=\"b:42\" ; m",
+ "a=\"b:42\" ; min-age", "a=\"b:42\" ; ma", "a=\"b:42\" ; ma=",
+ "a=\"b:42\" ; ma=ma", "a=\"b:42\" ; ma=123bar", "a=\"b:42\" ; p=-2",
+ "a=\"b:42\" ; p=..", "a=\"b:42\" ; p=1.05"};
+ for (const char* invalid_field_value : invalid_field_value_array) {
+ EXPECT_FALSE(SpdyAltSvcWireFormat::ParseHeaderFieldValue(
+ invalid_field_value, &protocol_id, &host, &port, &max_age, &p))
+ << invalid_field_value;
+ }
+}
+
+// ParseHeaderFieldValue() should return false on a field values truncated
+// before closing quotation mark, without trying to access memory beyond the end
+// of the input.
+TEST(SpdyAltSvcWireFormatTest, ParseTruncatedHeaderFieldValue) {
+ std::string protocol_id;
+ std::string host;
+ uint16 port;
+ uint32 max_age;
+ double p;
+ const char* field_value_array[] = {
+ "p=\":137\"", "p=\"foo:137\"", "p%25=\"foo\\\"bar\\\\baz:137\""};
+ for (std::string field_value : field_value_array) {
+ for (size_t len = 1; len < field_value.size(); ++len) {
+ EXPECT_FALSE(SpdyAltSvcWireFormat::ParseHeaderFieldValue(
+ field_value.substr(0, len), &protocol_id, &host, &port, &max_age, &p))
+ << len;
+ }
+ }
+}
+
+// Tests of private methods.
+
+// Test SkipWhiteSpace().
+TEST(SpdyAltSvcWireFormatTest, SkipWhiteSpace) {
+ StringPiece input("a \tb ");
+ StringPiece::const_iterator c = input.begin();
+ test::SpdyAltSvcWireFormatPeer::SkipWhiteSpace(&c, input.end());
+ ASSERT_EQ(input.begin(), c);
+ ++c;
+ test::SpdyAltSvcWireFormatPeer::SkipWhiteSpace(&c, input.end());
+ ASSERT_EQ(input.begin() + 3, c);
+ ++c;
+ test::SpdyAltSvcWireFormatPeer::SkipWhiteSpace(&c, input.end());
+ ASSERT_EQ(input.end(), c);
+}
+
+// Test PercentDecode() on valid input.
+TEST(SpdyAltSvcWireFormatTest, PercentDecodeValid) {
+ StringPiece input("");
+ std::string output;
+ ASSERT_TRUE(test::SpdyAltSvcWireFormatPeer::PercentDecode(
+ input.begin(), input.end(), &output));
+ EXPECT_EQ("", output);
+
+ input = StringPiece("foo");
+ output.clear();
+ ASSERT_TRUE(test::SpdyAltSvcWireFormatPeer::PercentDecode(
+ input.begin(), input.end(), &output));
+ EXPECT_EQ("foo", output);
+
+ input = StringPiece("%2ca%5Cb");
+ output.clear();
+ ASSERT_TRUE(test::SpdyAltSvcWireFormatPeer::PercentDecode(
+ input.begin(), input.end(), &output));
+ EXPECT_EQ(",a\\b", output);
+}
+
+// Test PercentDecode() on invalid input.
+TEST(SpdyAltSvcWireFormatTest, PercentDecodeInvalid) {
+ const char* invalid_input_array[] = {"a%", "a%x", "a%b", "%J22", "%9z"};
+ for (const char* invalid_input : invalid_input_array) {
+ StringPiece input(invalid_input);
+ std::string output;
+ EXPECT_FALSE(test::SpdyAltSvcWireFormatPeer::PercentDecode(
+ input.begin(), input.end(), &output))
+ << input;
+ }
+}
+
+// Test ParseAltAuthority() on valid input.
+TEST(SpdyAltSvcWireFormatTest, ParseAltAuthorityValid) {
+ StringPiece input(":42");
+ std::string host;
+ uint16 port;
+ ASSERT_TRUE(test::SpdyAltSvcWireFormatPeer::ParseAltAuthority(
+ input.begin(), input.end(), &host, &port));
+ EXPECT_TRUE(host.empty());
+ EXPECT_EQ(42, port);
+
+ input = StringPiece("foo:137");
+ ASSERT_TRUE(test::SpdyAltSvcWireFormatPeer::ParseAltAuthority(
+ input.begin(), input.end(), &host, &port));
+ EXPECT_EQ("foo", host);
+ EXPECT_EQ(137, port);
+}
+
+// Test ParseAltAuthority() on invalid input: empty string, no port, zero port,
+// non-digit characters following port.
+TEST(SpdyAltSvcWireFormatTest, ParseAltAuthorityInvalid) {
+ const char* invalid_input_array[] = {"", ":", "foo:", ":bar", ":0", "foo:0",
+ ":12bar", "foo:23bar", " ", ":12 ", "foo:12 "};
+ for (const char* invalid_input : invalid_input_array) {
+ StringPiece input(invalid_input);
+ std::string host;
+ uint16 port;
+ EXPECT_FALSE(test::SpdyAltSvcWireFormatPeer::ParseAltAuthority(
+ input.begin(), input.end(), &host, &port))
+ << input;
+ }
+}
+
+// Test ParseInteger() on valid input.
+TEST(SpdyAltSvcWireFormatTest, ParseIntegerValid) {
+ StringPiece input("3");
+ uint16 value;
+ ASSERT_TRUE(test::SpdyAltSvcWireFormatPeer::ParsePositiveInteger16(
+ input.begin(), input.end(), &value));
+ EXPECT_EQ(3, value);
+
+ input = StringPiece("1337");
+ ASSERT_TRUE(test::SpdyAltSvcWireFormatPeer::ParsePositiveInteger16(
+ input.begin(), input.end(), &value));
+ EXPECT_EQ(1337, value);
+}
+
+// Test ParseIntegerValid() on invalid input: empty, zero, non-numeric, trailing
+// non-numeric characters.
+TEST(SpdyAltSvcWireFormatTest, ParseIntegerInvalid) {
+ const char* invalid_input_array[] = {"", " ", "a", "0", "00", "1 ", "12b"};
+ for (const char* invalid_input : invalid_input_array) {
+ StringPiece input(invalid_input);
+ uint16 value;
+ EXPECT_FALSE(test::SpdyAltSvcWireFormatPeer::ParsePositiveInteger16(
+ input.begin(), input.end(), &value))
+ << input;
+ }
+}
+
+// Test ParseIntegerValid() around overflow limit.
+TEST(SpdyAltSvcWireFormatTest, ParseIntegerOverflow) {
+ // Largest possible uint16 value.
+ StringPiece input("65535");
+ uint16 value16;
+ ASSERT_TRUE(test::SpdyAltSvcWireFormatPeer::ParsePositiveInteger16(
+ input.begin(), input.end(), &value16));
+ EXPECT_EQ(65535, value16);
+
+ // Overflow uint16, ParsePositiveInteger16() should return false.
+ input = StringPiece("65536");
+ ASSERT_FALSE(test::SpdyAltSvcWireFormatPeer::ParsePositiveInteger16(
+ input.begin(), input.end(), &value16));
+
+ // However, even if overflow is not checked for, 65536 overflows to 0, which
+ // returns false anyway. Check for a larger number which overflows to 1.
+ input = StringPiece("65537");
+ ASSERT_FALSE(test::SpdyAltSvcWireFormatPeer::ParsePositiveInteger16(
+ input.begin(), input.end(), &value16));
+
+ // Largest possible uint32 value.
+ input = StringPiece("4294967295");
+ uint32 value32;
+ ASSERT_TRUE(test::SpdyAltSvcWireFormatPeer::ParsePositiveInteger32(
+ input.begin(), input.end(), &value32));
+ EXPECT_EQ(4294967295, value32);
+
+ // Overflow uint32, ParsePositiveInteger32() should return false.
+ input = StringPiece("4294967296");
+ ASSERT_FALSE(test::SpdyAltSvcWireFormatPeer::ParsePositiveInteger32(
+ input.begin(), input.end(), &value32));
+
+ // However, even if overflow is not checked for, 4294967296 overflows to 0,
+ // which returns false anyway. Check for a larger number which overflows to
+ // 1.
+ input = StringPiece("4294967297");
+ ASSERT_FALSE(test::SpdyAltSvcWireFormatPeer::ParsePositiveInteger32(
+ input.begin(), input.end(), &value32));
+}
+
+// Test ParseProbability() on valid input.
+TEST(SpdyAltSvcWireFormatTest, ParseProbabilityValid) {
+ StringPiece input("0");
+ double probability = -2.0;
+ ASSERT_TRUE(test::SpdyAltSvcWireFormatPeer::ParseProbability(
+ input.begin(), input.end(), &probability));
+ EXPECT_DOUBLE_EQ(0.0, probability);
+
+ input = StringPiece("0.");
+ probability = -2.0;
+ ASSERT_TRUE(test::SpdyAltSvcWireFormatPeer::ParseProbability(
+ input.begin(), input.end(), &probability));
+ EXPECT_DOUBLE_EQ(0.0, probability);
+
+ input = StringPiece("0.0");
+ probability = -2.0;
+ ASSERT_TRUE(test::SpdyAltSvcWireFormatPeer::ParseProbability(
+ input.begin(), input.end(), &probability));
+ EXPECT_DOUBLE_EQ(0.0, probability);
+
+ input = StringPiece("1");
+ probability = -2.0;
+ ASSERT_TRUE(test::SpdyAltSvcWireFormatPeer::ParseProbability(
+ input.begin(), input.end(), &probability));
+ EXPECT_DOUBLE_EQ(1.0, probability);
+
+ input = StringPiece("1.");
+ probability = -2.0;
+ ASSERT_TRUE(test::SpdyAltSvcWireFormatPeer::ParseProbability(
+ input.begin(), input.end(), &probability));
+ EXPECT_DOUBLE_EQ(1.0, probability);
+
+ input = StringPiece("1.0");
+ probability = -2.0;
+ ASSERT_TRUE(test::SpdyAltSvcWireFormatPeer::ParseProbability(
+ input.begin(), input.end(), &probability));
+ EXPECT_DOUBLE_EQ(1.0, probability);
+
+ input = StringPiece("0.37");
+ probability = -2.0;
+ ASSERT_TRUE(test::SpdyAltSvcWireFormatPeer::ParseProbability(
+ input.begin(), input.end(), &probability));
+ EXPECT_DOUBLE_EQ(0.37, probability);
+
+ input = StringPiece("0.72");
+ probability = -2.0;
+ ASSERT_TRUE(test::SpdyAltSvcWireFormatPeer::ParseProbability(
+ input.begin(), input.end(), &probability));
+ EXPECT_DOUBLE_EQ(0.72, probability);
+}
+
+// Test ParseProbability() on invalid input: empty string, non-digit characters,
+// negative input, larger than 1.0.
+TEST(SpdyAltSvcWireFormatTest, ParseProbabilityInvalid) {
+ const char* invalid_input_array[] = {"", " ", ".", "a", "-2", "-0", "0a",
+ "1b ", "0.9z2", "0.33 ", "0.98x", "2.0", "1.0001", "1.00001",
+ "1.000001"};
+ for (const char* invalid_input : invalid_input_array) {
+ StringPiece input(invalid_input);
+ double probability;
+ EXPECT_FALSE(test::SpdyAltSvcWireFormatPeer::ParseProbability(
+ input.begin(), input.end(), &probability));
+ }
+}
+
+} // namespace
+
+} // namespace net
« no previous file with comments | « net/spdy/spdy_alt_svc_wire_format.cc ('k') | net/spdy/spdy_framer.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698