Remove SpdyHexDigitToInt() and SpdyHexDecodeToUInt32() from platform.
Implement them and move them to SpdyAltSvcWireFormat. SpdyHexDigitToIntImpl()
is very small, the binary size savings of having it in platform is not worth the
extra complexity. SpdyHexDecodeToUInt32Impl() is quite messy both internally
and in Chromium, even less worth to keep in platform.
Also move anonymous namespace encompassing all SpdyAltSvcWireFormatTests into
test namespace.
PiperOrigin-RevId: 374604463
diff --git a/spdy/core/spdy_alt_svc_wire_format.cc b/spdy/core/spdy_alt_svc_wire_format.cc
index dd35a48..94218f6 100644
--- a/spdy/core/spdy_alt_svc_wire_format.cc
+++ b/spdy/core/spdy_alt_svc_wire_format.cc
@@ -196,9 +196,9 @@
// hq=":443";quic=51303338
// ... will be stored in |versions| as 0x51303338.
uint32_t quic_version;
- if (!SpdyHexDecodeToUInt32(absl::string_view(&*parameter_value_begin,
- c - parameter_value_begin),
- &quic_version) ||
+ if (!HexDecodeToUInt32(absl::string_view(&*parameter_value_begin,
+ c - parameter_value_begin),
+ &quic_version) ||
quic_version == 0) {
return false;
}
@@ -315,12 +315,12 @@
return false;
}
// Network byte order is big-endian.
- char decoded = SpdyHexDigitToInt(*c) << 4;
+ char decoded = HexDigitToInt(*c) << 4;
++c;
if (c == end || !std::isxdigit(*c)) {
return false;
}
- decoded += SpdyHexDigitToInt(*c);
+ decoded += HexDigitToInt(*c);
output->push_back(decoded);
}
return true;
@@ -389,4 +389,41 @@
return ParsePositiveIntegerImpl<uint32_t>(c, end, value);
}
+// static
+char SpdyAltSvcWireFormat::HexDigitToInt(char c) {
+ QUICHE_DCHECK(std::isxdigit(c));
+
+ if (std::isdigit(c)) {
+ return c - '0';
+ }
+ if (c >= 'A' && c <= 'F') {
+ return c - 'A' + 10;
+ }
+ if (c >= 'a' && c <= 'f') {
+ return c - 'a' + 10;
+ }
+
+ return 0;
+}
+
+// static
+bool SpdyAltSvcWireFormat::HexDecodeToUInt32(absl::string_view data,
+ uint32_t* value) {
+ if (data.empty() || data.length() > 8u) {
+ return false;
+ }
+
+ *value = 0;
+ for (char c : data) {
+ if (!std::isxdigit(c)) {
+ return false;
+ }
+
+ *value <<= 4;
+ *value += HexDigitToInt(c);
+ }
+
+ return true;
+}
+
} // namespace spdy
diff --git a/spdy/core/spdy_alt_svc_wire_format.h b/spdy/core/spdy_alt_svc_wire_format.h
index fccda75..a8e1094 100644
--- a/spdy/core/spdy_alt_svc_wire_format.h
+++ b/spdy/core/spdy_alt_svc_wire_format.h
@@ -66,21 +66,40 @@
const AlternativeServiceVector& altsvc_vector);
private:
+ // Forward |*c| over space and tab or until |end| is reached.
static void SkipWhiteSpace(absl::string_view::const_iterator* c,
absl::string_view::const_iterator end);
+ // Decode percent-decoded string between |c| and |end| into |*output|.
+ // Return true on success, false if input is invalid.
static bool PercentDecode(absl::string_view::const_iterator c,
absl::string_view::const_iterator end,
std::string* output);
+ // Parse the authority part of Alt-Svc between |c| and |end| into |*host| and
+ // |*port|. Return true on success, false if input is invalid.
static bool ParseAltAuthority(absl::string_view::const_iterator c,
absl::string_view::const_iterator end,
std::string* host,
uint16_t* port);
+ // Parse a positive integer between |c| and |end| into |*value|.
+ // Return true on success, false if input is not a positive integer or it
+ // cannot be represented on uint16_t.
static bool ParsePositiveInteger16(absl::string_view::const_iterator c,
absl::string_view::const_iterator end,
uint16_t* value);
+ // Parse a positive integer between |c| and |end| into |*value|.
+ // Return true on success, false if input is not a positive integer or it
+ // cannot be represented on uint32_t.
static bool ParsePositiveInteger32(absl::string_view::const_iterator c,
absl::string_view::const_iterator end,
uint32_t* value);
+ // Parse |c| as hexadecimal digit, case insensitive. |c| must be [0-9a-fA-F].
+ // Output is between 0 and 15.
+ static char HexDigitToInt(char c);
+ // Parse |data| as hexadecimal number into |*value|. |data| must only contain
+ // hexadecimal digits, no "0x" prefix.
+ // Return true on success, false if input is empty, not valid hexadecimal
+ // number, or cannot be represented on uint32_t.
+ static bool HexDecodeToUInt32(absl::string_view data, uint32_t* value);
};
} // namespace spdy
diff --git a/spdy/core/spdy_alt_svc_wire_format_test.cc b/spdy/core/spdy_alt_svc_wire_format_test.cc
index 80f846d..497f19d 100644
--- a/spdy/core/spdy_alt_svc_wire_format_test.cc
+++ b/spdy/core/spdy_alt_svc_wire_format_test.cc
@@ -38,10 +38,14 @@
uint32_t* max_age) {
return SpdyAltSvcWireFormat::ParsePositiveInteger32(c, end, max_age);
}
+ static char HexDigitToInt(char c) {
+ return SpdyAltSvcWireFormat::HexDigitToInt(c);
+ }
+ static bool HexDecodeToUInt32(absl::string_view data, uint32_t* value) {
+ return SpdyAltSvcWireFormat::HexDecodeToUInt32(data, value);
+ }
};
-} // namespace test
-
namespace {
// Generate header field values, possibly with multiply defined parameters and
@@ -388,13 +392,13 @@
TEST(SpdyAltSvcWireFormatTest, SkipWhiteSpace) {
absl::string_view input("a \tb ");
absl::string_view::const_iterator c = input.begin();
- test::SpdyAltSvcWireFormatPeer::SkipWhiteSpace(&c, input.end());
+ SpdyAltSvcWireFormatPeer::SkipWhiteSpace(&c, input.end());
ASSERT_EQ(input.begin(), c);
++c;
- test::SpdyAltSvcWireFormatPeer::SkipWhiteSpace(&c, input.end());
+ SpdyAltSvcWireFormatPeer::SkipWhiteSpace(&c, input.end());
ASSERT_EQ(input.begin() + 3, c);
++c;
- test::SpdyAltSvcWireFormatPeer::SkipWhiteSpace(&c, input.end());
+ SpdyAltSvcWireFormatPeer::SkipWhiteSpace(&c, input.end());
ASSERT_EQ(input.end(), c);
}
@@ -402,20 +406,20 @@
TEST(SpdyAltSvcWireFormatTest, PercentDecodeValid) {
absl::string_view input("");
std::string output;
- ASSERT_TRUE(test::SpdyAltSvcWireFormatPeer::PercentDecode(
- input.begin(), input.end(), &output));
+ ASSERT_TRUE(SpdyAltSvcWireFormatPeer::PercentDecode(input.begin(),
+ input.end(), &output));
EXPECT_EQ("", output);
input = absl::string_view("foo");
output.clear();
- ASSERT_TRUE(test::SpdyAltSvcWireFormatPeer::PercentDecode(
- input.begin(), input.end(), &output));
+ ASSERT_TRUE(SpdyAltSvcWireFormatPeer::PercentDecode(input.begin(),
+ input.end(), &output));
EXPECT_EQ("foo", output);
input = absl::string_view("%2ca%5Cb");
output.clear();
- ASSERT_TRUE(test::SpdyAltSvcWireFormatPeer::PercentDecode(
- input.begin(), input.end(), &output));
+ ASSERT_TRUE(SpdyAltSvcWireFormatPeer::PercentDecode(input.begin(),
+ input.end(), &output));
EXPECT_EQ(",a\\b", output);
}
@@ -425,8 +429,8 @@
for (const char* invalid_input : invalid_input_array) {
absl::string_view input(invalid_input);
std::string output;
- EXPECT_FALSE(test::SpdyAltSvcWireFormatPeer::PercentDecode(
- input.begin(), input.end(), &output))
+ EXPECT_FALSE(SpdyAltSvcWireFormatPeer::PercentDecode(input.begin(),
+ input.end(), &output))
<< input;
}
}
@@ -436,19 +440,19 @@
absl::string_view input(":42");
std::string host;
uint16_t port;
- ASSERT_TRUE(test::SpdyAltSvcWireFormatPeer::ParseAltAuthority(
+ ASSERT_TRUE(SpdyAltSvcWireFormatPeer::ParseAltAuthority(
input.begin(), input.end(), &host, &port));
EXPECT_TRUE(host.empty());
EXPECT_EQ(42, port);
input = absl::string_view("foo:137");
- ASSERT_TRUE(test::SpdyAltSvcWireFormatPeer::ParseAltAuthority(
+ ASSERT_TRUE(SpdyAltSvcWireFormatPeer::ParseAltAuthority(
input.begin(), input.end(), &host, &port));
EXPECT_EQ("foo", host);
EXPECT_EQ(137, port);
input = absl::string_view("[2003:8:0:16::509d:9615]:443");
- ASSERT_TRUE(test::SpdyAltSvcWireFormatPeer::ParseAltAuthority(
+ ASSERT_TRUE(SpdyAltSvcWireFormatPeer::ParseAltAuthority(
input.begin(), input.end(), &host, &port));
EXPECT_EQ("[2003:8:0:16::509d:9615]", host);
EXPECT_EQ(443, port);
@@ -477,7 +481,7 @@
absl::string_view input(invalid_input);
std::string host;
uint16_t port;
- EXPECT_FALSE(test::SpdyAltSvcWireFormatPeer::ParseAltAuthority(
+ EXPECT_FALSE(SpdyAltSvcWireFormatPeer::ParseAltAuthority(
input.begin(), input.end(), &host, &port))
<< input;
}
@@ -487,12 +491,12 @@
TEST(SpdyAltSvcWireFormatTest, ParseIntegerValid) {
absl::string_view input("3");
uint16_t value;
- ASSERT_TRUE(test::SpdyAltSvcWireFormatPeer::ParsePositiveInteger16(
+ ASSERT_TRUE(SpdyAltSvcWireFormatPeer::ParsePositiveInteger16(
input.begin(), input.end(), &value));
EXPECT_EQ(3, value);
input = absl::string_view("1337");
- ASSERT_TRUE(test::SpdyAltSvcWireFormatPeer::ParsePositiveInteger16(
+ ASSERT_TRUE(SpdyAltSvcWireFormatPeer::ParsePositiveInteger16(
input.begin(), input.end(), &value));
EXPECT_EQ(1337, value);
}
@@ -504,7 +508,7 @@
for (const char* invalid_input : invalid_input_array) {
absl::string_view input(invalid_input);
uint16_t value;
- EXPECT_FALSE(test::SpdyAltSvcWireFormatPeer::ParsePositiveInteger16(
+ EXPECT_FALSE(SpdyAltSvcWireFormatPeer::ParsePositiveInteger16(
input.begin(), input.end(), &value))
<< input;
}
@@ -515,38 +519,38 @@
// Largest possible uint16_t value.
absl::string_view input("65535");
uint16_t value16;
- ASSERT_TRUE(test::SpdyAltSvcWireFormatPeer::ParsePositiveInteger16(
+ ASSERT_TRUE(SpdyAltSvcWireFormatPeer::ParsePositiveInteger16(
input.begin(), input.end(), &value16));
EXPECT_EQ(65535, value16);
// Overflow uint16_t, ParsePositiveInteger16() should return false.
input = absl::string_view("65536");
- ASSERT_FALSE(test::SpdyAltSvcWireFormatPeer::ParsePositiveInteger16(
+ ASSERT_FALSE(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 = absl::string_view("65537");
- ASSERT_FALSE(test::SpdyAltSvcWireFormatPeer::ParsePositiveInteger16(
+ ASSERT_FALSE(SpdyAltSvcWireFormatPeer::ParsePositiveInteger16(
input.begin(), input.end(), &value16));
// Largest possible uint32_t value.
input = absl::string_view("4294967295");
uint32_t value32;
- ASSERT_TRUE(test::SpdyAltSvcWireFormatPeer::ParsePositiveInteger32(
+ ASSERT_TRUE(SpdyAltSvcWireFormatPeer::ParsePositiveInteger32(
input.begin(), input.end(), &value32));
EXPECT_EQ(4294967295, value32);
// Overflow uint32_t, ParsePositiveInteger32() should return false.
input = absl::string_view("4294967296");
- ASSERT_FALSE(test::SpdyAltSvcWireFormatPeer::ParsePositiveInteger32(
+ ASSERT_FALSE(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 = absl::string_view("4294967297");
- ASSERT_FALSE(test::SpdyAltSvcWireFormatPeer::ParsePositiveInteger32(
+ ASSERT_FALSE(SpdyAltSvcWireFormatPeer::ParsePositiveInteger32(
input.begin(), input.end(), &value32));
}
@@ -566,6 +570,64 @@
EXPECT_THAT(altsvc_vector[0].version, ::testing::ElementsAre(36, 35));
}
+TEST(SpdyAltSvcWireFormatTest, HexDigitToInt) {
+ EXPECT_EQ(0, SpdyAltSvcWireFormatPeer::HexDigitToInt('0'));
+ EXPECT_EQ(1, SpdyAltSvcWireFormatPeer::HexDigitToInt('1'));
+ EXPECT_EQ(2, SpdyAltSvcWireFormatPeer::HexDigitToInt('2'));
+ EXPECT_EQ(3, SpdyAltSvcWireFormatPeer::HexDigitToInt('3'));
+ EXPECT_EQ(4, SpdyAltSvcWireFormatPeer::HexDigitToInt('4'));
+ EXPECT_EQ(5, SpdyAltSvcWireFormatPeer::HexDigitToInt('5'));
+ EXPECT_EQ(6, SpdyAltSvcWireFormatPeer::HexDigitToInt('6'));
+ EXPECT_EQ(7, SpdyAltSvcWireFormatPeer::HexDigitToInt('7'));
+ EXPECT_EQ(8, SpdyAltSvcWireFormatPeer::HexDigitToInt('8'));
+ EXPECT_EQ(9, SpdyAltSvcWireFormatPeer::HexDigitToInt('9'));
+
+ EXPECT_EQ(10, SpdyAltSvcWireFormatPeer::HexDigitToInt('a'));
+ EXPECT_EQ(11, SpdyAltSvcWireFormatPeer::HexDigitToInt('b'));
+ EXPECT_EQ(12, SpdyAltSvcWireFormatPeer::HexDigitToInt('c'));
+ EXPECT_EQ(13, SpdyAltSvcWireFormatPeer::HexDigitToInt('d'));
+ EXPECT_EQ(14, SpdyAltSvcWireFormatPeer::HexDigitToInt('e'));
+ EXPECT_EQ(15, SpdyAltSvcWireFormatPeer::HexDigitToInt('f'));
+
+ EXPECT_EQ(10, SpdyAltSvcWireFormatPeer::HexDigitToInt('A'));
+ EXPECT_EQ(11, SpdyAltSvcWireFormatPeer::HexDigitToInt('B'));
+ EXPECT_EQ(12, SpdyAltSvcWireFormatPeer::HexDigitToInt('C'));
+ EXPECT_EQ(13, SpdyAltSvcWireFormatPeer::HexDigitToInt('D'));
+ EXPECT_EQ(14, SpdyAltSvcWireFormatPeer::HexDigitToInt('E'));
+ EXPECT_EQ(15, SpdyAltSvcWireFormatPeer::HexDigitToInt('F'));
+}
+
+TEST(SpdyAltSvcWireFormatTest, HexDecodeToUInt32) {
+ uint32_t out;
+ EXPECT_TRUE(SpdyAltSvcWireFormatPeer::HexDecodeToUInt32("0", &out));
+ EXPECT_EQ(0u, out);
+ EXPECT_TRUE(SpdyAltSvcWireFormatPeer::HexDecodeToUInt32("00", &out));
+ EXPECT_EQ(0u, out);
+ EXPECT_TRUE(SpdyAltSvcWireFormatPeer::HexDecodeToUInt32("0000000", &out));
+ EXPECT_EQ(0u, out);
+ EXPECT_TRUE(SpdyAltSvcWireFormatPeer::HexDecodeToUInt32("00000000", &out));
+ EXPECT_EQ(0u, out);
+ EXPECT_TRUE(SpdyAltSvcWireFormatPeer::HexDecodeToUInt32("1", &out));
+ EXPECT_EQ(1u, out);
+ EXPECT_TRUE(SpdyAltSvcWireFormatPeer::HexDecodeToUInt32("ffffFFF", &out));
+ EXPECT_EQ(0xFFFFFFFu, out);
+ EXPECT_TRUE(SpdyAltSvcWireFormatPeer::HexDecodeToUInt32("fFfFffFf", &out));
+ EXPECT_EQ(0xFFFFFFFFu, out);
+ EXPECT_TRUE(SpdyAltSvcWireFormatPeer::HexDecodeToUInt32("01AEF", &out));
+ EXPECT_EQ(0x1AEFu, out);
+ EXPECT_TRUE(SpdyAltSvcWireFormatPeer::HexDecodeToUInt32("abcde", &out));
+ EXPECT_EQ(0xABCDEu, out);
+ EXPECT_TRUE(SpdyAltSvcWireFormatPeer::HexDecodeToUInt32("1234abcd", &out));
+ EXPECT_EQ(0x1234ABCDu, out);
+
+ EXPECT_FALSE(SpdyAltSvcWireFormatPeer::HexDecodeToUInt32("", &out));
+ EXPECT_FALSE(SpdyAltSvcWireFormatPeer::HexDecodeToUInt32("111111111", &out));
+ EXPECT_FALSE(SpdyAltSvcWireFormatPeer::HexDecodeToUInt32("1111111111", &out));
+ EXPECT_FALSE(SpdyAltSvcWireFormatPeer::HexDecodeToUInt32("0x1111", &out));
+}
+
} // namespace
+} // namespace test
+
} // namespace spdy
diff --git a/spdy/platform/api/spdy_string_utils.h b/spdy/platform/api/spdy_string_utils.h
index cc8d942..83660ba 100644
--- a/spdy/platform/api/spdy_string_utils.h
+++ b/spdy/platform/api/spdy_string_utils.h
@@ -6,22 +6,12 @@
#define QUICHE_SPDY_PLATFORM_API_SPDY_STRING_UTILS_H_
#include <string>
-#include <utility>
#include "absl/strings/string_view.h"
#include "net/spdy/platform/impl/spdy_string_utils_impl.h"
namespace spdy {
-inline char SpdyHexDigitToInt(char c) {
- return SpdyHexDigitToIntImpl(c);
-}
-
-
-inline bool SpdyHexDecodeToUInt32(absl::string_view data, uint32_t* out) {
- return SpdyHexDecodeToUInt32Impl(data, out);
-}
-
inline std::string SpdyHexDump(absl::string_view data) {
return SpdyHexDumpImpl(data);
}
diff --git a/spdy/platform/api/spdy_string_utils_test.cc b/spdy/platform/api/spdy_string_utils_test.cc
deleted file mode 100644
index 23ff82c..0000000
--- a/spdy/platform/api/spdy_string_utils_test.cc
+++ /dev/null
@@ -1,72 +0,0 @@
-// Copyright 2017 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 "spdy/platform/api/spdy_string_utils.h"
-
-#include <cstdint>
-
-#include "absl/strings/string_view.h"
-#include "common/platform/api/quiche_test.h"
-
-namespace spdy {
-namespace test {
-namespace {
-
-TEST(SpdyStringUtilsTest, SpdyHexDigitToInt) {
- EXPECT_EQ(0, SpdyHexDigitToInt('0'));
- EXPECT_EQ(1, SpdyHexDigitToInt('1'));
- EXPECT_EQ(2, SpdyHexDigitToInt('2'));
- EXPECT_EQ(3, SpdyHexDigitToInt('3'));
- EXPECT_EQ(4, SpdyHexDigitToInt('4'));
- EXPECT_EQ(5, SpdyHexDigitToInt('5'));
- EXPECT_EQ(6, SpdyHexDigitToInt('6'));
- EXPECT_EQ(7, SpdyHexDigitToInt('7'));
- EXPECT_EQ(8, SpdyHexDigitToInt('8'));
- EXPECT_EQ(9, SpdyHexDigitToInt('9'));
-
- EXPECT_EQ(10, SpdyHexDigitToInt('a'));
- EXPECT_EQ(11, SpdyHexDigitToInt('b'));
- EXPECT_EQ(12, SpdyHexDigitToInt('c'));
- EXPECT_EQ(13, SpdyHexDigitToInt('d'));
- EXPECT_EQ(14, SpdyHexDigitToInt('e'));
- EXPECT_EQ(15, SpdyHexDigitToInt('f'));
-
- EXPECT_EQ(10, SpdyHexDigitToInt('A'));
- EXPECT_EQ(11, SpdyHexDigitToInt('B'));
- EXPECT_EQ(12, SpdyHexDigitToInt('C'));
- EXPECT_EQ(13, SpdyHexDigitToInt('D'));
- EXPECT_EQ(14, SpdyHexDigitToInt('E'));
- EXPECT_EQ(15, SpdyHexDigitToInt('F'));
-}
-
-TEST(SpdyStringUtilsTest, SpdyHexDecodeToUInt32) {
- uint32_t out;
- EXPECT_TRUE(SpdyHexDecodeToUInt32("0", &out));
- EXPECT_EQ(0u, out);
- EXPECT_TRUE(SpdyHexDecodeToUInt32("00", &out));
- EXPECT_EQ(0u, out);
- EXPECT_TRUE(SpdyHexDecodeToUInt32("0000000", &out));
- EXPECT_EQ(0u, out);
- EXPECT_TRUE(SpdyHexDecodeToUInt32("00000000", &out));
- EXPECT_EQ(0u, out);
- EXPECT_TRUE(SpdyHexDecodeToUInt32("1", &out));
- EXPECT_EQ(1u, out);
- EXPECT_TRUE(SpdyHexDecodeToUInt32("ffffFFF", &out));
- EXPECT_EQ(0xFFFFFFFu, out);
- EXPECT_TRUE(SpdyHexDecodeToUInt32("fFfFffFf", &out));
- EXPECT_EQ(0xFFFFFFFFu, out);
- EXPECT_TRUE(SpdyHexDecodeToUInt32("01AEF", &out));
- EXPECT_EQ(0x1AEFu, out);
- EXPECT_TRUE(SpdyHexDecodeToUInt32("abcde", &out));
- EXPECT_EQ(0xABCDEu, out);
-
- EXPECT_FALSE(SpdyHexDecodeToUInt32("", &out));
- EXPECT_FALSE(SpdyHexDecodeToUInt32("111111111", &out));
- EXPECT_FALSE(SpdyHexDecodeToUInt32("1111111111", &out));
- EXPECT_FALSE(SpdyHexDecodeToUInt32("0x1111", &out));
-}
-
-} // namespace
-} // namespace test
-} // namespace spdy