Commit 9fb36e6d authored by Piotr Pawliczek's avatar Piotr Pawliczek Committed by Chromium LUCI CQ

Uri: the ":" separator omitted for an empty scheme

This patch changes slightly the grammar used by the Uri class. In the
previous version, the ":" separator following the schema was always
required. In the new grammar, the ":" separator is omitted for an empty
schema. As a result, the normalized representation of an empty Uri is an
empty string. This is more intuitive behavior than the previous one,
when empty Uri was represented by ":" string. All URIs accepted by the
old grammar are also accepted by the new one. Additionally, URIs
without scheme and without the ":" separator are also accepted now.

BUG=none
TEST=with unittests on my workstation

Change-Id: I4bc8875af4a5d05a227aca47863c7d659b8d4223
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2553529
Auto-Submit: Piotr Pawliczek <pawliczek@chromium.org>
Commit-Queue: Sean Kau <skau@chromium.org>
Reviewed-by: default avatarSean Kau <skau@chromium.org>
Cr-Commit-Position: refs/heads/master@{#831958}
parent 8ba93a4b
...@@ -180,7 +180,8 @@ std::string Uri::GetNormalized(bool always_print_port) const { ...@@ -180,7 +180,8 @@ std::string Uri::GetNormalized(bool always_print_port) const {
// Output string. Adds Scheme. // Output string. Adds Scheme.
std::string out = pim_->scheme(); std::string out = pim_->scheme();
out.push_back(':'); if (!out.empty())
out.push_back(':');
// Adds authority (Userinfo + Host + Port) if non-empty. // Adds authority (Userinfo + Host + Port) if non-empty.
Encoder enc("+&=:"); Encoder enc("+&=:");
......
...@@ -50,7 +50,7 @@ namespace chromeos { ...@@ -50,7 +50,7 @@ namespace chromeos {
// //
// 1. The grammar is simplified: // 1. The grammar is simplified:
// //
// uri = Scheme ":" [ authority ] [ Path ] [ "?" Query ] [ "#" Fragment ] // uri = [ Scheme ":" ] [ authority ] [ Path ] [ "?" Query ] [ "#" Fragment ]
// //
// authority = "//" [ Userinfo "@" ] Host [ ":" Port ] // authority = "//" [ Userinfo "@" ] Host [ ":" Port ]
// //
...@@ -215,7 +215,7 @@ class CHROMEOS_EXPORT Uri { ...@@ -215,7 +215,7 @@ class CHROMEOS_EXPORT Uri {
kInvalidPercentEncoding, // cannot parse hex number after % sign kInvalidPercentEncoding, // cannot parse hex number after % sign
kDisallowedASCIICharacter, // non-printable ASCII character kDisallowedASCIICharacter, // non-printable ASCII character
kInvalidUTF8Character, // error when tried to parse UTF-8 character kInvalidUTF8Character, // error when tried to parse UTF-8 character
kInvalidScheme, // invalid Scheme format or no ':' in input kInvalidScheme, // invalid Scheme format
kInvalidPortNumber, kInvalidPortNumber,
kRelativePathsNotAllowed, // non-empty Path that does not start with '/' kRelativePathsNotAllowed, // non-empty Path that does not start with '/'
kEmptySegmentInPath, kEmptySegmentInPath,
...@@ -279,8 +279,8 @@ class CHROMEOS_EXPORT Uri { ...@@ -279,8 +279,8 @@ class CHROMEOS_EXPORT Uri {
// - Set*Encoded(...) methods // - Set*Encoded(...) methods
const ParserError& GetLastParsingError() const; const ParserError& GetLastParsingError() const;
// Returns the URL in the normalized form. It never returns empty string! // Returns the URL in the normalized form. It returns empty string if and only
// When all components are empty, this method returns ":" (see the grammar). // if all components are empty (see the grammar).
// If the Port is specified (GetPort() != -1) and |always_print_port| is set // If the Port is specified (GetPort() != -1) and |always_print_port| is set
// to true, a Port number is always included in the returned URI (even when // to true, a Port number is always included in the returned URI (even when
// it equals to a Scheme's default port number). // it equals to a Scheme's default port number).
......
...@@ -420,8 +420,10 @@ bool Uri::Pim::ParseUri(const Iter& begin, const Iter end) { ...@@ -420,8 +420,10 @@ bool Uri::Pim::ParseUri(const Iter& begin, const Iter end) {
parser_error_.parsed_strings = 0; parser_error_.parsed_strings = 0;
parser_error_.parsed_chars = 0; parser_error_.parsed_chars = 0;
Iter it1 = begin; Iter it1 = begin;
// The Scheme component ends at the first colon (":"). // The Scheme component starts from character different than slash ("/"),
{ // question mark ("?"), and number sign ("#"). Non-empty Scheme must be
// followed by the colon (":") character.
if (it1 < end && *it1 != '/' && *it1 != '?' && *it1 != '#') {
auto it2 = std::find(it1, end, ':'); auto it2 = std::find(it1, end, ':');
if (it2 == end) { if (it2 == end) {
parser_error_.status = ParserStatus::kInvalidScheme; parser_error_.status = ParserStatus::kInvalidScheme;
......
...@@ -84,7 +84,7 @@ void TestNormalization(const std::string& input_uri, ...@@ -84,7 +84,7 @@ void TestNormalization(const std::string& input_uri,
TEST(UriTest, DefaultConstructor) { TEST(UriTest, DefaultConstructor) {
Uri uri; Uri uri;
EXPECT_EQ(uri.GetNormalized(), ":"); EXPECT_EQ(uri.GetNormalized(), "");
EXPECT_EQ(uri.GetLastParsingError().status, Uri::ParserStatus::kNoErrors); EXPECT_EQ(uri.GetLastParsingError().status, Uri::ParserStatus::kNoErrors);
EXPECT_EQ(uri.GetScheme(), ""); EXPECT_EQ(uri.GetScheme(), "");
EXPECT_EQ(uri.GetUserinfo(), ""); EXPECT_EQ(uri.GetUserinfo(), "");
...@@ -262,7 +262,7 @@ TEST(UriTest, ParsingOfUriWithLeadingAndTrailingWhitespaces) { ...@@ -262,7 +262,7 @@ TEST(UriTest, ParsingOfUriWithLeadingAndTrailingWhitespaces) {
// Empty components are accepted. // Empty components are accepted.
TEST(UriTest, NormalizationOfEmptyUri) { TEST(UriTest, NormalizationOfEmptyUri) {
TestNormalization("://@:/?#", ":"); TestNormalization("://@:/?#", "");
} }
TEST(UriTest, NormalizationOfUriWithoutAuthority) { TEST(UriTest, NormalizationOfUriWithoutAuthority) {
......
...@@ -121,7 +121,9 @@ TEST_P(UriConsistencyTest, QueryBuilding) { ...@@ -121,7 +121,9 @@ TEST_P(UriConsistencyTest, QueryBuilding) {
// Build normalized URI from encoded components and make sure that it is // Build normalized URI from encoded components and make sure that it is
// equal to the value returned by GetNormalized(). // equal to the value returned by GetNormalized().
TEST_P(UriConsistencyTest, UriBuilding) { TEST_P(UriConsistencyTest, UriBuilding) {
std::string scheme = uri_.GetScheme() + ":"; std::string scheme = uri_.GetScheme();
if (!scheme.empty())
scheme += ":";
// Build a part of URI called Authority (Userinfo@Host:Port). // Build a part of URI called Authority (Userinfo@Host:Port).
std::string authority_encoded; std::string authority_encoded;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment