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,6 +180,7 @@ std::string Uri::GetNormalized(bool always_print_port) const {
// Output string. Adds Scheme.
std::string out = pim_->scheme();
if (!out.empty())
out.push_back(':');
// Adds authority (Userinfo + Host + Port) if non-empty.
......
......@@ -50,7 +50,7 @@ namespace chromeos {
//
// 1. The grammar is simplified:
//
// uri = Scheme ":" [ authority ] [ Path ] [ "?" Query ] [ "#" Fragment ]
// uri = [ Scheme ":" ] [ authority ] [ Path ] [ "?" Query ] [ "#" Fragment ]
//
// authority = "//" [ Userinfo "@" ] Host [ ":" Port ]
//
......@@ -215,7 +215,7 @@ class CHROMEOS_EXPORT Uri {
kInvalidPercentEncoding, // cannot parse hex number after % sign
kDisallowedASCIICharacter, // non-printable ASCII character
kInvalidUTF8Character, // error when tried to parse UTF-8 character
kInvalidScheme, // invalid Scheme format or no ':' in input
kInvalidScheme, // invalid Scheme format
kInvalidPortNumber,
kRelativePathsNotAllowed, // non-empty Path that does not start with '/'
kEmptySegmentInPath,
......@@ -279,8 +279,8 @@ class CHROMEOS_EXPORT Uri {
// - Set*Encoded(...) methods
const ParserError& GetLastParsingError() const;
// Returns the URL in the normalized form. It never returns empty string!
// When all components are empty, this method returns ":" (see the grammar).
// Returns the URL in the normalized form. It returns empty string if and only
// if all components are empty (see the grammar).
// 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
// it equals to a Scheme's default port number).
......
......@@ -420,8 +420,10 @@ bool Uri::Pim::ParseUri(const Iter& begin, const Iter end) {
parser_error_.parsed_strings = 0;
parser_error_.parsed_chars = 0;
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, ':');
if (it2 == end) {
parser_error_.status = ParserStatus::kInvalidScheme;
......
......@@ -84,7 +84,7 @@ void TestNormalization(const std::string& input_uri,
TEST(UriTest, DefaultConstructor) {
Uri uri;
EXPECT_EQ(uri.GetNormalized(), ":");
EXPECT_EQ(uri.GetNormalized(), "");
EXPECT_EQ(uri.GetLastParsingError().status, Uri::ParserStatus::kNoErrors);
EXPECT_EQ(uri.GetScheme(), "");
EXPECT_EQ(uri.GetUserinfo(), "");
......@@ -262,7 +262,7 @@ TEST(UriTest, ParsingOfUriWithLeadingAndTrailingWhitespaces) {
// Empty components are accepted.
TEST(UriTest, NormalizationOfEmptyUri) {
TestNormalization("://@:/?#", ":");
TestNormalization("://@:/?#", "");
}
TEST(UriTest, NormalizationOfUriWithoutAuthority) {
......
......@@ -121,7 +121,9 @@ TEST_P(UriConsistencyTest, QueryBuilding) {
// Build normalized URI from encoded components and make sure that it is
// equal to the value returned by GetNormalized().
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).
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