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

Unified Diff: url/scheme_host_port.cc

Issue 1272113002: Allow url::SchemeHostPort to hold non-file scheme without port (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Rebase Created 5 years, 4 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 | « url/scheme_host_port.h ('k') | url/url_util.h » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: url/scheme_host_port.cc
diff --git a/url/scheme_host_port.cc b/url/scheme_host_port.cc
index c2fe830e377fa2edde0260265fd5a6b013fd4d35..9c122957947f3ac09dc53cedff2582f16ac7448a 100644
--- a/url/scheme_host_port.cc
+++ b/url/scheme_host_port.cc
@@ -7,6 +7,7 @@
#include <string.h>
#include "base/logging.h"
+#include "base/numerics/safe_conversions.h"
#include "base/strings/string_number_conversions.h"
#include "url/gurl.h"
#include "url/url_canon.h"
@@ -16,25 +17,21 @@
namespace url {
-SchemeHostPort::SchemeHostPort() : port_(0) {
-}
+namespace {
-SchemeHostPort::SchemeHostPort(base::StringPiece scheme,
- base::StringPiece host,
- uint16 port)
- : scheme_(scheme.data(), scheme.length()),
- host_(host.data(), host.length()),
- port_(port) {
- // Try to canonicalize the host (copy/pasted from net/base. :( ).
- const url::Component raw_host_component(0, static_cast<int>(host.length()));
+bool IsCanonicalHost(const base::StringPiece& host) {
std::string canon_host;
- url::StdStringCanonOutput canon_host_output(&canon_host);
- url::CanonHostInfo host_info;
- url::CanonicalizeHostVerbose(host.data(), raw_host_component,
- &canon_host_output, &host_info);
+
+ // Try to canonicalize the host (copy/pasted from net/base. :( ).
+ const Component raw_host_component(0,
+ base::checked_cast<int>(host.length()));
+ StdStringCanonOutput canon_host_output(&canon_host);
+ CanonHostInfo host_info;
+ CanonicalizeHostVerbose(host.data(), raw_host_component,
+ &canon_host_output, &host_info);
if (host_info.out_host.is_nonempty() &&
- host_info.family != url::CanonHostInfo::BROKEN) {
+ host_info.family != CanonHostInfo::BROKEN) {
// Success! Assert that there's no extra garbage.
canon_host_output.Complete();
DCHECK_EQ(host_info.out_host.len, static_cast<int>(canon_host.length()));
@@ -43,44 +40,95 @@ SchemeHostPort::SchemeHostPort(base::StringPiece scheme,
canon_host.clear();
}
- // Return an invalid SchemeHostPort object if any of the following conditions
- // hold:
- //
- // 1. The provided scheme is non-standard, 'blob:', or 'filesystem:'.
- // 2. The provided host is non-canonical.
- // 3. The scheme is 'file' and the port is non-zero.
- // 4. The scheme is not 'file', and the port is zero or the host is empty.
- bool isUnsupportedScheme =
- !url::IsStandard(scheme.data(),
- url::Component(0, static_cast<int>(scheme.length()))) ||
- scheme == kFileSystemScheme || scheme == kBlobScheme;
- bool isNoncanonicalHost = host != canon_host;
- bool isFileSchemeWithPort = scheme == kFileScheme && port != 0;
- bool isNonFileSchemeWithoutPortOrHost =
- scheme != kFileScheme && (port == 0 || host.empty());
- if (isUnsupportedScheme || isNoncanonicalHost || isFileSchemeWithPort ||
- isNonFileSchemeWithoutPortOrHost) {
- scheme_.clear();
- host_.clear();
- port_ = 0;
- }
+ return host == canon_host;
}
-SchemeHostPort::SchemeHostPort(const GURL& url) : port_(0) {
- if (!url.is_valid() || !url.IsStandard())
- return;
+bool IsValidInput(const base::StringPiece& scheme,
+ const base::StringPiece& host,
+ uint16 port) {
+ SchemeType scheme_type = SCHEME_WITH_PORT;
+ bool is_standard = GetStandardSchemeType(
+ scheme.data(),
+ Component(0, base::checked_cast<int>(scheme.length())),
+ &scheme_type);
+ if (!is_standard)
+ return false;
// These schemes do not follow the generic URL syntax, so we treat them as
// invalid (scheme, host, port) tuples (even though such URLs' _Origin_ might
// have a (scheme, host, port) tuple, they themselves do not).
- if (url.SchemeIsBlob() || url.SchemeIsFileSystem())
+ if (scheme == kFileSystemScheme || scheme == kBlobScheme)
+ return false;
+
+ switch (scheme_type) {
+ case SCHEME_WITH_PORT:
+ // A URL with |scheme| is required to have the host and port (may be
+ // omitted in a serialization if it's the same as the default value).
+ // Return an invalid instance if either of them is not given.
+ if (host.empty() || port == 0)
+ return false;
+
+ if (!IsCanonicalHost(host))
+ return false;
+
+ return true;
+
+ case SCHEME_WITHOUT_PORT:
+ if (port != 0) {
+ // Return an invalid object if a URL with the scheme never represents
+ // the port data but the given |port| is non-zero.
+ return false;
+ }
+
+ if (!IsCanonicalHost(host))
+ return false;
+
+ return true;
+
+ case SCHEME_WITHOUT_AUTHORITY:
+ return false;
+
+ default:
+ NOTREACHED();
+ return false;
+ }
+}
+
+} // namespace
+
+SchemeHostPort::SchemeHostPort() : port_(0) {
+}
+
+SchemeHostPort::SchemeHostPort(base::StringPiece scheme,
+ base::StringPiece host,
+ uint16 port)
+ : port_(0) {
+ if (!IsValidInput(scheme, host, port))
return;
- scheme_ = url.scheme();
- host_ = url.host();
- port_ = url.EffectiveIntPort() == url::PORT_UNSPECIFIED
- ? 0
- : url.EffectiveIntPort();
+ scheme.CopyToString(&scheme_);
+ host.CopyToString(&host_);
+ port_ = port;
+}
+
+SchemeHostPort::SchemeHostPort(const GURL& url) : port_(0) {
+ if (!url.is_valid())
+ return;
+
+ const std::string& scheme = url.scheme();
+ const std::string& host = url.host();
+
+ // A valid GURL never returns PORT_INVALID.
+ int port = url.EffectiveIntPort();
+ if (port == PORT_UNSPECIFIED)
+ port = 0;
+
+ if (!IsValidInput(scheme, host, port))
+ return;
+
+ scheme_ = scheme;
+ host_ = host;
+ port_ = port;
}
SchemeHostPort::~SchemeHostPort() {
@@ -95,15 +143,20 @@ std::string SchemeHostPort::Serialize() const {
if (IsInvalid())
return result;
- bool is_default_port =
- port_ == url::DefaultPortForScheme(scheme_.data(),
- static_cast<int>(scheme_.length()));
-
result.append(scheme_);
result.append(kStandardSchemeSeparator);
result.append(host_);
- if (scheme_ != kFileScheme && !is_default_port) {
+ if (port_ == 0)
+ return result;
+
+ // Omit the port component if the port matches with the default port
+ // defined for the scheme, if any.
+ int default_port = DefaultPortForScheme(scheme_.data(),
+ static_cast<int>(scheme_.length()));
+ if (default_port == PORT_UNSPECIFIED)
+ return result;
+ if (port_ != default_port) {
result.push_back(':');
result.append(base::IntToString(port_));
}
« no previous file with comments | « url/scheme_host_port.h ('k') | url/url_util.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698