diff options
-rw-r--r-- | base/strings/utf_string_conversions.h | 10 | ||||
-rw-r--r-- | net/base/net_util.h | 34 | ||||
-rw-r--r-- | net/base/net_util_icu.cc | 44 | ||||
-rw-r--r-- | net/base/net_util_icu_unittest.cc | 179 | ||||
-rw-r--r-- | url/gurl.h | 4 |
5 files changed, 258 insertions, 13 deletions
diff --git a/base/strings/utf_string_conversions.h b/base/strings/utf_string_conversions.h index 06a3bc6..0d2e233 100644 --- a/base/strings/utf_string_conversions.h +++ b/base/strings/utf_string_conversions.h @@ -15,10 +15,10 @@ namespace base { // These convert between UTF-8, -16, and -32 strings. They are potentially slow, // so avoid unnecessary conversions. The low-level versions return a boolean -// indicating whether the conversion was 100% valid. In this case, it will still -// do the best it can and put the result in the output buffer. The versions that -// return strings ignore this error and just return the best conversion -// possible. +// indicating whether the conversion was 100% valid. In case the conversion is +// not 100% valid, these functions will still do the best they can and put the +// result in the output buffer. The versions that return strings ignore this +// error and just return the best conversion possible. BASE_EXPORT bool WideToUTF8(const wchar_t* src, size_t src_len, std::string* output); BASE_EXPORT std::string WideToUTF8(const std::wstring& wide); @@ -39,7 +39,7 @@ BASE_EXPORT bool UTF16ToUTF8(const char16* src, size_t src_len, std::string* output); BASE_EXPORT std::string UTF16ToUTF8(const string16& utf16); -// This converts an ASCII string, typically a hardcoded constant, to a UTF16 +// This converts an ASCII string, typically a hardcoded constant, to a UTF-16 // string. BASE_EXPORT string16 ASCIIToUTF16(const StringPiece& ascii); diff --git a/net/base/net_util.h b/net/base/net_util.h index 32e2287..03da43d 100644 --- a/net/base/net_util.h +++ b/net/base/net_util.h @@ -58,7 +58,7 @@ static const size_t kIPv6AddressSize = 16; static const size_t kBluetoothAddressSize = 6; #endif -// Nothing is ommitted. +// Nothing is omitted. NET_EXPORT extern const FormatUrlType kFormatUrlOmitNothing; // If set, any username and password are removed. @@ -71,13 +71,13 @@ NET_EXPORT extern const FormatUrlType kFormatUrlOmitHTTP; // meaningful for non-file "standard" URLs. NET_EXPORT extern const FormatUrlType kFormatUrlOmitTrailingSlashOnBareHostname; -// Convenience for omitting all unecessary types. +// Convenience for omitting all unnecessary types. NET_EXPORT extern const FormatUrlType kFormatUrlOmitAll; // Returns the number of explicitly allowed ports; for testing. NET_EXPORT_PRIVATE extern size_t GetCountOfExplicitlyAllowedPorts(); -// Splits an input of the form <host>[":"<port>] into its consitituent parts. +// Splits an input of the form <host>[":"<port>] into its constituent parts. // Saves the result into |*host| and |*port|. If the input did not have // the optional port, sets |*port| to -1. // Returns true if the parsing was successful, false otherwise. @@ -105,13 +105,13 @@ NET_EXPORT std::string GetHostAndPort(const GURL& url); NET_EXPORT_PRIVATE std::string GetHostAndOptionalPort(const GURL& url); // Returns true if |hostname| contains a non-registerable or non-assignable -// domain name (eg: a gTLD that has not been assigned by IANA) or an IP address -// that falls in an IANA-reserved range. +// domain name (e.g.: a gTLD that has not been assigned by IANA) or an IP +// address that falls in an IANA-reserved range. NET_EXPORT bool IsHostnameNonUnique(const std::string& hostname); // Returns true if an IP address hostname is in a range reserved by the IANA. // Works with both IPv4 and IPv6 addresses, and only compares against a given -// protocols's reserved ranges. +// protocol's reserved ranges. NET_EXPORT bool IsIPAddressReserved(const IPAddressNumber& address); // Convenience struct for when you need a |struct sockaddr|. @@ -339,6 +339,26 @@ inline base::string16 FormatUrl(const GURL& url, const std::string& languages) { NULL, NULL, NULL); } +// This is a convenience function for formatting a URL as an origin in a concise +// and human-friendly way. Use this instead of |FormatUrl| when the reader needs +// only to understand the origin (rather than the entire URL). +// +// - Omits the path for standard schemes, excepting file and filesystem. +// - Omits the port if it is the default for the scheme. +// +// Do not use this for URLs which will be parsed or sent to other applications. +// +// Callers should only set |omit_scheme| to true when it is safe to do so: in +// contexts where the origin is known to be secure or is always secure by +// necessity. As examples: +// +// display = FormatOriginForDisplay(url, ..., url.SchemeIsCryptographic()); +// +// display = FormatOriginForDisplay(url, ..., IsOriginSecure(url)); +NET_EXPORT base::string16 FormatOriginForDisplay(const GURL& origin, + const std::string& languages, + bool omit_scheme); + // Returns whether FormatUrl() would strip a trailing slash from |url|, given a // format flag including kFormatUrlOmitTrailingSlashOnBareHostname. NET_EXPORT bool CanStripTrailingSlash(const GURL& url); @@ -441,7 +461,7 @@ NET_EXPORT_PRIVATE bool IsLocalhost(const std::string& host); NET_EXPORT_PRIVATE bool IsLocalhostTLD(const std::string& host); -// Returns true if the url's host is a Google server. This should only be used +// Returns true if the URL's host is a Google server. This should only be used // for histograms and shouldn't be used to affect behavior. NET_EXPORT_PRIVATE bool HasGoogleHost(const GURL& url); diff --git a/net/base/net_util_icu.cc b/net/base/net_util_icu.cc index 94e1a0d..bdbe270 100644 --- a/net/base/net_util_icu.cc +++ b/net/base/net_util_icu.cc @@ -797,7 +797,7 @@ base::string16 FormatUrlWithAdjustments( // after stripping the prefix. The only thing necessary is to add an // adjustment to reflect the stripped prefix. adjustments->insert(adjustments->begin(), - base::OffsetAdjuster::Adjustment(0, kHTTPSize, 0)); + base::OffsetAdjuster::Adjustment(0, kHTTPSize, 0)); if (prefix_end) *prefix_end -= kHTTPSize; @@ -829,4 +829,46 @@ base::string16 FormatUrl(const GURL& url, return result; } +base::string16 FormatOriginForDisplay(const GURL& url, + const std::string& languages, + bool omit_scheme) { + if (!url.IsStandard()) + return FormatUrl(url, languages); + + if (url.SchemeIsFile()) { + // TODO(palmer): Determine whether to encode this policy in GURL::GetOrigin. + return (omit_scheme ? base::ASCIIToUTF16("") + : base::ASCIIToUTF16("file://")) + + base::UTF8ToUTF16(url.path()); + } + + if (url.SchemeIsFileSystem()) { + // TODO(palmer): Determine whether to encode this policy in GURL::GetOrigin. + const GURL inner_url(url.spec().substr(strlen("filesystem:"))); + return base::ASCIIToUTF16("filesystem:") + + FormatOriginForDisplay(inner_url, languages, omit_scheme); + } + + const GURL origin = url.GetOrigin(); + const std::string& scheme = origin.scheme(); + const std::string& host = origin.host(); + if (scheme.empty() || host.empty()) + return FormatUrl(url, languages); + + base::string16 result; + + if (!omit_scheme) + result = base::UTF8ToUTF16(scheme) + base::ASCIIToUTF16("://"); + + result += base::UTF8ToUTF16(host); + + const int port = origin.IntPort(); + const int default_port = url::DefaultPortForScheme(origin.scheme().c_str(), + origin.scheme().length()); + if (origin.port().length() > 0 && port != 0 && port != default_port) + result += base::ASCIIToUTF16(":") + base::UTF8ToUTF16(origin.port()); + + return result; +} + } // namespace net diff --git a/net/base/net_util_icu_unittest.cc b/net/base/net_util_icu_unittest.cc index 1b315c2..811a46d 100644 --- a/net/base/net_util_icu_unittest.cc +++ b/net/base/net_util_icu_unittest.cc @@ -364,6 +364,14 @@ struct UrlTestData { size_t prefix_len; }; +struct OriginTestData { + const char* description; + const char* input; + const char* languages; + const bool omit_scheme; + const wchar_t* output; +}; + // A helper for IDN*{Fast,Slow}. // Append "::<language list>" to |expected| and |actual| to make it // easy to tell which sub-case fails without debugging. @@ -1081,4 +1089,175 @@ TEST(NetUtilTest, FormatUrlWithOffsets) { UnescapeRule::NORMAL, omit_all_offsets); } +TEST(NetUtilTest, FormatOriginForDisplay) { + const OriginTestData tests[] = { + {"Empty URL", "", "", false, L""}, + {"HTTP URL, no omit scheme", + "http://www.google.com/", + "", + false, + L"http://www.google.com"}, + {"HTTP URL, omit scheme", + "http://www.google.com/", + "", + true, + L"www.google.com"}, + {"HTTPS URL, no omit scheme", + "https://www.google.com/", + "", + false, + L"https://www.google.com"}, + {"HTTPS URL, omit scheme", + "https://www.google.com/", + "", + true, + L"www.google.com"}, + {"Standard HTTP port", + "http://www.google.com:80/", + "", + false, + L"http://www.google.com"}, + {"Standard HTTPS port", + "https://www.google.com:443/", + "", + false, + L"https://www.google.com"}, + {"Non-standard HTTP port", + "http://www.google.com:9000/", + "", + false, + L"http://www.google.com:9000"}, + {"Non-standard HTTPS port", + "https://www.google.com:9000/", + "", + false, + L"https://www.google.com:9000"}, + {"File URI, omit scheme", + "file:///usr/example/file.html", + "", + true, + L"/usr/example/file.html"}, + {"File URI, no omit scheme", + "file:///usr/example/file.html", + "", + false, + L"file:///usr/example/file.html"}, + {"File URI with hostname, omit scheme", + "file://localhost/usr/example/file.html", + "", + true, + L"/usr/example/file.html"}, + {"File URI with hostname, no omit scheme", + "file://localhost/usr/example/file.html", + "", + false, + L"file:///usr/example/file.html"}, + {"HTTP URL with path", + "http://www.google.com/test.html", + "", + false, + L"http://www.google.com"}, + {"HTTPS URL with path", + "https://www.google.com/test.html", + "", + false, + L"https://www.google.com"}, + {"Unusual secure scheme (wss)", + "wss://www.google.com/", + "", + false, + L"wss://www.google.com"}, + {"Unusual non-secure scheme (gopher)", + "gopher://www.google.com/", + "", + false, + L"gopher://www.google.com"}, + {"Unlisted scheme (chrome)", + "chrome://version", + "", + false, + L"chrome://version"}, + {"HTTP IP address", + "http://173.194.65.103", + "", + false, + L"http://173.194.65.103"}, + {"HTTPS IP address", + "https://173.194.65.103", + "", + false, + L"https://173.194.65.103"}, + {"HTTPS IP address, non-default port", + "https://173.194.65.103:8443", + "", + false, + L"https://173.194.65.103:8443"}, + {"HTTPS IP address, omit scheme", + "https://173.194.65.103", + "", + true, + L"173.194.65.103"}, + {"HTTP filesystem: URL with path", + "filesystem:http://www.google.com/temporary/test.html", + "", + false, + L"filesystem:http://www.google.com"}, + {"HTTP filesystem: URL with path, omit scheme", + "filesystem:http://www.google.com/persistent/test.html", + "", + true, + L"filesystem:www.google.com"}, + {"File filesystem: URL with path", + "filesystem:file://localhost/temporary/stuff/test.html?z=fun&goat=billy", + "", + false, + L"filesystem:file:///temporary/stuff/test.html"}, + {"File filesystem: URL with path, omit scheme", + "filesystem:file://cyber.com/persistent/stuff/test.html?y=z#abc", + "", + true, + L"filesystem:/persistent/stuff/test.html"}, + {"Invalid scheme 1", + "twelve://www.cyber.org/wow.php", + "", + false, + L"twelve://www.cyber.org/wow.php"}, + {"Invalid scheme 2", + "://www.cyber.org/wow.php", + "", + false, + L"://www.cyber.org/wow.php"}, + {"Invalid host 1", + "https://www.cyber../wow.php", + "", + false, + L"https://www.cyber.."}, + {"Invalid host 2", + "https://www...cyber/wow.php", + "", + false, + L"https://www...cyber"}, + {"Invalid port 1", + "https://173.194.65.103:000", + "", + false, + L"https://173.194.65.103"}, + {"Invalid port 2", + "https://173.194.65.103:gruffle", + "", + false, + L"https://173.194.65.103:gruffle"}, + {"Invalid port 3", + "https://173.194.65.103:/hello.aspx", + "", + false, + L"https://173.194.65.103"}, + }; + for (size_t i = 0; i < arraysize(tests); ++i) { + base::string16 formatted = FormatOriginForDisplay( + GURL(tests[i].input), tests[i].languages, tests[i].omit_scheme); + EXPECT_EQ(WideToUTF16(tests[i].output), formatted) << tests[i].description; + } +} + } // namespace net @@ -198,6 +198,10 @@ class URL_EXPORT GURL { // scheme. Standard schemes have an authority and a path section. This // includes file: and filesystem:, which some callers may want to filter out // explicitly by calling SchemeIsFile[System]. + // + // TODO(palmer): Determine whether GURL::IsStandard should return false for + // filesystem: URLs. + // https://code.google.com/p/chromium/issues/detail?id=487399 bool IsStandard() const; // Returns true if the given parameter (should be lower-case ASCII to match |