diff options
author | rsleevi <rsleevi@chromium.org> | 2015-08-07 14:39:21 -0700 |
---|---|---|
committer | Commit bot <commit-bot@chromium.org> | 2015-08-07 21:39:50 +0000 |
commit | 24f64dc221628032b7843f1af6b277a7f0d6c562 (patch) | |
tree | ba2c4bb1d37847b2cd76a4d8d243d1f000e0284e | |
parent | d9773981c8733eb55314efad66398350f862c8be (diff) | |
download | chromium_src-24f64dc221628032b7843f1af6b277a7f0d6c562.zip chromium_src-24f64dc221628032b7843f1af6b277a7f0d6c562.tar.gz chromium_src-24f64dc221628032b7843f1af6b277a7f0d6c562.tar.bz2 |
Move net::FormatUrl and friends outside of //net and into //components
net::FormatUrl and related are specifically concerned with display
policies of URLs, which is not something that //net needs to be aware
of, as that's a UX question.
This folds in net::FormatURL along with the existing //components/url_fixer
and //components/secure_display into a common component,
//components/url_formatter, that handles reformatting URLs for user-friendly
or data storage (url_formatter), for use in security prompts (elide_url),
or for reformatting URLs from user input (url_fixer)
(Disabling presubmit since this is intentionally not fixing a legacy API, just moving it for future cleanups)
BUG=486979
NOPRESUBMIT=true
Review URL: https://codereview.chromium.org/1171333003
Cr-Commit-Position: refs/heads/master@{#342445}
172 files changed, 2659 insertions, 2585 deletions
@@ -42,7 +42,7 @@ check_targets = [ "//components/pref_registry/*", "//components/undo/*", "//components/update_client/*", - "//components/url_fixer/*", + "//components/url_formatter/*", "//components/url_matcher/*", "//components/user_manager/*", "//components/user_prefs/*", diff --git a/chrome/DEPS b/chrome/DEPS index b5972c7..c9bf84e 100644 --- a/chrome/DEPS +++ b/chrome/DEPS @@ -20,7 +20,7 @@ include_rules = [ "+components/content_settings/core/common", "+components/error_page/common", "+components/omnibox/common", - "+components/url_fixer", + "+components/url_formatter", "+components/variations", "+content/public/common", "+content/public/test", diff --git a/chrome/android/java/src/org/chromium/chrome/browser/UrlUtilities.java b/chrome/android/java/src/org/chromium/chrome/browser/UrlUtilities.java index d786f9f..bbd359f 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/UrlUtilities.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/UrlUtilities.java @@ -126,7 +126,7 @@ public class UrlUtilities { } /** - * Refer to url_fixer::FixupURL. + * Refer to url_formatter::FixupURL. * * Given a URL-like string, returns a real URL or null. For example: * - "google.com" -> "http://google.com/" diff --git a/chrome/browser/BUILD.gn b/chrome/browser/BUILD.gn index 5bf259a..9b9bcfe 100644 --- a/chrome/browser/BUILD.gn +++ b/chrome/browser/BUILD.gn @@ -147,7 +147,7 @@ source_set("browser") { "//components/ui/zoom:ui_zoom", "//components/undo", "//components/update_client", - "//components/url_fixer", + "//components/url_formatter", "//components/user_prefs", "//components/variations", "//components/variations/net", diff --git a/chrome/browser/DEPS b/chrome/browser/DEPS index c978a1f..2b83d91 100644 --- a/chrome/browser/DEPS +++ b/chrome/browser/DEPS @@ -96,6 +96,7 @@ include_rules = [ "+components/undo", "+components/update_client", "+components/upload_list", + "+components/url_formatter", "+components/url_matcher", "+components/user_manager", "+components/user_prefs", diff --git a/chrome/browser/android/fullscreen/fullscreen_infobar_delegate.cc b/chrome/browser/android/fullscreen/fullscreen_infobar_delegate.cc index 73178ff..04d0ab3 100644 --- a/chrome/browser/android/fullscreen/fullscreen_infobar_delegate.cc +++ b/chrome/browser/android/fullscreen/fullscreen_infobar_delegate.cc @@ -13,10 +13,10 @@ #include "chrome/common/pref_names.h" #include "chrome/grit/generated_resources.h" #include "components/infobars/core/infobar.h" +#include "components/url_formatter/url_formatter.h" #include "grit/components_strings.h" #include "grit/theme_resources.h" #include "jni/FullscreenInfoBarDelegate_jni.h" -#include "net/base/net_util.h" #include "ui/base/l10n/l10n_util.h" #include "url/gurl.h" @@ -69,7 +69,8 @@ base::string16 FullscreenInfoBarDelegate::GetMessageText() const { std::string language = profile->GetPrefs()->GetString(prefs::kAcceptLanguages); return l10n_util::GetStringFUTF16( - IDS_FULLSCREEN_INFOBAR_TEXT, net::FormatUrl(GURL(origin_), language)); + IDS_FULLSCREEN_INFOBAR_TEXT, + url_formatter::FormatUrl(GURL(origin_), language)); } base::string16 FullscreenInfoBarDelegate::GetButtonLabel( diff --git a/chrome/browser/android/omnibox/autocomplete_controller_android.cc b/chrome/browser/android/omnibox/autocomplete_controller_android.cc index 37b8b1b..60b6683 100644 --- a/chrome/browser/android/omnibox/autocomplete_controller_android.cc +++ b/chrome/browser/android/omnibox/autocomplete_controller_android.cc @@ -43,6 +43,7 @@ #include "components/search/search.h" #include "components/search_engines/template_url_service.h" #include "components/toolbar/toolbar_model.h" +#include "components/url_formatter/url_formatter.h" #include "content/public/browser/notification_details.h" #include "content/public/browser/notification_service.h" #include "content/public/browser/notification_source.h" @@ -50,7 +51,6 @@ #include "content/public/common/url_constants.h" #include "jni/AutocompleteController_jni.h" #include "net/base/escape.h" -#include "net/base/net_util.h" #include "net/base/registry_controlled_domains/registry_controlled_domain.h" using base::android::AttachCurrentThread; @@ -477,8 +477,9 @@ base::string16 AutocompleteControllerAndroid::FormatURLUsingAcceptLanguages( std::string languages( profile_->GetPrefs()->GetString(prefs::kAcceptLanguages)); - return net::FormatUrl(url, languages, net::kFormatUrlOmitAll, - net::UnescapeRule::SPACES, NULL, NULL, NULL); + return url_formatter::FormatUrl( + url, languages, url_formatter::kFormatUrlOmitAll, + net::UnescapeRule::SPACES, nullptr, nullptr, nullptr); } ScopedJavaLocalRef<jobject> diff --git a/chrome/browser/android/tab_android.cc b/chrome/browser/android/tab_android.cc index 81b61a4..ab3a25c 100644 --- a/chrome/browser/android/tab_android.cc +++ b/chrome/browser/android/tab_android.cc @@ -56,7 +56,7 @@ #include "components/infobars/core/infobar_container.h" #include "components/navigation_interception/intercept_navigation_delegate.h" #include "components/navigation_interception/navigation_params.h" -#include "components/url_fixer/url_fixer.h" +#include "components/url_formatter/url_fixer.h" #include "content/public/browser/android/compositor.h" #include "content/public/browser/android/content_view_core.h" #include "content/public/browser/browser_thread.h" @@ -571,7 +571,7 @@ TabAndroid::TabLoadStatus TabAndroid::LoadUrl(JNIEnv* env, } GURL fixed_url( - url_fixer::FixupURL(gurl.possibly_invalid_spec(), std::string())); + url_formatter::FixupURL(gurl.possibly_invalid_spec(), std::string())); if (!fixed_url.is_valid()) return PAGE_LOAD_FAILED; diff --git a/chrome/browser/android/url_utilities.cc b/chrome/browser/android/url_utilities.cc index 495a0cd..e9224f4 100644 --- a/chrome/browser/android/url_utilities.cc +++ b/chrome/browser/android/url_utilities.cc @@ -5,7 +5,7 @@ #include "base/android/jni_android.h" #include "base/android/jni_string.h" #include "components/google/core/browser/google_util.h" -#include "components/url_fixer/url_fixer.h" +#include "components/url_formatter/url_fixer.h" #include "jni/UrlUtilities_jni.h" #include "net/base/registry_controlled_domains/registry_controlled_domain.h" #include "url/gurl.h" @@ -80,7 +80,7 @@ static jstring FixupUrl(JNIEnv* env, jstring url, jstring optional_desired_tld) { DCHECK(url); - GURL fixed_url = url_fixer::FixupURL( + GURL fixed_url = url_formatter::FixupURL( base::android::ConvertJavaStringToUTF8(env, url), optional_desired_tld ? base::android::ConvertJavaStringToUTF8(env, optional_desired_tld) diff --git a/chrome/browser/autocomplete/history_url_provider_unittest.cc b/chrome/browser/autocomplete/history_url_provider_unittest.cc index 67542dc..21dad67 100644 --- a/chrome/browser/autocomplete/history_url_provider_unittest.cc +++ b/chrome/browser/autocomplete/history_url_provider_unittest.cc @@ -33,7 +33,7 @@ #include "components/search_engines/search_terms_data.h" #include "components/search_engines/template_url.h" #include "components/search_engines/template_url_service.h" -#include "components/url_fixer/url_fixer.h" +#include "components/url_formatter/url_fixer.h" #include "content/public/test/test_browser_thread_bundle.h" #include "testing/gtest/include/gtest/gtest.h" @@ -728,7 +728,7 @@ TEST_F(HistoryURLProviderTest, IntranetURLsWithPaths) { RunTest(ASCIIToUTF16(test_cases[i].input), std::string(), false, NULL, 0); } else { const UrlAndLegalDefault output[] = { - {url_fixer::FixupURL(test_cases[i].input, std::string()).spec(), + {url_formatter::FixupURL(test_cases[i].input, std::string()).spec(), true}}; ASSERT_NO_FATAL_FAILURE(RunTest(ASCIIToUTF16(test_cases[i].input), std::string(), false, output, arraysize(output))); @@ -1042,8 +1042,9 @@ TEST_F(HistoryURLProviderTest, HUPScoringExperiment) { if (test_cases[i].matches[max_matches].url == NULL) break; output[max_matches].url = - url_fixer::FixupURL(test_cases[i].matches[max_matches].url, - std::string()).spec(); + url_formatter::FixupURL(test_cases[i].matches[max_matches].url, + std::string()) + .spec(); output[max_matches].allowed_to_be_default_match = true; } autocomplete_->scoring_params_ = test_cases[i].scoring_params; diff --git a/chrome/browser/browser_about_handler.cc b/chrome/browser/browser_about_handler.cc index 4142dec4..616d290 100644 --- a/chrome/browser/browser_about_handler.cc +++ b/chrome/browser/browser_about_handler.cc @@ -16,7 +16,7 @@ #include "chrome/browser/ui/browser_dialogs.h" #include "chrome/common/chrome_switches.h" #include "chrome/common/url_constants.h" -#include "components/url_fixer/url_fixer.h" +#include "components/url_formatter/url_fixer.h" bool FixupBrowserAboutURL(GURL* url, content::BrowserContext* browser_context) { @@ -24,7 +24,7 @@ bool FixupBrowserAboutURL(GURL* url, // phase that determines the virtual URL, by including it in an initial // URLHandler. This prevents minor changes from producing a virtual URL, // which could lead to a URL spoof. - *url = url_fixer::FixupURL(url->possibly_invalid_spec(), std::string()); + *url = url_formatter::FixupURL(url->possibly_invalid_spec(), std::string()); return true; } @@ -34,11 +34,11 @@ bool WillHandleBrowserAboutURL(GURL* url, // then hopefully we can remove this forced fixup. FixupBrowserAboutURL(url, browser_context); - // Check that about: URLs are fixed up to chrome: by url_fixer::FixupURL. + // Check that about: URLs are fixed up to chrome: by url_formatter::FixupURL. DCHECK((*url == GURL(url::kAboutBlankURL)) || !url->SchemeIs(url::kAboutScheme)); - // Only handle chrome://foo/, url_fixer::FixupURL translates about:foo. + // Only handle chrome://foo/, url_formatter::FixupURL translates about:foo. if (!url->SchemeIs(content::kChromeUIScheme)) return false; diff --git a/chrome/browser/browser_about_handler.h b/chrome/browser/browser_about_handler.h index 7cc3785..2bbe5a8 100644 --- a/chrome/browser/browser_about_handler.h +++ b/chrome/browser/browser_about_handler.h @@ -17,7 +17,7 @@ bool FixupBrowserAboutURL(GURL* url, content::BrowserContext* browser_context); // Returns true if the given URL will be handled by the browser about handler. // Nowadays, these go through the webui, so the return is always false. -// Either way, |url| will be processed by url_fixer::FixupURL, which +// Either way, |url| will be processed by url_formatter::FixupURL, which // replaces the about: scheme with chrome:// for all about:foo URLs except // "about:blank". // Some |url| host values will be replaced with their respective redirects. diff --git a/chrome/browser/chrome_content_browser_client.cc b/chrome/browser/chrome_content_browser_client.cc index a0b0ed0..36a224cd0 100644 --- a/chrome/browser/chrome_content_browser_client.cc +++ b/chrome/browser/chrome_content_browser_client.cc @@ -108,7 +108,7 @@ #include "components/rappor/rappor_utils.h" #include "components/signin/core/common/profile_management_switches.h" #include "components/translate/core/common/translate_switches.h" -#include "components/url_fixer/url_fixer.h" +#include "components/url_formatter/url_fixer.h" #include "components/variations/variations_associated_data.h" #include "components/version_info/version_info.h" #include "content/public/browser/browser_child_process_host.h" diff --git a/chrome/browser/chrome_quota_permission_context.cc b/chrome/browser/chrome_quota_permission_context.cc index cc4db36..332afb6 100644 --- a/chrome/browser/chrome_quota_permission_context.cc +++ b/chrome/browser/chrome_quota_permission_context.cc @@ -19,11 +19,11 @@ #include "chrome/grit/locale_settings.h" #include "components/infobars/core/confirm_infobar_delegate.h" #include "components/infobars/core/infobar.h" +#include "components/url_formatter/url_formatter.h" #include "content/public/browser/browser_thread.h" #include "content/public/browser/navigation_details.h" #include "content/public/browser/web_contents.h" #include "grit/theme_resources.h" -#include "net/base/net_util.h" #include "storage/common/quota/quota_types.h" #include "ui/base/l10n/l10n_util.h" #include "url/gurl.h" @@ -93,14 +93,14 @@ int QuotaPermissionRequest::GetIconID() const { base::string16 QuotaPermissionRequest::GetMessageText() const { return l10n_util::GetStringFUTF16( - (requested_quota_ > kRequestLargeQuotaThreshold ? - IDS_REQUEST_LARGE_QUOTA_INFOBAR_QUESTION : - IDS_REQUEST_QUOTA_INFOBAR_QUESTION), - net::FormatUrl(origin_url_, display_languages_, - net::kFormatUrlOmitUsernamePassword | - net::kFormatUrlOmitTrailingSlashOnBareHostname, - net::UnescapeRule::SPACES, NULL, NULL, NULL) - ); + (requested_quota_ > kRequestLargeQuotaThreshold + ? IDS_REQUEST_LARGE_QUOTA_INFOBAR_QUESTION + : IDS_REQUEST_QUOTA_INFOBAR_QUESTION), + url_formatter::FormatUrl( + origin_url_, display_languages_, + url_formatter::kFormatUrlOmitUsernamePassword | + url_formatter::kFormatUrlOmitTrailingSlashOnBareHostname, + net::UnescapeRule::SPACES, nullptr, nullptr, nullptr)); } base::string16 QuotaPermissionRequest::GetMessageTextFragment() const { @@ -219,14 +219,14 @@ base::string16 RequestQuotaInfoBarDelegate::GetMessageText() const { // If the site requested larger quota than this threshold, show a different // message to the user. return l10n_util::GetStringFUTF16( - (requested_quota_ > kRequestLargeQuotaThreshold ? - IDS_REQUEST_LARGE_QUOTA_INFOBAR_QUESTION : - IDS_REQUEST_QUOTA_INFOBAR_QUESTION), - net::FormatUrl(origin_url_, display_languages_, - net::kFormatUrlOmitUsernamePassword | - net::kFormatUrlOmitTrailingSlashOnBareHostname, - net::UnescapeRule::SPACES, NULL, NULL, NULL) - ); + (requested_quota_ > kRequestLargeQuotaThreshold + ? IDS_REQUEST_LARGE_QUOTA_INFOBAR_QUESTION + : IDS_REQUEST_QUOTA_INFOBAR_QUESTION), + url_formatter::FormatUrl( + origin_url_, display_languages_, + url_formatter::kFormatUrlOmitUsernamePassword | + url_formatter::kFormatUrlOmitTrailingSlashOnBareHostname, + net::UnescapeRule::SPACES, nullptr, nullptr, nullptr)); } bool RequestQuotaInfoBarDelegate::Accept() { diff --git a/chrome/browser/custom_home_pages_table_model.cc b/chrome/browser/custom_home_pages_table_model.cc index 8b5aab4..8b25d0a 100644 --- a/chrome/browser/custom_home_pages_table_model.cc +++ b/chrome/browser/custom_home_pages_table_model.cc @@ -19,8 +19,8 @@ #include "chrome/common/url_constants.h" #include "chrome/grit/generated_resources.h" #include "components/history/core/browser/history_service.h" +#include "components/url_formatter/url_formatter.h" #include "content/public/browser/web_contents.h" -#include "net/base/net_util.h" #include "ui/base/l10n/l10n_util.h" #include "ui/base/models/table_model_observer.h" #include "ui/gfx/codec/png_codec.h" @@ -305,7 +305,7 @@ void CustomHomePagesTableModel::OnGotTitle(const GURL& entry_url, base::string16 CustomHomePagesTableModel::FormattedURL(int row) const { std::string languages = profile_->GetPrefs()->GetString(prefs::kAcceptLanguages); - base::string16 url = net::FormatUrl(entries_[row].url, languages); + base::string16 url = url_formatter::FormatUrl(entries_[row].url, languages); url = base::i18n::GetDisplayStringInLTRDirectionality(url); return url; } diff --git a/chrome/browser/dom_distiller/tab_utils_android.cc b/chrome/browser/dom_distiller/tab_utils_android.cc index 83598cb..7dcef25 100644 --- a/chrome/browser/dom_distiller/tab_utils_android.cc +++ b/chrome/browser/dom_distiller/tab_utils_android.cc @@ -12,6 +12,7 @@ #include "chrome/browser/profiles/profile.h" #include "chrome/browser/profiles/profile_manager.h" #include "chrome/common/pref_names.h" +#include "components/url_formatter/url_formatter.h" #include "content/public/browser/web_contents.h" #include "content/public/common/content_constants.h" #include "jni/DomDistillerTabUtils_jni.h" @@ -56,14 +57,10 @@ jstring GetFormattedUrlFromOriginalDistillerUrl(JNIEnv* env, // and pastes it into another program, that program may think the URL ends at // the space. return base::android::ConvertUTF16ToJavaString( - env, - net::FormatUrl(url, - languages, - net::kFormatUrlOmitAll, - net::UnescapeRule::NORMAL, - NULL, - NULL, - NULL)).Release(); + env, url_formatter::FormatUrl( + url, languages, url_formatter::kFormatUrlOmitAll, + net::UnescapeRule::NORMAL, nullptr, nullptr, nullptr)) + .Release(); } } // namespace android diff --git a/chrome/browser/download/download_query.cc b/chrome/browser/download/download_query.cc index 456f4cc..f800888 100644 --- a/chrome/browser/download/download_query.cc +++ b/chrome/browser/download/download_query.cc @@ -25,9 +25,9 @@ #include "base/values.h" #include "chrome/browser/profiles/profile.h" #include "chrome/common/pref_names.h" +#include "components/url_formatter/url_formatter.h" #include "content/public/browser/content_browser_client.h" #include "content/public/browser/download_item.h" -#include "net/base/net_util.h" #include "third_party/re2/re2/re2.h" #include "url/gurl.h" @@ -77,7 +77,7 @@ static bool MatchesQuery( base::string16 url_formatted = url_raw; if (item.GetBrowserContext()) { Profile* profile = Profile::FromBrowserContext(item.GetBrowserContext()); - url_formatted = net::FormatUrl( + url_formatted = url_formatter::FormatUrl( item.GetOriginalUrl(), profile->GetPrefs()->GetString(prefs::kAcceptLanguages)); } diff --git a/chrome/browser/extensions/api/sessions/sessions_api.cc b/chrome/browser/extensions/api/sessions/sessions_api.cc index c46f0e4..ae342b7 100644 --- a/chrome/browser/extensions/api/sessions/sessions_api.cc +++ b/chrome/browser/extensions/api/sessions/sessions_api.cc @@ -32,12 +32,12 @@ #include "chrome/common/pref_names.h" #include "components/sync_driver/glue/synced_session.h" #include "components/sync_driver/open_tabs_ui_delegate.h" +#include "components/url_formatter/url_formatter.h" #include "content/public/browser/web_contents.h" #include "extensions/browser/extension_function_dispatcher.h" #include "extensions/browser/extension_function_registry.h" #include "extensions/browser/extension_system.h" #include "extensions/common/error_utils.h" -#include "net/base/net_util.h" #include "ui/base/layout.h" namespace extensions { @@ -93,8 +93,8 @@ scoped_ptr<tabs::Tab> CreateTabModelHelper( } else { const std::string languages = profile->GetPrefs()->GetString(prefs::kAcceptLanguages); - tab_struct->title.reset( - new std::string(base::UTF16ToUTF8(net::FormatUrl(url, languages)))); + tab_struct->title.reset(new std::string( + base::UTF16ToUTF8(url_formatter::FormatUrl(url, languages)))); } tab_struct->index = index; tab_struct->pinned = pinned; diff --git a/chrome/browser/extensions/api/settings_private/prefs_util.cc b/chrome/browser/extensions/api/settings_private/prefs_util.cc index 01fac9f..97ada01 100644 --- a/chrome/browser/extensions/api/settings_private/prefs_util.cc +++ b/chrome/browser/extensions/api/settings_private/prefs_util.cc @@ -9,7 +9,7 @@ #include "chrome/browser/extensions/chrome_extension_function.h" #include "chrome/browser/profiles/profile.h" #include "chrome/common/pref_names.h" -#include "components/url_fixer/url_fixer.h" +#include "components/url_formatter/url_fixer.h" #if defined(OS_CHROMEOS) #include "chrome/browser/chromeos/ownership/owner_settings_service_chromeos.h" @@ -215,7 +215,7 @@ bool PrefsUtil::SetPref(const std::string& pref_name, return false; if (IsPrefTypeURL(pref_name)) { - GURL fixed = url_fixer::FixupURL(original, std::string()); + GURL fixed = url_formatter::FixupURL(original, std::string()); temp_value.reset(new base::StringValue(fixed.spec())); value = temp_value.get(); } diff --git a/chrome/browser/extensions/extension_tab_util.cc b/chrome/browser/extensions/extension_tab_util.cc index 384c94d..22a2dea 100644 --- a/chrome/browser/extensions/extension_tab_util.cc +++ b/chrome/browser/extensions/extension_tab_util.cc @@ -25,7 +25,7 @@ #include "chrome/browser/ui/tabs/tab_utils.h" #include "chrome/common/extensions/api/tabs.h" #include "chrome/common/url_constants.h" -#include "components/url_fixer/url_fixer.h" +#include "components/url_formatter/url_fixer.h" #include "content/public/browser/favicon_status.h" #include "content/public/browser/navigation_entry.h" #include "content/public/browser/web_contents.h" @@ -551,7 +551,7 @@ bool ExtensionTabUtil::IsKillURL(const GURL& url) { // Check a fixed-up URL, to normalize the scheme and parse hosts correctly. GURL fixed_url = - url_fixer::FixupURL(url.possibly_invalid_spec(), std::string()); + url_formatter::FixupURL(url.possibly_invalid_spec(), std::string()); if (!fixed_url.SchemeIs(content::kChromeUIScheme)) return false; diff --git a/chrome/browser/geolocation/geolocation_infobar_delegate.cc b/chrome/browser/geolocation/geolocation_infobar_delegate.cc index 1b6eb2d..52cf183 100644 --- a/chrome/browser/geolocation/geolocation_infobar_delegate.cc +++ b/chrome/browser/geolocation/geolocation_infobar_delegate.cc @@ -7,9 +7,9 @@ #include "chrome/browser/infobars/infobar_service.h" #include "chrome/grit/generated_resources.h" #include "components/infobars/core/infobar.h" +#include "components/url_formatter/url_formatter.h" #include "grit/generated_resources.h" #include "grit/theme_resources.h" -#include "net/base/net_util.h" #include "ui/base/l10n/l10n_util.h" @@ -44,9 +44,11 @@ int GeolocationInfoBarDelegate::GetIconID() const { } base::string16 GeolocationInfoBarDelegate::GetMessageText() const { - return l10n_util::GetStringFUTF16(IDS_GEOLOCATION_INFOBAR_QUESTION, - net::FormatUrl(requesting_frame_, display_languages_, - net::kFormatUrlOmitUsernamePassword | - net::kFormatUrlOmitTrailingSlashOnBareHostname, - net::UnescapeRule::SPACES, NULL, NULL, NULL)); + return l10n_util::GetStringFUTF16( + IDS_GEOLOCATION_INFOBAR_QUESTION, + url_formatter::FormatUrl( + requesting_frame_, display_languages_, + url_formatter::kFormatUrlOmitUsernamePassword | + url_formatter::kFormatUrlOmitTrailingSlashOnBareHostname, + net::UnescapeRule::SPACES, nullptr, nullptr, nullptr)); } diff --git a/chrome/browser/interstitials/security_interstitial_page.cc b/chrome/browser/interstitials/security_interstitial_page.cc index 082e505..b983456 100644 --- a/chrome/browser/interstitials/security_interstitial_page.cc +++ b/chrome/browser/interstitials/security_interstitial_page.cc @@ -18,10 +18,10 @@ #include "chrome/grit/generated_resources.h" #include "components/google/core/browser/google_util.h" #include "components/security_interstitials/core/metrics_helper.h" +#include "components/url_formatter/url_formatter.h" #include "content/public/browser/interstitial_page.h" #include "content/public/browser/page_navigator.h" #include "content/public/browser/web_contents.h" -#include "net/base/net_util.h" #include "ui/base/l10n/l10n_util.h" #include "ui/base/resource/resource_bundle.h" #include "ui/base/webui/jstemplate_builder.h" @@ -124,7 +124,8 @@ base::string16 SecurityInterstitialPage::GetFormattedHostName() const { Profile::FromBrowserContext(web_contents()->GetBrowserContext()); if (profile) languages = profile->GetPrefs()->GetString(prefs::kAcceptLanguages); - base::string16 host = net::IDNToUnicode(request_url_.host(), languages); + base::string16 host = + url_formatter::IDNToUnicode(request_url_.host(), languages); if (base::i18n::IsRTL()) base::i18n::WrapStringWithLTRFormatting(&host); return host; diff --git a/chrome/browser/media/media_stream_capture_indicator.cc b/chrome/browser/media/media_stream_capture_indicator.cc index 978e0e8..0c91b5b 100644 --- a/chrome/browser/media/media_stream_capture_indicator.cc +++ b/chrome/browser/media/media_stream_capture_indicator.cc @@ -18,13 +18,13 @@ #include "chrome/browser/tab_contents/tab_util.h" #include "chrome/common/pref_names.h" #include "chrome/grit/chromium_strings.h" +#include "components/url_formatter/url_formatter.h" #include "content/public/browser/browser_thread.h" #include "content/public/browser/content_browser_client.h" #include "content/public/browser/web_contents.h" #include "content/public/browser/web_contents_delegate.h" #include "content/public/browser/web_contents_observer.h" #include "grit/theme_resources.h" -#include "net/base/net_util.h" #include "ui/base/l10n/l10n_util.h" #include "ui/base/resource/resource_bundle.h" #include "ui/gfx/image/image_skia.h" @@ -112,7 +112,8 @@ base::string16 GetTitle(WebContents* web_contents) { Profile::FromBrowserContext(web_contents->GetBrowserContext()); std::string languages = profile->GetPrefs()->GetString(prefs::kAcceptLanguages); - if (tab_title == net::FormatUrl(web_contents->GetURL(), languages)) + if (tab_title == + url_formatter::FormatUrl(web_contents->GetURL(), languages)) tab_title = GetSecurityOrigin(web_contents); } diff --git a/chrome/browser/media/midi_permission_infobar_delegate.cc b/chrome/browser/media/midi_permission_infobar_delegate.cc index 5a590cd..40cc694 100644 --- a/chrome/browser/media/midi_permission_infobar_delegate.cc +++ b/chrome/browser/media/midi_permission_infobar_delegate.cc @@ -7,8 +7,8 @@ #include "chrome/browser/infobars/infobar_service.h" #include "chrome/grit/generated_resources.h" #include "components/infobars/core/infobar.h" +#include "components/url_formatter/url_formatter.h" #include "grit/theme_resources.h" -#include "net/base/net_util.h" #include "ui/base/l10n/l10n_util.h" // static @@ -45,8 +45,9 @@ int MidiPermissionInfoBarDelegate::GetIconID() const { base::string16 MidiPermissionInfoBarDelegate::GetMessageText() const { return l10n_util::GetStringFUTF16( IDS_MIDI_SYSEX_INFOBAR_QUESTION, - net::FormatUrl(requesting_frame_.GetOrigin(), display_languages_, - net::kFormatUrlOmitUsernamePassword | - net::kFormatUrlOmitTrailingSlashOnBareHostname, - net::UnescapeRule::SPACES, NULL, NULL, NULL)); + url_formatter::FormatUrl( + requesting_frame_.GetOrigin(), display_languages_, + url_formatter::kFormatUrlOmitUsernamePassword | + url_formatter::kFormatUrlOmitTrailingSlashOnBareHostname, + net::UnescapeRule::SPACES, nullptr, nullptr, nullptr)); } diff --git a/chrome/browser/media/protected_media_identifier_infobar_delegate.cc b/chrome/browser/media/protected_media_identifier_infobar_delegate.cc index 4d4cbcc..5dbd69e 100644 --- a/chrome/browser/media/protected_media_identifier_infobar_delegate.cc +++ b/chrome/browser/media/protected_media_identifier_infobar_delegate.cc @@ -10,9 +10,9 @@ #include "chrome/common/url_constants.h" #include "chrome/grit/generated_resources.h" #include "components/infobars/core/infobar.h" +#include "components/url_formatter/url_formatter.h" #include "grit/components_strings.h" #include "grit/theme_resources.h" -#include "net/base/net_util.h" #include "ui/base/l10n/l10n_util.h" // static @@ -77,7 +77,8 @@ void ProtectedMediaIdentifierInfoBarDelegate::InfoBarDismissed() { base::string16 ProtectedMediaIdentifierInfoBarDelegate::GetMessageText() const { return l10n_util::GetStringFUTF16( IDS_PROTECTED_MEDIA_IDENTIFIER_INFOBAR_QUESTION, - net::FormatUrl(requesting_frame_.GetOrigin(), display_languages_)); + url_formatter::FormatUrl(requesting_frame_.GetOrigin(), + display_languages_)); } base::string16 ProtectedMediaIdentifierInfoBarDelegate::GetButtonLabel( diff --git a/chrome/browser/notifications/notification_permission_infobar_delegate.cc b/chrome/browser/notifications/notification_permission_infobar_delegate.cc index 54ccf0b..00316e2 100644 --- a/chrome/browser/notifications/notification_permission_infobar_delegate.cc +++ b/chrome/browser/notifications/notification_permission_infobar_delegate.cc @@ -7,8 +7,9 @@ #include "chrome/browser/infobars/infobar_service.h" #include "chrome/grit/generated_resources.h" #include "components/infobars/core/infobar.h" +#include "components/url_formatter/url_formatter.h" #include "grit/theme_resources.h" -#include "net/base/net_util.h" +#include "net/base/escape.h" #include "ui/base/l10n/l10n_util.h" // static @@ -45,8 +46,9 @@ int NotificationPermissionInfobarDelegate::GetIconID() const { base::string16 NotificationPermissionInfobarDelegate::GetMessageText() const { return l10n_util::GetStringFUTF16( IDS_NOTIFICATION_PERMISSIONS, - net::FormatUrl(requesting_frame_.GetOrigin(), display_languages_, - net::kFormatUrlOmitUsernamePassword | - net::kFormatUrlOmitTrailingSlashOnBareHostname, - net::UnescapeRule::SPACES, nullptr, nullptr, nullptr)); + url_formatter::FormatUrl( + requesting_frame_.GetOrigin(), display_languages_, + url_formatter::kFormatUrlOmitUsernamePassword | + url_formatter::kFormatUrlOmitTrailingSlashOnBareHostname, + net::UnescapeRule::SPACES, nullptr, nullptr, nullptr)); } diff --git a/chrome/browser/notifications/platform_notification_service_impl.cc b/chrome/browser/notifications/platform_notification_service_impl.cc index 55815d8..f03f2be 100644 --- a/chrome/browser/notifications/platform_notification_service_impl.cc +++ b/chrome/browser/notifications/platform_notification_service_impl.cc @@ -17,13 +17,13 @@ #include "chrome/common/pref_names.h" #include "components/content_settings/core/browser/host_content_settings_map.h" #include "components/content_settings/core/common/content_settings.h" +#include "components/url_formatter/url_formatter.h" #include "content/public/browser/browser_thread.h" #include "content/public/browser/desktop_notification_delegate.h" #include "content/public/browser/notification_event_dispatcher.h" #include "content/public/browser/platform_notification_context.h" #include "content/public/browser/storage_partition.h" #include "content/public/common/platform_notification_data.h" -#include "net/base/net_util.h" #include "ui/message_center/notifier_settings.h" #include "url/url_constants.h" @@ -399,7 +399,8 @@ base::string16 PlatformNotificationServiceImpl::WebOriginDisplayName( spec.begin() + parsed.CountCharactersBefore(url::Parsed::USERNAME, true)); } - formatted_origin.append(net::IDNToUnicode(origin.host(), languages)); + formatted_origin.append( + url_formatter::IDNToUnicode(origin.host(), languages)); if (origin.has_port()) { formatted_origin.push_back(':'); formatted_origin.append(base::UTF8ToUTF16(origin.port())); @@ -409,5 +410,5 @@ base::string16 PlatformNotificationServiceImpl::WebOriginDisplayName( // TODO(dewittj): Once file:// URLs are passed in to the origin // GURL here, begin returning the path as the display name. - return net::FormatUrl(origin, languages); + return url_formatter::FormatUrl(origin, languages); } diff --git a/chrome/browser/pepper_broker_infobar_delegate.cc b/chrome/browser/pepper_broker_infobar_delegate.cc index ca7a597..0fa86d4 100644 --- a/chrome/browser/pepper_broker_infobar_delegate.cc +++ b/chrome/browser/pepper_broker_infobar_delegate.cc @@ -14,6 +14,7 @@ #include "chrome/grit/generated_resources.h" #include "components/content_settings/core/browser/host_content_settings_map.h" #include "components/infobars/core/infobar.h" +#include "components/url_formatter/url_formatter.h" #include "content/public/browser/page_navigator.h" #include "content/public/browser/plugin_service.h" #include "content/public/browser/user_metrics.h" @@ -22,7 +23,6 @@ #include "content/public/common/webplugininfo.h" #include "grit/components_strings.h" #include "grit/theme_resources.h" -#include "net/base/net_util.h" #include "ui/base/l10n/l10n_util.h" @@ -104,10 +104,9 @@ base::string16 PepperBrokerInfoBarDelegate::GetMessageText() const { DCHECK(success); scoped_ptr<PluginMetadata> plugin_metadata( PluginFinder::GetInstance()->GetPluginMetadata(plugin)); - return l10n_util::GetStringFUTF16(IDS_PEPPER_BROKER_MESSAGE, - plugin_metadata->name(), - net::FormatUrl(url_.GetOrigin(), - languages_)); + return l10n_util::GetStringFUTF16( + IDS_PEPPER_BROKER_MESSAGE, plugin_metadata->name(), + url_formatter::FormatUrl(url_.GetOrigin(), languages_)); } base::string16 PepperBrokerInfoBarDelegate::GetButtonLabel( diff --git a/chrome/browser/permissions/permission_bubble_request_impl.cc b/chrome/browser/permissions/permission_bubble_request_impl.cc index f175962..1e2b13c 100644 --- a/chrome/browser/permissions/permission_bubble_request_impl.cc +++ b/chrome/browser/permissions/permission_bubble_request_impl.cc @@ -7,8 +7,9 @@ #include "chrome/browser/permissions/permission_context_base.h" #include "chrome/browser/permissions/permission_context_uma_util.h" #include "chrome/grit/generated_resources.h" +#include "components/url_formatter/url_formatter.h" #include "grit/theme_resources.h" -#include "net/base/net_util.h" +#include "net/base/escape.h" #include "ui/base/l10n/l10n_util.h" #include "ui/gfx/vector_icons_public2.h" @@ -109,10 +110,11 @@ base::string16 PermissionBubbleRequestImpl::GetMessageText() const { } return l10n_util::GetStringFUTF16( message_id, - net::FormatUrl(request_origin_, display_languages_, - net::kFormatUrlOmitUsernamePassword | - net::kFormatUrlOmitTrailingSlashOnBareHostname, - net::UnescapeRule::SPACES, NULL, NULL, NULL)); + url_formatter::FormatUrl( + request_origin_, display_languages_, + url_formatter::kFormatUrlOmitUsernamePassword | + url_formatter::kFormatUrlOmitTrailingSlashOnBareHostname, + net::UnescapeRule::SPACES, nullptr, nullptr, nullptr)); } base::string16 PermissionBubbleRequestImpl::GetMessageTextFragment() const { diff --git a/chrome/browser/policy/managed_bookmarks_policy_handler.cc b/chrome/browser/policy/managed_bookmarks_policy_handler.cc index 8c71fd3..75c8e78 100644 --- a/chrome/browser/policy/managed_bookmarks_policy_handler.cc +++ b/chrome/browser/policy/managed_bookmarks_policy_handler.cc @@ -10,7 +10,7 @@ #include "components/bookmarks/managed/managed_bookmarks_tracker.h" #include "components/policy/core/browser/policy_error_map.h" #include "components/policy/core/common/policy_map.h" -#include "components/url_fixer/url_fixer.h" +#include "components/url_formatter/url_fixer.h" #include "policy/policy_constants.h" #include "url/gurl.h" @@ -71,7 +71,7 @@ void ManagedBookmarksPolicyHandler::FilterBookmarks(base::ListValue* list) { } else { // Make sure the URL is valid before passing a bookmark to the pref. dict->Remove(ManagedBookmarksTracker::kChildren, NULL); - GURL gurl = url_fixer::FixupURL(url, ""); + GURL gurl = url_formatter::FixupURL(url, std::string()); if (!gurl.is_valid()) { it = list->Erase(it, NULL); continue; diff --git a/chrome/browser/policy/url_blacklist_manager_unittest.cc b/chrome/browser/policy/url_blacklist_manager_unittest.cc index a21df06..b00a9a3 100644 --- a/chrome/browser/policy/url_blacklist_manager_unittest.cc +++ b/chrome/browser/policy/url_blacklist_manager_unittest.cc @@ -15,7 +15,7 @@ #include "base/thread_task_runner_handle.h" #include "chrome/browser/policy/policy_helpers.h" #include "components/policy/core/common/policy_pref_names.h" -#include "components/url_fixer/url_fixer.h" +#include "components/url_formatter/url_fixer.h" #include "google_apis/gaia/gaia_urls.h" #include "net/base/load_flags.h" #include "net/base/net_errors.h" @@ -25,7 +25,7 @@ // TODO(joaodasilva): this file should be moved next to // components/policy/core/browser/url_blacklist_manager.(cc|h). // However, url_fixer_upper.h can't be included from the component. Rather -// than having it mocked out, the actual url_fixer::SegmentURL call is used +// than having it mocked out, the actual url_formatter::SegmentURL call is used // to make sure that the parsing of URL filters is correct. namespace policy { @@ -34,7 +34,7 @@ namespace { // Helper to get the disambiguated SegmentURL() function. URLBlacklist::SegmentURLCallback GetSegmentURLCallback() { - return url_fixer::SegmentURL; + return url_formatter::SegmentURL; } class TestingURLBlacklistManager : public URLBlacklistManager { diff --git a/chrome/browser/prefs/session_startup_pref.cc b/chrome/browser/prefs/session_startup_pref.cc index 996adc84..b75739f 100644 --- a/chrome/browser/prefs/session_startup_pref.cc +++ b/chrome/browser/prefs/session_startup_pref.cc @@ -15,7 +15,7 @@ #include "chrome/browser/profiles/profile.h" #include "chrome/common/pref_names.h" #include "components/pref_registry/pref_registry_syncable.h" -#include "components/url_fixer/url_fixer.h" +#include "components/url_formatter/url_fixer.h" #if defined(OS_MACOSX) #include "chrome/browser/ui/cocoa/window_restore_utils.h" @@ -54,7 +54,7 @@ void URLListToPref(const base::ListValue* url_list, SessionStartupPref* pref) { for (size_t i = 0; i < url_list->GetSize(); ++i) { std::string url_text; if (url_list->GetString(i, &url_text)) { - GURL fixed_url = url_fixer::FixupURL(url_text, std::string()); + GURL fixed_url = url_formatter::FixupURL(url_text, std::string()); pref->urls.push_back(fixed_url); } } diff --git a/chrome/browser/profiles/profile_impl.cc b/chrome/browser/profiles/profile_impl.cc index 6e90605..7f05c2c 100644 --- a/chrome/browser/profiles/profile_impl.cc +++ b/chrome/browser/profiles/profile_impl.cc @@ -90,7 +90,7 @@ #include "components/pref_registry/pref_registry_syncable.h" #include "components/signin/core/browser/signin_manager.h" #include "components/ui/zoom/zoom_event_manager.h" -#include "components/url_fixer/url_fixer.h" +#include "components/url_formatter/url_fixer.h" #include "components/user_prefs/user_prefs.h" #include "content/public/browser/browser_thread.h" #include "content/public/browser/dom_storage_context.h" @@ -1207,7 +1207,7 @@ GURL ProfileImpl::GetHomePage() { base::FilePath browser_directory; PathService::Get(base::DIR_CURRENT, &browser_directory); - GURL home_page(url_fixer::FixupRelativeFile( + GURL home_page(url_formatter::FixupRelativeFile( browser_directory, command_line.GetSwitchValuePath(switches::kHomePage))); if (home_page.is_valid()) @@ -1216,8 +1216,8 @@ GURL ProfileImpl::GetHomePage() { if (GetPrefs()->GetBoolean(prefs::kHomePageIsNewTabPage)) return GURL(chrome::kChromeUINewTabURL); - GURL home_page(url_fixer::FixupURL(GetPrefs()->GetString(prefs::kHomePage), - std::string())); + GURL home_page(url_formatter::FixupURL( + GetPrefs()->GetString(prefs::kHomePage), std::string())); if (!home_page.is_valid()) return GURL(chrome::kChromeUINewTabURL); return home_page; diff --git a/chrome/browser/profiles/profile_io_data.cc b/chrome/browser/profiles/profile_io_data.cc index b8db2b3..bf7e2a9 100644 --- a/chrome/browser/profiles/profile_io_data.cc +++ b/chrome/browser/profiles/profile_io_data.cc @@ -58,7 +58,7 @@ #include "components/data_reduction_proxy/core/browser/data_reduction_proxy_io_data.h" #include "components/dom_distiller/core/url_constants.h" #include "components/sync_driver/pref_names.h" -#include "components/url_fixer/url_fixer.h" +#include "components/url_formatter/url_fixer.h" #include "content/public/browser/browser_thread.h" #include "content/public/browser/host_zoom_map.h" #include "content/public/browser/notification_service.h" @@ -511,7 +511,7 @@ void ProfileIOData::InitializeOnUIThread(Profile* profile) { #if defined(ENABLE_CONFIGURATION_POLICY) policy::URLBlacklist::SegmentURLCallback callback = static_cast<policy::URLBlacklist::SegmentURLCallback>( - url_fixer::SegmentURL); + url_formatter::SegmentURL); base::SequencedWorkerPool* pool = BrowserThread::GetBlockingPool(); scoped_refptr<base::SequencedTaskRunner> background_task_runner = pool->GetSequencedTaskRunner(pool->GetSequenceToken()); diff --git a/chrome/browser/ssl/captive_portal_blocking_page.cc b/chrome/browser/ssl/captive_portal_blocking_page.cc index 955fea0..9287fe4e 100644 --- a/chrome/browser/ssl/captive_portal_blocking_page.cc +++ b/chrome/browser/ssl/captive_portal_blocking_page.cc @@ -17,6 +17,7 @@ #include "chrome/browser/ssl/ssl_cert_reporter.h" #include "chrome/common/pref_names.h" #include "components/captive_portal/captive_portal_detector.h" +#include "components/url_formatter/url_formatter.h" #include "components/wifi/wifi_service.h" #include "content/public/browser/web_contents.h" #include "grit/generated_resources.h" @@ -169,7 +170,8 @@ void CaptivePortalBlockingPage::PopulateInterstitialStrings( web_contents()->GetBrowserContext()); if (profile) languages = profile->GetPrefs()->GetString(prefs::kAcceptLanguages); - base::string16 login_host = net::IDNToUnicode(login_url_.host(), languages); + base::string16 login_host = + url_formatter::IDNToUnicode(login_url_.host(), languages); if (base::i18n::IsRTL()) base::i18n::WrapStringWithLTRFormatting(&login_host); diff --git a/chrome/browser/supervised_user/supervised_user_bookmarks_handler.cc b/chrome/browser/supervised_user/supervised_user_bookmarks_handler.cc index feaeb61..2b35d14 100644 --- a/chrome/browser/supervised_user/supervised_user_bookmarks_handler.cc +++ b/chrome/browser/supervised_user/supervised_user_bookmarks_handler.cc @@ -7,7 +7,7 @@ #include "base/logging.h" #include "base/strings/string_number_conversions.h" #include "base/values.h" -#include "components/url_fixer/url_fixer.h" +#include "components/url_formatter/url_fixer.h" namespace { @@ -187,7 +187,7 @@ void SupervisedUserBookmarksHandler::AddFoldersToTree() { void SupervisedUserBookmarksHandler::AddLinksToTree() { for (const auto& link : links_) { scoped_ptr<base::DictionaryValue> node(new base::DictionaryValue); - GURL url = url_fixer::FixupURL(link.url, std::string()); + GURL url = url_formatter::FixupURL(link.url, std::string()); if (!url.is_valid()) { LOG(WARNING) << "Got invalid URL: " << link.url; continue; diff --git a/chrome/browser/supervised_user/supervised_user_url_filter.cc b/chrome/browser/supervised_user/supervised_user_url_filter.cc index 1711b16..2702aaa 100644 --- a/chrome/browser/supervised_user/supervised_user_url_filter.cc +++ b/chrome/browser/supervised_user/supervised_user_url_filter.cc @@ -19,7 +19,7 @@ #include "chrome/browser/supervised_user/experimental/supervised_user_blacklist.h" #include "chrome/grit/generated_resources.h" #include "components/policy/core/browser/url_blacklist_manager.h" -#include "components/url_fixer/url_fixer.h" +#include "components/url_formatter/url_fixer.h" #include "components/url_matcher/url_matcher.h" #include "content/public/browser/browser_thread.h" #include "net/base/registry_controlled_domains/registry_controlled_domain.h" @@ -95,7 +95,7 @@ bool FilterBuilder::AddPattern(const std::string& pattern, int site_id) { std::string query; bool match_subdomains = true; URLBlacklist::SegmentURLCallback callback = - static_cast<URLBlacklist::SegmentURLCallback>(url_fixer::SegmentURL); + static_cast<URLBlacklist::SegmentURLCallback>(url_formatter::SegmentURL); if (!URLBlacklist::FilterToComponents( callback, pattern, &scheme, &host, &match_subdomains, &port, &path, &query)) { diff --git a/chrome/browser/ui/BUILD.gn b/chrome/browser/ui/BUILD.gn index 0631543..b13909c 100644 --- a/chrome/browser/ui/BUILD.gn +++ b/chrome/browser/ui/BUILD.gn @@ -92,8 +92,8 @@ source_set("ui") { "//chrome/installer/util", "//components/autofill/content/browser:risk_proto", "//components/power", - "//components/secure_display", "//components/suggestions/proto", + "//components/url_formatter", "//device/nfc", "//media", "//net:net_with_v8", diff --git a/chrome/browser/ui/DEPS b/chrome/browser/ui/DEPS index a04f569..1e7e329 100644 --- a/chrome/browser/ui/DEPS +++ b/chrome/browser/ui/DEPS @@ -1,7 +1,7 @@ include_rules = [ "+components/auto_login_parser", "+components/favicon/core", - "+components/secure_display", "+components/toolbar", + "+components/url_formatter", "-chrome/browser/ui/views", ] diff --git a/chrome/browser/ui/bookmarks/bookmark_utils.cc b/chrome/browser/ui/bookmarks/bookmark_utils.cc index f2f4bc1..9d7fca2 100644 --- a/chrome/browser/ui/bookmarks/bookmark_utils.cc +++ b/chrome/browser/ui/bookmarks/bookmark_utils.cc @@ -25,9 +25,9 @@ #include "components/bookmarks/browser/bookmark_model.h" #include "components/bookmarks/browser/bookmark_node_data.h" #include "components/search/search.h" +#include "components/url_formatter/url_formatter.h" #include "components/user_prefs/user_prefs.h" #include "content/public/browser/web_contents.h" -#include "net/base/net_util.h" #include "ui/base/dragdrop/drag_drop_types.h" #include "ui/base/dragdrop/drop_target_event.h" #include "ui/base/l10n/l10n_util.h" @@ -325,10 +325,10 @@ base::string16 FormatBookmarkURLForDisplay(const GURL& url, // and trailing slash, and unescape most characters. However, it's // important not to drop any username/password, or unescape anything that // changes the URL's meaning. - return net::FormatUrl( - url, languages, - net::kFormatUrlOmitAll & ~net::kFormatUrlOmitUsernamePassword, - net::UnescapeRule::SPACES, NULL, NULL, NULL); + return url_formatter::FormatUrl( + url, languages, url_formatter::kFormatUrlOmitAll & + ~url_formatter::kFormatUrlOmitUsernamePassword, + net::UnescapeRule::SPACES, nullptr, nullptr, nullptr); } bool IsAppsShortcutEnabled(Profile* profile, diff --git a/chrome/browser/ui/bookmarks/bookmark_utils.h b/chrome/browser/ui/bookmarks/bookmark_utils.h index dbd7d0f7..b9682a7 100644 --- a/chrome/browser/ui/bookmarks/bookmark_utils.h +++ b/chrome/browser/ui/bookmarks/bookmark_utils.h @@ -95,7 +95,7 @@ void ToggleBookmarkBarWhenVisible(content::BrowserContext* browser_context); // Returns a formatted version of |url| appropriate to display to a user with // the given |prefs|, which may be NULL. When re-parsing this URL, clients -// should call url_fixer::FixupURL(). +// should call url_formatter::FixupURL(). base::string16 FormatBookmarkURLForDisplay(const GURL& url, const PrefService* prefs); diff --git a/chrome/browser/ui/cocoa/bookmarks/bookmark_editor_controller.mm b/chrome/browser/ui/cocoa/bookmarks/bookmark_editor_controller.mm index 079e509..ec02dac 100644 --- a/chrome/browser/ui/cocoa/bookmarks/bookmark_editor_controller.mm +++ b/chrome/browser/ui/cocoa/bookmarks/bookmark_editor_controller.mm @@ -11,7 +11,7 @@ #include "chrome/browser/ui/bookmarks/bookmark_utils.h" #include "components/bookmarks/browser/bookmark_expanded_state_tracker.h" #include "components/bookmarks/browser/bookmark_model.h" -#include "components/url_fixer/url_fixer.h" +#include "components/url_formatter/url_fixer.h" #include "components/user_prefs/user_prefs.h" using bookmarks::BookmarkExpandedStateTracker; @@ -104,7 +104,7 @@ using bookmarks::BookmarkNode; // If possible, return a valid GURL from the URL text field. - (GURL)GURLFromUrlField { NSString* url = [self displayURL]; - return url_fixer::FixupURL([url UTF8String], std::string()); + return url_formatter::FixupURL([url UTF8String], std::string()); } // Enable the OK button if there is a valid URL. diff --git a/chrome/browser/ui/cocoa/status_bubble_mac.mm b/chrome/browser/ui/cocoa/status_bubble_mac.mm index d7418d9..dfa18af 100644 --- a/chrome/browser/ui/cocoa/status_bubble_mac.mm +++ b/chrome/browser/ui/cocoa/status_bubble_mac.mm @@ -17,8 +17,8 @@ #include "base/strings/sys_string_conversions.h" #include "base/strings/utf_string_conversions.h" #import "chrome/browser/ui/cocoa/bubble_view.h" -#include "components/secure_display/elide_url.h" -#include "net/base/net_util.h" +#include "components/url_formatter/elide_url.h" +#include "components/url_formatter/url_formatter.h" #import "third_party/google_toolbox_for_mac/src/AppKit/GTMNSAnimation+Duration.h" #import "third_party/google_toolbox_for_mac/src/AppKit/GTMNSBezierPath+RoundRect.h" #import "third_party/google_toolbox_for_mac/src/AppKit/GTMNSColor+Luminance.h" @@ -235,9 +235,9 @@ void StatusBubbleMac::SetURL(const GURL& url, const std::string& languages) { gfx::FontList font_list_chr( gfx::Font(gfx::PlatformFont::CreateFromNativeFont(font))); - base::string16 original_url_text = net::FormatUrl(url, languages); + base::string16 original_url_text = url_formatter::FormatUrl(url, languages); base::string16 status = - secure_display::ElideUrl(url, font_list_chr, text_width, languages); + url_formatter::ElideUrl(url, font_list_chr, text_width, languages); SetText(status, true); @@ -706,7 +706,7 @@ void StatusBubbleMac::ExpandBubble() { NSFont* font = [[window_ contentView] font]; gfx::FontList font_list_chr( gfx::Font(gfx::PlatformFont::CreateFromNativeFont(font))); - base::string16 expanded_url = secure_display::ElideUrl( + base::string16 expanded_url = url_formatter::ElideUrl( url_, font_list_chr, max_bubble_width, languages_); // Scale width from gfx::Font in view coordinates to window coordinates. diff --git a/chrome/browser/ui/cocoa/tabs/tab_strip_controller.mm b/chrome/browser/ui/cocoa/tabs/tab_strip_controller.mm index ded9e13..8771039 100644 --- a/chrome/browser/ui/cocoa/tabs/tab_strip_controller.mm +++ b/chrome/browser/ui/cocoa/tabs/tab_strip_controller.mm @@ -51,7 +51,7 @@ #include "components/metrics/proto/omnibox_event.pb.h" #include "components/omnibox/browser/autocomplete_classifier.h" #include "components/omnibox/browser/autocomplete_match.h" -#include "components/url_fixer/url_fixer.h" +#include "components/url_formatter/url_fixer.h" #include "components/web_modal/web_contents_modal_dialog_manager.h" #include "content/public/browser/navigation_controller.h" #include "content/public/browser/user_metrics.h" @@ -2093,7 +2093,7 @@ NSImage* Overlay(NSImage* ground, NSImage* overlay, CGFloat alpha) { NOTIMPLEMENTED(); // Get the first URL and fix it up. - GURL url(GURL(url_fixer::FixupURL( + GURL url(GURL(url_formatter::FixupURL( base::SysNSStringToUTF8([urls objectAtIndex:0]), std::string()))); [self openURL:&url inView:view at:point]; diff --git a/chrome/browser/ui/cocoa/toolbar/toolbar_controller.mm b/chrome/browser/ui/cocoa/toolbar/toolbar_controller.mm index 306d3ea..c6fdc6f 100644 --- a/chrome/browser/ui/cocoa/toolbar/toolbar_controller.mm +++ b/chrome/browser/ui/cocoa/toolbar/toolbar_controller.mm @@ -53,7 +53,7 @@ #include "components/omnibox/browser/autocomplete_match.h" #include "components/omnibox/browser/omnibox_view.h" #include "components/search_engines/template_url_service.h" -#include "components/url_fixer/url_fixer.h" +#include "components/url_formatter/url_fixer.h" #include "content/public/browser/web_contents.h" #include "grit/theme_resources.h" #import "ui/base/cocoa/menu_controller.h" @@ -905,8 +905,8 @@ class NotificationBridge : public WrenchMenuBadgeController::Delegate { NOTIMPLEMENTED(); // Get the first URL and fix it up. - GURL url(url_fixer::FixupURL(base::SysNSStringToUTF8([urls objectAtIndex:0]), - std::string())); + GURL url(url_formatter::FixupURL( + base::SysNSStringToUTF8([urls objectAtIndex:0]), std::string())); if (url.SchemeIs(url::kJavaScriptScheme)) { browser_->window()->GetLocationBar()->GetOmniboxView()->SetUserText( diff --git a/chrome/browser/ui/content_settings/content_setting_bubble_model.cc b/chrome/browser/ui/content_settings/content_setting_bubble_model.cc index 339c596..0a03d05 100644 --- a/chrome/browser/ui/content_settings/content_setting_bubble_model.cc +++ b/chrome/browser/ui/content_settings/content_setting_bubble_model.cc @@ -29,7 +29,7 @@ #include "components/content_settings/core/browser/content_settings_utils.h" #include "components/content_settings/core/browser/cookie_settings.h" #include "components/content_settings/core/common/content_settings.h" -#include "components/secure_display/elide_url.h" +#include "components/url_formatter/elide_url.h" #include "content/public/browser/notification_service.h" #include "content/public/browser/render_frame_host.h" #include "content/public/browser/render_process_host.h" @@ -275,7 +275,7 @@ bool ContentSettingSingleRadioGroup::settings_changed() const { // content type and setting the default value based on the content setting. void ContentSettingSingleRadioGroup::SetRadioGroup() { GURL url = web_contents()->GetURL(); - base::string16 display_host = secure_display::FormatUrlForSecurityDisplay( + base::string16 display_host = url_formatter::FormatUrlForSecurityDisplay( url, profile()->GetPrefs()->GetString(prefs::kAcceptLanguages)); if (display_host.empty()) display_host = base::ASCIIToUTF16(url.spec()); @@ -719,7 +719,7 @@ void ContentSettingMediaStreamBubbleModel::SetRadioGroup() { radio_group.url = url; base::string16 display_host_utf16 = - secure_display::FormatUrlForSecurityDisplay( + url_formatter::FormatUrlForSecurityDisplay( url, profile()->GetPrefs()->GetString(prefs::kAcceptLanguages)); std::string display_host(base::UTF16ToUTF8(display_host_utf16)); if (display_host.empty()) diff --git a/chrome/browser/ui/content_settings/content_setting_bubble_model_unittest.cc b/chrome/browser/ui/content_settings/content_setting_bubble_model_unittest.cc index e9b8d29..5f960b4 100644 --- a/chrome/browser/ui/content_settings/content_setting_bubble_model_unittest.cc +++ b/chrome/browser/ui/content_settings/content_setting_bubble_model_unittest.cc @@ -21,7 +21,7 @@ #include "components/content_settings/core/browser/host_content_settings_map.h" #include "components/content_settings/core/common/content_settings.h" #include "components/infobars/core/infobar_delegate.h" -#include "components/secure_display/elide_url.h" +#include "components/url_formatter/elide_url.h" #include "content/public/browser/web_contents.h" #include "content/public/test/web_contents_tester.h" #include "testing/gtest/include/gtest/gtest.h" @@ -118,7 +118,7 @@ TEST_F(ContentSettingBubbleModelTest, Cookies) { EXPECT_EQ(bubble_content_2.radio_group.radio_items[1], l10n_util::GetStringFUTF8( IDS_ALLOWED_COOKIES_BLOCK, - secure_display::FormatUrlForSecurityDisplay( + url_formatter::FormatUrlForSecurityDisplay( web_contents()->GetURL(), profile()->GetPrefs()->GetString( prefs::kAcceptLanguages)))); EXPECT_FALSE(bubble_content_2.custom_link.empty()); @@ -157,7 +157,7 @@ TEST_F(ContentSettingBubbleModelTest, MediastreamMicAndCamera) { EXPECT_EQ(bubble_content.radio_group.radio_items[0], l10n_util::GetStringFUTF8( IDS_ALLOWED_MEDIASTREAM_MIC_AND_CAMERA_NO_ACTION, - secure_display::FormatUrlForSecurityDisplay( + url_formatter::FormatUrlForSecurityDisplay( security_origin, profile()->GetPrefs()->GetString( prefs::kAcceptLanguages)))); EXPECT_EQ(bubble_content.radio_group.radio_items[1], @@ -542,7 +542,7 @@ TEST_F(ContentSettingBubbleModelTest, MediastreamMic) { EXPECT_EQ(bubble_content.radio_group.radio_items[0], l10n_util::GetStringFUTF8( IDS_ALLOWED_MEDIASTREAM_MIC_NO_ACTION, - secure_display::FormatUrlForSecurityDisplay( + url_formatter::FormatUrlForSecurityDisplay( security_origin, profile()->GetPrefs()->GetString( prefs::kAcceptLanguages)))); EXPECT_EQ(bubble_content.radio_group.radio_items[1], @@ -576,7 +576,7 @@ TEST_F(ContentSettingBubbleModelTest, MediastreamMic) { EXPECT_EQ(new_bubble_content.radio_group.radio_items[0], l10n_util::GetStringFUTF8( IDS_BLOCKED_MEDIASTREAM_MIC_ASK, - secure_display::FormatUrlForSecurityDisplay( + url_formatter::FormatUrlForSecurityDisplay( security_origin, profile()->GetPrefs()->GetString( prefs::kAcceptLanguages)))); EXPECT_EQ(new_bubble_content.radio_group.radio_items[1], @@ -621,7 +621,7 @@ TEST_F(ContentSettingBubbleModelTest, MediastreamCamera) { EXPECT_EQ(bubble_content.radio_group.radio_items[0], l10n_util::GetStringFUTF8( IDS_ALLOWED_MEDIASTREAM_CAMERA_NO_ACTION, - secure_display::FormatUrlForSecurityDisplay( + url_formatter::FormatUrlForSecurityDisplay( security_origin, profile()->GetPrefs()->GetString( prefs::kAcceptLanguages)))); EXPECT_EQ(bubble_content.radio_group.radio_items[1], @@ -655,7 +655,7 @@ TEST_F(ContentSettingBubbleModelTest, MediastreamCamera) { EXPECT_EQ(new_bubble_content.radio_group.radio_items[0], l10n_util::GetStringFUTF8( IDS_BLOCKED_MEDIASTREAM_CAMERA_ASK, - secure_display::FormatUrlForSecurityDisplay( + url_formatter::FormatUrlForSecurityDisplay( security_origin, profile()->GetPrefs()->GetString( prefs::kAcceptLanguages)))); EXPECT_EQ(new_bubble_content.radio_group.radio_items[1], @@ -702,7 +702,7 @@ TEST_F(ContentSettingBubbleModelTest, AccumulateMediastreamMicAndCamera) { EXPECT_EQ(bubble_content.radio_group.radio_items[0], l10n_util::GetStringFUTF8( IDS_ALLOWED_MEDIASTREAM_MIC_NO_ACTION, - secure_display::FormatUrlForSecurityDisplay( + url_formatter::FormatUrlForSecurityDisplay( security_origin, profile()->GetPrefs()->GetString( prefs::kAcceptLanguages)))); EXPECT_EQ(bubble_content.radio_group.radio_items[1], @@ -734,7 +734,7 @@ TEST_F(ContentSettingBubbleModelTest, AccumulateMediastreamMicAndCamera) { EXPECT_EQ(new_bubble_content.radio_group.radio_items[0], l10n_util::GetStringFUTF8( IDS_ALLOWED_MEDIASTREAM_MIC_AND_CAMERA_NO_ACTION, - secure_display::FormatUrlForSecurityDisplay( + url_formatter::FormatUrlForSecurityDisplay( security_origin, profile()->GetPrefs()->GetString( prefs::kAcceptLanguages)))); EXPECT_EQ(new_bubble_content.radio_group.radio_items[1], diff --git a/chrome/browser/ui/passwords/manage_passwords_view_utils.cc b/chrome/browser/ui/passwords/manage_passwords_view_utils.cc index 717959e..11206be 100644 --- a/chrome/browser/ui/passwords/manage_passwords_view_utils.cc +++ b/chrome/browser/ui/passwords/manage_passwords_view_utils.cc @@ -8,7 +8,7 @@ #include "chrome/grit/chromium_strings.h" #include "chrome/grit/generated_resources.h" #include "components/password_manager/core/browser/affiliation_utils.h" -#include "components/secure_display/elide_url.h" +#include "components/url_formatter/elide_url.h" #include "net/base/net_util.h" #include "net/base/registry_controlled_domains/registry_controlled_domain.h" #include "ui/base/l10n/l10n_util.h" @@ -56,7 +56,7 @@ void GetSavePasswordDialogTitleTextAndLinkRange( net::registry_controlled_domains::INCLUDE_PRIVATE_REGISTRIES); if (target_domain_differs) { title_id = IDS_SAVE_PASSWORD_TITLE; - replacements.push_back(secure_display::FormatUrlForSecurityDisplay( + replacements.push_back(url_formatter::FormatUrlForSecurityDisplay( form_origin_url, std::string())); } diff --git a/chrome/browser/ui/search_engines/edit_search_engine_controller.cc b/chrome/browser/ui/search_engines/edit_search_engine_controller.cc index 29b4574..126af58 100644 --- a/chrome/browser/ui/search_engines/edit_search_engine_controller.cc +++ b/chrome/browser/ui/search_engines/edit_search_engine_controller.cc @@ -10,7 +10,7 @@ #include "chrome/browser/search_engines/template_url_service_factory.h" #include "components/search_engines/template_url.h" #include "components/search_engines/template_url_service.h" -#include "components/url_fixer/url_fixer.h" +#include "components/url_formatter/url_fixer.h" #include "content/public/browser/user_metrics.h" #include "url/gurl.h" @@ -142,7 +142,7 @@ std::string EditSearchEngineController::GetFixedUpURL( TemplateURLRef::SearchTermsArgs(base::ASCIIToUTF16("x")), TemplateURLServiceFactory::GetForProfile(profile_)->search_terms_data())); url::Parsed parts; - std::string scheme(url_fixer::SegmentURL(expanded_url, &parts)); + std::string scheme(url_formatter::SegmentURL(expanded_url, &parts)); if (!parts.scheme.is_valid()) url.insert(0, scheme + "://"); diff --git a/chrome/browser/ui/startup/startup_browser_creator.cc b/chrome/browser/ui/startup/startup_browser_creator.cc index cb97bd8..b0ed5aa 100644 --- a/chrome/browser/ui/startup/startup_browser_creator.cc +++ b/chrome/browser/ui/startup/startup_browser_creator.cc @@ -61,7 +61,7 @@ #include "components/google/core/browser/google_util.h" #include "components/search_engines/util.h" #include "components/signin/core/common/profile_management_switches.h" -#include "components/url_fixer/url_fixer.h" +#include "components/url_formatter/url_fixer.h" #include "content/public/browser/browser_thread.h" #include "content/public/browser/child_process_security_policy.h" #include "content/public/browser/navigation_controller.h" @@ -473,7 +473,7 @@ std::vector<GURL> StartupBrowserCreator::GetURLsFromCommandLine( // 'about' if the browser was started with a about:foo argument. if (!url.is_valid()) { base::ThreadRestrictions::ScopedAllowIO allow_io; - url = url_fixer::FixupRelativeFile(cur_dir, param); + url = url_formatter::FixupRelativeFile(cur_dir, param); } // Exclude dangerous schemes. if (url.is_valid()) { diff --git a/chrome/browser/ui/toolbar/toolbar_model_impl.cc b/chrome/browser/ui/toolbar/toolbar_model_impl.cc index ef83620..6f2c542 100644 --- a/chrome/browser/ui/toolbar/toolbar_model_impl.cc +++ b/chrome/browser/ui/toolbar/toolbar_model_impl.cc @@ -19,6 +19,7 @@ #include "components/omnibox/browser/autocomplete_classifier.h" #include "components/omnibox/browser/autocomplete_input.h" #include "components/omnibox/browser/autocomplete_match.h" +#include "components/url_formatter/url_formatter.h" #include "content/public/browser/cert_store.h" #include "content/public/browser/navigation_controller.h" #include "content/public/browser/navigation_entry.h" @@ -28,7 +29,6 @@ #include "content/public/common/ssl_status.h" #include "grit/components_scaled_resources.h" #include "grit/theme_resources.h" -#include "net/base/net_util.h" #include "net/cert/cert_status_flags.h" #include "net/cert/x509_certificate.h" #include "net/ssl/ssl_connection_status_flags.h" @@ -67,8 +67,9 @@ base::string16 ToolbarModelImpl::GetFormattedURL(size_t* prefix_end) const { // and pastes it into another program, that program may think the URL ends at // the space. return AutocompleteInput::FormattedStringWithEquivalentMeaning( - url, net::FormatUrl(url, languages, net::kFormatUrlOmitAll, - net::UnescapeRule::NORMAL, NULL, prefix_end, NULL), + url, url_formatter::FormatUrl( + url, languages, url_formatter::kFormatUrlOmitAll, + net::UnescapeRule::NORMAL, nullptr, prefix_end, nullptr), ChromeAutocompleteSchemeClassifier(profile)); } diff --git a/chrome/browser/ui/views/bookmarks/bookmark_bar_view.cc b/chrome/browser/ui/views/bookmarks/bookmark_bar_view.cc index a5700d8..9e26c78 100644 --- a/chrome/browser/ui/views/bookmarks/bookmark_bar_view.cc +++ b/chrome/browser/ui/views/bookmarks/bookmark_bar_view.cc @@ -55,7 +55,7 @@ #include "components/metrics/metrics_service.h" #include "components/omnibox/browser/omnibox_popup_model.h" #include "components/omnibox/browser/omnibox_view.h" -#include "components/secure_display/elide_url.h" +#include "components/url_formatter/elide_url.h" #include "content/public/browser/notification_details.h" #include "content/public/browser/notification_source.h" #include "content/public/browser/page_navigator.h" @@ -722,7 +722,7 @@ base::string16 BookmarkBarView::CreateToolTipForURLAndTitle( std::string languages = profile->GetPrefs()->GetString( prefs::kAcceptLanguages); base::string16 elided_url( - secure_display::ElideUrl(url, tt_fonts, max_width, languages)); + url_formatter::ElideUrl(url, tt_fonts, max_width, languages)); elided_url = base::i18n::GetDisplayStringInLTRDirectionality(elided_url); result.append(elided_url); } diff --git a/chrome/browser/ui/views/bookmarks/bookmark_editor_view.cc b/chrome/browser/ui/views/bookmarks/bookmark_editor_view.cc index 0ef71fe..a591923 100644 --- a/chrome/browser/ui/views/bookmarks/bookmark_editor_view.cc +++ b/chrome/browser/ui/views/bookmarks/bookmark_editor_view.cc @@ -20,7 +20,7 @@ #include "components/bookmarks/browser/bookmark_utils.h" #include "components/constrained_window/constrained_window_views.h" #include "components/history/core/browser/history_service.h" -#include "components/url_fixer/url_fixer.h" +#include "components/url_formatter/url_fixer.h" #include "components/user_prefs/user_prefs.h" #include "ui/accessibility/ax_view_state.h" #include "ui/base/l10n/l10n_util.h" @@ -440,7 +440,8 @@ void BookmarkEditorView::Reset() { GURL BookmarkEditorView::GetInputURL() const { if (details_.GetNodeType() == BookmarkNode::FOLDER) return GURL(); - return url_fixer::FixupURL(base::UTF16ToUTF8(url_tf_->text()), std::string()); + return url_formatter::FixupURL(base::UTF16ToUTF8(url_tf_->text()), + std::string()); } void BookmarkEditorView::UserInputChanged() { diff --git a/chrome/browser/ui/views/status_bubble_views.cc b/chrome/browser/ui/views/status_bubble_views.cc index 608c45c..52115f4 100644 --- a/chrome/browser/ui/views/status_bubble_views.cc +++ b/chrome/browser/ui/views/status_bubble_views.cc @@ -14,8 +14,8 @@ #include "base/strings/utf_string_conversions.h" #include "base/thread_task_runner_handle.h" #include "chrome/browser/themes/theme_properties.h" -#include "components/secure_display/elide_url.h" -#include "net/base/net_util.h" +#include "components/url_formatter/elide_url.h" +#include "components/url_formatter/url_formatter.h" #include "third_party/skia/include/core/SkPaint.h" #include "third_party/skia/include/core/SkRRect.h" #include "ui/base/theme_provider.h" @@ -695,7 +695,7 @@ void StatusBubbleViews::SetURL(const GURL& url, const std::string& languages) { int text_width = static_cast<int>(popup_bounds.width() - (kShadowThickness * 2) - kTextPositionX - kTextHorizPadding - 1); url_text_ = - secure_display::ElideUrl(url, gfx::FontList(), text_width, languages); + url_formatter::ElideUrl(url, gfx::FontList(), text_width, languages); // An URL is always treated as a left-to-right string. On right-to-left UIs // we need to explicitly mark the URL as LTR to make sure it is displayed @@ -711,7 +711,8 @@ void StatusBubbleViews::SetURL(const GURL& url, const std::string& languages) { // size (shrinking or expanding). Otherwise delay. if (is_expanded_ && !url.is_empty()) { ExpandBubble(); - } else if (net::FormatUrl(url, languages).length() > url_text_.length()) { + } else if (url_formatter::FormatUrl(url, languages).length() > + url_text_.length()) { base::ThreadTaskRunnerHandle::Get()->PostDelayedTask( FROM_HERE, base::Bind(&StatusBubbleViews::ExpandBubble, expand_timer_factory_.GetWeakPtr()), @@ -858,7 +859,7 @@ void StatusBubbleViews::ExpandBubble() { gfx::Rect popup_bounds = popup_->GetWindowBoundsInScreen(); int max_status_bubble_width = GetMaxStatusBubbleWidth(); const gfx::FontList font_list; - url_text_ = secure_display::ElideUrl(url_, font_list, max_status_bubble_width, + url_text_ = url_formatter::ElideUrl(url_, font_list, max_status_bubble_width, languages_); int expanded_bubble_width = std::max(GetStandardStatusBubbleWidth(), diff --git a/chrome/browser/ui/views/website_settings/permissions_bubble_view.cc b/chrome/browser/ui/views/website_settings/permissions_bubble_view.cc index e885ebf..8f27164 100644 --- a/chrome/browser/ui/views/website_settings/permissions_bubble_view.cc +++ b/chrome/browser/ui/views/website_settings/permissions_bubble_view.cc @@ -18,7 +18,7 @@ #include "chrome/browser/ui/website_settings/permission_bubble_request.h" #include "chrome/common/pref_names.h" #include "chrome/grit/generated_resources.h" -#include "net/base/net_util.h" +#include "components/url_formatter/url_formatter.h" #include "ui/accessibility/ax_view_state.h" #include "ui/base/l10n/l10n_util.h" #include "ui/base/models/combobox_model.h" @@ -216,12 +216,11 @@ PermissionsBubbleDelegateView::PermissionsBubbleDelegateView( SetLayoutManager(new views::BoxLayout( views::BoxLayout::kVertical, kBubbleOuterMargin, 0, kItemMajorSpacing)); - hostname_ = net::FormatUrl(requests[0]->GetRequestingHostname(), - languages, - net::kFormatUrlOmitUsernamePassword | - net::kFormatUrlOmitTrailingSlashOnBareHostname, - net::UnescapeRule::SPACES, - nullptr, nullptr, nullptr); + hostname_ = url_formatter::FormatUrl( + requests[0]->GetRequestingHostname(), languages, + url_formatter::kFormatUrlOmitUsernamePassword | + url_formatter::kFormatUrlOmitTrailingSlashOnBareHostname, + net::UnescapeRule::SPACES, nullptr, nullptr, nullptr); ui::ResourceBundle& bundle = ui::ResourceBundle::GetSharedInstance(); for (size_t index = 0; index < requests.size(); index++) { diff --git a/chrome/browser/ui/webui/history_ui.cc b/chrome/browser/ui/webui/history_ui.cc index 0fd41b3..69de94b 100644 --- a/chrome/browser/ui/webui/history_ui.cc +++ b/chrome/browser/ui/webui/history_ui.cc @@ -46,13 +46,13 @@ #include "components/search/search.h" #include "components/signin/core/browser/signin_manager.h" #include "components/sync_driver/device_info.h" +#include "components/url_formatter/url_formatter.h" #include "content/public/browser/url_data_source.h" #include "content/public/browser/web_ui.h" #include "content/public/browser/web_ui_data_source.h" #include "grit/browser_resources.h" #include "grit/theme_resources.h" #include "net/base/escape.h" -#include "net/base/net_util.h" #include "sync/protocol/history_delete_directive_specifics.pb.h" #include "ui/base/l10n/l10n_util.h" #include "ui/base/l10n/time_format.h" @@ -352,7 +352,8 @@ scoped_ptr<base::DictionaryValue> BrowsingHistoryHandler::HistoryEntry::ToValue( scoped_ptr<base::DictionaryValue> result(new base::DictionaryValue()); SetUrlAndTitle(result.get()); - base::string16 domain = net::IDNToUnicode(url.host(), accept_languages); + base::string16 domain = + url_formatter::IDNToUnicode(url.host(), accept_languages); // When the domain is empty, use the scheme instead. This allows for a // sensible treatment of e.g. file: URLs when group by domain is on. if (domain.empty()) diff --git a/chrome/browser/ui/webui/net_internals/net_internals_ui.cc b/chrome/browser/ui/webui/net_internals/net_internals_ui.cc index a1b971a..8a60bf2 100644 --- a/chrome/browser/ui/webui/net_internals/net_internals_ui.cc +++ b/chrome/browser/ui/webui/net_internals/net_internals_ui.cc @@ -48,7 +48,7 @@ #include "components/data_reduction_proxy/core/browser/data_reduction_proxy_service.h" #include "components/data_reduction_proxy/core/common/data_reduction_proxy_event_store.h" #include "components/onc/onc_constants.h" -#include "components/url_fixer/url_fixer.h" +#include "components/url_formatter/url_fixer.h" #include "components/version_info/version_info.h" #include "content/public/browser/browser_thread.h" #include "content/public/browser/notification_details.h" diff --git a/chrome/browser/ui/webui/options/core_options_handler.cc b/chrome/browser/ui/webui/options/core_options_handler.cc index 9682bb95..77a4acd 100644 --- a/chrome/browser/ui/webui/options/core_options_handler.cc +++ b/chrome/browser/ui/webui/options/core_options_handler.cc @@ -23,7 +23,7 @@ #include "chrome/grit/chromium_strings.h" #include "chrome/grit/generated_resources.h" #include "chrome/grit/locale_settings.h" -#include "components/url_fixer/url_fixer.h" +#include "components/url_formatter/url_fixer.h" #include "content/public/browser/notification_details.h" #include "content/public/browser/notification_types.h" #include "content/public/browser/user_metrics.h" @@ -575,7 +575,7 @@ void CoreOptionsHandler::HandleSetPref(const base::ListValue* args, NOTREACHED(); return; } - GURL fixed = url_fixer::FixupURL(original, std::string()); + GURL fixed = url_formatter::FixupURL(original, std::string()); temp_value.reset(new base::StringValue(fixed.spec())); value = temp_value.get(); break; diff --git a/chrome/browser/ui/webui/options/startup_pages_handler.cc b/chrome/browser/ui/webui/options/startup_pages_handler.cc index c8ebc9a..6f9946c 100644 --- a/chrome/browser/ui/webui/options/startup_pages_handler.cc +++ b/chrome/browser/ui/webui/options/startup_pages_handler.cc @@ -21,7 +21,7 @@ #include "components/omnibox/browser/autocomplete_controller.h" #include "components/omnibox/browser/autocomplete_input.h" #include "components/omnibox/browser/autocomplete_result.h" -#include "components/url_fixer/url_fixer.h" +#include "components/url_formatter/url_fixer.h" #include "content/public/browser/notification_details.h" #include "content/public/browser/web_ui.h" @@ -163,7 +163,7 @@ void StartupPagesHandler::AddStartupPage(const base::ListValue* args) { std::string url_string; CHECK(args->GetString(0, &url_string)); - GURL url = url_fixer::FixupURL(url_string, std::string()); + GURL url = url_formatter::FixupURL(url_string, std::string()); if (!url.is_valid()) return; @@ -188,7 +188,7 @@ void StartupPagesHandler::EditStartupPage(const base::ListValue* args) { return; } - fixed_url = url_fixer::FixupURL(url_string, std::string()); + fixed_url = url_formatter::FixupURL(url_string, std::string()); if (!fixed_url.is_empty()) { std::vector<GURL> urls = startup_custom_pages_table_model_->GetURLs(); urls[index] = fixed_url; diff --git a/chrome/chrome_browser.gypi b/chrome/chrome_browser.gypi index 405dd9d..342bf07 100644 --- a/chrome/chrome_browser.gypi +++ b/chrome/chrome_browser.gypi @@ -3195,7 +3195,6 @@ '../components/components.gyp:translate_core_common', '../components/components.gyp:update_client', '../components/components.gyp:undo_component', - '../components/components.gyp:url_fixer', '../components/components.gyp:user_prefs', '../components/components.gyp:wallpaper', '../components/components_strings.gyp:components_strings', @@ -3207,6 +3206,7 @@ '../components/components.gyp:webdata_common', '../components/components.gyp:webdata_services', '../components/mime_util/mime_util.gyp:mime_util', + '../components/url_formatter/url_formatter.gyp:url_formatter', '../content/content.gyp:content_browser', '../content/content.gyp:content_common', '../courgette/courgette.gyp:courgette_lib', diff --git a/chrome/chrome_browser_ui.gypi b/chrome/chrome_browser_ui.gypi index 2f8638e..6da6b83 100644 --- a/chrome/chrome_browser_ui.gypi +++ b/chrome/chrome_browser_ui.gypi @@ -2747,13 +2747,13 @@ '../components/components.gyp:omnibox_common', '../components/components.gyp:onc_component', '../components/components.gyp:password_manager_core_browser', - '../components/components.gyp:secure_display', '../components/components.gyp:sync_driver', '../components/components.gyp:toolbar', '../components/components.gyp:ui_zoom', '../components/components.gyp:update_client', '../components/components_resources.gyp:components_resources', '../components/components_strings.gyp:components_strings', + '../components/url_formatter/url_formatter.gyp:url_formatter', '../content/content.gyp:content_browser', '../content/content.gyp:content_common', '../crypto/crypto.gyp:crypto', @@ -2804,7 +2804,6 @@ 'installer_util', '../components/components.gyp:app_modal', '../components/components.gyp:autofill_content_risk_proto', - '../components/components.gyp:secure_display', '../components/components.gyp:translate_content_common', '../content/app/resources/content_resources.gyp:content_resources', '../media/media.gyp:media', diff --git a/chrome/chrome_common.gypi b/chrome/chrome_common.gypi index c9e5ea1..1bf051c 100644 --- a/chrome/chrome_common.gypi +++ b/chrome/chrome_common.gypi @@ -345,6 +345,7 @@ '<(DEPTH)/components/components.gyp:translate_core_common', '<(DEPTH)/components/components.gyp:variations', '<(DEPTH)/components/components.gyp:version_info', + '<(DEPTH)/components/url_formatter/url_formatter.gyp:url_formatter', '<(DEPTH)/content/content.gyp:content_common', '<(DEPTH)/crypto/crypto.gyp:crypto', '<(DEPTH)/net/net.gyp:net', diff --git a/chrome/chrome_utility.gypi b/chrome/chrome_utility.gypi index 76cdbc8..6f6b24c 100644 --- a/chrome/chrome_utility.gypi +++ b/chrome/chrome_utility.gypi @@ -105,7 +105,7 @@ '../components/components_strings.gyp:components_strings', '../components/components.gyp:safe_json_parser_message_filter', '../components/components.gyp:search_engines', - '../components/components.gyp:url_fixer', + '../components/url_formatter/url_formatter.gyp:url_formatter', '../content/content.gyp:content_common', '../content/content.gyp:content_utility', '../media/media.gyp:media', diff --git a/chrome/common/BUILD.gn b/chrome/common/BUILD.gn index 382bd64..273b197 100644 --- a/chrome/common/BUILD.gn +++ b/chrome/common/BUILD.gn @@ -71,6 +71,7 @@ static_library("common") { "//components/omnibox/common", "//components/policy:policy_component_common", "//components/translate/core/common", + "//components/url_formatter", "//components/variations", "//components/version_info", "//content/public/common", diff --git a/chrome/common/DEPS b/chrome/common/DEPS index 6eb3de4..35f48fa 100644 --- a/chrome/common/DEPS +++ b/chrome/common/DEPS @@ -19,6 +19,7 @@ include_rules = [ "+components/policy/core/common", "+components/signin/core/common", "+components/translate/core/common", + "+components/url_formatter", "+components/version_info", "+extensions/common", "+gin/public", # For profiling.cc diff --git a/chrome/common/localized_error.cc b/chrome/common/localized_error.cc index 2de84ac..b7c73ee 100644 --- a/chrome/common/localized_error.cc +++ b/chrome/common/localized_error.cc @@ -18,9 +18,9 @@ #include "chrome/grit/generated_resources.h" #include "components/error_page/common/error_page_params.h" #include "components/error_page/common/net_error_info.h" +#include "components/url_formatter/url_formatter.h" #include "net/base/escape.h" #include "net/base/net_errors.h" -#include "net/base/net_util.h" #include "third_party/WebKit/public/platform/WebURLError.h" #include "ui/base/l10n/l10n_util.h" #include "ui/base/webui/web_ui_util.h" @@ -555,9 +555,9 @@ void LocalizedError::GetStrings(int error_code, options.suggestions = SUGGEST_NONE; } - base::string16 failed_url_string(net::FormatUrl( - failed_url, accept_languages, net::kFormatUrlOmitNothing, - net::UnescapeRule::NORMAL, NULL, NULL, NULL)); + base::string16 failed_url_string(url_formatter::FormatUrl( + failed_url, accept_languages, url_formatter::kFormatUrlOmitNothing, + net::UnescapeRule::NORMAL, nullptr, nullptr, nullptr)); // URLs are always LTR. if (base::i18n::IsRTL()) base::i18n::WrapStringWithLTRFormatting(&failed_url_string); @@ -594,8 +594,8 @@ void LocalizedError::GetStrings(int error_code, l10n_util::GetStringUTF16(options.summary_resource_id)); } summary->SetString("failedUrl", failed_url_string); - summary->SetString("hostName", net::IDNToUnicode(failed_url.host(), - accept_languages)); + summary->SetString("hostName", url_formatter::IDNToUnicode(failed_url.host(), + accept_languages)); summary->SetString("productName", l10n_util::GetStringUTF16(IDS_PRODUCT_NAME)); diff --git a/chrome/common/net/url_util.cc b/chrome/common/net/url_util.cc index 9a62afd..76354b0 100644 --- a/chrome/common/net/url_util.cc +++ b/chrome/common/net/url_util.cc @@ -5,8 +5,8 @@ #include "chrome/common/net/url_util.h" #include "base/strings/utf_string_conversions.h" +#include "components/url_formatter/url_formatter.h" #include "net/base/escape.h" -#include "net/base/net_util.h" #include "ui/base/clipboard/scoped_clipboard_writer.h" #include "url/gurl.h" #include "url/url_constants.h" @@ -19,10 +19,12 @@ void WriteURLToClipboard(const GURL& url, const std::string& languages) { // Unescaping path and query is not a good idea because other applications // may not encode non-ASCII characters in UTF-8. See crbug.com/2820. - base::string16 text = url.SchemeIs(url::kMailToScheme) ? - base::ASCIIToUTF16(url.path()) : - net::FormatUrl(url, languages, net::kFormatUrlOmitNothing, - net::UnescapeRule::NONE, NULL, NULL, NULL); + base::string16 text = + url.SchemeIs(url::kMailToScheme) + ? base::ASCIIToUTF16(url.path()) + : url_formatter::FormatUrl( + url, languages, url_formatter::kFormatUrlOmitNothing, + net::UnescapeRule::NONE, nullptr, nullptr, nullptr); ui::ScopedClipboardWriter scw(ui::CLIPBOARD_TYPE_COPY_PASTE); scw.WriteURL(text); diff --git a/chrome/common/net/x509_certificate_model.cc b/chrome/common/net/x509_certificate_model.cc index ee502a1..1a95b7a 100644 --- a/chrome/common/net/x509_certificate_model.cc +++ b/chrome/common/net/x509_certificate_model.cc @@ -10,7 +10,7 @@ #include "base/strings/utf_string_conversions.h" #include "chrome/grit/generated_resources.h" -#include "net/base/net_util.h" +#include "components/url_formatter/url_formatter.h" #include "ui/base/l10n/l10n_util.h" namespace x509_certificate_model { @@ -21,7 +21,7 @@ std::string ProcessIDN(const std::string& input) { input16.reserve(input.length()); input16.insert(input16.end(), input.begin(), input.end()); - base::string16 output16 = net::IDNToUnicode(input, std::string()); + base::string16 output16 = url_formatter::IDNToUnicode(input, std::string()); if (input16 == output16) return input; // Input did not contain any encoded data. diff --git a/chrome/utility/BUILD.gn b/chrome/utility/BUILD.gn index edcf002..4fe08e4 100644 --- a/chrome/utility/BUILD.gn +++ b/chrome/utility/BUILD.gn @@ -21,7 +21,7 @@ static_library("utility") { "//components/safe_json:safe_json_parser_message_filter", "//components/search_engines", "//components/strings", - "//components/url_fixer", + "//components/url_formatter", "//content/public/common", "//content/public/utility", "//media", diff --git a/chrome/utility/importer/bookmarks_file_importer.cc b/chrome/utility/importer/bookmarks_file_importer.cc index 1ae2fb1..488b2be 100644 --- a/chrome/utility/importer/bookmarks_file_importer.cc +++ b/chrome/utility/importer/bookmarks_file_importer.cc @@ -12,7 +12,7 @@ #include "chrome/grit/generated_resources.h" #include "chrome/utility/importer/bookmark_html_reader.h" #include "components/favicon_base/favicon_usage_data.h" -#include "components/url_fixer/url_fixer.h" +#include "components/url_formatter/url_fixer.h" #include "content/public/common/url_constants.h" namespace { @@ -51,7 +51,7 @@ bool CanImportURL(const GURL& url) { url.host() == chrome::kChromeUIAboutHost) return true; - GURL fixed_url(url_fixer::FixupURL(url.spec(), std::string())); + GURL fixed_url(url_formatter::FixupURL(url.spec(), std::string())); for (size_t i = 0; i < chrome::kNumberOfChromeHostURLs; ++i) { if (fixed_url.DomainIs(chrome::kChromeHostURLs[i])) return true; diff --git a/components/BUILD.gn b/components/BUILD.gn index bb6f9e9..7fddcb6 100644 --- a/components/BUILD.gn +++ b/components/BUILD.gn @@ -92,7 +92,6 @@ group("all_components") { "//components/search", "//components/search_engines", "//components/search_provider_logos", - "//components/secure_display", "//components/security_interstitials/core", "//components/sessions", "//components/signin/core/browser", @@ -110,7 +109,7 @@ group("all_components") { "//components/undo", "//components/update_client", "//components/upload_list", - "//components/url_fixer", + "//components/url_formatter", "//components/url_matcher", "//components/user_manager", "//components/user_prefs", @@ -321,7 +320,7 @@ test("components_unittests") { "//components/omnibox/browser:unit_tests", "//components/packed_ct_ev_whitelist:unit_tests", "//components/undo:unit_tests", - "//components/secure_display:unit_tests", + "//components/url_formatter:unit_tests", "//components/update_client:unit_tests", "//components/upload_list:unit_tests", "//components/variations:unit_tests", diff --git a/components/OWNERS b/components/OWNERS index 2e358a97..25ee959 100644 --- a/components/OWNERS +++ b/components/OWNERS @@ -299,7 +299,7 @@ per-file user_manager.gypi=dpolukhin@chromium.org per-file user_manager.gypi=dzhioev@chromium.org per-file user_manager.gypi=nkostylev@chromium.org -per-file url_fixer.gypi=pkasting@chromium.org +per-file url_formatter.gypi=pkasting@chromium.org per-file user_prefs.gypi=battre@chromium.org per-file user_prefs.gypi=bauerb@chromium.org diff --git a/components/app_modal.gypi b/components/app_modal.gypi index 8f85d8cb..045b1ec 100644 --- a/components/app_modal.gypi +++ b/components/app_modal.gypi @@ -7,10 +7,11 @@ 'target_name': 'app_modal', 'type': 'static_library', 'dependencies': [ - '../content/content.gyp:content_browser', - '../content/content.gyp:content_common', + '../content/content.gyp:content_browser', + '../content/content.gyp:content_common', '../skia/skia.gyp:skia', 'components_strings.gyp:components_strings', + 'url_formatter/url_formatter.gyp:url_formatter', ], 'include_dirs': [ '..', diff --git a/components/app_modal/BUILD.gn b/components/app_modal/BUILD.gn index 942b723..9e5bdb5 100644 --- a/components/app_modal/BUILD.gn +++ b/components/app_modal/BUILD.gn @@ -23,6 +23,7 @@ static_library("app_modal") { "//base", "//base:i18n", "//components/strings", + "//components/url_formatter", "//content/public/browser", "//content/public/common", "//net", diff --git a/components/app_modal/DEPS b/components/app_modal/DEPS index bc65d1f..aa04b80 100644 --- a/components/app_modal/DEPS +++ b/components/app_modal/DEPS @@ -1,4 +1,5 @@ include_rules = [ + "+components/url_formatter", "+content/public/browser", "+content/public/common", "+grit/components_strings.h", diff --git a/components/app_modal/javascript_dialog_manager.cc b/components/app_modal/javascript_dialog_manager.cc index f426e4a..ccf566a 100644 --- a/components/app_modal/javascript_dialog_manager.cc +++ b/components/app_modal/javascript_dialog_manager.cc @@ -12,6 +12,7 @@ #include "components/app_modal/javascript_dialog_extensions_client.h" #include "components/app_modal/javascript_native_dialog_factory.h" #include "components/app_modal/native_app_modal_dialog.h" +#include "components/url_formatter/url_formatter.h" #include "content/public/common/javascript_message_type.h" #include "grit/components_strings.h" #include "net/base/net_util.h" @@ -209,7 +210,7 @@ base::string16 JavaScriptDialogManager::GetTitle( // Otherwise, return the formatted URL. // In this case, force URL to have LTR directionality. - base::string16 url_string = net::FormatUrl(origin_url, accept_lang); + base::string16 url_string = url_formatter::FormatUrl(origin_url, accept_lang); return l10n_util::GetStringFUTF16( is_alert ? IDS_JAVASCRIPT_ALERT_TITLE : IDS_JAVASCRIPT_MESSAGEBOX_TITLE, diff --git a/components/bookmarks.gypi b/components/bookmarks.gypi index a0bef4a..00b45b7 100644 --- a/components/bookmarks.gypi +++ b/components/bookmarks.gypi @@ -27,6 +27,7 @@ 'pref_registry', 'query_parser', 'startup_metric_utils', + 'url_formatter/url_formatter.gyp:url_formatter', ], 'sources': [ 'bookmarks/browser/base_bookmark_model_observer.cc', diff --git a/components/bookmarks/DEPS b/components/bookmarks/DEPS index bc82e28..75997b1 100644 --- a/components/bookmarks/DEPS +++ b/components/bookmarks/DEPS @@ -4,6 +4,7 @@ include_rules = [ "+components/pref_registry", "+components/query_parser", "+components/startup_metric_utils", + "+components/url_formatter", "+grit/components_strings.h", "+jni", "+net/base", diff --git a/components/bookmarks/browser/BUILD.gn b/components/bookmarks/browser/BUILD.gn index 14ed172..03aaee9 100644 --- a/components/bookmarks/browser/BUILD.gn +++ b/components/bookmarks/browser/BUILD.gn @@ -50,6 +50,7 @@ source_set("browser") { "//components/query_parser", "//components/startup_metric_utils", "//components/strings", + "//components/url_formatter", "//net", "//third_party/icu", "//ui/base", diff --git a/components/bookmarks/browser/bookmark_utils.cc b/components/bookmarks/browser/bookmark_utils.cc index a815d1c..6d60a4f 100644 --- a/components/bookmarks/browser/bookmark_utils.cc +++ b/components/bookmarks/browser/bookmark_utils.cc @@ -25,7 +25,7 @@ #include "components/bookmarks/common/bookmark_pref_names.h" #include "components/pref_registry/pref_registry_syncable.h" #include "components/query_parser/query_parser.h" -#include "net/base/net_util.h" +#include "components/url_formatter/url_formatter.h" #include "ui/base/clipboard/clipboard.h" #include "ui/base/models/tree_node_iterator.h" #include "url/gurl.h" @@ -96,13 +96,14 @@ bool DoesBookmarkTextContainWords(const base::string16& text, bool DoesBookmarkContainWords(const BookmarkNode* node, const std::vector<base::string16>& words, const std::string& languages) { - return - DoesBookmarkTextContainWords(node->GetTitle(), words) || - DoesBookmarkTextContainWords( - base::UTF8ToUTF16(node->url().spec()), words) || - DoesBookmarkTextContainWords(net::FormatUrl( - node->url(), languages, net::kFormatUrlOmitNothing, - net::UnescapeRule::NORMAL, NULL, NULL, NULL), words); + return DoesBookmarkTextContainWords(node->GetTitle(), words) || + DoesBookmarkTextContainWords(base::UTF8ToUTF16(node->url().spec()), + words) || + DoesBookmarkTextContainWords( + url_formatter::FormatUrl( + node->url(), languages, url_formatter::kFormatUrlOmitNothing, + net::UnescapeRule::NORMAL, NULL, NULL, NULL), + words); } // This is used with a tree iterator to skip subtrees which are not visible. @@ -516,11 +517,11 @@ base::string16 CleanUpUrlForMatching( const std::string& languages, base::OffsetAdjuster::Adjustments* adjustments) { base::OffsetAdjuster::Adjustments tmp_adjustments; - return base::i18n::ToLower(net::FormatUrlWithAdjustments( + return base::i18n::ToLower(url_formatter::FormatUrlWithAdjustments( GURL(TruncateUrl(gurl.spec())), languages, - net::kFormatUrlOmitUsernamePassword, - net::UnescapeRule::SPACES | net::UnescapeRule::URL_SPECIAL_CHARS, - NULL, NULL, adjustments ? adjustments : &tmp_adjustments)); + url_formatter::kFormatUrlOmitUsernamePassword, + net::UnescapeRule::SPACES | net::UnescapeRule::URL_SPECIAL_CHARS, NULL, + NULL, adjustments ? adjustments : &tmp_adjustments)); } base::string16 CleanUpTitleForMatching(const base::string16& title) { diff --git a/components/bookmarks/browser/bookmark_utils.h b/components/bookmarks/browser/bookmark_utils.h index 57bd4bb..32e72d2 100644 --- a/components/bookmarks/browser/bookmark_utils.h +++ b/components/bookmarks/browser/bookmark_utils.h @@ -112,12 +112,12 @@ void AddIfNotBookmarked(BookmarkModel* model, void RemoveAllBookmarks(BookmarkModel* model, const GURL& url); // Truncates an overly-long URL, unescapes it and interprets the characters -// as UTF-8 (both via net::FormatUrl()), and lower-cases it, returning the -// result. |languages| is passed to net::FormatUrl(). |adjustments|, if -// non-NULL, is set to reflect the transformations the URL spec underwent to -// become the return value. If a caller computes offsets (e.g., for the -// position of matched text) in this cleaned-up string, it can use -// |adjustments| to calculate the location of these offsets in the original +// as UTF-8 (both via url_formatter::FormatUrl()), and lower-cases it, returning +// the result. |languages| is passed to url_formatter::FormatUrl(). +// |adjustments|, if non-NULL, is set to reflect the transformations the URL +// spec underwent to become the return value. If a caller computes offsets +// (e.g., for the position of matched text) in this cleaned-up string, it can +// use |adjustments| to calculate the location of these offsets in the original // string (via base::OffsetAdjuster::UnadjustOffsets()). This is useful if // later the original string gets formatted in a different way for displaying. // In this case, knowing the offsets in the original string will allow them to diff --git a/components/components.gyp b/components/components.gyp index 21181b1..e618f9c 100644 --- a/components/components.gyp +++ b/components/components.gyp @@ -62,7 +62,6 @@ 'search.gypi', 'search_engines.gypi', 'search_provider_logos.gypi', - 'secure_display.gypi', 'security_interstitials.gypi', 'sessions.gypi', 'signin.gypi', @@ -75,7 +74,6 @@ 'undo.gypi', 'update_client.gypi', 'upload_list.gypi', - 'url_fixer.gypi', 'url_matcher.gypi', 'user_prefs.gypi', 'variations.gypi', diff --git a/components/components_tests.gyp b/components/components_tests.gyp index 2ab3b6a..475b750 100644 --- a/components/components_tests.gyp +++ b/components/components_tests.gyp @@ -465,7 +465,6 @@ 'proximity_auth/bluetooth_throttler_impl_unittest.cc', 'proximity_auth/client_impl_unittest.cc', 'proximity_auth/connection_unittest.cc', - 'proximity_auth/device_to_device_operations_unittest.cc', 'proximity_auth/cryptauth/base64url_unittest.cc', 'proximity_auth/cryptauth/cryptauth_access_token_fetcher_impl_unittest.cc', 'proximity_auth/cryptauth/cryptauth_api_call_flow_unittest.cc', @@ -477,6 +476,7 @@ 'proximity_auth/cryptauth/fake_secure_message_delegate_unittest.cc', 'proximity_auth/cryptauth/sync_scheduler_impl_unittest.cc', 'proximity_auth/device_to_device_operations_unittest.cc', + 'proximity_auth/device_to_device_operations_unittest.cc', 'proximity_auth/device_to_device_secure_context_unittest.cc', 'proximity_auth/logging/logging_unittest.cc', 'proximity_auth/proximity_auth_system_unittest.cc', @@ -548,9 +548,6 @@ 'search_provider_logos/logo_cache_unittest.cc', 'search_provider_logos/logo_tracker_unittest.cc', ], - 'secure_display_unittest_sources': [ - 'secure_display/elide_url_unittest.cc', - ], 'sessions_unittest_sources': [ 'sessions/content/content_serialized_navigation_builder_unittest.cc', 'sessions/content/content_serialized_navigation_driver_unittest.cc', @@ -628,8 +625,10 @@ 'upload_list_unittest_sources': [ 'upload_list/upload_list_unittest.cc', ], - 'url_fixer_unittest_sources': [ - 'url_fixer/url_fixer_unittest.cc', + 'url_formatter_unittest_sources': [ + 'url_formatter/elide_url_unittest.cc', + 'url_formatter/url_fixer_unittest.cc', + 'url_formatter/url_formatter_unittest.cc', ], 'url_matcher_unittest_sources': [ 'url_matcher/regex_set_matcher_unittest.cc', @@ -762,7 +761,6 @@ '<@(search_unittest_sources)', '<@(search_engines_unittest_sources)', '<@(search_provider_logos_unittest_sources)', - '<@(secure_display_unittest_sources)', '<@(sessions_unittest_sources)', '<@(signin_unittest_sources)', '<@(suggestions_unittest_sources)', @@ -771,7 +769,7 @@ '<@(undo_unittest_sources)', '<@(update_client_unittest_sources)', '<@(upload_list_unittest_sources)', - '<@(url_fixer_unittest_sources)', + '<@(url_formatter_unittest_sources)', '<@(url_matcher_unittest_sources)', '<@(variations_unittest_sources)', '<@(wallpaper_unittest_sources)', @@ -875,7 +873,6 @@ 'components.gyp:search_engines', 'components.gyp:search_engines_test_support', 'components.gyp:search_provider_logos', - 'components.gyp:secure_display', 'components.gyp:sessions_test_support', 'components.gyp:signin_core_browser', 'components.gyp:signin_core_browser_test_support', @@ -889,7 +886,6 @@ 'components.gyp:update_client', 'components.gyp:update_client_test_support', 'components.gyp:upload_list', - 'components.gyp:url_fixer', 'components.gyp:variations', 'components.gyp:variations_http_provider', 'components.gyp:wallpaper', @@ -899,6 +895,7 @@ 'components_strings.gyp:components_strings', 'components_tests_pak', 'mime_util/mime_util.gyp:mime_util', + 'url_formatter/url_formatter.gyp:url_formatter', ], 'conditions': [ ['enable_rlz_support==1', { diff --git a/components/content_settings.gypi b/components/content_settings.gypi index 0242088..c4ea3a2 100644 --- a/components/content_settings.gypi +++ b/components/content_settings.gypi @@ -16,6 +16,7 @@ 'content_settings_core_common', 'plugins_common', 'pref_registry', + 'url_formatter/url_formatter.gyp:url_formatter', ], 'variables': { 'enable_wexit_time_destructors': 1, }, 'include_dirs': [ diff --git a/components/content_settings/core/browser/BUILD.gn b/components/content_settings/core/browser/BUILD.gn index 6db040a..85358c0 100644 --- a/components/content_settings/core/browser/BUILD.gn +++ b/components/content_settings/core/browser/BUILD.gn @@ -48,6 +48,7 @@ static_library("browser") { "//components/content_settings/core/common", "//components/plugins/common", "//components/pref_registry:pref_registry", + "//components/url_formatter", "//net", "//url", ] diff --git a/components/content_settings/core/browser/DEPS b/components/content_settings/core/browser/DEPS index ee92881..106fea2 100644 --- a/components/content_settings/core/browser/DEPS +++ b/components/content_settings/core/browser/DEPS @@ -4,6 +4,7 @@ include_rules = [ "+components/keyed_service/core", "+components/plugins/common", "+components/pref_registry", + "+components/url_formatter", "+net/base", "+net/cookies", ] diff --git a/components/content_settings/core/browser/content_settings_usages_state.cc b/components/content_settings/core/browser/content_settings_usages_state.cc index 89b938c..8113260 100644 --- a/components/content_settings/core/browser/content_settings_usages_state.cc +++ b/components/content_settings/core/browser/content_settings_usages_state.cc @@ -9,7 +9,7 @@ #include "base/prefs/pref_service.h" #include "base/strings/utf_string_conversions.h" #include "components/content_settings/core/browser/host_content_settings_map.h" -#include "net/base/net_util.h" +#include "components/url_formatter/url_formatter.h" ContentSettingsUsagesState::CommittedDetails::CommittedDetails() : current_url_valid(false) { @@ -106,7 +106,7 @@ void ContentSettingsUsagesState::GetDetailedInfo( std::string ContentSettingsUsagesState::GURLToFormattedHost( const GURL& url) const { base::string16 display_host; - net::AppendFormattedHost(url, pref_service_->GetString(accept_language_pref_), - &display_host); + url_formatter::AppendFormattedHost( + url, pref_service_->GetString(accept_language_pref_), &display_host); return base::UTF16ToUTF8(display_host); } diff --git a/components/error_page.gypi b/components/error_page.gypi index a281610..bc465cc 100644 --- a/components/error_page.gypi +++ b/components/error_page.gypi @@ -11,6 +11,7 @@ 'dependencies': [ '../base/base.gyp:base', '../url/url.gyp:url_lib', + 'url_formatter/url_formatter.gyp:url_formatter', ], 'include_dirs': [ '..', diff --git a/components/error_page/renderer/BUILD.gn b/components/error_page/renderer/BUILD.gn index e47fd69..bafaada 100644 --- a/components/error_page/renderer/BUILD.gn +++ b/components/error_page/renderer/BUILD.gn @@ -12,6 +12,7 @@ static_library("renderer") { "//base", "//components/error_page/common", "//components/strings", + "//components/url_formatter", "//content/public/common", "//net", "//third_party/WebKit/public:blink", diff --git a/components/error_page/renderer/DEPS b/components/error_page/renderer/DEPS index 5d271a9..3238bc4 100644 --- a/components/error_page/renderer/DEPS +++ b/components/error_page/renderer/DEPS @@ -1,4 +1,5 @@ include_rules = [ + "+components/url_formatter", "+content/public/common", "+grit/components_strings.h", "+net", diff --git a/components/error_page/renderer/net_error_helper_core.cc b/components/error_page/renderer/net_error_helper_core.cc index be7be7d..e5f3dc3 100644 --- a/components/error_page/renderer/net_error_helper_core.cc +++ b/components/error_page/renderer/net_error_helper_core.cc @@ -23,11 +23,11 @@ #include "base/strings/string_util.h" #include "base/values.h" #include "components/error_page/common/error_page_params.h" +#include "components/url_formatter/url_formatter.h" #include "content/public/common/url_constants.h" #include "grit/components_strings.h" #include "net/base/escape.h" #include "net/base/net_errors.h" -#include "net/base/net_util.h" #include "third_party/WebKit/public/platform/WebString.h" #include "third_party/WebKit/public/platform/WebURLError.h" #include "ui/base/l10n/l10n_util.h" @@ -146,7 +146,7 @@ GURL SanitizeURL(const GURL& url) { // Sanitizes and formats a URL for upload to the error correction service. std::string PrepareUrlForUpload(const GURL& url) { - // TODO(yuusuke): Change to net::FormatUrl when Link Doctor becomes + // TODO(yuusuke): Change to url_formatter::FormatUrl when Link Doctor becomes // unicode-capable. std::string spec_to_send = SanitizeURL(url).spec(); @@ -265,9 +265,9 @@ std::string CreateClickTrackingUrlRequestBody( base::string16 FormatURLForDisplay(const GURL& url, bool is_rtl, const std::string accept_languages) { // Translate punycode into UTF8, unescape UTF8 URLs. - base::string16 url_for_display(net::FormatUrl( - url, accept_languages, net::kFormatUrlOmitNothing, - net::UnescapeRule::NORMAL, NULL, NULL, NULL)); + base::string16 url_for_display(url_formatter::FormatUrl( + url, accept_languages, url_formatter::kFormatUrlOmitNothing, + net::UnescapeRule::NORMAL, nullptr, nullptr, nullptr)); // URLs are always LTR. if (is_rtl) base::i18n::WrapStringWithLTRFormatting(&url_for_display); diff --git a/components/google.gypi b/components/google.gypi index 9ab6bac..18b06a9 100644 --- a/components/google.gypi +++ b/components/google.gypi @@ -15,7 +15,7 @@ 'components_strings.gyp:components_strings', 'keyed_service_core', 'pref_registry', - 'url_fixer', + 'url_formatter/url_formatter.gyp:url_formatter', ], 'include_dirs': [ '..', diff --git a/components/google/DEPS b/components/google/DEPS index c39802b..683dd04 100644 --- a/components/google/DEPS +++ b/components/google/DEPS @@ -1,4 +1,4 @@ include_rules = [ - "+components/url_fixer", + "+components/url_formatter", "+net", ] diff --git a/components/google/core/browser/BUILD.gn b/components/google/core/browser/BUILD.gn index f499496..fbff1240 100644 --- a/components/google/core/browser/BUILD.gn +++ b/components/google/core/browser/BUILD.gn @@ -24,7 +24,7 @@ static_library("browser") { "//components/keyed_service/core", "//components/pref_registry", "//components/strings", - "//components/url_fixer", + "//components/url_formatter", "//net", "//url", ] diff --git a/components/google/core/browser/google_util.cc b/components/google/core/browser/google_util.cc index 2cdfe05..b24ba21 100644 --- a/components/google/core/browser/google_util.cc +++ b/components/google/core/browser/google_util.cc @@ -15,7 +15,7 @@ #include "base/strings/utf_string_conversions.h" #include "components/google/core/browser/google_switches.h" #include "components/google/core/browser/google_url_tracker.h" -#include "components/url_fixer/url_fixer.h" +#include "components/url_formatter/url_fixer.h" #include "net/base/registry_controlled_domains/registry_controlled_domain.h" #include "net/base/url_util.h" #include "url/gurl.h" @@ -153,7 +153,7 @@ GURL CommandLineGoogleBaseURL() { switches::kGoogleBaseURL)); if (current_switch_value != switch_value) { switch_value = current_switch_value; - base_url = url_fixer::FixupURL(switch_value, std::string()); + base_url = url_formatter::FixupURL(switch_value, std::string()); if (!base_url.is_valid() || base_url.has_query() || base_url.has_ref()) base_url = GURL(); } diff --git a/components/history.gypi b/components/history.gypi index e07b782..64adec8 100644 --- a/components/history.gypi +++ b/components/history.gypi @@ -29,6 +29,7 @@ 'keyed_service_core', 'query_parser', 'signin_core_browser', + 'url_formatter/url_formatter.gyp:url_formatter', ], 'export_dependent_settings': [ '../skia/skia.gyp:skia', diff --git a/components/history/core/DEPS b/components/history/core/DEPS index 062cbac..636e200 100644 --- a/components/history/core/DEPS +++ b/components/history/core/DEPS @@ -2,4 +2,6 @@ include_rules = [ # history is a layered-component, forbid dependency on //content "-components/history/content", "-content", + + "+components/url_formatter", ] diff --git a/components/history/core/browser/BUILD.gn b/components/history/core/browser/BUILD.gn index ea7fee6..fa8cc4d 100644 --- a/components/history/core/browser/BUILD.gn +++ b/components/history/core/browser/BUILD.gn @@ -93,6 +93,7 @@ static_library("browser") { "//components/keyed_service/core", "//components/query_parser", "//components/signin/core/browser", + "//components/url_formatter", "//google_apis", "//net", "//sql", diff --git a/components/history/core/browser/url_database.cc b/components/history/core/browser/url_database.cc index 65ac67e..48847b4 100644 --- a/components/history/core/browser/url_database.cc +++ b/components/history/core/browser/url_database.cc @@ -12,7 +12,7 @@ #include "base/memory/scoped_vector.h" #include "base/strings/utf_string_conversions.h" #include "components/history/core/browser/keyword_search_term.h" -#include "net/base/net_util.h" +#include "components/url_formatter/url_formatter.h" #include "sql/statement.h" #include "url/gurl.h" @@ -372,7 +372,8 @@ bool URLDatabase::GetTextMatches(const base::string16& query, // |query_words| won't be shown to user - therefore we can use empty // |languages| to reduce dependency (no need to call PrefService). base::string16 ascii = base::ASCIIToUTF16(gurl.host()); - base::string16 utf = net::IDNToUnicode(gurl.host(), std::string()); + base::string16 utf = + url_formatter::IDNToUnicode(gurl.host(), std::string()); if (ascii != utf) query_parser_.ExtractQueryWords(utf, &query_words); } diff --git a/components/nacl.gyp b/components/nacl.gyp index b02102b..5673b0d 100644 --- a/components/nacl.gyp +++ b/components/nacl.gyp @@ -119,6 +119,7 @@ 'dependencies': [ 'nacl_common', 'nacl_switches', + 'url_formatter/url_formatter.gyp:url_formatter', '../native_client/src/trusted/service_runtime/service_runtime.gyp:sel', '../content/content.gyp:content_browser', ], diff --git a/components/nacl/browser/DEPS b/components/nacl/browser/DEPS index 1381695..53ba192 100644 --- a/components/nacl/browser/DEPS +++ b/components/nacl/browser/DEPS @@ -1,4 +1,5 @@ include_rules = [ + "+components/url_formatter", "+content/public/browser", "+content/public/test", "+native_client/src/public", diff --git a/components/nacl/browser/nacl_process_host.cc b/components/nacl/browser/nacl_process_host.cc index 3e7f923..52a016f 100644 --- a/components/nacl/browser/nacl_process_host.cc +++ b/components/nacl/browser/nacl_process_host.cc @@ -37,6 +37,7 @@ #include "components/nacl/common/nacl_messages.h" #include "components/nacl/common/nacl_process_type.h" #include "components/nacl/common/nacl_switches.h" +#include "components/url_formatter/url_formatter.h" #include "content/public/browser/browser_child_process_host.h" #include "content/public/browser/browser_ppapi_host.h" #include "content/public/browser/child_process_data.h" @@ -50,7 +51,6 @@ #include "ipc/ipc_channel.h" #include "ipc/ipc_switches.h" #include "native_client/src/shared/imc/nacl_imc_c.h" -#include "net/base/net_util.h" #include "net/socket/socket_descriptor.h" #include "ppapi/host/host_factory.h" #include "ppapi/host/ppapi_host.h" @@ -310,7 +310,7 @@ NaClProcessHost::NaClProcessHost( // We aren't on the UI thread so getting the pref locale for language // formatting isn't possible, so IDN will be lost, but this is probably OK // for this use case. - process_->SetName(net::FormatUrl(manifest_url_, std::string())); + process_->SetName(url_formatter::FormatUrl(manifest_url_, std::string())); enable_debug_stub_ = base::CommandLine::ForCurrentProcess()->HasSwitch( switches::kEnableNaClDebug); diff --git a/components/omnibox.gypi b/components/omnibox.gypi index a8ed972..9133592 100644 --- a/components/omnibox.gypi +++ b/components/omnibox.gypi @@ -31,7 +31,7 @@ 'search', 'search_engines', 'toolbar', - 'url_fixer', + 'url_formatter/url_formatter.gyp:url_formatter', 'variations_http_provider', ], 'export_dependent_settings': [ diff --git a/components/omnibox/browser/BUILD.gn b/components/omnibox/browser/BUILD.gn index b4845bd..709fbdf 100644 --- a/components/omnibox/browser/BUILD.gn +++ b/components/omnibox/browser/BUILD.gn @@ -112,7 +112,7 @@ source_set("browser") { "//components/sessions", "//components/strings", "//components/toolbar", - "//components/url_fixer", + "//components/url_formatter", "//components/variations", "//components/variations/net", "//net", diff --git a/components/omnibox/browser/DEPS b/components/omnibox/browser/DEPS index 7b494a0..7c81237 100644 --- a/components/omnibox/browser/DEPS +++ b/components/omnibox/browser/DEPS @@ -9,7 +9,7 @@ include_rules = [ "+components/search_engines", "+components/sessions", "+components/toolbar", - "+components/url_fixer", + "+components/url_formatter", "+components/variations", "+grit", "+net", diff --git a/components/omnibox/browser/autocomplete_input.cc b/components/omnibox/browser/autocomplete_input.cc index c8b744a..d5e10f5b 100644 --- a/components/omnibox/browser/autocomplete_input.cc +++ b/components/omnibox/browser/autocomplete_input.cc @@ -10,7 +10,8 @@ #include "components/metrics/proto/omnibox_event.pb.h" #include "components/omnibox/browser/autocomplete_scheme_classifier.h" #include "components/omnibox/browser/omnibox_field_trial.h" -#include "components/url_fixer/url_fixer.h" +#include "components/url_formatter/url_fixer.h" +#include "components/url_formatter/url_formatter.h" #include "net/base/net_util.h" #include "net/base/registry_controlled_domains/registry_controlled_domain.h" #include "url/url_canon_ip.h" @@ -188,7 +189,7 @@ metrics::OmniboxInputType::Type AutocompleteInput::Parse( url::Parsed local_parts; if (!parts) parts = &local_parts; - const base::string16 parsed_scheme(url_fixer::SegmentURL(text, parts)); + const base::string16 parsed_scheme(url_formatter::SegmentURL(text, parts)); if (scheme) *scheme = parsed_scheme; const std::string parsed_scheme_utf8(base::UTF16ToUTF8(parsed_scheme)); @@ -200,7 +201,7 @@ metrics::OmniboxInputType::Type AutocompleteInput::Parse( if (!canonicalized_url) canonicalized_url = &placeholder_canonicalized_url; *canonicalized_url = - url_fixer::FixupURL(base::UTF16ToUTF8(text), desired_tld); + url_formatter::FixupURL(base::UTF16ToUTF8(text), desired_tld); if (!canonicalized_url->is_valid()) return metrics::OmniboxInputType::QUERY; @@ -255,7 +256,7 @@ metrics::OmniboxInputType::Type AutocompleteInput::Parse( &http_parts.ref, }; for (size_t i = 0; i < arraysize(components); ++i) { - url_fixer::OffsetComponent( + url_formatter::OffsetComponent( -static_cast<int>(http_scheme_prefix.length()), components[i]); } @@ -504,7 +505,7 @@ base::string16 AutocompleteInput::FormattedStringWithEquivalentMeaning( const GURL& url, const base::string16& formatted_url, const AutocompleteSchemeClassifier& scheme_classifier) { - if (!net::CanStripTrailingSlash(url)) + if (!url_formatter::CanStripTrailingSlash(url)) return formatted_url; const base::string16 url_with_path(formatted_url + base::char16('/')); return (AutocompleteInput::Parse(formatted_url, std::string(), diff --git a/components/omnibox/browser/autocomplete_match.cc b/components/omnibox/browser/autocomplete_match.cc index 77bcf25..03dc219 100644 --- a/components/omnibox/browser/autocomplete_match.cc +++ b/components/omnibox/browser/autocomplete_match.cc @@ -17,8 +17,8 @@ #include "components/omnibox/browser/suggestion_answer.h" #include "components/search_engines/template_url.h" #include "components/search_engines/template_url_service.h" +#include "components/url_formatter/url_formatter.h" #include "grit/components_scaled_resources.h" -#include "net/base/net_util.h" namespace { @@ -42,9 +42,9 @@ bool WordMatchesURLContent( size_t prefix_length = url.scheme().length() + strlen(url::kStandardSchemeSeparator); DCHECK_GE(url.spec().length(), prefix_length); - const base::string16& formatted_url = net::FormatUrl( - url, languages, net::kFormatUrlOmitNothing, net::UnescapeRule::NORMAL, - NULL, NULL, &prefix_length); + const base::string16& formatted_url = url_formatter::FormatUrl( + url, languages, url_formatter::kFormatUrlOmitNothing, + net::UnescapeRule::NORMAL, nullptr, nullptr, &prefix_length); if (prefix_length == base::string16::npos) return false; const base::string16& formatted_url_without_scheme = diff --git a/components/omnibox/browser/autocomplete_provider.cc b/components/omnibox/browser/autocomplete_provider.cc index 7c43ab4..5072af2 100644 --- a/components/omnibox/browser/autocomplete_provider.cc +++ b/components/omnibox/browser/autocomplete_provider.cc @@ -8,7 +8,7 @@ #include "base/strings/utf_string_conversions.h" #include "components/omnibox/browser/autocomplete_input.h" #include "components/omnibox/browser/autocomplete_match.h" -#include "components/url_fixer/url_fixer.h" +#include "components/url_formatter/url_fixer.h" #include "net/base/net_util.h" #include "url/gurl.h" @@ -102,7 +102,7 @@ AutocompleteProvider::FixupReturn AutocompleteProvider::FixupUserInput( // Fixup and canonicalize user input. const GURL canonical_gurl( - url_fixer::FixupURL(base::UTF16ToUTF8(input_text), std::string())); + url_formatter::FixupURL(base::UTF16ToUTF8(input_text), std::string())); std::string canonical_gurl_str(canonical_gurl.possibly_invalid_spec()); if (canonical_gurl_str.empty()) { // This probably won't happen, but there are no guarantees. diff --git a/components/omnibox/browser/autocomplete_result.cc b/components/omnibox/browser/autocomplete_result.cc index da7f1ca..f1e03a7 100644 --- a/components/omnibox/browser/autocomplete_result.cc +++ b/components/omnibox/browser/autocomplete_result.cc @@ -18,7 +18,7 @@ #include "components/omnibox/browser/omnibox_field_trial.h" #include "components/omnibox/browser/omnibox_switches.h" #include "components/search/search.h" -#include "components/url_fixer/url_fixer.h" +#include "components/url_formatter/url_fixer.h" using metrics::OmniboxEventProto; @@ -250,7 +250,7 @@ void AutocompleteResult::SortAndCull( const std::string& in_scheme = base::UTF16ToUTF8(input.scheme()); const std::string& dest_scheme = default_match_->destination_url.scheme(); - DCHECK(url_fixer::IsEquivalentScheme(in_scheme, dest_scheme)) + DCHECK(url_formatter::IsEquivalentScheme(in_scheme, dest_scheme)) << debug_info; } } diff --git a/components/omnibox/browser/bookmark_provider.cc b/components/omnibox/browser/bookmark_provider.cc index ffce9b8..fc55713 100644 --- a/components/omnibox/browser/bookmark_provider.cc +++ b/components/omnibox/browser/bookmark_provider.cc @@ -18,7 +18,7 @@ #include "components/omnibox/browser/autocomplete_result.h" #include "components/omnibox/browser/history_provider.h" #include "components/omnibox/browser/url_prefix.h" -#include "net/base/net_util.h" +#include "components/url_formatter/url_formatter.h" #include "url/url_constants.h" using bookmarks::BookmarkMatch; @@ -188,9 +188,10 @@ AutocompleteMatch BookmarkProvider::BookmarkMatchToACMatch( // |offsets|, compute how everything is transformed, then remove it from the // end. offsets.push_back(inline_autocomplete_offset); - match.contents = net::FormatUrlWithOffsets(url, languages_, - net::kFormatUrlOmitAll & ~(trim_http ? 0 : net::kFormatUrlOmitHTTP), - net::UnescapeRule::SPACES, NULL, NULL, &offsets); + match.contents = url_formatter::FormatUrlWithOffsets( + url, languages_, url_formatter::kFormatUrlOmitAll & + ~(trim_http ? 0 : url_formatter::kFormatUrlOmitHTTP), + net::UnescapeRule::SPACES, nullptr, nullptr, &offsets); inline_autocomplete_offset = offsets.back(); offsets.pop_back(); BookmarkMatch::MatchPositions new_url_match_positions = diff --git a/components/omnibox/browser/builtin_provider.cc b/components/omnibox/browser/builtin_provider.cc index 43e728b..6e3dde6 100644 --- a/components/omnibox/browser/builtin_provider.cc +++ b/components/omnibox/browser/builtin_provider.cc @@ -12,7 +12,7 @@ #include "components/omnibox/browser/autocomplete_input.h" #include "components/omnibox/browser/autocomplete_provider_client.h" #include "components/omnibox/browser/history_provider.h" -#include "components/url_fixer/url_fixer.h" +#include "components/url_formatter/url_fixer.h" const int BuiltinProvider::kRelevance = 860; @@ -61,7 +61,7 @@ void BuiltinProvider::Start(const AutocompleteInput& input, AddMatch(url, base::string16(), styles); } else { // Match input about: or |embedderAbout| URL input against builtin URLs. - GURL url = url_fixer::FixupURL(base::UTF16ToUTF8(text), std::string()); + GURL url = url_formatter::FixupURL(base::UTF16ToUTF8(text), std::string()); // BuiltinProvider doesn't know how to suggest valid ?query or #fragment // extensions to builtin URLs. if (url.SchemeIs( diff --git a/components/omnibox/browser/history_quick_provider.cc b/components/omnibox/browser/history_quick_provider.cc index d2f15cf..32ac0e7 100644 --- a/components/omnibox/browser/history_quick_provider.cc +++ b/components/omnibox/browser/history_quick_provider.cc @@ -28,8 +28,8 @@ #include "components/omnibox/browser/omnibox_field_trial.h" #include "components/search_engines/template_url.h" #include "components/search_engines/template_url_service.h" +#include "components/url_formatter/url_formatter.h" #include "net/base/escape.h" -#include "net/base/net_util.h" #include "net/base/registry_controlled_domains/registry_controlled_domain.h" #include "url/third_party/mozilla/url_parse.h" #include "url/url_util.h" @@ -221,20 +221,21 @@ AutocompleteMatch HistoryQuickProvider::QuickMatchToACMatch( DCHECK(match.destination_url.is_valid()); // Format the URL autocomplete presentation. - const net::FormatUrlTypes format_types = net::kFormatUrlOmitAll & - ~(!history_match.match_in_scheme ? 0 : net::kFormatUrlOmitHTTP); + const url_formatter::FormatUrlTypes format_types = + url_formatter::kFormatUrlOmitAll & + ~(!history_match.match_in_scheme ? 0 : url_formatter::kFormatUrlOmitHTTP); match.fill_into_edit = AutocompleteInput::FormattedStringWithEquivalentMeaning( - info.url(), - net::FormatUrl(info.url(), languages_, format_types, - net::UnescapeRule::SPACES, NULL, NULL, NULL), + info.url(), url_formatter::FormatUrl( + info.url(), languages_, format_types, + net::UnescapeRule::SPACES, nullptr, nullptr, nullptr), client()->GetSchemeClassifier()); std::vector<size_t> offsets = OffsetsFromTermMatches(history_match.url_matches); base::OffsetAdjuster::Adjustments adjustments; - match.contents = net::FormatUrlWithAdjustments( - info.url(), languages_, format_types, net::UnescapeRule::SPACES, NULL, - NULL, &adjustments); + match.contents = url_formatter::FormatUrlWithAdjustments( + info.url(), languages_, format_types, net::UnescapeRule::SPACES, nullptr, + nullptr, &adjustments); base::OffsetAdjuster::AdjustOffsets(adjustments, &offsets); TermMatches new_matches = ReplaceOffsetsInTermMatches(history_match.url_matches, offsets); diff --git a/components/omnibox/browser/history_url_provider.cc b/components/omnibox/browser/history_url_provider.cc index 2140fbd..3ad59b5 100644 --- a/components/omnibox/browser/history_url_provider.cc +++ b/components/omnibox/browser/history_url_provider.cc @@ -32,8 +32,8 @@ #include "components/omnibox/browser/url_prefix.h" #include "components/search_engines/search_terms_data.h" #include "components/search_engines/template_url_service.h" -#include "components/url_fixer/url_fixer.h" -#include "net/base/net_util.h" +#include "components/url_formatter/url_fixer.h" +#include "components/url_formatter/url_formatter.h" #include "net/base/registry_controlled_domains/registry_controlled_domain.h" #include "url/gurl.h" #include "url/third_party/mozilla/url_parse.h" @@ -494,7 +494,7 @@ void HistoryURLProvider::Start(const AutocompleteInput& input, if (!fixup_return.first) return; url::Parsed parts; - url_fixer::SegmentURL(fixup_return.second, &parts); + url_formatter::SegmentURL(fixup_return.second, &parts); AutocompleteInput fixed_up_input(input); fixed_up_input.UpdateText(fixup_return.second, base::string16::npos, parts); @@ -590,10 +590,10 @@ AutocompleteMatch HistoryURLProvider::SuggestExactInput( // Trim off "http://" if the user didn't type it. DCHECK(!trim_http || !AutocompleteInput::HasHTTPScheme(input.text())); - base::string16 display_string( - net::FormatUrl(destination_url, std::string(), - net::kFormatUrlOmitAll & ~net::kFormatUrlOmitHTTP, - net::UnescapeRule::SPACES, NULL, NULL, NULL)); + base::string16 display_string(url_formatter::FormatUrl( + destination_url, std::string(), + url_formatter::kFormatUrlOmitAll & ~url_formatter::kFormatUrlOmitHTTP, + net::UnescapeRule::SPACES, nullptr, nullptr, nullptr)); const size_t offset = trim_http ? TrimHttpPrefix(&display_string) : 0; match.fill_into_edit = AutocompleteInput::FormattedStringWithEquivalentMeaning( @@ -1160,14 +1160,17 @@ AutocompleteMatch HistoryURLProvider::HistoryMatchToACMatch( history_match.input_location + params.input.text().length(); std::string languages = (match_type == WHAT_YOU_TYPED) ? std::string() : params.languages; - const net::FormatUrlTypes format_types = net::kFormatUrlOmitAll & - ~((params.trim_http && !history_match.match_in_scheme) ? - 0 : net::kFormatUrlOmitHTTP); + const url_formatter::FormatUrlTypes format_types = + url_formatter::kFormatUrlOmitAll & + ~((params.trim_http && !history_match.match_in_scheme) + ? 0 + : url_formatter::kFormatUrlOmitHTTP); match.fill_into_edit = AutocompleteInput::FormattedStringWithEquivalentMeaning( - info.url(), net::FormatUrl(info.url(), languages, format_types, - net::UnescapeRule::SPACES, NULL, NULL, - &inline_autocomplete_offset), + info.url(), + url_formatter::FormatUrl(info.url(), languages, format_types, + net::UnescapeRule::SPACES, nullptr, nullptr, + &inline_autocomplete_offset), client()->GetSchemeClassifier()); if (!params.prevent_inline_autocomplete && (inline_autocomplete_offset != base::string16::npos)) { @@ -1182,8 +1185,9 @@ AutocompleteMatch HistoryURLProvider::HistoryMatchToACMatch( (inline_autocomplete_offset >= match.fill_into_edit.length())); size_t match_start = history_match.input_location; - match.contents = net::FormatUrl(info.url(), languages, - format_types, net::UnescapeRule::SPACES, NULL, NULL, &match_start); + match.contents = url_formatter::FormatUrl(info.url(), languages, format_types, + net::UnescapeRule::SPACES, nullptr, + nullptr, &match_start); if ((match_start != base::string16::npos) && (inline_autocomplete_offset != base::string16::npos) && (inline_autocomplete_offset != match_start)) { diff --git a/components/omnibox/browser/omnibox_edit_model.cc b/components/omnibox/browser/omnibox_edit_model.cc index 4285238..8b2355f 100644 --- a/components/omnibox/browser/omnibox_edit_model.cc +++ b/components/omnibox/browser/omnibox_edit_model.cc @@ -36,7 +36,7 @@ #include "components/search_engines/template_url_prepopulate_data.h" #include "components/search_engines/template_url_service.h" #include "components/toolbar/toolbar_model.h" -#include "components/url_fixer/url_fixer.h" +#include "components/url_formatter/url_fixer.h" #include "ui/gfx/image/image.h" #include "url/url_util.h" @@ -299,7 +299,8 @@ bool OmniboxEditModel::UpdatePermanentText() { } GURL OmniboxEditModel::PermanentURL() { - return url_fixer::FixupURL(base::UTF16ToUTF8(permanent_text_), std::string()); + return url_formatter::FixupURL(base::UTF16ToUTF8(permanent_text_), + std::string()); } void OmniboxEditModel::SetUserText(const base::string16& text) { diff --git a/components/omnibox/browser/search_provider.cc b/components/omnibox/browser/search_provider.cc index 9067f859..7f4aab1 100644 --- a/components/omnibox/browser/search_provider.cc +++ b/components/omnibox/browser/search_provider.cc @@ -31,11 +31,11 @@ #include "components/search/search.h" #include "components/search_engines/template_url_prepopulate_data.h" #include "components/search_engines/template_url_service.h" +#include "components/url_formatter/url_formatter.h" #include "components/variations/net/variations_http_header_provider.h" #include "grit/components_strings.h" #include "net/base/escape.h" #include "net/base/load_flags.h" -#include "net/base/net_util.h" #include "net/http/http_request_headers.h" #include "net/url_request/url_fetcher.h" #include "net/url_request/url_request_status.h" @@ -1379,8 +1379,9 @@ AutocompleteMatch SearchProvider::NavigationToMatch( navigation.formatted_url().find(input) : prefix->prefix.length(); bool trim_http = !AutocompleteInput::HasHTTPScheme(input) && (!prefix || (match_start != 0)); - const net::FormatUrlTypes format_types = - net::kFormatUrlOmitAll & ~(trim_http ? 0 : net::kFormatUrlOmitHTTP); + const url_formatter::FormatUrlTypes format_types = + url_formatter::kFormatUrlOmitAll & + ~(trim_http ? 0 : url_formatter::kFormatUrlOmitHTTP); const std::string languages(client()->GetAcceptLanguages()); size_t inline_autocomplete_offset = (prefix == NULL) ? @@ -1388,9 +1389,9 @@ AutocompleteMatch SearchProvider::NavigationToMatch( match.fill_into_edit += AutocompleteInput::FormattedStringWithEquivalentMeaning( navigation.url(), - net::FormatUrl(navigation.url(), languages, format_types, - net::UnescapeRule::SPACES, NULL, NULL, - &inline_autocomplete_offset), + url_formatter::FormatUrl(navigation.url(), languages, format_types, + net::UnescapeRule::SPACES, nullptr, nullptr, + &inline_autocomplete_offset), client()->GetSchemeClassifier()); // Preserve the forced query '?' prefix in |match.fill_into_edit|. // Otherwise, user edits to a suggestion would show non-Search results. diff --git a/components/omnibox/browser/search_suggestion_parser.cc b/components/omnibox/browser/search_suggestion_parser.cc index 30543fc..24ab637 100644 --- a/components/omnibox/browser/search_suggestion_parser.cc +++ b/components/omnibox/browser/search_suggestion_parser.cc @@ -18,8 +18,8 @@ #include "components/omnibox/browser/autocomplete_i18n.h" #include "components/omnibox/browser/autocomplete_input.h" #include "components/omnibox/browser/url_prefix.h" -#include "components/url_fixer/url_fixer.h" -#include "net/base/net_util.h" +#include "components/url_formatter/url_fixer.h" +#include "components/url_formatter/url_formatter.h" #include "net/http/http_response_headers.h" #include "net/url_request/url_fetcher.h" #include "url/url_constants.h" @@ -226,13 +226,22 @@ SearchSuggestionParser::NavigationResult::NavigationResult( bool relevance_from_server, const base::string16& input_text, const std::string& languages) - : Result(from_keyword_provider, relevance, relevance_from_server, type, + : Result(from_keyword_provider, + relevance, + relevance_from_server, + type, deletion_url), url_(url), formatted_url_(AutocompleteInput::FormattedStringWithEquivalentMeaning( - url, net::FormatUrl(url, languages, - net::kFormatUrlOmitAll & ~net::kFormatUrlOmitHTTP, - net::UnescapeRule::SPACES, NULL, NULL, NULL), + url, + url_formatter::FormatUrl(url, + languages, + url_formatter::kFormatUrlOmitAll & + ~url_formatter::kFormatUrlOmitHTTP, + net::UnescapeRule::SPACES, + nullptr, + nullptr, + nullptr), scheme_classifier)), description_(description) { DCHECK(url_.is_valid()); @@ -262,11 +271,13 @@ SearchSuggestionParser::NavigationResult::CalculateAndClassifyMatchContents( formatted_url_.find(input_text) : prefix->prefix.length(); bool trim_http = !AutocompleteInput::HasHTTPScheme(input_text) && (!prefix || (match_start != 0)); - const net::FormatUrlTypes format_types = - net::kFormatUrlOmitAll & ~(trim_http ? 0 : net::kFormatUrlOmitHTTP); + const url_formatter::FormatUrlTypes format_types = + url_formatter::kFormatUrlOmitAll & + ~(trim_http ? 0 : url_formatter::kFormatUrlOmitHTTP); - base::string16 match_contents = net::FormatUrl(url_, languages, format_types, - net::UnescapeRule::SPACES, NULL, NULL, &match_start); + base::string16 match_contents = url_formatter::FormatUrl( + url_, languages, format_types, net::UnescapeRule::SPACES, nullptr, + nullptr, &match_start); // If the first match in the untrimmed string was inside a scheme that we // trimmed, look for a subsequent match. if (match_start == base::string16::npos) @@ -470,8 +481,8 @@ bool SearchSuggestionParser::ParseSuggestResults( if ((match_type == AutocompleteMatchType::NAVSUGGEST) || (match_type == AutocompleteMatchType::NAVSUGGEST_PERSONALIZED)) { // Do not blindly trust the URL coming from the server to be valid. - GURL url( - url_fixer::FixupURL(base::UTF16ToUTF8(suggestion), std::string())); + GURL url(url_formatter::FixupURL(base::UTF16ToUTF8(suggestion), + std::string())); if (url.is_valid() && allow_navsuggest) { base::string16 title; if (descriptions != NULL) diff --git a/components/omnibox/browser/shortcuts_provider.cc b/components/omnibox/browser/shortcuts_provider.cc index 8d43be6..2b5eead 100644 --- a/components/omnibox/browser/shortcuts_provider.cc +++ b/components/omnibox/browser/shortcuts_provider.cc @@ -28,7 +28,7 @@ #include "components/omnibox/browser/history_provider.h" #include "components/omnibox/browser/omnibox_field_trial.h" #include "components/omnibox/browser/url_prefix.h" -#include "components/url_fixer/url_fixer.h" +#include "components/url_formatter/url_fixer.h" #include "url/third_party/mozilla/url_parse.h" namespace { diff --git a/components/omnibox/browser/url_index_private_data.cc b/components/omnibox/browser/url_index_private_data.cc index a965c86..a468d2b 100644 --- a/components/omnibox/browser/url_index_private_data.cc +++ b/components/omnibox/browser/url_index_private_data.cc @@ -26,7 +26,7 @@ #include "components/history/core/browser/history_db_task.h" #include "components/history/core/browser/history_service.h" #include "components/omnibox/browser/in_memory_url_index.h" -#include "net/base/net_util.h" +#include "components/url_formatter/url_formatter.h" #if defined(USE_SYSTEM_PROTOBUF) #include <google/protobuf/repeated_field.h> @@ -707,10 +707,9 @@ bool URLIndexPrivateData::IndexRow( history::URLID row_id = row.id(); // Strip out username and password before saving and indexing. - base::string16 url(net::FormatUrl(gurl, languages, - net::kFormatUrlOmitUsernamePassword, - net::UnescapeRule::NONE, - NULL, NULL, NULL)); + base::string16 url(url_formatter::FormatUrl( + gurl, languages, url_formatter::kFormatUrlOmitUsernamePassword, + net::UnescapeRule::NONE, nullptr, nullptr, nullptr)); HistoryID history_id = static_cast<HistoryID>(row_id); DCHECK_LT(history_id, std::numeric_limits<HistoryID>::max()); diff --git a/components/omnibox/browser/zero_suggest_provider.cc b/components/omnibox/browser/zero_suggest_provider.cc index ad75cc0..17a1bc9 100644 --- a/components/omnibox/browser/zero_suggest_provider.cc +++ b/components/omnibox/browser/zero_suggest_provider.cc @@ -27,10 +27,10 @@ #include "components/omnibox/browser/search_provider.h" #include "components/pref_registry/pref_registry_syncable.h" #include "components/search_engines/template_url_service.h" +#include "components/url_formatter/url_formatter.h" #include "components/variations/net/variations_http_header_provider.h" #include "net/base/escape.h" #include "net/base/load_flags.h" -#include "net/base/net_util.h" #include "net/http/http_request_headers.h" #include "net/url_request/url_fetcher.h" #include "net/url_request/url_request_status.h" @@ -288,8 +288,9 @@ AutocompleteMatch ZeroSuggestProvider::NavigationToMatch( // Zero suggest results should always omit protocols and never appear bold. const std::string languages(client()->GetAcceptLanguages()); - match.contents = net::FormatUrl(navigation.url(), languages, - net::kFormatUrlOmitAll, net::UnescapeRule::SPACES, NULL, NULL, NULL); + match.contents = url_formatter::FormatUrl( + navigation.url(), languages, url_formatter::kFormatUrlOmitAll, + net::UnescapeRule::SPACES, nullptr, nullptr, nullptr); match.fill_into_edit += AutocompleteInput::FormattedStringWithEquivalentMeaning( navigation.url(), match.contents, client()->GetSchemeClassifier()); diff --git a/components/password_manager.gypi b/components/password_manager.gypi index 1c69880..3c917e3 100644 --- a/components/password_manager.gypi +++ b/components/password_manager.gypi @@ -22,6 +22,7 @@ '../third_party/re2/re2.gyp:re2', 'password_manager_core_common', 'password_manager_core_browser_proto', + 'url_formatter/url_formatter.gyp:url_formatter', ], 'include_dirs': [ '..', diff --git a/components/password_manager/core/browser/BUILD.gn b/components/password_manager/core/browser/BUILD.gn index f2a24c8..6693b3c 100644 --- a/components/password_manager/core/browser/BUILD.gn +++ b/components/password_manager/core/browser/BUILD.gn @@ -102,6 +102,7 @@ static_library("browser") { "//components/os_crypt", "//components/password_manager/core/common", "//components/strings", + "//components/url_formatter", "//net", "//sql", "//sync", diff --git a/components/password_manager/core/browser/DEPS b/components/password_manager/core/browser/DEPS index e1fc861..593c27c 100644 --- a/components/password_manager/core/browser/DEPS +++ b/components/password_manager/core/browser/DEPS @@ -3,8 +3,9 @@ include_rules = [ "+components/keyed_service/core", "+components/pref_registry", "+components/sync_driver", - "+components/webdata/common", + "+components/url_formatter", "+components/variations", + "+components/webdata/common", "+google_apis", "+grit", ] diff --git a/components/password_manager/core/browser/affiliation_utils.cc b/components/password_manager/core/browser/affiliation_utils.cc index 49b25c2..059d5f8 100644 --- a/components/password_manager/core/browser/affiliation_utils.cc +++ b/components/password_manager/core/browser/affiliation_utils.cc @@ -14,6 +14,7 @@ #include "base/strings/string_util.h" #include "components/autofill/core/common/password_form.h" #include "components/password_manager/core/common/password_manager_switches.h" +#include "components/url_formatter/url_formatter.h" #include "components/variations/variations_associated_data.h" #include "net/base/escape.h" #include "url/third_party/mozilla/url_parse.h" @@ -342,6 +343,8 @@ std::string GetHumanReadableOrigin(const autofill::PasswordForm& password_form, password_form.signon_realm); if (facet_uri.IsValidAndroidFacetURI()) return facet_uri.scheme() + "://" + facet_uri.android_package_name(); - return base::UTF16ToUTF8(net::FormatUrl(password_form.origin, languages)); + return base::UTF16ToUTF8( + url_formatter::FormatUrl(password_form.origin, languages)); } + } // namespace password_manager diff --git a/components/policy/core/browser/url_blacklist_manager.h b/components/policy/core/browser/url_blacklist_manager.h index 03e44ad..2fd782e 100644 --- a/components/policy/core/browser/url_blacklist_manager.h +++ b/components/policy/core/browser/url_blacklist_manager.h @@ -37,7 +37,7 @@ namespace policy { // against this set. The filters are currently kept in memory. class POLICY_EXPORT URLBlacklist { public: - // This is meant to be bound to url_fixer::SegmentURL. See that function + // This is meant to be bound to url_formatter::SegmentURL. See that function // for documentation on the parameters and return value. typedef std::string (*SegmentURLCallback)(const std::string&, url::Parsed*); diff --git a/components/search_engines.gypi b/components/search_engines.gypi index 1e45003..1ed485e 100644 --- a/components/search_engines.gypi +++ b/components/search_engines.gypi @@ -26,7 +26,7 @@ 'pref_registry', 'rappor', 'search_engines/prepopulated_engines.gyp:prepopulated_engines', - 'url_fixer', + 'url_formatter/url_formatter.gyp:url_formatter', 'webdata_common', ], 'export_dependent_settings': [ diff --git a/components/search_engines/BUILD.gn b/components/search_engines/BUILD.gn index 3ef20d0..c5aeec9 100644 --- a/components/search_engines/BUILD.gn +++ b/components/search_engines/BUILD.gn @@ -57,7 +57,7 @@ static_library("search_engines") { "//components/pref_registry", "//components/rappor", "//components/strings", - "//components/url_fixer", + "//components/url_formatter", "//components/webdata/common", "//google_apis", "//net", diff --git a/components/search_engines/DEPS b/components/search_engines/DEPS index ec40c3e..d03a920 100644 --- a/components/search_engines/DEPS +++ b/components/search_engines/DEPS @@ -6,7 +6,7 @@ include_rules = [ "+components/policy/core", "+components/pref_registry", "+components/rappor", - "+components/url_fixer", + "+components/url_formatter", "+components/webdata", "+google_apis", "+grit/components_strings.h", diff --git a/components/search_engines/template_url.cc b/components/search_engines/template_url.cc index 3ca7188..8241252 100644 --- a/components/search_engines/template_url.cc +++ b/components/search_engines/template_url.cc @@ -25,6 +25,7 @@ #include "components/metrics/proto/omnibox_input_type.pb.h" #include "components/search_engines/search_engines_switches.h" #include "components/search_engines/search_terms_data.h" +#include "components/url_formatter/url_formatter.h" #include "google_apis/google_api_keys.h" #include "net/base/escape.h" #include "net/base/mime_util.h" @@ -1217,7 +1218,7 @@ base::string16 TemplateURL::GenerateKeyword( // convert to Unicode using the user's accept-languages, so it won't look like // a confusing punycode string. base::string16 keyword = - net::StripWWW(net::IDNToUnicode(url.host(), accept_languages)); + net::StripWWW(url_formatter::IDNToUnicode(url.host(), accept_languages)); // Special case: if the host was exactly "www." (not sure this can happen but // perhaps with some weird intranet and custom DNS server?), ensure we at // least don't return the empty string. diff --git a/components/search_engines/template_url_service.cc b/components/search_engines/template_url_service.cc index a6b137b..4098c0d 100644 --- a/components/search_engines/template_url_service.cc +++ b/components/search_engines/template_url_service.cc @@ -32,7 +32,7 @@ #include "components/search_engines/template_url_service_client.h" #include "components/search_engines/template_url_service_observer.h" #include "components/search_engines/util.h" -#include "components/url_fixer/url_fixer.h" +#include "components/url_formatter/url_fixer.h" #include "net/base/net_util.h" #include "net/base/registry_controlled_domains/registry_controlled_domain.h" #include "sync/api/sync_change.h" @@ -1725,8 +1725,8 @@ void TemplateURLService::AddTabToSearchVisit(const TemplateURL& t_url) { if (!client_) return; - GURL url( - url_fixer::FixupURL(base::UTF16ToUTF8(t_url.keyword()), std::string())); + GURL url(url_formatter::FixupURL(base::UTF16ToUTF8(t_url.keyword()), + std::string())); if (!url.is_valid()) return; diff --git a/components/secure_display.gypi b/components/secure_display.gypi deleted file mode 100644 index 390ef11..0000000 --- a/components/secure_display.gypi +++ /dev/null @@ -1,26 +0,0 @@ -# Copyright (c) 2015 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. - -{ - 'targets': [ - { - # GN version: //components/secure_display - 'target_name': 'secure_display', - 'type': 'static_library', - 'dependencies': [ - '../base/base.gyp:base', - '../net/net.gyp:net', - '../url/url.gyp:url_lib', - '../ui/gfx/gfx.gyp:gfx', - ], - - 'sources': [ - # Note: file list duplicated in GN build. - 'secure_display/elide_url.h', - 'secure_display/elide_url.cc', - ] - } - ] -} - diff --git a/components/secure_display/BUILD.gn b/components/secure_display/BUILD.gn deleted file mode 100644 index 5e7439d..0000000 --- a/components/secure_display/BUILD.gn +++ /dev/null @@ -1,29 +0,0 @@ -import("//testing/test.gni") - -source_set("secure_display") { - sources = [ - "elide_url.cc", - "elide_url.h", - ] - - deps = [ - "//base:base", - "//net:net", - "//ui/gfx", - "//url", - ] -} - -source_set("unit_tests") { - testonly = true - sources = [ - "elide_url_unittest.cc", - ] - - deps = [ - ":secure_display", - "//base:base", - "//base/test:test_support", - "//testing/gtest", - ] -} diff --git a/components/secure_display/DEPS b/components/secure_display/DEPS deleted file mode 100644 index e378ef8..0000000 --- a/components/secure_display/DEPS +++ /dev/null @@ -1,7 +0,0 @@ -include_rules = [ - "+base/", - "+base/strings", - "+net/base", - "+ui/gfx", - "+url/", -] diff --git a/components/secure_display/OWNERS b/components/secure_display/OWNERS deleted file mode 100644 index b0e35156c7..0000000 --- a/components/secure_display/OWNERS +++ /dev/null @@ -1,2 +0,0 @@ -felt@chromium.org -palmer@chromium.org diff --git a/components/url_fixer.gypi b/components/url_fixer.gypi deleted file mode 100644 index 917e9d7..0000000 --- a/components/url_fixer.gypi +++ /dev/null @@ -1,27 +0,0 @@ -# Copyright 2014 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. - -{ - 'targets': [ - { - # GN version: //components/url_fixer - 'target_name': 'url_fixer', - 'type': 'static_library', - 'include_dirs': [ - '..', - ], - 'dependencies': [ - '../base/base.gyp:base', - '../net/net.gyp:net', - ], - 'sources': [ - # Note: sources list duplicated in GN build. - 'url_fixer/url_fixer.cc', - 'url_fixer/url_fixer.h', - ], - # TODO(jschuh): crbug.com/167187 fix size_t to int truncations. - 'msvs_disabled_warnings': [4267, ], - }, - ], -} diff --git a/components/url_fixer/BUILD.gn b/components/url_fixer/BUILD.gn deleted file mode 100644 index 93eac1f3..0000000 --- a/components/url_fixer/BUILD.gn +++ /dev/null @@ -1,18 +0,0 @@ -# Copyright 2014 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. - -static_library("url_fixer") { - sources = [ - "url_fixer.cc", - "url_fixer.h", - ] - - # TODO(jschuh): crbug.com/167187 fix size_t to int truncations. - configs += [ "//build/config/compiler:no_size_t_to_int_warning" ] - - deps = [ - "//base", - "//net", - ] -} diff --git a/components/url_fixer/DEPS b/components/url_fixer/DEPS deleted file mode 100644 index 8fa9d48..0000000 --- a/components/url_fixer/DEPS +++ /dev/null @@ -1,3 +0,0 @@ -include_rules = [ - "+net", -] diff --git a/components/url_fixer/OWNERS b/components/url_fixer/OWNERS deleted file mode 100644 index bf426d6..0000000 --- a/components/url_fixer/OWNERS +++ /dev/null @@ -1 +0,0 @@ -pkasting@chromium.org diff --git a/components/url_formatter/BUILD.gn b/components/url_formatter/BUILD.gn new file mode 100644 index 0000000..3b777de --- /dev/null +++ b/components/url_formatter/BUILD.gn @@ -0,0 +1,50 @@ +# Copyright 2015 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. + +source_set("url_formatter") { + sources = [ + "elide_url.cc", + "elide_url.h", + "url_fixer.cc", + "url_fixer.h", + "url_formatter.cc", + "url_formatter.h", + ] + + # TODO(jschuh): crbug.com/167187 fix size_t to int truncations. + configs += [ "//build/config/compiler:no_size_t_to_int_warning" ] + + deps = [ + "//base", + "//third_party/icu", + "//net", + "//url", + ] + + if (!is_android) { + deps += [ "//ui/gfx" ] + } +} + +source_set("unit_tests") { + testonly = true + sources = [ + "elide_url_unittest.cc", + "url_fixer_unittest.cc", + "url_formatter_unittest.cc", + ] + + deps = [ + ":url_formatter", + "//base", + "//net", + "//testing/gtest", + "//ui/gfx", + "//url", + ] + + if (is_android) { + deps -= [ "//ui/gfx" ] + } +} diff --git a/components/url_formatter/DEPS b/components/url_formatter/DEPS new file mode 100644 index 0000000..3c1754f --- /dev/null +++ b/components/url_formatter/DEPS @@ -0,0 +1,11 @@ +include_rules = [ + # This is a shared component (Mandoline, iOS, content), and as such, MUST NOT + # depend on content or other components that do. + "-components/html_viewer", + "-content", + "-ios", + "-mandoline", + + "+net", + "+ui/gfx", +] diff --git a/components/url_formatter/OWNERS b/components/url_formatter/OWNERS new file mode 100644 index 0000000..49e5b76 --- /dev/null +++ b/components/url_formatter/OWNERS @@ -0,0 +1,9 @@ +pkasting@chromium.org + +# Backup reviewer +brettw@chromium.org + +# Changes to FormatUrlForSecurityDisplay require a security review to avoid +# introducing security bugs. +per-file elide_url.*=palmer@chromium.org +per-file elide_url.*=felt@chromium.org diff --git a/components/secure_display/elide_url.cc b/components/url_formatter/elide_url.cc index ec4d65a..f9535b4 100644 --- a/components/secure_display/elide_url.cc +++ b/components/url_formatter/elide_url.cc @@ -2,24 +2,21 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "components/secure_display/elide_url.h" +#include "components/url_formatter/elide_url.h" #include "base/logging.h" #include "base/strings/string_split.h" #include "base/strings/utf_string_conversions.h" +#include "components/url_formatter/url_formatter.h" #include "net/base/escape.h" -#include "net/base/net_util.h" #include "net/base/registry_controlled_domains/registry_controlled_domain.h" -#include "ui/gfx/text_elider.h" -#include "ui/gfx/text_utils.h" #include "url/gurl.h" #include "url/url_constants.h" -using base::UTF8ToUTF16; -using gfx::ElideText; -using gfx::GetStringWidthF; -using gfx::kEllipsisUTF16; -using gfx::kForwardSlash; +#if !defined(OS_ANDROID) +#include "ui/gfx/text_elider.h" // nogncheck +#include "ui/gfx/text_utils.h" // nogncheck +#endif namespace { @@ -38,11 +35,11 @@ base::string16 BuildPathFromComponents( // Build path from first |num_components| elements. for (size_t j = 0; j < num_components; ++j) - path += path_elements[j] + kForwardSlash; + path += path_elements[j] + gfx::kForwardSlash; // Add |filename|, ellipsis if necessary. if (num_components != (path_elements.size() - 1)) - path += base::string16(kEllipsisUTF16) + kForwardSlash; + path += base::string16(gfx::kEllipsisUTF16) + gfx::kForwardSlash; path += filename; return path; @@ -64,8 +61,8 @@ base::string16 ElideComponentizedPath( for (size_t i = url_path_number_of_elements - 1; i > 0; --i) { base::string16 elided_path = BuildPathFromComponents( url_path_prefix, url_path_elements, url_filename, i); - if (available_pixel_width >= GetStringWidthF(elided_path, font_list)) - return ElideText(elided_path + url_query, font_list, + if (available_pixel_width >= gfx::GetStringWidthF(elided_path, font_list)) + return gfx::ElideText(elided_path + url_query, font_list, available_pixel_width, gfx::ELIDE_TAIL); } @@ -79,24 +76,24 @@ void SplitHost(const GURL& url, base::string16* url_domain, base::string16* url_subdomain) { // Get Host. - *url_host = UTF8ToUTF16(url.host()); + *url_host = base::UTF8ToUTF16(url.host()); // Get domain and registry information from the URL. *url_domain = - UTF8ToUTF16(net::registry_controlled_domains::GetDomainAndRegistry( + base::UTF8ToUTF16(net::registry_controlled_domains::GetDomainAndRegistry( url, net::registry_controlled_domains::EXCLUDE_PRIVATE_REGISTRIES)); if (url_domain->empty()) *url_domain = *url_host; // Add port if required. if (!url.port().empty()) { - *url_host += UTF8ToUTF16(":" + url.port()); - *url_domain += UTF8ToUTF16(":" + url.port()); + *url_host += base::UTF8ToUTF16(":" + url.port()); + *url_domain += base::UTF8ToUTF16(":" + url.port()); } // Get sub domain. const size_t domain_start_index = url_host->find(*url_domain); - base::string16 kWwwPrefix = UTF8ToUTF16("www."); + base::string16 kWwwPrefix = base::UTF8ToUTF16("www."); if (domain_start_index != base::string16::npos) *url_subdomain = url_host->substr(0, domain_start_index); if ((*url_subdomain == kWwwPrefix || url_subdomain->empty() || @@ -108,7 +105,7 @@ void SplitHost(const GURL& url, #endif // !defined(OS_ANDROID) } // namespace -namespace secure_display { +namespace url_formatter { #if !defined(OS_ANDROID) @@ -122,20 +119,21 @@ base::string16 ElideUrl(const GURL& url, const std::string& languages) { // Get a formatted string and corresponding parsing of the url. url::Parsed parsed; - const base::string16 url_string = - net::FormatUrl(url, languages, net::kFormatUrlOmitAll, - net::UnescapeRule::SPACES, &parsed, NULL, NULL); + const base::string16 url_string = url_formatter::FormatUrl( + url, languages, url_formatter::kFormatUrlOmitAll, + net::UnescapeRule::SPACES, &parsed, nullptr, nullptr); if (available_pixel_width <= 0) return url_string; // If non-standard, return plain eliding. if (!url.IsStandard()) - return ElideText(url_string, font_list, available_pixel_width, - gfx::ELIDE_TAIL); + return gfx::ElideText(url_string, font_list, available_pixel_width, + gfx::ELIDE_TAIL); // Now start eliding url_string to fit within available pixel width. // Fist pass - check to see whether entire url_string fits. - const float pixel_width_url_string = GetStringWidthF(url_string, font_list); + const float pixel_width_url_string = + gfx::GetStringWidthF(url_string, font_list); if (available_pixel_width >= pixel_width_url_string) return url_string; @@ -148,9 +146,9 @@ base::string16 ElideUrl(const GURL& url, // Return general elided text if url minus the query fits. const base::string16 url_minus_query = url_string.substr(0, path_start_index + path_len); - if (available_pixel_width >= GetStringWidthF(url_minus_query, font_list)) - return ElideText(url_string, font_list, available_pixel_width, - gfx::ELIDE_TAIL); + if (available_pixel_width >= gfx::GetStringWidthF(url_minus_query, font_list)) + return gfx::ElideText(url_string, font_list, available_pixel_width, + gfx::ELIDE_TAIL); base::string16 url_host; base::string16 url_domain; @@ -176,16 +174,17 @@ base::string16 ElideUrl(const GURL& url, } // Second Pass - remove scheme - the rest fits. - const float pixel_width_url_host = GetStringWidthF(url_host, font_list); + const float pixel_width_url_host = gfx::GetStringWidthF(url_host, font_list); const float pixel_width_url_path = - GetStringWidthF(url_path_query_etc, font_list); + gfx::GetStringWidthF(url_path_query_etc, font_list); if (available_pixel_width >= pixel_width_url_host + pixel_width_url_path) return url_host + url_path_query_etc; // Third Pass: Subdomain, domain and entire path fits. - const float pixel_width_url_domain = GetStringWidthF(url_domain, font_list); + const float pixel_width_url_domain = + gfx::GetStringWidthF(url_domain, font_list); const float pixel_width_url_subdomain = - GetStringWidthF(url_subdomain, font_list); + gfx::GetStringWidthF(url_subdomain, font_list); if (available_pixel_width >= pixel_width_url_subdomain + pixel_width_url_domain + pixel_width_url_path) return url_subdomain + url_domain + url_path_query_etc; @@ -193,20 +192,20 @@ base::string16 ElideUrl(const GURL& url, // Query element. base::string16 url_query; const float kPixelWidthDotsTrailer = - GetStringWidthF(base::string16(kEllipsisUTF16), font_list); + gfx::GetStringWidthF(base::string16(gfx::kEllipsisUTF16), font_list); if (parsed.query.is_nonempty()) { - url_query = UTF8ToUTF16("?") + url_string.substr(parsed.query.begin); + url_query = base::UTF8ToUTF16("?") + url_string.substr(parsed.query.begin); if (available_pixel_width >= (pixel_width_url_subdomain + pixel_width_url_domain + - pixel_width_url_path - GetStringWidthF(url_query, font_list))) { - return ElideText(url_subdomain + url_domain + url_path_query_etc, - font_list, available_pixel_width, gfx::ELIDE_TAIL); + pixel_width_url_path - gfx::GetStringWidthF(url_query, font_list))) { + return gfx::ElideText(url_subdomain + url_domain + url_path_query_etc, + font_list, available_pixel_width, gfx::ELIDE_TAIL); } } // Parse url_path using '/'. std::vector<base::string16> url_path_elements = - base::SplitString(url_path, base::string16(1, kForwardSlash), + base::SplitString(url_path, base::string16(1, gfx::kForwardSlash), base::TRIM_WHITESPACE, base::SPLIT_WANT_ALL); // Get filename - note that for a path ending with / @@ -218,7 +217,7 @@ base::string16 ElideUrl(const GURL& url, // Path ends with a '/'. --url_path_number_of_elements; url_filename = - url_path_elements[url_path_number_of_elements - 1] + kForwardSlash; + url_path_elements[url_path_number_of_elements - 1] + gfx::kForwardSlash; } const size_t kMaxNumberOfUrlPathElementsAllowed = 1024; @@ -226,15 +225,15 @@ base::string16 ElideUrl(const GURL& url, url_path_number_of_elements > kMaxNumberOfUrlPathElementsAllowed) { // No path to elide, or too long of a path (could overflow in loop below) // Just elide this as a text string. - return ElideText(url_subdomain + url_domain + url_path_query_etc, font_list, - available_pixel_width, gfx::ELIDE_TAIL); + return gfx::ElideText(url_subdomain + url_domain + url_path_query_etc, + font_list, available_pixel_width, gfx::ELIDE_TAIL); } // Start eliding the path and replacing elements by ".../". const base::string16 kEllipsisAndSlash = - base::string16(kEllipsisUTF16) + kForwardSlash; + base::string16(gfx::kEllipsisUTF16) + gfx::kForwardSlash; const float pixel_width_ellipsis_slash = - GetStringWidthF(kEllipsisAndSlash, font_list); + gfx::GetStringWidthF(kEllipsisAndSlash, font_list); // Check with both subdomain and domain. base::string16 elided_path = ElideComponentizedPath( @@ -266,20 +265,20 @@ base::string16 ElideUrl(const GURL& url, // Return elided domain/.../filename anyway. base::string16 final_elided_url_string(url_elided_domain); const float url_elided_domain_width = - GetStringWidthF(url_elided_domain, font_list); + gfx::GetStringWidthF(url_elided_domain, font_list); // A hack to prevent trailing ".../...". if ((available_pixel_width - url_elided_domain_width) > pixel_width_ellipsis_slash + kPixelWidthDotsTrailer + - GetStringWidthF(base::ASCIIToUTF16("UV"), font_list)) { + gfx::GetStringWidthF(base::ASCIIToUTF16("UV"), font_list)) { final_elided_url_string += BuildPathFromComponents( base::string16(), url_path_elements, url_filename, 1); } else { final_elided_url_string += url_path; } - return ElideText(final_elided_url_string, font_list, available_pixel_width, - gfx::ELIDE_TAIL); + return gfx::ElideText(final_elided_url_string, font_list, + available_pixel_width, gfx::ELIDE_TAIL); } base::string16 ElideHost(const GURL& url, @@ -290,20 +289,21 @@ base::string16 ElideHost(const GURL& url, base::string16 url_subdomain; SplitHost(url, &url_host, &url_domain, &url_subdomain); - const float pixel_width_url_host = GetStringWidthF(url_host, font_list); + const float pixel_width_url_host = gfx::GetStringWidthF(url_host, font_list); if (available_pixel_width >= pixel_width_url_host) return url_host; if (url_subdomain.empty()) return url_domain; - const float pixel_width_url_domain = GetStringWidthF(url_domain, font_list); + const float pixel_width_url_domain = + gfx::GetStringWidthF(url_domain, font_list); float subdomain_width = available_pixel_width - pixel_width_url_domain; if (subdomain_width <= 0) - return base::string16(kEllipsisUTF16) + kDot + url_domain; + return base::string16(gfx::kEllipsisUTF16) + kDot + url_domain; - const base::string16 elided_subdomain = - ElideText(url_subdomain, font_list, subdomain_width, gfx::ELIDE_HEAD); + const base::string16 elided_subdomain = gfx::ElideText( + url_subdomain, font_list, subdomain_width, gfx::ELIDE_HEAD); return elided_subdomain + url_domain; } @@ -312,7 +312,7 @@ base::string16 ElideHost(const GURL& url, base::string16 FormatUrlForSecurityDisplay(const GURL& url, const std::string& languages) { if (!url.is_valid() || url.is_empty() || !url.IsStandard()) - return net::FormatUrl(url, languages); + return url_formatter::FormatUrl(url, languages); const base::string16 colon(base::ASCIIToUTF16(":")); const base::string16 scheme_separator( @@ -350,4 +350,4 @@ base::string16 FormatUrlForSecurityDisplay(const GURL& url, return result; } -} // namespace secure_display +} // namespace url_formatter diff --git a/components/secure_display/elide_url.h b/components/url_formatter/elide_url.h index 7d77b04..528b20e 100644 --- a/components/secure_display/elide_url.h +++ b/components/url_formatter/elide_url.h @@ -4,8 +4,8 @@ // // This file defines utility functions for eliding URLs. -#ifndef COMPONENTS_SECURE_DISPLAY_ELIDE_URL_H_ -#define COMPONENTS_SECURE_DISPLAY_ELIDE_URL_H_ +#ifndef COMPONENTS_URL_FORMATTER_ELIDE_URL_H_ +#define COMPONENTS_URL_FORMATTER_ELIDE_URL_H_ #include <string> @@ -17,7 +17,7 @@ namespace gfx { class FontList; } -namespace secure_display { +namespace url_formatter { // ElideUrl and Elide host require // gfx::GetStringWidthF which is not implemented in Android @@ -57,8 +57,8 @@ base::string16 ElideHost(const GURL& host_url, // otherwise-simplified URLs from each other). // // Internationalized domain names (IDN) may be presented in Unicode if -// |languages| accepts the Unicode representation (see |net::FormatUrl| for more -// details on the algorithm). +// |languages| accepts the Unicode representation (see +// |url_formatter::FormatUrl| for more details on the algorithm). // // - Omits the path for standard schemes, excepting file and filesystem. // - Omits the port if it is the default for the scheme. @@ -67,6 +67,6 @@ base::string16 ElideHost(const GURL& host_url, base::string16 FormatUrlForSecurityDisplay(const GURL& origin, const std::string& languages); -} // namespace secure_display +} // namespace url_formatter -#endif // COMPONENTS_SECURE_DISPLAY_ELIDE_URL_H_ +#endif // COMPONENTS_URL_FORMATTER_ELIDE_URL_H_ diff --git a/components/secure_display/elide_url_unittest.cc b/components/url_formatter/elide_url_unittest.cc index 71e1a5e..704335f 100644 --- a/components/secure_display/elide_url_unittest.cc +++ b/components/url_formatter/elide_url_unittest.cc @@ -2,19 +2,18 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "components/secure_display/elide_url.h" +#include "components/url_formatter/elide_url.h" #include "base/ios/ios_util.h" #include "base/strings/utf_string_conversions.h" #include "testing/gtest/include/gtest/gtest.h" -#include "ui/gfx/font_list.h" -#include "ui/gfx/text_elider.h" -#include "ui/gfx/text_utils.h" #include "url/gurl.h" -using base::UTF8ToUTF16; -using gfx::GetStringWidthF; -using gfx::kEllipsis; +#if !defined(OS_ANDROID) +#include "ui/gfx/font_list.h" // nogncheck +#include "ui/gfx/text_elider.h" // nogncheck +#include "ui/gfx/text_utils.h" // nogncheck +#endif namespace { @@ -31,16 +30,16 @@ void RunUrlTest(Testcase* testcases, size_t num_testcases) { // Should we test with non-empty language list? // That's kinda redundant with net_util_unittests. const float available_width = - GetStringWidthF(UTF8ToUTF16(testcases[i].output), font_list); - EXPECT_EQ(UTF8ToUTF16(testcases[i].output), - secure_display::ElideUrl(url, font_list, available_width, - std::string())); + gfx::GetStringWidthF(base::UTF8ToUTF16(testcases[i].output), font_list); + EXPECT_EQ(base::UTF8ToUTF16(testcases[i].output), + url_formatter::ElideUrl(url, font_list, available_width, + std::string())); } } // Test eliding of commonplace URLs. TEST(TextEliderTest, TestGeneralEliding) { - const std::string kEllipsisStr(kEllipsis); + const std::string kEllipsisStr(gfx::kEllipsis); Testcase testcases[] = { {"http://www.google.com/intl/en/ads/", "www.google.com/intl/en/ads/"}, {"http://www.google.com/intl/en/ads/", "www.google.com/intl/en/ads/"}, @@ -68,29 +67,30 @@ TEST(TextEliderTest, TestGeneralEliding) { // there is a hack in place that simply treats them as one string in this // case. TEST(TextEliderTest, TestTrailingEllipsisSlashEllipsisHack) { - const std::string kEllipsisStr(kEllipsis); + const std::string kEllipsisStr(gfx::kEllipsis); // Very little space, would cause double ellipsis. gfx::FontList font_list; GURL url("http://battersbox.com/directory/foo/peter_paul_and_mary.html"); - float available_width = GetStringWidthF( - UTF8ToUTF16("battersbox.com/" + kEllipsisStr + "/" + kEllipsisStr), + float available_width = gfx::GetStringWidthF( + base::UTF8ToUTF16("battersbox.com/" + kEllipsisStr + "/" + kEllipsisStr), font_list); // Create the expected string, after elision. Depending on font size, the // directory might become /dir... or /di... or/d... - it never should be // shorter than that. (If it is, the font considers d... to be longer // than .../... - that should never happen). - ASSERT_GT(GetStringWidthF(UTF8ToUTF16(kEllipsisStr + "/" + kEllipsisStr), - font_list), - GetStringWidthF(UTF8ToUTF16("d" + kEllipsisStr), font_list)); + ASSERT_GT( + gfx::GetStringWidthF(base::UTF8ToUTF16(kEllipsisStr + "/" + kEllipsisStr), + font_list), + gfx::GetStringWidthF(base::UTF8ToUTF16("d" + kEllipsisStr), font_list)); GURL long_url("http://battersbox.com/directorynameisreallylongtoforcetrunc"); - base::string16 expected = secure_display::ElideUrl( + base::string16 expected = url_formatter::ElideUrl( long_url, font_list, available_width, std::string()); // Ensure that the expected result still contains part of the directory name. ASSERT_GT(expected.length(), std::string("battersbox.com/d").length()); - EXPECT_EQ(expected, secure_display::ElideUrl(url, font_list, available_width, - std::string())); + EXPECT_EQ(expected, url_formatter::ElideUrl(url, font_list, available_width, + std::string())); // More space available - elide directories, partially elide filename. Testcase testcases[] = { @@ -102,7 +102,7 @@ TEST(TextEliderTest, TestTrailingEllipsisSlashEllipsisHack) { // Test eliding of empty strings, URLs with ports, passwords, queries, etc. TEST(TextEliderTest, TestMoreEliding) { - const std::string kEllipsisStr(kEllipsis); + const std::string kEllipsisStr(gfx::kEllipsis); Testcase testcases[] = { {"http://www.google.com/foo?bar", "www.google.com/foo?bar"}, {"http://xyz.google.com/foo?bar", "xyz.google.com/foo?" + kEllipsisStr}, @@ -142,7 +142,7 @@ TEST(TextEliderTest, TestMoreEliding) { // Test eliding of file: URLs. TEST(TextEliderTest, TestFileURLEliding) { - const std::string kEllipsisStr(kEllipsis); + const std::string kEllipsisStr(gfx::kEllipsis); Testcase testcases[] = { {"file:///C:/path1/path2/path3/filename", "file:///C:/path1/path2/path3/filename"}, @@ -178,7 +178,7 @@ TEST(TextEliderTest, TestHostEliding) { return; } #endif - const std::string kEllipsisStr(kEllipsis); + const std::string kEllipsisStr(gfx::kEllipsis); Testcase testcases[] = { {"http://google.com", "google.com"}, {"http://subdomain.google.com", kEllipsisStr + ".google.com"}, @@ -199,23 +199,23 @@ TEST(TextEliderTest, TestHostEliding) { }; for (size_t i = 0; i < arraysize(testcases); ++i) { - const float available_width = - GetStringWidthF(UTF8ToUTF16(testcases[i].output), gfx::FontList()); - EXPECT_EQ(UTF8ToUTF16(testcases[i].output), - secure_display::ElideHost(GURL(testcases[i].input), - gfx::FontList(), available_width)); + const float available_width = gfx::GetStringWidthF( + base::UTF8ToUTF16(testcases[i].output), gfx::FontList()); + EXPECT_EQ(base::UTF8ToUTF16(testcases[i].output), + url_formatter::ElideHost(GURL(testcases[i].input), + gfx::FontList(), available_width)); } // Trying to elide to a really short length will still keep the full TLD+1 EXPECT_EQ( base::ASCIIToUTF16("google.com"), - secure_display::ElideHost(GURL("http://google.com"), gfx::FontList(), 2)); + url_formatter::ElideHost(GURL("http://google.com"), gfx::FontList(), 2)); EXPECT_EQ(base::UTF8ToUTF16(kEllipsisStr + ".google.com"), - secure_display::ElideHost(GURL("http://subdomain.google.com"), - gfx::FontList(), 2)); + url_formatter::ElideHost(GURL("http://subdomain.google.com"), + gfx::FontList(), 2)); EXPECT_EQ( base::ASCIIToUTF16("foo.bar"), - secure_display::ElideHost(GURL("http://foo.bar"), gfx::FontList(), 2)); + url_formatter::ElideHost(GURL("http://foo.bar"), gfx::FontList(), 2)); } #endif // !defined(OS_ANDROID) @@ -304,19 +304,19 @@ TEST(TextEliderTest, FormatUrlForSecurityDisplay) { const char languages[] = "zh-TW,en-US,en,am,ar-EG,ar"; for (size_t i = 0; i < arraysize(tests); ++i) { - base::string16 formatted = secure_display::FormatUrlForSecurityDisplay( + base::string16 formatted = url_formatter::FormatUrlForSecurityDisplay( GURL(tests[i].input), std::string()); EXPECT_EQ(base::WideToUTF16(tests[i].output), formatted) << tests[i].description; base::string16 formatted_with_languages = - secure_display::FormatUrlForSecurityDisplay(GURL(tests[i].input), - languages); + url_formatter::FormatUrlForSecurityDisplay(GURL(tests[i].input), + languages); EXPECT_EQ(base::WideToUTF16(tests[i].output), formatted_with_languages) << tests[i].description; } base::string16 formatted = - secure_display::FormatUrlForSecurityDisplay(GURL(), std::string()); + url_formatter::FormatUrlForSecurityDisplay(GURL(), std::string()); EXPECT_EQ(base::string16(), formatted) << "Explicitly test the 0-argument GURL constructor"; } diff --git a/components/url_fixer/url_fixer.cc b/components/url_formatter/url_fixer.cc index c34ac90..c49a902 100644 --- a/components/url_fixer/url_fixer.cc +++ b/components/url_formatter/url_fixer.cc @@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "components/url_fixer/url_fixer.h" +#include "components/url_formatter/url_fixer.h" #include <algorithm> @@ -14,15 +14,17 @@ #endif #include "base/strings/string_util.h" #include "base/strings/utf_string_conversions.h" +#include "components/url_formatter/url_formatter.h" #include "net/base/escape.h" #include "net/base/filename_util.h" -#include "net/base/net_util.h" #include "net/base/registry_controlled_domains/registry_controlled_domain.h" #include "url/third_party/mozilla/url_parse.h" #include "url/url_file.h" #include "url/url_util.h" -const char* url_fixer::home_directory_override = NULL; +namespace url_formatter { + +const char* home_directory_override = nullptr; namespace { @@ -124,8 +126,8 @@ std::string FixupHomedir(const std::string& text) { if (text.length() == 1 || text[1] == '/') { base::FilePath file_path; - if (url_fixer::home_directory_override) - file_path = base::FilePath(url_fixer::home_directory_override); + if (home_directory_override) + file_path = base::FilePath(home_directory_override); else PathService::Get(base::DIR_HOME, &file_path); @@ -180,13 +182,9 @@ std::string FixupPath(const std::string& text) { // Here, we know the input looks like a file. GURL file_url = net::FilePathToFileURL(base::FilePath(filename)); if (file_url.is_valid()) { - return base::UTF16ToUTF8(net::FormatUrl(file_url, - std::string(), - net::kFormatUrlOmitUsernamePassword, - net::UnescapeRule::NORMAL, - NULL, - NULL, - NULL)); + return base::UTF16ToUTF8(url_formatter::FormatUrl( + file_url, std::string(), url_formatter::kFormatUrlOmitUsernamePassword, + net::UnescapeRule::NORMAL, nullptr, nullptr, nullptr)); } // Invalid file URL, just return the input. @@ -210,8 +208,7 @@ void AddDesiredTLD(const std::string& desired_tld, std::string* domain) { // "www.mail.yahoo.com". const size_t registry_length = net::registry_controlled_domains::GetRegistryLength( - *domain, - net::registry_controlled_domains::EXCLUDE_UNKNOWN_REGISTRIES, + *domain, net::registry_controlled_domains::EXCLUDE_UNKNOWN_REGISTRIES, net::registry_controlled_domains::EXCLUDE_PRIVATE_REGISTRIES); if ((registry_length != 0) && (registry_length != std::string::npos)) return; @@ -360,8 +357,8 @@ bool GetValidScheme(const std::string& text, canon_scheme->clear(); // Locate everything up to (but not including) the first ':' - if (!url::ExtractScheme( - text.data(), static_cast<int>(text.length()), scheme_component)) { + if (!url::ExtractScheme(text.data(), static_cast<int>(text.length()), + scheme_component)) { return false; } @@ -370,10 +367,8 @@ bool GetValidScheme(const std::string& text, // brackets are not in the whitelist. url::StdStringCanonOutput canon_scheme_output(canon_scheme); url::Component canon_scheme_component; - if (!url::CanonicalizeScheme(text.data(), - *scheme_component, - &canon_scheme_output, - &canon_scheme_component)) { + if (!url::CanonicalizeScheme(text.data(), *scheme_component, + &canon_scheme_output, &canon_scheme_component)) { return false; } @@ -396,7 +391,7 @@ bool GetValidScheme(const std::string& text, return true; } -// Performs the work for url_fixer::SegmentURL. |text| may be modified on +// Performs the work for url_formatter::SegmentURL. |text| may be modified on // output on success: a semicolon following a valid scheme is replaced with a // colon. std::string SegmentURLInternal(std::string* text, url::Parsed* parts) { @@ -436,9 +431,10 @@ std::string SegmentURLInternal(std::string* text, url::Parsed* parts) { if (!found_scheme) { // Couldn't determine the scheme, so just pick one. parts->scheme.reset(); - scheme = base::StartsWith(*text, "ftp.", - base::CompareCase::INSENSITIVE_ASCII) ? - url::kFtpScheme : url::kHttpScheme; + scheme = + base::StartsWith(*text, "ftp.", base::CompareCase::INSENSITIVE_ASCII) + ? url::kFtpScheme + : url::kHttpScheme; } } @@ -453,15 +449,15 @@ std::string SegmentURLInternal(std::string* text, url::Parsed* parts) { if (scheme == url::kFileSystemScheme) { // Have the GURL parser do the heavy lifting for us. - url::ParseFileSystemURL( - text->data(), static_cast<int>(text->length()), parts); + url::ParseFileSystemURL(text->data(), static_cast<int>(text->length()), + parts); return scheme; } if (parts->scheme.is_valid()) { // Have the GURL parser do the heavy lifting for us. - url::ParseStandardURL( - text->data(), static_cast<int>(text->length()), parts); + url::ParseStandardURL(text->data(), static_cast<int>(text->length()), + parts); return scheme; } @@ -480,32 +476,31 @@ std::string SegmentURLInternal(std::string* text, url::Parsed* parts) { text_to_parse.append(first_nonwhite, text->end()); // Have the GURL parser do the heavy lifting for us. - url::ParseStandardURL( - text_to_parse.data(), static_cast<int>(text_to_parse.length()), parts); + url::ParseStandardURL(text_to_parse.data(), + static_cast<int>(text_to_parse.length()), parts); // Offset the results of the parse to match the original text. const int offset = -static_cast<int>(inserted_text.length()); - url_fixer::OffsetComponent(offset, &parts->scheme); - url_fixer::OffsetComponent(offset, &parts->username); - url_fixer::OffsetComponent(offset, &parts->password); - url_fixer::OffsetComponent(offset, &parts->host); - url_fixer::OffsetComponent(offset, &parts->port); - url_fixer::OffsetComponent(offset, &parts->path); - url_fixer::OffsetComponent(offset, &parts->query); - url_fixer::OffsetComponent(offset, &parts->ref); + OffsetComponent(offset, &parts->scheme); + OffsetComponent(offset, &parts->username); + OffsetComponent(offset, &parts->password); + OffsetComponent(offset, &parts->host); + OffsetComponent(offset, &parts->port); + OffsetComponent(offset, &parts->path); + OffsetComponent(offset, &parts->query); + OffsetComponent(offset, &parts->ref); return scheme; } } // namespace -std::string url_fixer::SegmentURL(const std::string& text, url::Parsed* parts) { +std::string SegmentURL(const std::string& text, url::Parsed* parts) { std::string mutable_text(text); return SegmentURLInternal(&mutable_text, parts); } -base::string16 url_fixer::SegmentURL(const base::string16& text, - url::Parsed* parts) { +base::string16 SegmentURL(const base::string16& text, url::Parsed* parts) { std::string text_utf8 = base::UTF16ToUTF8(text); url::Parsed parts_utf8; std::string scheme_utf8 = SegmentURL(text_utf8, &parts_utf8); @@ -513,8 +508,7 @@ base::string16 url_fixer::SegmentURL(const base::string16& text, return base::UTF8ToUTF16(scheme_utf8); } -GURL url_fixer::FixupURL(const std::string& text, - const std::string& desired_tld) { +GURL FixupURL(const std::string& text, const std::string& desired_tld) { std::string trimmed; TrimWhitespaceUTF8(text, base::TRIM_ALL, &trimmed); if (trimmed.empty()) @@ -596,8 +590,8 @@ GURL url_fixer::FixupURL(const std::string& text, // fixup will look for cues that it is actually a file path before trying to // figure out what file it is. If our logic doesn't work, we will fall back on // regular fixup. -GURL url_fixer::FixupRelativeFile(const base::FilePath& base_dir, - const base::FilePath& text) { +GURL FixupRelativeFile(const base::FilePath& base_dir, + const base::FilePath& text) { base::FilePath old_cur_directory; if (!base_dir.empty()) { // Save the old current directory before we move to the new one. @@ -640,14 +634,10 @@ GURL url_fixer::FixupRelativeFile(const base::FilePath& base_dir, if (is_file) { GURL file_url = net::FilePathToFileURL(full_path); if (file_url.is_valid()) - return GURL( - base::UTF16ToUTF8(net::FormatUrl(file_url, - std::string(), - net::kFormatUrlOmitUsernamePassword, - net::UnescapeRule::NORMAL, - NULL, - NULL, - NULL))); + return GURL(base::UTF16ToUTF8(url_formatter::FormatUrl( + file_url, std::string(), + url_formatter::kFormatUrlOmitUsernamePassword, + net::UnescapeRule::NORMAL, nullptr, nullptr, nullptr))); // Invalid files fall through to regular processing. } @@ -660,7 +650,7 @@ GURL url_fixer::FixupRelativeFile(const base::FilePath& base_dir, return FixupURL(text_utf8, std::string()); } -void url_fixer::OffsetComponent(int offset, url::Component* part) { +void OffsetComponent(int offset, url::Component* part) { DCHECK(part); if (part->is_valid()) { @@ -673,9 +663,11 @@ void url_fixer::OffsetComponent(int offset, url::Component* part) { } } -bool url_fixer::IsEquivalentScheme(const std::string& scheme1, - const std::string& scheme2) { +bool IsEquivalentScheme(const std::string& scheme1, + const std::string& scheme2) { return scheme1 == scheme2 || - (scheme1 == url::kAboutScheme && scheme2 == kChromeUIScheme) || - (scheme1 == kChromeUIScheme && scheme2 == url::kAboutScheme); + (scheme1 == url::kAboutScheme && scheme2 == kChromeUIScheme) || + (scheme1 == kChromeUIScheme && scheme2 == url::kAboutScheme); } + +} // namespace url_formatter diff --git a/components/url_fixer/url_fixer.h b/components/url_formatter/url_fixer.h index baf14c6..b7c592d 100644 --- a/components/url_fixer/url_fixer.h +++ b/components/url_formatter/url_fixer.h @@ -2,8 +2,8 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#ifndef COMPONENTS_URL_FIXER_URL_FIXER_H_ -#define COMPONENTS_URL_FIXER_URL_FIXER_H_ +#ifndef COMPONENTS_URL_FORMATTER_URL_FIXER_H_ +#define COMPONENTS_URL_FORMATTER_URL_FIXER_H_ #include <string> @@ -23,7 +23,7 @@ struct Parsed; // know are valid. For example, user typing in the URL bar or command line // options. This is NOT the place for converting between different types of URLs // or parsing them, see net_util.h for that. -namespace url_fixer { +namespace url_formatter { // Segments the given text string into parts of a URL. This is most useful for // schemes such as http, https, and ftp where |SegmentURL| will find many @@ -82,6 +82,6 @@ bool IsEquivalentScheme(const std::string& scheme1, const std::string& scheme2); // For tests, we allow our idea of $HOME to be overriden by this variable. extern const char* home_directory_override; -} // namespace url_fixer +} // namespace url_formatter -#endif // COMPONENTS_URL_FIXER_URL_FIXER_H_ +#endif // COMPONENTS_URL_FORMATTER_URL_FIXER_H_ diff --git a/components/url_fixer/url_fixer_unittest.cc b/components/url_formatter/url_fixer_unittest.cc index ee19289..900b553 100644 --- a/components/url_fixer/url_fixer_unittest.cc +++ b/components/url_formatter/url_fixer_unittest.cc @@ -11,7 +11,7 @@ #include "base/files/scoped_temp_dir.h" #include "base/strings/string_util.h" #include "base/strings/utf_string_conversions.h" -#include "components/url_fixer/url_fixer.h" +#include "components/url_formatter/url_fixer.h" #include "net/base/filename_util.h" #include "testing/gtest/include/gtest/gtest.h" #include "url/gurl.h" @@ -201,7 +201,7 @@ TEST(URLFixerTest, SegmentURL) { for (size_t i = 0; i < arraysize(segment_cases); ++i) { SegmentCase value = segment_cases[i]; - result = url_fixer::SegmentURL(value.input, &parts); + result = url_formatter::SegmentURL(value.input, &parts); EXPECT_EQ(value.result, result); EXPECT_EQ(value.scheme, parts.scheme); EXPECT_EQ(value.username, parts.username); @@ -315,7 +315,7 @@ TEST(URLFixerTest, FixupURL) { for (size_t i = 0; i < arraysize(fixup_cases); ++i) { FixupCase value = fixup_cases[i]; EXPECT_EQ(value.output, - url_fixer::FixupURL(value.input, "").possibly_invalid_spec()) + url_formatter::FixupURL(value.input, "").possibly_invalid_spec()) << "input: " << value.input; } @@ -359,8 +359,8 @@ TEST(URLFixerTest, FixupURL) { }; for (size_t i = 0; i < arraysize(tld_cases); ++i) { FixupCase value = tld_cases[i]; - EXPECT_EQ(value.output, - url_fixer::FixupURL(value.input, "com").possibly_invalid_spec()); + EXPECT_EQ(value.output, url_formatter::FixupURL(value.input, "com") + .possibly_invalid_spec()); } } @@ -381,7 +381,7 @@ TEST(URLFixerTest, FixupFile) { GURL golden(net::FilePathToFileURL(original)); // c:\foo\bar.txt -> file:///c:/foo/bar.txt (basic) - GURL fixedup(url_fixer::FixupURL(original.AsUTF8Unsafe(), std::string())); + GURL fixedup(url_formatter::FixupURL(original.AsUTF8Unsafe(), std::string())); EXPECT_EQ(golden, fixedup); // TODO(port): Make some equivalent tests for posix. @@ -390,7 +390,7 @@ TEST(URLFixerTest, FixupFile) { std::string cur(base::WideToUTF8(original.value())); EXPECT_EQ(':', cur[1]); cur[1] = '|'; - EXPECT_EQ(golden, url_fixer::FixupURL(cur, std::string())); + EXPECT_EQ(golden, url_formatter::FixupURL(cur, std::string())); FixupCase cases[] = { {"c:\\Non-existent%20file.txt", "file:///C:/Non-existent%2520file.txt"}, @@ -426,7 +426,7 @@ TEST(URLFixerTest, FixupFile) { #else #define HOME "/home/" #endif - url_fixer::home_directory_override = "/foo"; + url_formatter::home_directory_override = "/foo"; FixupCase cases[] = { // File URLs go through GURL, which tries to escape intelligently. {"/A%20non-existent file.txt", "file:///A%2520non-existent%20file.txt"}, @@ -445,7 +445,8 @@ TEST(URLFixerTest, FixupFile) { for (size_t i = 0; i < arraysize(cases); i++) { EXPECT_EQ(cases[i].output, - url_fixer::FixupURL(cases[i].input, "").possibly_invalid_spec()); + url_formatter::FixupURL(cases[i].input, std::string()) + .possibly_invalid_spec()); } EXPECT_TRUE(base::DeleteFile(original, false)); @@ -466,14 +467,14 @@ TEST(URLFixerTest, FixupRelativeFile) { FixupCase value = fixup_cases[i]; base::FilePath input = base::FilePath::FromUTF8Unsafe(value.input); EXPECT_EQ(value.output, - url_fixer::FixupRelativeFile(temp_dir_.path(), + url_formatter::FixupRelativeFile(temp_dir_.path(), input).possibly_invalid_spec()); } // make sure the existing file got fixed-up to a file URL, and that there // are no backslashes EXPECT_TRUE(IsMatchingFileURL( - url_fixer::FixupRelativeFile(temp_dir_.path(), + url_formatter::FixupRelativeFile(temp_dir_.path(), file_part).possibly_invalid_spec(), full_path)); EXPECT_TRUE(base::DeleteFile(full_path, false)); @@ -481,7 +482,7 @@ TEST(URLFixerTest, FixupRelativeFile) { // fixed up to a file URL base::FilePath nonexistent_file( FILE_PATH_LITERAL("url_fixer_upper_nonexistent_file.txt")); - std::string fixedup(url_fixer::FixupRelativeFile( + std::string fixedup(url_formatter::FixupRelativeFile( temp_dir_.path(), nonexistent_file).possibly_invalid_spec()); EXPECT_NE(std::string("file:///"), fixedup.substr(0, 8)); EXPECT_FALSE(IsMatchingFileURL(fixedup, nonexistent_file)); @@ -501,7 +502,7 @@ TEST(URLFixerTest, FixupRelativeFile) { // test file in the subdir base::FilePath relative_file = sub_dir.Append(sub_file); EXPECT_TRUE(IsMatchingFileURL( - url_fixer::FixupRelativeFile(temp_dir_.path(), + url_formatter::FixupRelativeFile(temp_dir_.path(), relative_file).possibly_invalid_spec(), full_path)); // test file in the subdir with different slashes and escaping. @@ -510,7 +511,7 @@ TEST(URLFixerTest, FixupRelativeFile) { base::ReplaceSubstringsAfterOffset(&relative_file_str, 0, FILE_PATH_LITERAL(" "), FILE_PATH_LITERAL("%20")); EXPECT_TRUE(IsMatchingFileURL( - url_fixer::FixupRelativeFile(temp_dir_.path(), + url_formatter::FixupRelativeFile(temp_dir_.path(), base::FilePath(relative_file_str)).possibly_invalid_spec(), full_path)); @@ -519,7 +520,7 @@ TEST(URLFixerTest, FixupRelativeFile) { relative_file_str = sub_dir.value() + FILE_PATH_LITERAL("/../") + sub_dir.value() + FILE_PATH_LITERAL("///./") + sub_file.value(); EXPECT_TRUE(IsMatchingFileURL( - url_fixer::FixupRelativeFile(temp_dir_.path(), + url_formatter::FixupRelativeFile(temp_dir_.path(), base::FilePath(relative_file_str)).possibly_invalid_spec(), full_path)); @@ -531,6 +532,6 @@ TEST(URLFixerTest, FixupRelativeFile) { // file path (on account of system-specific craziness). base::FilePath empty_path; base::FilePath http_url_path(FILE_PATH_LITERAL("http://../")); - EXPECT_TRUE( - url_fixer::FixupRelativeFile(empty_path, http_url_path).SchemeIs("http")); + EXPECT_TRUE(url_formatter::FixupRelativeFile(empty_path, http_url_path) + .SchemeIs("http")); } diff --git a/components/url_formatter/url_formatter.cc b/components/url_formatter/url_formatter.cc new file mode 100644 index 0000000..cc209d8 --- /dev/null +++ b/components/url_formatter/url_formatter.cc @@ -0,0 +1,807 @@ +// Copyright 2015 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 "components/url_formatter/url_formatter.h" + +#include <algorithm> +#include <map> +#include <utility> + +#include "base/lazy_instance.h" +#include "base/logging.h" +#include "base/macros.h" +#include "base/memory/singleton.h" +#include "base/stl_util.h" +#include "base/strings/string_tokenizer.h" +#include "base/strings/string_util.h" +#include "base/strings/utf_offset_string_conversions.h" +#include "base/strings/utf_string_conversions.h" +#include "base/synchronization/lock.h" +#include "third_party/icu/source/common/unicode/uidna.h" +#include "third_party/icu/source/common/unicode/uniset.h" +#include "third_party/icu/source/common/unicode/uscript.h" +#include "third_party/icu/source/i18n/unicode/regex.h" +#include "third_party/icu/source/i18n/unicode/ulocdata.h" +#include "url/gurl.h" +#include "url/third_party/mozilla/url_parse.h" + +namespace url_formatter { + +namespace { + +base::string16 IDNToUnicodeWithAdjustments( + const std::string& host, + const std::string& languages, + base::OffsetAdjuster::Adjustments* adjustments); +bool IDNToUnicodeOneComponent(const base::char16* comp, + size_t comp_len, + const std::string& languages, + base::string16* out); + +class AppendComponentTransform { + public: + AppendComponentTransform() {} + virtual ~AppendComponentTransform() {} + + virtual base::string16 Execute( + const std::string& component_text, + base::OffsetAdjuster::Adjustments* adjustments) const = 0; + + // NOTE: No DISALLOW_COPY_AND_ASSIGN here, since gcc < 4.3.0 requires an + // accessible copy constructor in order to call AppendFormattedComponent() + // with an inline temporary (see http://gcc.gnu.org/bugs/#cxx%5Frvalbind ). +}; + +class HostComponentTransform : public AppendComponentTransform { + public: + explicit HostComponentTransform(const std::string& languages) + : languages_(languages) {} + + private: + base::string16 Execute( + const std::string& component_text, + base::OffsetAdjuster::Adjustments* adjustments) const override { + return IDNToUnicodeWithAdjustments(component_text, languages_, adjustments); + } + + const std::string& languages_; +}; + +class NonHostComponentTransform : public AppendComponentTransform { + public: + explicit NonHostComponentTransform(net::UnescapeRule::Type unescape_rules) + : unescape_rules_(unescape_rules) {} + + private: + base::string16 Execute( + const std::string& component_text, + base::OffsetAdjuster::Adjustments* adjustments) const override { + return (unescape_rules_ == net::UnescapeRule::NONE) + ? base::UTF8ToUTF16WithAdjustments(component_text, adjustments) + : net::UnescapeAndDecodeUTF8URLComponentWithAdjustments( + component_text, unescape_rules_, adjustments); + } + + const net::UnescapeRule::Type unescape_rules_; +}; + +// Transforms the portion of |spec| covered by |original_component| according to +// |transform|. Appends the result to |output|. If |output_component| is +// non-NULL, its start and length are set to the transformed component's new +// start and length. If |adjustments| is non-NULL, appends adjustments (if +// any) that reflect the transformation the original component underwent to +// become the transformed value appended to |output|. +void AppendFormattedComponent(const std::string& spec, + const url::Component& original_component, + const AppendComponentTransform& transform, + base::string16* output, + url::Component* output_component, + base::OffsetAdjuster::Adjustments* adjustments) { + DCHECK(output); + if (original_component.is_nonempty()) { + size_t original_component_begin = + static_cast<size_t>(original_component.begin); + size_t output_component_begin = output->length(); + std::string component_str(spec, original_component_begin, + static_cast<size_t>(original_component.len)); + + // Transform |component_str| and modify |adjustments| appropriately. + base::OffsetAdjuster::Adjustments component_transform_adjustments; + output->append( + transform.Execute(component_str, &component_transform_adjustments)); + + // Shift all the adjustments made for this component so the offsets are + // valid for the original string and add them to |adjustments|. + for (base::OffsetAdjuster::Adjustments::iterator comp_iter = + component_transform_adjustments.begin(); + comp_iter != component_transform_adjustments.end(); ++comp_iter) + comp_iter->original_offset += original_component_begin; + if (adjustments) { + adjustments->insert(adjustments->end(), + component_transform_adjustments.begin(), + component_transform_adjustments.end()); + } + + // Set positions of the parsed component. + if (output_component) { + output_component->begin = static_cast<int>(output_component_begin); + output_component->len = + static_cast<int>(output->length() - output_component_begin); + } + } else if (output_component) { + output_component->reset(); + } +} + +// If |component| is valid, its begin is incremented by |delta|. +void AdjustComponent(int delta, url::Component* component) { + if (!component->is_valid()) + return; + + DCHECK(delta >= 0 || component->begin >= -delta); + component->begin += delta; +} + +// Adjusts all the components of |parsed| by |delta|, except for the scheme. +void AdjustAllComponentsButScheme(int delta, url::Parsed* parsed) { + AdjustComponent(delta, &(parsed->username)); + AdjustComponent(delta, &(parsed->password)); + AdjustComponent(delta, &(parsed->host)); + AdjustComponent(delta, &(parsed->port)); + AdjustComponent(delta, &(parsed->path)); + AdjustComponent(delta, &(parsed->query)); + AdjustComponent(delta, &(parsed->ref)); +} + +// Helper for FormatUrlWithOffsets(). +base::string16 FormatViewSourceUrl( + const GURL& url, + const std::string& languages, + FormatUrlTypes format_types, + net::UnescapeRule::Type unescape_rules, + url::Parsed* new_parsed, + size_t* prefix_end, + base::OffsetAdjuster::Adjustments* adjustments) { + DCHECK(new_parsed); + const char kViewSource[] = "view-source:"; + const size_t kViewSourceLength = arraysize(kViewSource) - 1; + + // Format the underlying URL and record adjustments. + const std::string& url_str(url.possibly_invalid_spec()); + adjustments->clear(); + base::string16 result( + base::ASCIIToUTF16(kViewSource) + + FormatUrlWithAdjustments(GURL(url_str.substr(kViewSourceLength)), + languages, format_types, unescape_rules, + new_parsed, prefix_end, adjustments)); + // Revise |adjustments| by shifting to the offsets to prefix that the above + // call to FormatUrl didn't get to see. + for (base::OffsetAdjuster::Adjustments::iterator it = adjustments->begin(); + it != adjustments->end(); ++it) + it->original_offset += kViewSourceLength; + + // Adjust positions of the parsed components. + if (new_parsed->scheme.is_nonempty()) { + // Assume "view-source:real-scheme" as a scheme. + new_parsed->scheme.len += kViewSourceLength; + } else { + new_parsed->scheme.begin = 0; + new_parsed->scheme.len = kViewSourceLength - 1; + } + AdjustAllComponentsButScheme(kViewSourceLength, new_parsed); + + if (prefix_end) + *prefix_end += kViewSourceLength; + + return result; +} + +// TODO(brettw) bug 734373: check the scripts for each host component and +// don't un-IDN-ize if there is more than one. Alternatively, only IDN for +// scripts that the user has installed. For now, just put the entire +// path through IDN. Maybe this feature can be implemented in ICU itself? +// +// We may want to skip this step in the case of file URLs to allow unicode +// UNC hostnames regardless of encodings. +base::string16 IDNToUnicodeWithAdjustments( + const std::string& host, + const std::string& languages, + base::OffsetAdjuster::Adjustments* adjustments) { + if (adjustments) + adjustments->clear(); + // Convert the ASCII input to a base::string16 for ICU. + base::string16 input16; + input16.reserve(host.length()); + input16.insert(input16.end(), host.begin(), host.end()); + + // Do each component of the host separately, since we enforce script matching + // on a per-component basis. + base::string16 out16; + for (size_t component_start = 0, component_end; + component_start < input16.length(); + component_start = component_end + 1) { + // Find the end of the component. + component_end = input16.find('.', component_start); + if (component_end == base::string16::npos) + component_end = input16.length(); // For getting the last component. + size_t component_length = component_end - component_start; + size_t new_component_start = out16.length(); + bool converted_idn = false; + if (component_end > component_start) { + // Add the substring that we just found. + converted_idn = + IDNToUnicodeOneComponent(input16.data() + component_start, + component_length, languages, &out16); + } + size_t new_component_length = out16.length() - new_component_start; + + if (converted_idn && adjustments) { + adjustments->push_back(base::OffsetAdjuster::Adjustment( + component_start, component_length, new_component_length)); + } + + // Need to add the dot we just found (if we found one). + if (component_end < input16.length()) + out16.push_back('.'); + } + return out16; +} + +// Does some simple normalization of scripts so we can allow certain scripts +// to exist together. +// TODO(brettw) bug 880223: we should allow some other languages to be +// oombined such as Chinese and Latin. We will probably need a more +// complicated system of language pairs to have more fine-grained control. +UScriptCode NormalizeScript(UScriptCode code) { + switch (code) { + case USCRIPT_KATAKANA: + case USCRIPT_HIRAGANA: + case USCRIPT_KATAKANA_OR_HIRAGANA: + case USCRIPT_HANGUL: // This one is arguable. + return USCRIPT_HAN; + default: + return code; + } +} + +bool IsIDNComponentInSingleScript(const base::char16* str, int str_len) { + UScriptCode first_script = USCRIPT_INVALID_CODE; + bool is_first = true; + + int i = 0; + while (i < str_len) { + unsigned code_point; + U16_NEXT(str, i, str_len, code_point); + + UErrorCode err = U_ZERO_ERROR; + UScriptCode cur_script = uscript_getScript(code_point, &err); + if (err != U_ZERO_ERROR) + return false; // Report mixed on error. + cur_script = NormalizeScript(cur_script); + + // TODO(brettw) We may have to check for USCRIPT_INHERENT as well. + if (is_first && cur_script != USCRIPT_COMMON) { + first_script = cur_script; + is_first = false; + } else { + if (cur_script != USCRIPT_COMMON && cur_script != first_script) + return false; + } + } + return true; +} + +// Check if the script of a language can be 'safely' mixed with +// Latin letters in the ASCII range. +bool IsCompatibleWithASCIILetters(const std::string& lang) { + // For now, just list Chinese, Japanese and Korean (positive list). + // An alternative is negative-listing (languages using Greek and + // Cyrillic letters), but it can be more dangerous. + return !lang.substr(0, 2).compare("zh") || !lang.substr(0, 2).compare("ja") || + !lang.substr(0, 2).compare("ko"); +} + +typedef std::map<std::string, icu::UnicodeSet*> LangToExemplarSetMap; + +class LangToExemplarSet { + public: + static LangToExemplarSet* GetInstance() { + return Singleton<LangToExemplarSet>::get(); + } + + private: + LangToExemplarSetMap map; + LangToExemplarSet() {} + ~LangToExemplarSet() { + STLDeleteContainerPairSecondPointers(map.begin(), map.end()); + } + + friend class Singleton<LangToExemplarSet>; + friend struct DefaultSingletonTraits<LangToExemplarSet>; + friend bool GetExemplarSetForLang(const std::string&, icu::UnicodeSet**); + friend void SetExemplarSetForLang(const std::string&, icu::UnicodeSet*); + + DISALLOW_COPY_AND_ASSIGN(LangToExemplarSet); +}; + +bool GetExemplarSetForLang(const std::string& lang, + icu::UnicodeSet** lang_set) { + const LangToExemplarSetMap& map = LangToExemplarSet::GetInstance()->map; + LangToExemplarSetMap::const_iterator pos = map.find(lang); + if (pos != map.end()) { + *lang_set = pos->second; + return true; + } + return false; +} + +void SetExemplarSetForLang(const std::string& lang, icu::UnicodeSet* lang_set) { + LangToExemplarSetMap& map = LangToExemplarSet::GetInstance()->map; + map.insert(std::make_pair(lang, lang_set)); +} + +static base::LazyInstance<base::Lock>::Leaky g_lang_set_lock = + LAZY_INSTANCE_INITIALIZER; + +// Returns true if all the characters in component_characters are used by +// the language |lang|. +bool IsComponentCoveredByLang(const icu::UnicodeSet& component_characters, + const std::string& lang) { + CR_DEFINE_STATIC_LOCAL(const icu::UnicodeSet, kASCIILetters, ('a', 'z')); + icu::UnicodeSet* lang_set = nullptr; + // We're called from both the UI thread and the history thread. + { + base::AutoLock lock(g_lang_set_lock.Get()); + if (!GetExemplarSetForLang(lang, &lang_set)) { + UErrorCode status = U_ZERO_ERROR; + ULocaleData* uld = ulocdata_open(lang.c_str(), &status); + // TODO(jungshik) Turn this check on when the ICU data file is + // rebuilt with the minimal subset of locale data for languages + // to which Chrome is not localized but which we offer in the list + // of languages selectable for Accept-Languages. With the rebuilt ICU + // data, ulocdata_open never should fall back to the default locale. + // (issue 2078) + // DCHECK(U_SUCCESS(status) && status != U_USING_DEFAULT_WARNING); + if (U_SUCCESS(status) && status != U_USING_DEFAULT_WARNING) { + lang_set = reinterpret_cast<icu::UnicodeSet*>(ulocdata_getExemplarSet( + uld, nullptr, 0, ULOCDATA_ES_STANDARD, &status)); + // On success, if |lang| is compatible with ASCII Latin letters, add + // them. + if (lang_set && IsCompatibleWithASCIILetters(lang)) + lang_set->addAll(kASCIILetters); + } + + if (!lang_set) + lang_set = new icu::UnicodeSet(1, 0); + + lang_set->freeze(); + SetExemplarSetForLang(lang, lang_set); + ulocdata_close(uld); + } + } + return !lang_set->isEmpty() && lang_set->containsAll(component_characters); +} + +// Returns true if the given Unicode host component is safe to display to the +// user. +bool IsIDNComponentSafe(const base::char16* str, + int str_len, + const std::string& languages) { + // Most common cases (non-IDN) do not reach here so that we don't + // need a fast return path. + // TODO(jungshik) : Check if there's any character inappropriate + // (although allowed) for domain names. + // See http://www.unicode.org/reports/tr39/#IDN_Security_Profiles and + // http://www.unicode.org/reports/tr39/data/xidmodifications.txt + // For now, we borrow the list from Mozilla and tweaked it slightly. + // (e.g. Characters like U+00A0, U+3000, U+3002 are omitted because + // they're gonna be canonicalized to U+0020 and full stop before + // reaching here.) + // The original list is available at + // http://kb.mozillazine.org/Network.IDN.blacklist_chars and + // at + // http://mxr.mozilla.org/seamonkey/source/modules/libpref/src/init/all.js#703 + + UErrorCode status = U_ZERO_ERROR; +#ifdef U_WCHAR_IS_UTF16 + icu::UnicodeSet dangerous_characters( + icu::UnicodeString( + L"[[\\ \u00ad\u00bc\u00bd\u01c3\u0337\u0338" + L"\u05c3\u05f4\u06d4\u0702\u115f\u1160][\u2000-\u200b]" + L"[\u2024\u2027\u2028\u2029\u2039\u203a\u2044\u205f]" + L"[\u2154-\u2156][\u2159-\u215b][\u215f\u2215\u23ae" + L"\u29f6\u29f8\u2afb\u2afd][\u2ff0-\u2ffb][\u3014" + L"\u3015\u3033\u3164\u321d\u321e\u33ae\u33af\u33c6\u33df\ufe14" + L"\ufe15\ufe3f\ufe5d\ufe5e\ufeff\uff0e\uff06\uff61\uffa0\ufff9]" + L"[\ufffa-\ufffd]\U0001f50f\U0001f510\U0001f512\U0001f513]"), + status); + DCHECK(U_SUCCESS(status)); + icu::RegexMatcher dangerous_patterns( + icu::UnicodeString( + // Lone katakana no, so, or n + L"[^\\p{Katakana}][\u30ce\u30f3\u30bd][^\\p{Katakana}]" + // Repeating Japanese accent characters + L"|[\u3099\u309a\u309b\u309c][\u3099\u309a\u309b\u309c]"), + 0, status); +#else + icu::UnicodeSet dangerous_characters( + icu::UnicodeString( + "[[\\u0020\\u00ad\\u00bc\\u00bd\\u01c3\\u0337\\u0338" + "\\u05c3\\u05f4\\u06d4\\u0702\\u115f\\u1160][\\u2000-\\u200b]" + "[\\u2024\\u2027\\u2028\\u2029\\u2039\\u203a\\u2044\\u205f]" + "[\\u2154-\\u2156][\\u2159-\\u215b][\\u215f\\u2215\\u23ae" + "\\u29f6\\u29f8\\u2afb\\u2afd][\\u2ff0-\\u2ffb][\\u3014" + "\\u3015\\u3033\\u3164\\u321d\\u321e\\u33ae\\u33af\\u33c6\\u33df\\ufe" + "14" + "\\ufe15\\ufe3f\\ufe5d\\ufe5e\\ufeff\\uff0e\\uff06\\uff61\\uffa0\\uff" + "f9]" + "[\\ufffa-\\ufffd]\\U0001f50f\\U0001f510\\U0001f512\\U0001f513]", + -1, US_INV), + status); + DCHECK(U_SUCCESS(status)); + icu::RegexMatcher dangerous_patterns( + icu::UnicodeString( + // Lone katakana no, so, or n + "[^\\p{Katakana}][\\u30ce\\u30f3\\u30bd][^\\p{Katakana}]" + // Repeating Japanese accent characters + "|[\\u3099\\u309a\\u309b\\u309c][\\u3099\\u309a\\u309b\\u309c]"), + 0, status); +#endif + DCHECK(U_SUCCESS(status)); + icu::UnicodeSet component_characters; + icu::UnicodeString component_string(str, str_len); + component_characters.addAll(component_string); + if (dangerous_characters.containsSome(component_characters)) + return false; + + DCHECK(U_SUCCESS(status)); + dangerous_patterns.reset(component_string); + if (dangerous_patterns.find()) + return false; + + // If the language list is empty, the result is completely determined + // by whether a component is a single script or not. This will block + // even "safe" script mixing cases like <Chinese, Latin-ASCII> that are + // allowed with |languages| (while it blocks Chinese + Latin letters with + // an accent as should be the case), but we want to err on the safe side + // when |languages| is empty. + if (languages.empty()) + return IsIDNComponentInSingleScript(str, str_len); + + // |common_characters| is made up of ASCII numbers, hyphen, plus and + // underscore that are used across scripts and allowed in domain names. + // (sync'd with characters allowed in url_canon_host with square + // brackets excluded.) See kHostCharLookup[] array in url_canon_host.cc. + icu::UnicodeSet common_characters(UNICODE_STRING_SIMPLE("[[0-9]\\-_+\\ ]"), + status); + DCHECK(U_SUCCESS(status)); + // Subtract common characters because they're always allowed so that + // we just have to check if a language-specific set contains + // the remainder. + component_characters.removeAll(common_characters); + + base::StringTokenizer t(languages, ","); + while (t.GetNext()) { + if (IsComponentCoveredByLang(component_characters, t.token())) + return true; + } + return false; +} + +// A wrapper to use LazyInstance<>::Leaky with ICU's UIDNA, a C pointer to +// a UTS46/IDNA 2008 handling object opened with uidna_openUTS46(). +// +// We use UTS46 with BiDiCheck to migrate from IDNA 2003 to IDNA 2008 with +// the backward compatibility in mind. What it does: +// +// 1. Use the up-to-date Unicode data. +// 2. Define a case folding/mapping with the up-to-date Unicode data as +// in IDNA 2003. +// 3. Use transitional mechanism for 4 deviation characters (sharp-s, +// final sigma, ZWJ and ZWNJ) for now. +// 4. Continue to allow symbols and punctuations. +// 5. Apply new BiDi check rules more permissive than the IDNA 2003 BiDI rules. +// 6. Do not apply STD3 rules +// 7. Do not allow unassigned code points. +// +// It also closely matches what IE 10 does except for the BiDi check ( +// http://goo.gl/3XBhqw ). +// See http://http://unicode.org/reports/tr46/ and references therein +// for more details. +struct UIDNAWrapper { + UIDNAWrapper() { + UErrorCode err = U_ZERO_ERROR; + // TODO(jungshik): Change options as different parties (browsers, + // registrars, search engines) converge toward a consensus. + value = uidna_openUTS46(UIDNA_CHECK_BIDI, &err); + if (U_FAILURE(err)) + value = NULL; + } + + UIDNA* value; +}; + +static base::LazyInstance<UIDNAWrapper>::Leaky g_uidna = + LAZY_INSTANCE_INITIALIZER; + +// Converts one component of a host (between dots) to IDN if safe. The result +// will be APPENDED to the given output string and will be the same as the input +// if it is not IDN or the IDN is unsafe to display. Returns whether any +// conversion was performed. +bool IDNToUnicodeOneComponent(const base::char16* comp, + size_t comp_len, + const std::string& languages, + base::string16* out) { + DCHECK(out); + if (comp_len == 0) + return false; + + // Only transform if the input can be an IDN component. + static const base::char16 kIdnPrefix[] = {'x', 'n', '-', '-'}; + if ((comp_len > arraysize(kIdnPrefix)) && + !memcmp(comp, kIdnPrefix, arraysize(kIdnPrefix) * sizeof(base::char16))) { + UIDNA* uidna = g_uidna.Get().value; + DCHECK(uidna != NULL); + size_t original_length = out->length(); + int output_length = 64; + UIDNAInfo info = UIDNA_INFO_INITIALIZER; + UErrorCode status; + do { + out->resize(original_length + output_length); + status = U_ZERO_ERROR; + // This returns the actual length required. If this is more than 64 + // code units, |status| will be U_BUFFER_OVERFLOW_ERROR and we'll try + // the conversion again, but with a sufficiently large buffer. + output_length = uidna_labelToUnicode( + uidna, comp, static_cast<int32_t>(comp_len), &(*out)[original_length], + output_length, &info, &status); + } while ((status == U_BUFFER_OVERFLOW_ERROR && info.errors == 0)); + + if (U_SUCCESS(status) && info.errors == 0) { + // Converted successfully. Ensure that the converted component + // can be safely displayed to the user. + out->resize(original_length + output_length); + if (IsIDNComponentSafe(out->data() + original_length, output_length, + languages)) + return true; + } + + // Something went wrong. Revert to original string. + out->resize(original_length); + } + + // We get here with no IDN or on error, in which case we just append the + // literal input. + out->append(comp, comp_len); + return false; +} + +} // namespace + +const FormatUrlType kFormatUrlOmitNothing = 0; +const FormatUrlType kFormatUrlOmitUsernamePassword = 1 << 0; +const FormatUrlType kFormatUrlOmitHTTP = 1 << 1; +const FormatUrlType kFormatUrlOmitTrailingSlashOnBareHostname = 1 << 2; +const FormatUrlType kFormatUrlOmitAll = + kFormatUrlOmitUsernamePassword | kFormatUrlOmitHTTP | + kFormatUrlOmitTrailingSlashOnBareHostname; + +base::string16 FormatUrl(const GURL& url, + const std::string& languages, + FormatUrlTypes format_types, + net::UnescapeRule::Type unescape_rules, + url::Parsed* new_parsed, + size_t* prefix_end, + size_t* offset_for_adjustment) { + std::vector<size_t> offsets; + if (offset_for_adjustment) + offsets.push_back(*offset_for_adjustment); + base::string16 result = + FormatUrlWithOffsets(url, languages, format_types, unescape_rules, + new_parsed, prefix_end, &offsets); + if (offset_for_adjustment) + *offset_for_adjustment = offsets[0]; + return result; +} + +base::string16 FormatUrlWithOffsets( + const GURL& url, + const std::string& languages, + FormatUrlTypes format_types, + net::UnescapeRule::Type unescape_rules, + url::Parsed* new_parsed, + size_t* prefix_end, + std::vector<size_t>* offsets_for_adjustment) { + base::OffsetAdjuster::Adjustments adjustments; + const base::string16& format_url_return_value = + FormatUrlWithAdjustments(url, languages, format_types, unescape_rules, + new_parsed, prefix_end, &adjustments); + base::OffsetAdjuster::AdjustOffsets(adjustments, offsets_for_adjustment); + if (offsets_for_adjustment) { + std::for_each( + offsets_for_adjustment->begin(), offsets_for_adjustment->end(), + base::LimitOffset<std::string>(format_url_return_value.length())); + } + return format_url_return_value; +} + +base::string16 FormatUrlWithAdjustments( + const GURL& url, + const std::string& languages, + FormatUrlTypes format_types, + net::UnescapeRule::Type unescape_rules, + url::Parsed* new_parsed, + size_t* prefix_end, + base::OffsetAdjuster::Adjustments* adjustments) { + DCHECK(adjustments != NULL); + adjustments->clear(); + url::Parsed parsed_temp; + if (!new_parsed) + new_parsed = &parsed_temp; + else + *new_parsed = url::Parsed(); + + // Special handling for view-source:. Don't use content::kViewSourceScheme + // because this library shouldn't depend on chrome. + const char kViewSource[] = "view-source"; + // Reject "view-source:view-source:..." to avoid deep recursion. + const char kViewSourceTwice[] = "view-source:view-source:"; + if (url.SchemeIs(kViewSource) && + !base::StartsWith(url.possibly_invalid_spec(), kViewSourceTwice, + base::CompareCase::INSENSITIVE_ASCII)) { + return FormatViewSourceUrl(url, languages, format_types, unescape_rules, + new_parsed, prefix_end, adjustments); + } + + // We handle both valid and invalid URLs (this will give us the spec + // regardless of validity). + const std::string& spec = url.possibly_invalid_spec(); + const url::Parsed& parsed = url.parsed_for_possibly_invalid_spec(); + + // Scheme & separators. These are ASCII. + base::string16 url_string; + url_string.insert( + url_string.end(), spec.begin(), + spec.begin() + parsed.CountCharactersBefore(url::Parsed::USERNAME, true)); + const char kHTTP[] = "http://"; + const char kFTP[] = "ftp."; + // url_formatter::FixupURL() treats "ftp.foo.com" as ftp://ftp.foo.com. This + // means that if we trim "http://" off a URL whose host starts with "ftp." and + // the user inputs this into any field subject to fixup (which is basically + // all input fields), the meaning would be changed. (In fact, often the + // formatted URL is directly pre-filled into an input field.) For this reason + // we avoid stripping "http://" in this case. + bool omit_http = + (format_types & kFormatUrlOmitHTTP) && + base::EqualsASCII(url_string, kHTTP) && + !base::StartsWith(url.host(), kFTP, base::CompareCase::SENSITIVE); + new_parsed->scheme = parsed.scheme; + + // Username & password. + if ((format_types & kFormatUrlOmitUsernamePassword) != 0) { + // Remove the username and password fields. We don't want to display those + // to the user since they can be used for attacks, + // e.g. "http://google.com:search@evil.ru/" + new_parsed->username.reset(); + new_parsed->password.reset(); + // Update the adjustments based on removed username and/or password. + if (parsed.username.is_nonempty() || parsed.password.is_nonempty()) { + if (parsed.username.is_nonempty() && parsed.password.is_nonempty()) { + // The seeming off-by-two is to account for the ':' after the username + // and '@' after the password. + adjustments->push_back(base::OffsetAdjuster::Adjustment( + static_cast<size_t>(parsed.username.begin), + static_cast<size_t>(parsed.username.len + parsed.password.len + 2), + 0)); + } else { + const url::Component* nonempty_component = + parsed.username.is_nonempty() ? &parsed.username : &parsed.password; + // The seeming off-by-one is to account for the '@' after the + // username/password. + adjustments->push_back(base::OffsetAdjuster::Adjustment( + static_cast<size_t>(nonempty_component->begin), + static_cast<size_t>(nonempty_component->len + 1), 0)); + } + } + } else { + AppendFormattedComponent(spec, parsed.username, + NonHostComponentTransform(unescape_rules), + &url_string, &new_parsed->username, adjustments); + if (parsed.password.is_valid()) + url_string.push_back(':'); + AppendFormattedComponent(spec, parsed.password, + NonHostComponentTransform(unescape_rules), + &url_string, &new_parsed->password, adjustments); + if (parsed.username.is_valid() || parsed.password.is_valid()) + url_string.push_back('@'); + } + if (prefix_end) + *prefix_end = static_cast<size_t>(url_string.length()); + + // Host. + AppendFormattedComponent(spec, parsed.host, HostComponentTransform(languages), + &url_string, &new_parsed->host, adjustments); + + // Port. + if (parsed.port.is_nonempty()) { + url_string.push_back(':'); + new_parsed->port.begin = url_string.length(); + url_string.insert(url_string.end(), spec.begin() + parsed.port.begin, + spec.begin() + parsed.port.end()); + new_parsed->port.len = url_string.length() - new_parsed->port.begin; + } else { + new_parsed->port.reset(); + } + + // Path & query. Both get the same general unescape & convert treatment. + if (!(format_types & kFormatUrlOmitTrailingSlashOnBareHostname) || + !CanStripTrailingSlash(url)) { + AppendFormattedComponent(spec, parsed.path, + NonHostComponentTransform(unescape_rules), + &url_string, &new_parsed->path, adjustments); + } else { + if (parsed.path.len > 0) { + adjustments->push_back(base::OffsetAdjuster::Adjustment( + parsed.path.begin, parsed.path.len, 0)); + } + } + if (parsed.query.is_valid()) + url_string.push_back('?'); + AppendFormattedComponent(spec, parsed.query, + NonHostComponentTransform(unescape_rules), + &url_string, &new_parsed->query, adjustments); + + // Ref. This is valid, unescaped UTF-8, so we can just convert. + if (parsed.ref.is_valid()) + url_string.push_back('#'); + AppendFormattedComponent(spec, parsed.ref, + NonHostComponentTransform(net::UnescapeRule::NONE), + &url_string, &new_parsed->ref, adjustments); + + // If we need to strip out http do it after the fact. + if (omit_http && base::StartsWith(url_string, base::ASCIIToUTF16(kHTTP), + base::CompareCase::SENSITIVE)) { + const size_t kHTTPSize = arraysize(kHTTP) - 1; + url_string = url_string.substr(kHTTPSize); + // Because offsets in the |adjustments| are already calculated with respect + // to the string with the http:// prefix in it, those offsets remain correct + // 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)); + + if (prefix_end) + *prefix_end -= kHTTPSize; + + // Adjust new_parsed. + DCHECK(new_parsed->scheme.is_valid()); + int delta = -(new_parsed->scheme.len + 3); // +3 for ://. + new_parsed->scheme.reset(); + AdjustAllComponentsButScheme(delta, new_parsed); + } + + return url_string; +} + +bool CanStripTrailingSlash(const GURL& url) { + // Omit the path only for standard, non-file URLs with nothing but "/" after + // the hostname. + return url.IsStandard() && !url.SchemeIsFile() && !url.SchemeIsFileSystem() && + !url.has_query() && !url.has_ref() && url.path() == "/"; +} + +void AppendFormattedHost(const GURL& url, + const std::string& languages, + base::string16* output) { + AppendFormattedComponent( + url.possibly_invalid_spec(), url.parsed_for_possibly_invalid_spec().host, + HostComponentTransform(languages), output, NULL, NULL); +} + +base::string16 IDNToUnicode(const std::string& host, + const std::string& languages) { + return IDNToUnicodeWithAdjustments(host, languages, NULL); +} + +} // url_formatter diff --git a/components/url_formatter/url_formatter.gyp b/components/url_formatter/url_formatter.gyp new file mode 100644 index 0000000..9375e96 --- /dev/null +++ b/components/url_formatter/url_formatter.gyp @@ -0,0 +1,39 @@ +# Copyright 2015 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. + +{ + 'targets': [ + { + # GN version: //components/url_formatter + 'target_name': 'url_formatter', + 'type': 'static_library', + 'dependencies': [ + '../../base/base.gyp:base', + '../../net/net.gyp:net', + '../../third_party/icu/icu.gyp:icui18n', + '../../third_party/icu/icu.gyp:icuuc', + '../../url/url.gyp:url_lib', + ], + 'sources': [ + # Note: sources list duplicated in GN build. + 'elide_url.cc', + 'elide_url.h', + 'url_fixer.cc', + 'url_fixer.h', + 'url_formatter.cc', + 'url_formatter.h', + ], + # TODO(jschuh): crbug.com/167187 fix size_t to int truncations. + 'msvs_disabled_warnings': [4267, ], + + 'conditions': [ + ['OS != "android"', { + 'dependencies': [ + '../../ui/gfx/gfx.gyp:gfx', + ] + }], + ], + }, + ], +} diff --git a/components/url_formatter/url_formatter.h b/components/url_formatter/url_formatter.h new file mode 100644 index 0000000..01c8795 --- /dev/null +++ b/components/url_formatter/url_formatter.h @@ -0,0 +1,155 @@ +// Copyright 2015 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. + +// url_formatter contains routines for formatting URLs in a way that can be +// safely and securely displayed to users. For example, it is responsible +// for determining when to convert an IDN A-Label (e.g. "xn--[something]") +// into the IDN U-Label. +// +// Note that this formatting is only intended for display purposes; it would +// be insecure and insufficient to make comparisons solely on formatted URLs +// (that is, it should not be used for normalizing URLs for comparison for +// security decisions). + +#ifndef COMPONENTS_URL_FORMATTER_URL_FORMATTER_H_ +#define COMPONENTS_URL_FORMATTER_URL_FORMATTER_H_ + +#include <stdint.h> + +#include <string> +#include <vector> + +#include "base/strings/string16.h" +#include "base/strings/utf_offset_string_conversions.h" +#include "net/base/escape.h" + +class GURL; + +namespace url { +struct Parsed; +} // url + +namespace url_formatter { + +// Used by FormatUrl to specify handling of certain parts of the url. +typedef uint32_t FormatUrlType; +typedef uint32_t FormatUrlTypes; + +// Nothing is ommitted. +extern const FormatUrlType kFormatUrlOmitNothing; + +// If set, any username and password are removed. +extern const FormatUrlType kFormatUrlOmitUsernamePassword; + +// If the scheme is 'http://', it's removed. +extern const FormatUrlType kFormatUrlOmitHTTP; + +// Omits the path if it is just a slash and there is no query or ref. This is +// meaningful for non-file "standard" URLs. +extern const FormatUrlType kFormatUrlOmitTrailingSlashOnBareHostname; + +// Convenience for omitting all unecessary types. +extern const FormatUrlType kFormatUrlOmitAll; + +// Creates a string representation of |url|. The IDN host name may be in Unicode +// if |languages| accepts the Unicode representation. |format_type| is a bitmask +// of FormatUrlTypes, see it for details. |unescape_rules| defines how to clean +// the URL for human readability. You will generally want |UnescapeRule::SPACES| +// for display to the user if you can handle spaces, or |UnescapeRule::NORMAL| +// if not. If the path part and the query part seem to be encoded in %-encoded +// UTF-8, decodes %-encoding and UTF-8. +// +// The last three parameters may be NULL. +// +// |new_parsed| will be set to the parsing parameters of the resultant URL. +// +// |prefix_end| will be the length before the hostname of the resultant URL. +// +// |offset[s]_for_adjustment| specifies one or more offsets into the original +// URL, representing insertion or selection points between characters: if the +// input is "http://foo.com/", offset 0 is before the entire URL, offset 7 is +// between the scheme and the host, and offset 15 is after the end of the URL. +// Valid input offsets range from 0 to the length of the input URL string. On +// exit, each offset will have been modified to reflect any changes made to the +// output string. For example, if |url| is "http://a:b@c.com/", +// |omit_username_password| is true, and an offset is 12 (pointing between 'c' +// and '.'), then on return the output string will be "http://c.com/" and the +// offset will be 8. If an offset cannot be successfully adjusted (e.g. because +// it points into the middle of a component that was entirely removed or into +// the middle of an encoding sequence), it will be set to base::string16::npos. +// For consistency, if an input offset points between the scheme and the +// username/password, and both are removed, on output this offset will be 0 +// rather than npos; this means that offsets at the starts and ends of removed +// components are always transformed the same way regardless of what other +// components are adjacent. +base::string16 FormatUrl(const GURL& url, + const std::string& languages, + FormatUrlTypes format_types, + net::UnescapeRule::Type unescape_rules, + url::Parsed* new_parsed, + size_t* prefix_end, + size_t* offset_for_adjustment); + +base::string16 FormatUrlWithOffsets( + const GURL& url, + const std::string& languages, + FormatUrlTypes format_types, + net::UnescapeRule::Type unescape_rules, + url::Parsed* new_parsed, + size_t* prefix_end, + std::vector<size_t>* offsets_for_adjustment); + +// This function is like those above except it takes |adjustments| rather +// than |offset[s]_for_adjustment|. |adjustments| will be set to reflect all +// the transformations that happened to |url| to convert it into the returned +// value. +base::string16 FormatUrlWithAdjustments( + const GURL& url, + const std::string& languages, + FormatUrlTypes format_types, + net::UnescapeRule::Type unescape_rules, + url::Parsed* new_parsed, + size_t* prefix_end, + base::OffsetAdjuster::Adjustments* adjustments); + +// This is a convenience function for FormatUrl() with +// format_types = kFormatUrlOmitAll and unescape = SPACES. This is the typical +// set of flags for "URLs to display to the user". You should be cautious about +// using this for URLs which will be parsed or sent to other applications. +inline base::string16 FormatUrl(const GURL& url, const std::string& languages) { + return FormatUrl(url, languages, kFormatUrlOmitAll, net::UnescapeRule::SPACES, + nullptr, nullptr, nullptr); +} + +// Returns whether FormatUrl() would strip a trailing slash from |url|, given a +// format flag including kFormatUrlOmitTrailingSlashOnBareHostname. +bool CanStripTrailingSlash(const GURL& url); + +// Formats the host in |url| and appends it to |output|. The host formatter +// takes the same accept languages component as ElideURL(). +void AppendFormattedHost(const GURL& url, + const std::string& languages, + base::string16* output); + +// Converts the given host name to unicode characters. This can be called for +// any host name, if the input is not IDN or is invalid in some way, we'll just +// return the ASCII source so it is still usable. +// +// The input should be the canonicalized ASCII host name from GURL. This +// function does NOT accept UTF-8! +// +// |languages| is a comma separated list of ISO 639 language codes. It +// is used to determine whether a hostname is 'comprehensible' to a user +// who understands languages listed. |host| will be converted to a +// human-readable form (Unicode) ONLY when each component of |host| is +// regarded as 'comprehensible'. Scipt-mixing is not allowed except that +// Latin letters in the ASCII range can be mixed with a limited set of +// script-language pairs (currently Han, Kana and Hangul for zh,ja and ko). +// When |languages| is empty, even that mixing is not allowed. +base::string16 IDNToUnicode(const std::string& host, + const std::string& languages); + +} // url_formatter + +#endif // COMPONENTS_URL_FORMATTER_URL_FORMATTER_H_ diff --git a/components/url_formatter/url_formatter_unittest.cc b/components/url_formatter/url_formatter_unittest.cc new file mode 100644 index 0000000..0dd635a --- /dev/null +++ b/components/url_formatter/url_formatter_unittest.cc @@ -0,0 +1,978 @@ +// Copyright 2015 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 "components/url_formatter/url_formatter.h" + +#include <string.h> + +#include <vector> + +#include "base/macros.h" +#include "base/strings/string_number_conversions.h" +#include "base/strings/stringprintf.h" +#include "base/strings/utf_string_conversions.h" +#include "testing/gtest/include/gtest/gtest.h" +#include "url/gurl.h" + + +namespace url_formatter { + +namespace { + +using base::WideToUTF16; +using base::ASCIIToUTF16; + +const size_t kNpos = base::string16::npos; + +const char* const kLanguages[] = { + "", "en", "zh-CN", "ja", "ko", + "he", "ar", "ru", "el", "fr", + "de", "pt", "sv", "th", "hi", + "de,en", "el,en", "zh-TW,en", "ko,ja", "he,ru,en", + "zh,ru,en" +}; + +struct IDNTestCase { + const char* const input; + const wchar_t* unicode_output; + const bool unicode_allowed[arraysize(kLanguages)]; +}; + +// TODO(jungshik) This is just a random sample of languages and is far +// from exhaustive. We may have to generate all the combinations +// of languages (powerset of a set of all the languages). +const IDNTestCase idn_cases[] = { + // No IDN + {"www.google.com", L"www.google.com", + {true, true, true, true, true, + true, true, true, true, true, + true, true, true, true, true, + true, true, true, true, true, + true}}, + {"www.google.com.", L"www.google.com.", + {true, true, true, true, true, + true, true, true, true, true, + true, true, true, true, true, + true, true, true, true, true, + true}}, + {".", L".", + {true, true, true, true, true, + true, true, true, true, true, + true, true, true, true, true, + true, true, true, true, true, + true}}, + {"", L"", + {true, true, true, true, true, + true, true, true, true, true, + true, true, true, true, true, + true, true, true, true, true, + true}}, + // IDN + // Hanzi (Traditional Chinese) + {"xn--1lq90ic7f1rc.cn", L"\x5317\x4eac\x5927\x5b78.cn", + {true, false, true, true, false, + false, false, false, false, false, + false, false, false, false, false, + false, false, true, true, false, + true}}, + // Hanzi ('video' in Simplified Chinese : will pass only in zh-CN,zh) + {"xn--cy2a840a.com", L"\x89c6\x9891.com", + {true, false, true, false, false, + false, false, false, false, false, + false, false, false, false, false, + false, false, false, false, false, + true}}, + // Hanzi + '123' + {"www.xn--123-p18d.com", L"www.\x4e00" L"123.com", + {true, false, true, true, false, + false, false, false, false, false, + false, false, false, false, false, + false, false, true, true, false, + true}}, + // Hanzi + Latin : U+56FD is simplified and is regarded + // as not supported in zh-TW. + {"www.xn--hello-9n1hm04c.com", L"www.hello\x4e2d\x56fd.com", + {false, false, true, true, false, + false, false, false, false, false, + false, false, false, false, false, + false, false, false, true, false, + true}}, + // Kanji + Kana (Japanese) + {"xn--l8jvb1ey91xtjb.jp", L"\x671d\x65e5\x3042\x3055\x3072.jp", + {true, false, false, true, false, + false, false, false, false, false, + false, false, false, false, false, + false, false, false, true, false, + false}}, + // Katakana including U+30FC + {"xn--tckm4i2e.jp", L"\x30b3\x30de\x30fc\x30b9.jp", + {true, false, false, true, false, + false, false, false, false, false, + false, false, false, false, false, + false, false, false, true, false, + }}, + {"xn--3ck7a7g.jp", L"\u30ce\u30f3\u30bd.jp", + {true, false, false, true, false, + false, false, false, false, false, + false, false, false, false, false, + false, false, false, true, false, + }}, + // Katakana + Latin (Japanese) + // TODO(jungshik): Change 'false' in the first element to 'true' + // after upgrading to ICU 4.2.1 to use new uspoof_* APIs instead + // of our IsIDNComponentInSingleScript(). + {"xn--e-efusa1mzf.jp", L"e\x30b3\x30de\x30fc\x30b9.jp", + {false, false, false, true, false, + false, false, false, false, false, + false, false, false, false, false, + false, false, false, true, false, + }}, + {"xn--3bkxe.jp", L"\x30c8\x309a.jp", + {false, false, false, true, false, + false, false, false, false, false, + false, false, false, false, false, + false, false, false, true, false, + }}, + // Hangul (Korean) + {"www.xn--or3b17p6jjc.kr", L"www.\xc804\xc790\xc815\xbd80.kr", + {true, false, false, false, true, + false, false, false, false, false, + false, false, false, false, false, + false, false, false, true, false, + false}}, + // b<u-umlaut>cher (German) + {"xn--bcher-kva.de", L"b\x00fc" L"cher.de", + {true, false, false, false, false, + false, false, false, false, true, + true, false, false, false, false, + true, false, false, false, false, + false}}, + // a with diaeresis + {"www.xn--frgbolaget-q5a.se", L"www.f\x00e4rgbolaget.se", + {true, false, false, false, false, + false, false, false, false, false, + true, false, true, false, false, + true, false, false, false, false, + false}}, + // c-cedilla (French) + {"www.xn--alliancefranaise-npb.fr", L"www.alliancefran\x00e7" L"aise.fr", + {true, false, false, false, false, + false, false, false, false, true, + false, true, false, false, false, + false, false, false, false, false, + false}}, + // caf'e with acute accent' (French) + {"xn--caf-dma.fr", L"caf\x00e9.fr", + {true, false, false, false, false, + false, false, false, false, true, + false, true, true, false, false, + false, false, false, false, false, + false}}, + // c-cedillla and a with tilde (Portuguese) + {"xn--poema-9qae5a.com.br", L"p\x00e3oema\x00e7\x00e3.com.br", + {true, false, false, false, false, + false, false, false, false, false, + false, true, false, false, false, + false, false, false, false, false, + false}}, + // s with caron + {"xn--achy-f6a.com", L"\x0161" L"achy.com", + {true, false, false, false, false, + false, false, false, false, false, + false, false, false, false, false, + false, false, false, false, false, + false}}, + // TODO(jungshik) : Add examples with Cyrillic letters + // only used in some languages written in Cyrillic. + // Eutopia (Greek) + {"xn--kxae4bafwg.gr", L"\x03bf\x03c5\x03c4\x03bf\x03c0\x03af\x03b1.gr", + {true, false, false, false, false, + false, false, false, true, false, + false, false, false, false, false, + false, true, false, false, false, + false}}, + // Eutopia + 123 (Greek) + {"xn---123-pldm0haj2bk.gr", + L"\x03bf\x03c5\x03c4\x03bf\x03c0\x03af\x03b1-123.gr", + {true, false, false, false, false, + false, false, false, true, false, + false, false, false, false, false, + false, true, false, false, false, + false}}, + // Cyrillic (Russian) + {"xn--n1aeec9b.ru", L"\x0442\x043e\x0440\x0442\x044b.ru", + {true, false, false, false, false, + false, false, true, false, false, + false, false, false, false, false, + false, false, false, false, true, + true}}, + // Cyrillic + 123 (Russian) + {"xn---123-45dmmc5f.ru", L"\x0442\x043e\x0440\x0442\x044b-123.ru", + {true, false, false, false, false, + false, false, true, false, false, + false, false, false, false, false, + false, false, false, false, true, + true}}, + // Arabic + {"xn--mgba1fmg.ar", L"\x0627\x0641\x0644\x0627\x0645.ar", + {true, false, false, false, false, + false, true, false, false, false, + false, false, false, false, false, + false, false, false, false, false, + false}}, + // Hebrew + {"xn--4dbib.he", L"\x05d5\x05d0\x05d4.he", + {true, false, false, false, false, + true, false, false, false, false, + false, false, false, false, false, + false, false, false, false, true, + false}}, + // Thai + {"xn--12c2cc4ag3b4ccu.th", + L"\x0e2a\x0e32\x0e22\x0e01\x0e32\x0e23\x0e1a\x0e34\x0e19.th", + {true, false, false, false, false, + false, false, false, false, false, + false, false, false, true, false, + false, false, false, false, false, + false}}, + // Devangari (Hindi) + {"www.xn--l1b6a9e1b7c.in", L"www.\x0905\x0915\x094b\x0932\x093e.in", + {true, false, false, false, false, + false, false, false, false, false, + false, false, false, false, true, + false, false, false, false, false, + false}}, + // Invalid IDN + {"xn--hello?world.com", NULL, + {false, false, false, false, false, + false, false, false, false, false, + false, false, false, false, false, + false, false, false, false, false, + false}}, + // Unsafe IDNs + // "payp<alpha>l.com" + {"www.xn--paypl-g9d.com", L"payp\x03b1l.com", + {false, false, false, false, false, + false, false, false, false, false, + false, false, false, false, false, + false, false, false, false, false, + false}}, + // google.gr with Greek omicron and epsilon + {"xn--ggl-6xc1ca.gr", L"g\x03bf\x03bfgl\x03b5.gr", + {false, false, false, false, false, + false, false, false, false, false, + false, false, false, false, false, + false, false, false, false, false, + false}}, + // google.ru with Cyrillic o + {"xn--ggl-tdd6ba.ru", L"g\x043e\x043egl\x0435.ru", + {false, false, false, false, false, + false, false, false, false, false, + false, false, false, false, false, + false, false, false, false, false, + false}}, + // h<e with acute>llo<China in Han>.cn + {"xn--hllo-bpa7979ih5m.cn", L"h\x00e9llo\x4e2d\x56fd.cn", + {false, false, false, false, false, + false, false, false, false, false, + false, false, false, false, false, + false, false, false, false, false, + false}}, + // <Greek rho><Cyrillic a><Cyrillic u>.ru + {"xn--2xa6t2b.ru", L"\x03c1\x0430\x0443.ru", + {false, false, false, false, false, + false, false, false, false, false, + false, false, false, false, false, + false, false, false, false, false, + false}}, + // One that's really long that will force a buffer realloc + {"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" + "aaaaaaa", + L"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" + L"aaaaaaaa", + {true, true, true, true, true, + true, true, true, true, true, + true, true, true, true, true, + true, true, true, true, true, + true}}, + // Test cases for characters we blacklisted although allowed in IDN. + // Embedded spaces will be turned to %20 in the display. + // TODO(jungshik): We need to have more cases. This is a typical + // data-driven trap. The following test cases need to be separated + // and tested only for a couple of languages. + {"xn--osd3820f24c.kr", L"\xac00\xb098\x115f.kr", + {false, false, false, false, false, + false, false, false, false, false, + false, false, false, false, false, + false, false, false, false, false, + false}}, + {"www.xn--google-ho0coa.com", L"www.\x2039google\x203a.com", + {false, false, false, false, false, + false, false, false, false, false, + false, false, false, false, false, + false, false, false, false, false, + }}, + {"google.xn--comabc-k8d", L"google.com\x0338" L"abc", + {false, false, false, false, false, + false, false, false, false, false, + false, false, false, false, false, + false, false, false, false, false, + }}, + {"google.xn--com-oh4ba.evil.jp", L"google.com\x309a\x309a.evil.jp", + {false, false, false, false, false, + false, false, false, false, false, + false, false, false, false, false, + false, false, false, false, false, + }}, + {"google.xn--comevil-v04f.jp", L"google.com\x30ce" L"evil.jp", + {false, false, false, false, false, + false, false, false, false, false, + false, false, false, false, false, + false, false, false, false, false, + }}, + // Padlock icon spoof. + {"xn--google-hj64e", L"\U0001f512google.com", + {false, false, false, false, false, + false, false, false, false, false, + false, false, false, false, false, + false, false, false, false, false, + }}, + // Ensure that blacklisting "\xd83d\xdd12" did not inadvertently blacklist + // all strings with the surrogate '\xdd12'. + {"xn--fk9c.com", L"\U00010912.com", + {true, false, false, false, false, + false, false, false, false, false, + false, false, false, false, false, + false, false, false, false, false, + }}, +#if 0 + // These two cases are special. We need a separate test. + // U+3000 and U+3002 are normalized to ASCII space and dot. + {"xn-- -kq6ay5z.cn", L"\x4e2d\x56fd\x3000.cn", + {false, false, true, false, false, + false, false, false, false, false, + false, false, false, false, false, + false, false, true, false, false, + true}}, + {"xn--fiqs8s.cn", L"\x4e2d\x56fd\x3002" L"cn", + {false, false, true, false, false, + false, false, false, false, false, + false, false, false, false, false, + false, false, true, false, false, + true}}, +#endif +}; + +struct AdjustOffsetCase { + size_t input_offset; + size_t output_offset; +}; + +struct UrlTestData { + const char* const description; + const char* const input; + const char* const languages; + FormatUrlTypes format_types; + net::UnescapeRule::Type escape_rules; + const wchar_t* output; // Use |wchar_t| to handle Unicode constants easily. + size_t prefix_len; +}; + +// 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. +void AppendLanguagesToOutputs(const char* languages, + base::string16* expected, + base::string16* actual) { + base::string16 to_append = ASCIIToUTF16("::") + ASCIIToUTF16(languages); + expected->append(to_append); + actual->append(to_append); +} + +// A pair of helpers for the FormatUrlWithOffsets() test. +void VerboseExpect(size_t expected, + size_t actual, + const std::string& original_url, + size_t position, + const base::string16& formatted_url) { + EXPECT_EQ(expected, actual) << "Original URL: " << original_url + << " (at char " << position << ")\nFormatted URL: " << formatted_url; +} + +void CheckAdjustedOffsets(const std::string& url_string, + const std::string& languages, + FormatUrlTypes format_types, + net::UnescapeRule::Type unescape_rules, + const size_t* output_offsets) { + GURL url(url_string); + size_t url_length = url_string.length(); + std::vector<size_t> offsets; + for (size_t i = 0; i <= url_length + 1; ++i) + offsets.push_back(i); + offsets.push_back(500000); // Something larger than any input length. + offsets.push_back(std::string::npos); + base::string16 formatted_url = FormatUrlWithOffsets(url, languages, + format_types, unescape_rules, NULL, NULL, &offsets); + for (size_t i = 0; i < url_length; ++i) + VerboseExpect(output_offsets[i], offsets[i], url_string, i, formatted_url); + VerboseExpect(formatted_url.length(), offsets[url_length], url_string, + url_length, formatted_url); + VerboseExpect(base::string16::npos, offsets[url_length + 1], url_string, + 500000, formatted_url); + VerboseExpect(base::string16::npos, offsets[url_length + 2], url_string, + std::string::npos, formatted_url); +} + +TEST(UrlFormatterTest, IDNToUnicodeFast) { + for (size_t i = 0; i < arraysize(idn_cases); i++) { + for (size_t j = 0; j < arraysize(kLanguages); j++) { + // ja || zh-TW,en || ko,ja -> IDNToUnicodeSlow + if (j == 3 || j == 17 || j == 18) + continue; + base::string16 output(IDNToUnicode(idn_cases[i].input, kLanguages[j])); + base::string16 expected(idn_cases[i].unicode_allowed[j] ? + WideToUTF16(idn_cases[i].unicode_output) : + ASCIIToUTF16(idn_cases[i].input)); + AppendLanguagesToOutputs(kLanguages[j], &expected, &output); + EXPECT_EQ(expected, output) << "input: \"" << idn_cases[i].input + << "\", languages: \"" << kLanguages[j] + << "\""; + } + } +} + +TEST(UrlFormatterTest, IDNToUnicodeSlow) { + for (size_t i = 0; i < arraysize(idn_cases); i++) { + for (size_t j = 0; j < arraysize(kLanguages); j++) { + // !(ja || zh-TW,en || ko,ja) -> IDNToUnicodeFast + if (!(j == 3 || j == 17 || j == 18)) + continue; + base::string16 output(IDNToUnicode(idn_cases[i].input, kLanguages[j])); + base::string16 expected(idn_cases[i].unicode_allowed[j] ? + WideToUTF16(idn_cases[i].unicode_output) : + ASCIIToUTF16(idn_cases[i].input)); + AppendLanguagesToOutputs(kLanguages[j], &expected, &output); + EXPECT_EQ(expected, output) << "input: \"" << idn_cases[i].input + << "\", languages: \"" << kLanguages[j] + << "\""; + } + } +} + +// ulocdata_getExemplarSet may fail with some locales (currently bn, gu, and +// te), which was causing a crash (See http://crbug.com/510551). This may be an +// icu bug, but regardless, that should not cause a crash. +TEST(UrlFormatterTest, IDNToUnicodeNeverCrashes) { + for (char c1 = 'a'; c1 <= 'z'; c1++) { + for (char c2 = 'a'; c2 <= 'z'; c2++) { + std::string lang = base::StringPrintf("%c%c", c1, c2); + base::string16 output(IDNToUnicode("xn--74h", lang)); + } + } +} + +TEST(UrlFormatterTest, FormatUrl) { + FormatUrlTypes default_format_type = kFormatUrlOmitUsernamePassword; + const UrlTestData tests[] = { + {"Empty URL", "", "", default_format_type, net::UnescapeRule::NORMAL, L"", + 0}, + + {"Simple URL", "http://www.google.com/", "", default_format_type, + net::UnescapeRule::NORMAL, L"http://www.google.com/", 7}, + + {"With a port number and a reference", + "http://www.google.com:8080/#\xE3\x82\xB0", "", default_format_type, + net::UnescapeRule::NORMAL, L"http://www.google.com:8080/#\x30B0", 7}, + + // -------- IDN tests -------- + {"Japanese IDN with ja", "http://xn--l8jvb1ey91xtjb.jp", "ja", + default_format_type, net::UnescapeRule::NORMAL, + L"http://\x671d\x65e5\x3042\x3055\x3072.jp/", 7}, + + {"Japanese IDN with en", "http://xn--l8jvb1ey91xtjb.jp", "en", + default_format_type, net::UnescapeRule::NORMAL, + L"http://xn--l8jvb1ey91xtjb.jp/", 7}, + + {"Japanese IDN without any languages", "http://xn--l8jvb1ey91xtjb.jp", "", + default_format_type, net::UnescapeRule::NORMAL, + // Single script is safe for empty languages. + L"http://\x671d\x65e5\x3042\x3055\x3072.jp/", 7}, + + {"mailto: with Japanese IDN", "mailto:foo@xn--l8jvb1ey91xtjb.jp", "ja", + default_format_type, net::UnescapeRule::NORMAL, + // GURL doesn't assume an email address's domain part as a host name. + L"mailto:foo@xn--l8jvb1ey91xtjb.jp", 7}, + + {"file: with Japanese IDN", "file://xn--l8jvb1ey91xtjb.jp/config.sys", + "ja", default_format_type, net::UnescapeRule::NORMAL, + L"file://\x671d\x65e5\x3042\x3055\x3072.jp/config.sys", 7}, + + {"ftp: with Japanese IDN", "ftp://xn--l8jvb1ey91xtjb.jp/config.sys", "ja", + default_format_type, net::UnescapeRule::NORMAL, + L"ftp://\x671d\x65e5\x3042\x3055\x3072.jp/config.sys", 6}, + + // -------- omit_username_password flag tests -------- + {"With username and password, omit_username_password=false", + "http://user:passwd@example.com/foo", "", kFormatUrlOmitNothing, + net::UnescapeRule::NORMAL, L"http://user:passwd@example.com/foo", 19}, + + {"With username and password, omit_username_password=true", + "http://user:passwd@example.com/foo", "", default_format_type, + net::UnescapeRule::NORMAL, L"http://example.com/foo", 7}, + + {"With username and no password", "http://user@example.com/foo", "", + default_format_type, net::UnescapeRule::NORMAL, + L"http://example.com/foo", 7}, + + {"Just '@' without username and password", "http://@example.com/foo", "", + default_format_type, net::UnescapeRule::NORMAL, + L"http://example.com/foo", 7}, + + // GURL doesn't think local-part of an email address is username for URL. + {"mailto:, omit_username_password=true", "mailto:foo@example.com", "", + default_format_type, net::UnescapeRule::NORMAL, + L"mailto:foo@example.com", 7}, + + // -------- unescape flag tests -------- + {"Do not unescape", + "http://%E3%82%B0%E3%83%BC%E3%82%B0%E3%83%AB.jp/" + "%E3%82%B0%E3%83%BC%E3%82%B0%E3%83%AB" + "?q=%E3%82%B0%E3%83%BC%E3%82%B0%E3%83%AB", + "en", default_format_type, net::UnescapeRule::NONE, + // GURL parses %-encoded hostnames into Punycode. + L"http://xn--qcka1pmc.jp/%E3%82%B0%E3%83%BC%E3%82%B0%E3%83%AB" + L"?q=%E3%82%B0%E3%83%BC%E3%82%B0%E3%83%AB", + 7}, + + {"Unescape normally", + "http://%E3%82%B0%E3%83%BC%E3%82%B0%E3%83%AB.jp/" + "%E3%82%B0%E3%83%BC%E3%82%B0%E3%83%AB" + "?q=%E3%82%B0%E3%83%BC%E3%82%B0%E3%83%AB", + "en", default_format_type, net::UnescapeRule::NORMAL, + L"http://xn--qcka1pmc.jp/\x30B0\x30FC\x30B0\x30EB" + L"?q=\x30B0\x30FC\x30B0\x30EB", + 7}, + + {"Unescape normally with BiDi control character", + "http://example.com/%E2%80%AEabc?q=%E2%80%8Fxy", "en", + default_format_type, net::UnescapeRule::NORMAL, + L"http://example.com/%E2%80%AEabc?q=%E2%80%8Fxy", 7}, + + {"Unescape normally including unescape spaces", + "http://www.google.com/search?q=Hello%20World", "en", + default_format_type, net::UnescapeRule::SPACES, + L"http://www.google.com/search?q=Hello World", 7}, + + /* + {"unescape=true with some special characters", + "http://user%3A:%40passwd@example.com/foo%3Fbar?q=b%26z", "", + kFormatUrlOmitNothing, net::UnescapeRule::NORMAL, + L"http://user%3A:%40passwd@example.com/foo%3Fbar?q=b%26z", 25}, + */ + // Disabled: the resultant URL becomes "...user%253A:%2540passwd...". + + // -------- omit http: -------- + {"omit http with user name", "http://user@example.com/foo", "", + kFormatUrlOmitAll, net::UnescapeRule::NORMAL, L"example.com/foo", 0}, + + {"omit http", "http://www.google.com/", "en", kFormatUrlOmitHTTP, + net::UnescapeRule::NORMAL, L"www.google.com/", 0}, + + {"omit http with https", "https://www.google.com/", "en", + kFormatUrlOmitHTTP, net::UnescapeRule::NORMAL, + L"https://www.google.com/", 8}, + + {"omit http starts with ftp.", "http://ftp.google.com/", "en", + kFormatUrlOmitHTTP, net::UnescapeRule::NORMAL, L"http://ftp.google.com/", + 7}, + + // -------- omit trailing slash on bare hostname -------- + {"omit slash when it's the entire path", "http://www.google.com/", "en", + kFormatUrlOmitTrailingSlashOnBareHostname, net::UnescapeRule::NORMAL, + L"http://www.google.com", 7}, + {"omit slash when there's a ref", "http://www.google.com/#ref", "en", + kFormatUrlOmitTrailingSlashOnBareHostname, net::UnescapeRule::NORMAL, + L"http://www.google.com/#ref", 7}, + {"omit slash when there's a query", "http://www.google.com/?", "en", + kFormatUrlOmitTrailingSlashOnBareHostname, net::UnescapeRule::NORMAL, + L"http://www.google.com/?", 7}, + {"omit slash when it's not the entire path", "http://www.google.com/foo", + "en", kFormatUrlOmitTrailingSlashOnBareHostname, + net::UnescapeRule::NORMAL, L"http://www.google.com/foo", 7}, + {"omit slash for nonstandard URLs", "data:/", "en", + kFormatUrlOmitTrailingSlashOnBareHostname, net::UnescapeRule::NORMAL, + L"data:/", 5}, + {"omit slash for file URLs", "file:///", "en", + kFormatUrlOmitTrailingSlashOnBareHostname, net::UnescapeRule::NORMAL, + L"file:///", 7}, + + // -------- view-source: -------- + {"view-source", "view-source:http://xn--qcka1pmc.jp/", "ja", + default_format_type, net::UnescapeRule::NORMAL, + L"view-source:http://\x30B0\x30FC\x30B0\x30EB.jp/", 19}, + + {"view-source of view-source", + "view-source:view-source:http://xn--qcka1pmc.jp/", "ja", + default_format_type, net::UnescapeRule::NORMAL, + L"view-source:view-source:http://xn--qcka1pmc.jp/", 12}, + + // view-source should omit http and trailing slash where non-view-source + // would. + {"view-source omit http", "view-source:http://a.b/c", "en", + kFormatUrlOmitAll, net::UnescapeRule::NORMAL, L"view-source:a.b/c", 12}, + {"view-source omit http starts with ftp.", "view-source:http://ftp.b/c", + "en", kFormatUrlOmitAll, net::UnescapeRule::NORMAL, + L"view-source:http://ftp.b/c", 19}, + {"view-source omit slash when it's the entire path", + "view-source:http://a.b/", "en", kFormatUrlOmitAll, + net::UnescapeRule::NORMAL, L"view-source:a.b", 12}, + }; + + for (size_t i = 0; i < arraysize(tests); ++i) { + size_t prefix_len; + base::string16 formatted = FormatUrl( + GURL(tests[i].input), tests[i].languages, tests[i].format_types, + tests[i].escape_rules, NULL, &prefix_len, NULL); + EXPECT_EQ(WideToUTF16(tests[i].output), formatted) << tests[i].description; + EXPECT_EQ(tests[i].prefix_len, prefix_len) << tests[i].description; + } +} + +TEST(UrlFormatterTest, FormatUrlParsed) { + // No unescape case. + url::Parsed parsed; + base::string16 formatted = + FormatUrl(GURL("http://\xE3\x82\xB0:\xE3\x83\xBC@xn--qcka1pmc.jp:8080/" + "%E3%82%B0/?q=%E3%82%B0#\xE3\x82\xB0"), + "ja", kFormatUrlOmitNothing, net::UnescapeRule::NONE, &parsed, + NULL, NULL); + EXPECT_EQ(WideToUTF16( + L"http://%E3%82%B0:%E3%83%BC@\x30B0\x30FC\x30B0\x30EB.jp:8080" + L"/%E3%82%B0/?q=%E3%82%B0#\x30B0"), formatted); + EXPECT_EQ(WideToUTF16(L"%E3%82%B0"), + formatted.substr(parsed.username.begin, parsed.username.len)); + EXPECT_EQ(WideToUTF16(L"%E3%83%BC"), + formatted.substr(parsed.password.begin, parsed.password.len)); + EXPECT_EQ(WideToUTF16(L"\x30B0\x30FC\x30B0\x30EB.jp"), + formatted.substr(parsed.host.begin, parsed.host.len)); + EXPECT_EQ(WideToUTF16(L"8080"), + formatted.substr(parsed.port.begin, parsed.port.len)); + EXPECT_EQ(WideToUTF16(L"/%E3%82%B0/"), + formatted.substr(parsed.path.begin, parsed.path.len)); + EXPECT_EQ(WideToUTF16(L"q=%E3%82%B0"), + formatted.substr(parsed.query.begin, parsed.query.len)); + EXPECT_EQ(WideToUTF16(L"\x30B0"), + formatted.substr(parsed.ref.begin, parsed.ref.len)); + + // Unescape case. + formatted = + FormatUrl(GURL("http://\xE3\x82\xB0:\xE3\x83\xBC@xn--qcka1pmc.jp:8080/" + "%E3%82%B0/?q=%E3%82%B0#\xE3\x82\xB0"), + "ja", kFormatUrlOmitNothing, net::UnescapeRule::NORMAL, &parsed, + NULL, NULL); + EXPECT_EQ(WideToUTF16(L"http://\x30B0:\x30FC@\x30B0\x30FC\x30B0\x30EB.jp:8080" + L"/\x30B0/?q=\x30B0#\x30B0"), formatted); + EXPECT_EQ(WideToUTF16(L"\x30B0"), + formatted.substr(parsed.username.begin, parsed.username.len)); + EXPECT_EQ(WideToUTF16(L"\x30FC"), + formatted.substr(parsed.password.begin, parsed.password.len)); + EXPECT_EQ(WideToUTF16(L"\x30B0\x30FC\x30B0\x30EB.jp"), + formatted.substr(parsed.host.begin, parsed.host.len)); + EXPECT_EQ(WideToUTF16(L"8080"), + formatted.substr(parsed.port.begin, parsed.port.len)); + EXPECT_EQ(WideToUTF16(L"/\x30B0/"), + formatted.substr(parsed.path.begin, parsed.path.len)); + EXPECT_EQ(WideToUTF16(L"q=\x30B0"), + formatted.substr(parsed.query.begin, parsed.query.len)); + EXPECT_EQ(WideToUTF16(L"\x30B0"), + formatted.substr(parsed.ref.begin, parsed.ref.len)); + + // Omit_username_password + unescape case. + formatted = + FormatUrl(GURL("http://\xE3\x82\xB0:\xE3\x83\xBC@xn--qcka1pmc.jp:8080/" + "%E3%82%B0/?q=%E3%82%B0#\xE3\x82\xB0"), + "ja", kFormatUrlOmitUsernamePassword, net::UnescapeRule::NORMAL, + &parsed, NULL, NULL); + EXPECT_EQ(WideToUTF16(L"http://\x30B0\x30FC\x30B0\x30EB.jp:8080" + L"/\x30B0/?q=\x30B0#\x30B0"), formatted); + EXPECT_FALSE(parsed.username.is_valid()); + EXPECT_FALSE(parsed.password.is_valid()); + EXPECT_EQ(WideToUTF16(L"\x30B0\x30FC\x30B0\x30EB.jp"), + formatted.substr(parsed.host.begin, parsed.host.len)); + EXPECT_EQ(WideToUTF16(L"8080"), + formatted.substr(parsed.port.begin, parsed.port.len)); + EXPECT_EQ(WideToUTF16(L"/\x30B0/"), + formatted.substr(parsed.path.begin, parsed.path.len)); + EXPECT_EQ(WideToUTF16(L"q=\x30B0"), + formatted.substr(parsed.query.begin, parsed.query.len)); + EXPECT_EQ(WideToUTF16(L"\x30B0"), + formatted.substr(parsed.ref.begin, parsed.ref.len)); + + // View-source case. + formatted = + FormatUrl(GURL("view-source:http://user:passwd@host:81/path?query#ref"), + std::string(), kFormatUrlOmitUsernamePassword, + net::UnescapeRule::NORMAL, &parsed, NULL, NULL); + EXPECT_EQ(WideToUTF16(L"view-source:http://host:81/path?query#ref"), + formatted); + EXPECT_EQ(WideToUTF16(L"view-source:http"), + formatted.substr(parsed.scheme.begin, parsed.scheme.len)); + EXPECT_FALSE(parsed.username.is_valid()); + EXPECT_FALSE(parsed.password.is_valid()); + EXPECT_EQ(WideToUTF16(L"host"), + formatted.substr(parsed.host.begin, parsed.host.len)); + EXPECT_EQ(WideToUTF16(L"81"), + formatted.substr(parsed.port.begin, parsed.port.len)); + EXPECT_EQ(WideToUTF16(L"/path"), + formatted.substr(parsed.path.begin, parsed.path.len)); + EXPECT_EQ(WideToUTF16(L"query"), + formatted.substr(parsed.query.begin, parsed.query.len)); + EXPECT_EQ(WideToUTF16(L"ref"), + formatted.substr(parsed.ref.begin, parsed.ref.len)); + + // omit http case. + formatted = FormatUrl(GURL("http://host:8000/a?b=c#d"), std::string(), + kFormatUrlOmitHTTP, net::UnescapeRule::NORMAL, &parsed, + NULL, NULL); + EXPECT_EQ(WideToUTF16(L"host:8000/a?b=c#d"), formatted); + EXPECT_FALSE(parsed.scheme.is_valid()); + EXPECT_FALSE(parsed.username.is_valid()); + EXPECT_FALSE(parsed.password.is_valid()); + EXPECT_EQ(WideToUTF16(L"host"), + formatted.substr(parsed.host.begin, parsed.host.len)); + EXPECT_EQ(WideToUTF16(L"8000"), + formatted.substr(parsed.port.begin, parsed.port.len)); + EXPECT_EQ(WideToUTF16(L"/a"), + formatted.substr(parsed.path.begin, parsed.path.len)); + EXPECT_EQ(WideToUTF16(L"b=c"), + formatted.substr(parsed.query.begin, parsed.query.len)); + EXPECT_EQ(WideToUTF16(L"d"), + formatted.substr(parsed.ref.begin, parsed.ref.len)); + + // omit http starts with ftp case. + formatted = FormatUrl(GURL("http://ftp.host:8000/a?b=c#d"), std::string(), + kFormatUrlOmitHTTP, net::UnescapeRule::NORMAL, &parsed, + NULL, NULL); + EXPECT_EQ(WideToUTF16(L"http://ftp.host:8000/a?b=c#d"), formatted); + EXPECT_TRUE(parsed.scheme.is_valid()); + EXPECT_FALSE(parsed.username.is_valid()); + EXPECT_FALSE(parsed.password.is_valid()); + EXPECT_EQ(WideToUTF16(L"http"), + formatted.substr(parsed.scheme.begin, parsed.scheme.len)); + EXPECT_EQ(WideToUTF16(L"ftp.host"), + formatted.substr(parsed.host.begin, parsed.host.len)); + EXPECT_EQ(WideToUTF16(L"8000"), + formatted.substr(parsed.port.begin, parsed.port.len)); + EXPECT_EQ(WideToUTF16(L"/a"), + formatted.substr(parsed.path.begin, parsed.path.len)); + EXPECT_EQ(WideToUTF16(L"b=c"), + formatted.substr(parsed.query.begin, parsed.query.len)); + EXPECT_EQ(WideToUTF16(L"d"), + formatted.substr(parsed.ref.begin, parsed.ref.len)); + + // omit http starts with 'f' case. + formatted = FormatUrl(GURL("http://f/"), std::string(), kFormatUrlOmitHTTP, + net::UnescapeRule::NORMAL, &parsed, NULL, NULL); + EXPECT_EQ(WideToUTF16(L"f/"), formatted); + EXPECT_FALSE(parsed.scheme.is_valid()); + EXPECT_FALSE(parsed.username.is_valid()); + EXPECT_FALSE(parsed.password.is_valid()); + EXPECT_FALSE(parsed.port.is_valid()); + EXPECT_TRUE(parsed.path.is_valid()); + EXPECT_FALSE(parsed.query.is_valid()); + EXPECT_FALSE(parsed.ref.is_valid()); + EXPECT_EQ(WideToUTF16(L"f"), + formatted.substr(parsed.host.begin, parsed.host.len)); + EXPECT_EQ(WideToUTF16(L"/"), + formatted.substr(parsed.path.begin, parsed.path.len)); +} + +// Make sure that calling FormatUrl on a GURL and then converting back to a GURL +// results in the original GURL, for each ASCII character in the path. +TEST(UrlFormatterTest, FormatUrlRoundTripPathASCII) { + for (unsigned char test_char = 32; test_char < 128; ++test_char) { + GURL url(std::string("http://www.google.com/") + + static_cast<char>(test_char)); + size_t prefix_len; + base::string16 formatted = + FormatUrl(url, std::string(), kFormatUrlOmitUsernamePassword, + net::UnescapeRule::NORMAL, NULL, &prefix_len, NULL); + EXPECT_EQ(url.spec(), GURL(formatted).spec()); + } +} + +// Make sure that calling FormatUrl on a GURL and then converting back to a GURL +// results in the original GURL, for each escaped ASCII character in the path. +TEST(UrlFormatterTest, FormatUrlRoundTripPathEscaped) { + for (unsigned char test_char = 32; test_char < 128; ++test_char) { + std::string original_url("http://www.google.com/"); + original_url.push_back('%'); + original_url.append(base::HexEncode(&test_char, 1)); + + GURL url(original_url); + size_t prefix_len; + base::string16 formatted = + FormatUrl(url, std::string(), kFormatUrlOmitUsernamePassword, + net::UnescapeRule::NORMAL, NULL, &prefix_len, NULL); + EXPECT_EQ(url.spec(), GURL(formatted).spec()); + } +} + +// Make sure that calling FormatUrl on a GURL and then converting back to a GURL +// results in the original GURL, for each ASCII character in the query. +TEST(UrlFormatterTest, FormatUrlRoundTripQueryASCII) { + for (unsigned char test_char = 32; test_char < 128; ++test_char) { + GURL url(std::string("http://www.google.com/?") + + static_cast<char>(test_char)); + size_t prefix_len; + base::string16 formatted = + FormatUrl(url, std::string(), kFormatUrlOmitUsernamePassword, + net::UnescapeRule::NORMAL, NULL, &prefix_len, NULL); + EXPECT_EQ(url.spec(), GURL(formatted).spec()); + } +} + +// Make sure that calling FormatUrl on a GURL and then converting back to a GURL +// only results in a different GURL for certain characters. +TEST(UrlFormatterTest, FormatUrlRoundTripQueryEscaped) { + // A full list of characters which FormatURL should unescape and GURL should + // not escape again, when they appear in a query string. + const char kUnescapedCharacters[] = + "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz-_~"; + for (unsigned char test_char = 0; test_char < 128; ++test_char) { + std::string original_url("http://www.google.com/?"); + original_url.push_back('%'); + original_url.append(base::HexEncode(&test_char, 1)); + + GURL url(original_url); + size_t prefix_len; + base::string16 formatted = + FormatUrl(url, std::string(), kFormatUrlOmitUsernamePassword, + net::UnescapeRule::NORMAL, NULL, &prefix_len, NULL); + + if (test_char && + strchr(kUnescapedCharacters, static_cast<char>(test_char))) { + EXPECT_NE(url.spec(), GURL(formatted).spec()); + } else { + EXPECT_EQ(url.spec(), GURL(formatted).spec()); + } + } +} + +TEST(UrlFormatterTest, FormatUrlWithOffsets) { + CheckAdjustedOffsets(std::string(), "en", kFormatUrlOmitNothing, + net::UnescapeRule::NORMAL, NULL); + + const size_t basic_offsets[] = { + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, + 21, 22, 23, 24, 25 + }; + CheckAdjustedOffsets("http://www.google.com/foo/", "en", + kFormatUrlOmitNothing, net::UnescapeRule::NORMAL, + basic_offsets); + + const size_t omit_auth_offsets_1[] = { + 0, 1, 2, 3, 4, 5, 6, 7, kNpos, kNpos, kNpos, kNpos, kNpos, kNpos, kNpos, 7, + 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21 + }; + CheckAdjustedOffsets("http://foo:bar@www.google.com/", "en", + kFormatUrlOmitUsernamePassword, + net::UnescapeRule::NORMAL, omit_auth_offsets_1); + + const size_t omit_auth_offsets_2[] = { + 0, 1, 2, 3, 4, 5, 6, 7, kNpos, kNpos, kNpos, 7, 8, 9, 10, 11, 12, 13, 14, + 15, 16, 17, 18, 19, 20, 21 + }; + CheckAdjustedOffsets("http://foo@www.google.com/", "en", + kFormatUrlOmitUsernamePassword, + net::UnescapeRule::NORMAL, omit_auth_offsets_2); + + const size_t dont_omit_auth_offsets[] = { + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, kNpos, kNpos, kNpos, kNpos, kNpos, kNpos, + kNpos, kNpos, 11, 12, kNpos, kNpos, kNpos, kNpos, kNpos, kNpos, kNpos, + kNpos, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, + 30, 31 + }; + // Unescape to "http://foo\x30B0:\x30B0bar@www.google.com". + CheckAdjustedOffsets("http://foo%E3%82%B0:%E3%82%B0bar@www.google.com/", "en", + kFormatUrlOmitNothing, net::UnescapeRule::NORMAL, + dont_omit_auth_offsets); + + const size_t view_source_offsets[] = { + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, kNpos, + kNpos, kNpos, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33 + }; + CheckAdjustedOffsets("view-source:http://foo@www.google.com/", "en", + kFormatUrlOmitUsernamePassword, + net::UnescapeRule::NORMAL, view_source_offsets); + + const size_t idn_hostname_offsets_1[] = { + 0, 1, 2, 3, 4, 5, 6, 7, kNpos, kNpos, kNpos, kNpos, kNpos, kNpos, kNpos, + kNpos, kNpos, kNpos, kNpos, kNpos, kNpos, kNpos, kNpos, kNpos, kNpos, 12, + 13, 14, 15, 16, 17, 18, 19 + }; + // Convert punycode to "http://\x671d\x65e5\x3042\x3055\x3072.jp/foo/". + CheckAdjustedOffsets("http://xn--l8jvb1ey91xtjb.jp/foo/", "ja", + kFormatUrlOmitNothing, net::UnescapeRule::NORMAL, + idn_hostname_offsets_1); + + const size_t idn_hostname_offsets_2[] = { + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, kNpos, kNpos, kNpos, kNpos, kNpos, + kNpos, kNpos, kNpos, kNpos, kNpos, kNpos, 14, 15, kNpos, kNpos, kNpos, + kNpos, kNpos, kNpos, kNpos, kNpos, kNpos, kNpos, kNpos, kNpos, kNpos, kNpos, + kNpos, 19, 20, 21, 22, 23, 24 + }; + // Convert punycode to + // "http://test.\x89c6\x9891.\x5317\x4eac\x5927\x5b78.test/". + CheckAdjustedOffsets("http://test.xn--cy2a840a.xn--1lq90ic7f1rc.test/", + "zh-CN", kFormatUrlOmitNothing, + net::UnescapeRule::NORMAL, idn_hostname_offsets_2); + + const size_t unescape_offsets[] = { + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, + 21, 22, 23, 24, 25, kNpos, kNpos, 26, 27, 28, 29, 30, kNpos, kNpos, kNpos, + kNpos, kNpos, kNpos, kNpos, kNpos, 31, kNpos, kNpos, kNpos, kNpos, kNpos, + kNpos, kNpos, kNpos, 32, kNpos, kNpos, kNpos, kNpos, kNpos, kNpos, kNpos, + kNpos, 33, kNpos, kNpos, kNpos, kNpos, kNpos, kNpos, kNpos, kNpos + }; + // Unescape to "http://www.google.com/foo bar/\x30B0\x30FC\x30B0\x30EB". + CheckAdjustedOffsets( + "http://www.google.com/foo%20bar/%E3%82%B0%E3%83%BC%E3%82%B0%E3%83%AB", + "en", kFormatUrlOmitNothing, net::UnescapeRule::SPACES, unescape_offsets); + + const size_t ref_offsets[] = { + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, + 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, kNpos, kNpos, 32, kNpos, kNpos, + 33 + }; + // Unescape to "http://www.google.com/foo.html#\x30B0\x30B0z". + CheckAdjustedOffsets( + "http://www.google.com/foo.html#\xE3\x82\xB0\xE3\x82\xB0z", "en", + kFormatUrlOmitNothing, net::UnescapeRule::NORMAL, ref_offsets); + + const size_t omit_http_offsets[] = { + 0, kNpos, kNpos, kNpos, kNpos, kNpos, kNpos, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, + 10, 11, 12, 13, 14 + }; + CheckAdjustedOffsets("http://www.google.com/", "en", kFormatUrlOmitHTTP, + net::UnescapeRule::NORMAL, omit_http_offsets); + + const size_t omit_http_start_with_ftp_offsets[] = { + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21 + }; + CheckAdjustedOffsets("http://ftp.google.com/", "en", kFormatUrlOmitHTTP, + net::UnescapeRule::NORMAL, + omit_http_start_with_ftp_offsets); + + const size_t omit_all_offsets[] = { + 0, kNpos, kNpos, kNpos, kNpos, kNpos, kNpos, 0, kNpos, kNpos, kNpos, kNpos, + 0, 1, 2, 3, 4, 5, 6, 7 + }; + CheckAdjustedOffsets("http://user@foo.com/", "en", kFormatUrlOmitAll, + net::UnescapeRule::NORMAL, omit_all_offsets); +} + +} // namespace + +} // namespace url_formatter diff --git a/content/browser/BUILD.gn b/content/browser/BUILD.gn index 6281b91..0c9d657 100644 --- a/content/browser/BUILD.gn +++ b/content/browser/BUILD.gn @@ -23,6 +23,7 @@ source_set("browser") { "//base", "//base:base_static", "//components/mime_util", + "//components/url_formatter", "//content:resources", "//content/browser/background_sync:background_sync_proto", "//content/browser/cache_storage:cache_storage_proto", diff --git a/content/browser/DEPS b/content/browser/DEPS index 8baf02e..c3668d8 100644 --- a/content/browser/DEPS +++ b/content/browser/DEPS @@ -4,6 +4,7 @@ include_rules = [ "+components/mime_util", "+components/scheduler/common", "+components/tracing", + "+components/url_formatter", "+content/app/strings/grit", # For generated headers "+content/public/browser", diff --git a/content/browser/download/save_package.cc b/content/browser/download/save_package.cc index f05c253..8b4fc11 100644 --- a/content/browser/download/save_package.cc +++ b/content/browser/download/save_package.cc @@ -18,6 +18,7 @@ #include "base/strings/sys_string_conversions.h" #include "base/strings/utf_string_conversions.h" #include "base/threading/thread.h" +#include "components/url_formatter/url_formatter.h" #include "content/browser/download/download_item_impl.h" #include "content/browser/download/download_manager_impl.h" #include "content/browser/download/download_stats.h" @@ -1214,7 +1215,7 @@ base::FilePath SavePackage::GetSuggestedNameForSaveAs( // back to a URL, and if it matches the original page URL, we know the page // had no title (or had a title equal to its URL, which is fine to treat // similarly). - if (title_ == net::FormatUrl(page_url_, accept_langs)) { + if (title_ == url_formatter::FormatUrl(page_url_, accept_langs)) { std::string url_path; if (!page_url_.SchemeIs(url::kDataScheme)) { std::vector<std::string> url_parts; diff --git a/content/browser/frame_host/navigation_entry_impl.cc b/content/browser/frame_host/navigation_entry_impl.cc index 70e01b6..3d55521 100644 --- a/content/browser/frame_host/navigation_entry_impl.cc +++ b/content/browser/frame_host/navigation_entry_impl.cc @@ -9,10 +9,10 @@ #include "base/metrics/histogram.h" #include "base/strings/string_util.h" #include "base/strings/utf_string_conversions.h" +#include "components/url_formatter/url_formatter.h" #include "content/common/navigation_params.h" #include "content/public/common/content_constants.h" #include "content/public/common/url_constants.h" -#include "net/base/net_util.h" #include "ui/gfx/text_elider.h" // Use this to get a new unique ID for a NavigationEntry during construction. @@ -225,9 +225,9 @@ const base::string16& NavigationEntryImpl::GetTitleForDisplay( // Use the virtual URL first if any, and fall back on using the real URL. base::string16 title; if (!virtual_url_.is_empty()) { - title = net::FormatUrl(virtual_url_, languages); + title = url_formatter::FormatUrl(virtual_url_, languages); } else if (!GetURL().is_empty()) { - title = net::FormatUrl(GetURL(), languages); + title = url_formatter::FormatUrl(GetURL(), languages); } // For file:// URLs use the filename as the title, not the full path. diff --git a/content/browser/web_contents/web_contents_impl.cc b/content/browser/web_contents/web_contents_impl.cc index 287d016..c235923 100644 --- a/content/browser/web_contents/web_contents_impl.cc +++ b/content/browser/web_contents/web_contents_impl.cc @@ -22,6 +22,7 @@ #include "base/time/time.h" #include "base/trace_event/trace_event.h" #include "components/mime_util/mime_util.h" +#include "components/url_formatter/url_formatter.h" #include "content/browser/accessibility/accessibility_mode_helper.h" #include "content/browser/accessibility/browser_accessibility_state_impl.h" #include "content/browser/bad_message.h" @@ -101,7 +102,6 @@ #include "content/public/common/web_preferences.h" #include "mojo/common/url_type_converters.h" #include "mojo/converters/geometry/geometry_type_converters.h" -#include "net/base/net_util.h" #include "net/http/http_cache.h" #include "net/http/http_transaction_factory.h" #include "net/url_request/url_request_context.h" @@ -4250,9 +4250,9 @@ void WebContentsImpl::LoadStateChanged( load_state_ = load_state; upload_position_ = upload_position; upload_size_ = upload_size; - load_state_host_ = net::IDNToUnicode(url.host(), - GetContentClient()->browser()->GetAcceptLangs( - GetBrowserContext())); + load_state_host_ = url_formatter::IDNToUnicode( + url.host(), + GetContentClient()->browser()->GetAcceptLangs(GetBrowserContext())); if (load_state_.state == net::LOAD_STATE_READING_RESPONSE) SetNotWaitingForResponse(); if (IsLoading()) { diff --git a/content/content_browser.gypi b/content/content_browser.gypi index fc005c6..5ce366c 100644 --- a/content/content_browser.gypi +++ b/content/content_browser.gypi @@ -5,6 +5,7 @@ { 'dependencies': [ '../base/base.gyp:base_static', + '../components/url_formatter/url_formatter.gyp:url_formatter', '../crypto/crypto.gyp:crypto', '../device/battery/battery.gyp:device_battery', '../device/battery/battery.gyp:device_battery_mojo_bindings', diff --git a/content/content_renderer.gypi b/content/content_renderer.gypi index 99108c3..9a24f9e 100644 --- a/content/content_renderer.gypi +++ b/content/content_renderer.gypi @@ -9,6 +9,7 @@ '../cc/cc.gyp:cc', '../cc/blink/cc_blink.gyp:cc_blink', '../components/scheduler/scheduler.gyp:scheduler', + '../components/url_formatter/url_formatter.gyp:url_formatter', '../device/battery/battery.gyp:device_battery', '../device/battery/battery.gyp:device_battery_mojo_bindings', '../device/vibration/vibration.gyp:device_vibration', diff --git a/content/content_shell.gypi b/content/content_shell.gypi index 4ae18d1..21a6213 100644 --- a/content/content_shell.gypi +++ b/content/content_shell.gypi @@ -52,6 +52,7 @@ '../components/components.gyp:web_cache_renderer', '../components/components.gyp:plugins_renderer', '../components/test_runner/test_runner.gyp:test_runner', + '../components/url_formatter/url_formatter.gyp:url_formatter', '../device/bluetooth/bluetooth.gyp:device_bluetooth', '../device/bluetooth/bluetooth.gyp:device_bluetooth_mocks', '../gin/gin.gyp:gin', diff --git a/content/renderer/BUILD.gn b/content/renderer/BUILD.gn index e4a9a0b..e05fe03 100644 --- a/content/renderer/BUILD.gn +++ b/content/renderer/BUILD.gn @@ -28,6 +28,7 @@ source_set("renderer") { "//base/allocator", "//cc", "//cc/blink", + "//components/url_formatter", "//components/scheduler:scheduler", "//content:resources", "//content/common:mojo_bindings", diff --git a/content/renderer/DEPS b/content/renderer/DEPS index 5ea2ee7..75024b9 100644 --- a/content/renderer/DEPS +++ b/content/renderer/DEPS @@ -2,6 +2,7 @@ include_rules = [ # Allow inclusion of specific components that we depend on. We may only # depend on components which we share with the mojo html_viewer. "+components/scheduler", + "+components/url_formatter", "+cc/blink", "+content/public/child", diff --git a/content/renderer/renderer_blink_platform_impl.cc b/content/renderer/renderer_blink_platform_impl.cc index ed79baa..d787860 100644 --- a/content/renderer/renderer_blink_platform_impl.cc +++ b/content/renderer/renderer_blink_platform_impl.cc @@ -21,6 +21,7 @@ #include "components/scheduler/child/web_scheduler_impl.h" #include "components/scheduler/renderer/renderer_scheduler.h" #include "components/scheduler/renderer/webthread_impl_for_renderer_scheduler.h" +#include "components/url_formatter/url_formatter.h" #include "content/child/database_util.h" #include "content/child/file_info_util.h" #include "content/child/fileapi/webfilesystem_impl.h" @@ -69,7 +70,6 @@ #include "media/base/mime_util.h" #include "media/blink/webcontentdecryptionmodule_impl.h" #include "media/filters/stream_parser_factory.h" -#include "net/base/net_util.h" #include "storage/common/database/database_identifier.h" #include "storage/common/quota/quota_types.h" #include "third_party/WebKit/public/platform/WebBatteryStatusListener.h" @@ -1033,7 +1033,7 @@ blink::WebCompositorSupport* RendererBlinkPlatformImpl::compositorSupport() { blink::WebString RendererBlinkPlatformImpl::convertIDNToUnicode( const blink::WebString& host, const blink::WebString& languages) { - return net::IDNToUnicode(host.utf8(), languages.utf8()); + return url_formatter::IDNToUnicode(host.utf8(), languages.utf8()); } //------------------------------------------------------------------------------ diff --git a/content/shell/BUILD.gn b/content/shell/BUILD.gn index d5b4c1e..126d1c7 100644 --- a/content/shell/BUILD.gn +++ b/content/shell/BUILD.gn @@ -203,6 +203,7 @@ static_library("content_shell_lib") { "//components/devtools_http_handler", "//components/plugins/renderer", "//components/test_runner:test_runner", + "//components/url_formatter", "//components/web_cache/renderer", "//content:resources", "//content/app/resources", diff --git a/content/shell/DEPS b/content/shell/DEPS index fadafc0..067c10f 100644 --- a/content/shell/DEPS +++ b/content/shell/DEPS @@ -26,6 +26,7 @@ include_rules = [ "+components/crash", "+components/devtools_discovery", "+components/devtools_http_handler", + "+components/url_formatter", # For enabling media related features. "+media/base/media_switches.h", diff --git a/content/shell/browser/shell_javascript_dialog_manager.cc b/content/shell/browser/shell_javascript_dialog_manager.cc index 3eceb34..b6d8d0a 100644 --- a/content/shell/browser/shell_javascript_dialog_manager.cc +++ b/content/shell/browser/shell_javascript_dialog_manager.cc @@ -7,11 +7,11 @@ #include "base/command_line.h" #include "base/logging.h" #include "base/strings/utf_string_conversions.h" +#include "components/url_formatter/url_formatter.h" #include "content/public/browser/web_contents.h" #include "content/shell/browser/blink_test_controller.h" #include "content/shell/browser/shell_javascript_dialog.h" #include "content/shell/common/shell_switches.h" -#include "net/base/net_util.h" namespace content { @@ -46,9 +46,9 @@ void ShellJavaScriptDialogManager::RunJavaScriptDialog( return; } - base::string16 new_message_text = net::FormatUrl(origin_url, accept_lang) + - base::ASCIIToUTF16("\n\n") + - message_text; + base::string16 new_message_text = + url_formatter::FormatUrl(origin_url, accept_lang) + + base::ASCIIToUTF16("\n\n") + message_text; gfx::NativeWindow parent_window = web_contents->GetTopLevelNativeWindow(); dialog_.reset(new ShellJavaScriptDialog(this, diff --git a/ios/web/DEPS b/ios/web/DEPS index a956ff6..237ab93 100644 --- a/ios/web/DEPS +++ b/ios/web/DEPS @@ -1,4 +1,5 @@ include_rules = [ + "+components/url_formatter", "+crypto", "+ios/public/provider/web", "+ios/net", diff --git a/ios/web/ios_web.gyp b/ios/web/ios_web.gyp index 22fb83b..577d15d 100644 --- a/ios/web/ios_web.gyp +++ b/ios/web/ios_web.gyp @@ -51,6 +51,7 @@ 'js_resources', 'user_agent', '../../base/base.gyp:base', + '../../components/url_formatter/url_formatter.gyp:url_formatter', '../../content/content.gyp:content_browser', '../../ios/net/ios_net.gyp:ios_net', '../../ios/third_party/blink/blink_html_tokenizer.gyp:blink_html_tokenizer', diff --git a/ios/web/navigation/navigation_item_impl.mm b/ios/web/navigation/navigation_item_impl.mm index 6b423d1..76ddec7 100644 --- a/ios/web/navigation/navigation_item_impl.mm +++ b/ios/web/navigation/navigation_item_impl.mm @@ -6,7 +6,7 @@ #include "base/logging.h" #include "base/memory/scoped_ptr.h" -#include "net/base/net_util.h" +#include "components/url_formatter/url_formatter.h" #include "ui/base/page_transition_types.h" #include "ui/gfx/text_elider.h" @@ -138,9 +138,9 @@ const base::string16& NavigationItemImpl::GetTitleForDisplay( // Use the virtual URL first if any, and fall back on using the real URL. base::string16 title; if (!virtual_url_.is_empty()) { - title = net::FormatUrl(virtual_url_, languages); + title = url_formatter::FormatUrl(virtual_url_, languages); } else if (!url_.is_empty()) { - title = net::FormatUrl(url_, languages); + title = url_formatter::FormatUrl(url_, languages); } // For file:// URLs use the filename as the title, not the full path. diff --git a/ios/web/web_state/ui/crw_web_controller.mm b/ios/web/web_state/ui/crw_web_controller.mm index 6d89070..165aff9 100644 --- a/ios/web/web_state/ui/crw_web_controller.mm +++ b/ios/web/web_state/ui/crw_web_controller.mm @@ -28,6 +28,7 @@ #include "base/strings/utf_string_conversions.h" #include "base/time/time.h" #include "base/values.h" +#include "components/url_formatter/url_formatter.h" #import "ios/net/nsurlrequest_util.h" #include "ios/public/provider/web/web_ui_ios.h" #import "ios/web/history_state_util.h" @@ -79,7 +80,6 @@ #import "ios/web/web_state/web_state_impl.h" #import "net/base/mac/url_conversions.h" #include "net/base/net_errors.h" -#include "net/base/net_util.h" #import "ui/base/ios/cru_context_menu_holder.h" #include "ui/base/page_transition_types.h" #include "url/gurl.h" @@ -3573,7 +3573,8 @@ const NSTimeInterval kSnapshotOverlayTransition = 0.5; DCHECK(web::GetWebClient()); const std::string& acceptLangs = web::GetWebClient()->GetAcceptLangs( self.webStateImpl->GetBrowserState()); - base::string16 urlText = net::FormatUrl(GURL(href), acceptLangs); + base::string16 urlText = + url_formatter::FormatUrl(GURL(href), acceptLangs); title = base::SysUTF16ToNSString(urlText); } } diff --git a/net/base/net_util.cc b/net/base/net_util.cc index d4b525b..b27246b 100644 --- a/net/base/net_util.cc +++ b/net/base/net_util.cc @@ -432,14 +432,6 @@ std::string GetHostOrSpecFromURL(const GURL& url) { return url.has_host() ? TrimEndingDot(url.host()) : url.spec(); } -bool CanStripTrailingSlash(const GURL& url) { - // Omit the path only for standard, non-file URLs with nothing but "/" after - // the hostname. - return url.IsStandard() && !url.SchemeIsFile() && - !url.SchemeIsFileSystem() && !url.has_query() && !url.has_ref() - && url.path() == "/"; -} - GURL SimplifyUrlForRequest(const GURL& url) { DCHECK(url.is_valid()); GURL::Replacements replacements; diff --git a/net/base/net_util.h b/net/base/net_util.h index 628abe2..597e52e 100644 --- a/net/base/net_util.h +++ b/net/base/net_util.h @@ -48,31 +48,11 @@ class AddressList; // Keep this in sync. typedef std::vector<unsigned char> IPAddressNumber; -// Used by FormatUrl to specify handling of certain parts of the url. -typedef uint32_t FormatUrlType; -typedef uint32_t FormatUrlTypes; - #if defined(OS_WIN) // Bluetooth address size. Windows Bluetooth is supported via winsock. static const size_t kBluetoothAddressSize = 6; #endif -// Nothing is ommitted. -NET_EXPORT extern const FormatUrlType kFormatUrlOmitNothing; - -// If set, any username and password are removed. -NET_EXPORT extern const FormatUrlType kFormatUrlOmitUsernamePassword; - -// If the scheme is 'http://', it's removed. -NET_EXPORT extern const FormatUrlType kFormatUrlOmitHTTP; - -// Omits the path if it is just a slash and there is no query or ref. This is -// meaningful for non-file "standard" URLs. -NET_EXPORT extern const FormatUrlType kFormatUrlOmitTrailingSlashOnBareHostname; - -// Convenience for omitting all unecessary types. -NET_EXPORT extern const FormatUrlType kFormatUrlOmitAll; - // Splits an input of the form <host>[":"<port>] into its consitituent parts. // Saves the result into |*host| and |*port|. If the input did not have // the optional port, sets |*port| to -1. @@ -147,24 +127,6 @@ NET_EXPORT_PRIVATE void GetIdentityFromURL(const GURL& url, // Returns either the host from |url|, or, if the host is empty, the full spec. NET_EXPORT std::string GetHostOrSpecFromURL(const GURL& url); -// Converts the given host name to unicode characters. This can be called for -// any host name, if the input is not IDN or is invalid in some way, we'll just -// return the ASCII source so it is still usable. -// -// The input should be the canonicalized ASCII host name from GURL. This -// function does NOT accept UTF-8! -// -// |languages| is a comma separated list of ISO 639 language codes. It -// is used to determine whether a hostname is 'comprehensible' to a user -// who understands languages listed. |host| will be converted to a -// human-readable form (Unicode) ONLY when each component of |host| is -// regarded as 'comprehensible'. Scipt-mixing is not allowed except that -// Latin letters in the ASCII range can be mixed with a limited set of -// script-language pairs (currently Han, Kana and Hangul for zh,ja and ko). -// When |languages| is empty, even that mixing is not allowed. -NET_EXPORT base::string16 IDNToUnicode(const std::string& host, - const std::string& languages); - // Canonicalizes |host| and returns it. Also fills |host_info| with // IP address information. |host_info| must not be NULL. NET_EXPORT std::string CanonicalizeHost(const std::string& host, @@ -214,84 +176,6 @@ NET_EXPORT base::string16 StripWWWFromHost(const GURL& url); // Set socket to non-blocking mode NET_EXPORT int SetNonBlocking(int fd); -// Formats the host in |url| and appends it to |output|. The host formatter -// takes the same accept languages component as ElideURL(). -NET_EXPORT void AppendFormattedHost(const GURL& url, - const std::string& languages, - base::string16* output); - -// Creates a string representation of |url|. The IDN host name may be in Unicode -// if |languages| accepts the Unicode representation. |format_type| is a bitmask -// of FormatUrlTypes, see it for details. |unescape_rules| defines how to clean -// the URL for human readability. You will generally want |UnescapeRule::SPACES| -// for display to the user if you can handle spaces, or |UnescapeRule::NORMAL| -// if not. If the path part and the query part seem to be encoded in %-encoded -// UTF-8, decodes %-encoding and UTF-8. -// -// The last three parameters may be NULL. -// -// |new_parsed| will be set to the parsing parameters of the resultant URL. -// -// |prefix_end| will be the length before the hostname of the resultant URL. -// -// |offset[s]_for_adjustment| specifies one or more offsets into the original -// URL, representing insertion or selection points between characters: if the -// input is "http://foo.com/", offset 0 is before the entire URL, offset 7 is -// between the scheme and the host, and offset 15 is after the end of the URL. -// Valid input offsets range from 0 to the length of the input URL string. On -// exit, each offset will have been modified to reflect any changes made to the -// output string. For example, if |url| is "http://a:b@c.com/", -// |omit_username_password| is true, and an offset is 12 (pointing between 'c' -// and '.'), then on return the output string will be "http://c.com/" and the -// offset will be 8. If an offset cannot be successfully adjusted (e.g. because -// it points into the middle of a component that was entirely removed or into -// the middle of an encoding sequence), it will be set to base::string16::npos. -// For consistency, if an input offset points between the scheme and the -// username/password, and both are removed, on output this offset will be 0 -// rather than npos; this means that offsets at the starts and ends of removed -// components are always transformed the same way regardless of what other -// components are adjacent. -NET_EXPORT base::string16 FormatUrl(const GURL& url, - const std::string& languages, - FormatUrlTypes format_types, - UnescapeRule::Type unescape_rules, - url::Parsed* new_parsed, - size_t* prefix_end, - size_t* offset_for_adjustment); -NET_EXPORT base::string16 FormatUrlWithOffsets( - const GURL& url, - const std::string& languages, - FormatUrlTypes format_types, - UnescapeRule::Type unescape_rules, - url::Parsed* new_parsed, - size_t* prefix_end, - std::vector<size_t>* offsets_for_adjustment); -// This function is like those above except it takes |adjustments| rather -// than |offset[s]_for_adjustment|. |adjustments| will be set to reflect all -// the transformations that happened to |url| to convert it into the returned -// value. -NET_EXPORT base::string16 FormatUrlWithAdjustments( - const GURL& url, - const std::string& languages, - FormatUrlTypes format_types, - UnescapeRule::Type unescape_rules, - url::Parsed* new_parsed, - size_t* prefix_end, - base::OffsetAdjuster::Adjustments* adjustments); - -// This is a convenience function for FormatUrl() with -// format_types = kFormatUrlOmitAll and unescape = SPACES. This is the typical -// set of flags for "URLs to display to the user". You should be cautious about -// using this for URLs which will be parsed or sent to other applications. -inline base::string16 FormatUrl(const GURL& url, const std::string& languages) { - return FormatUrl(url, languages, kFormatUrlOmitAll, UnescapeRule::SPACES, - NULL, NULL, NULL); -} - -// Returns whether FormatUrl() would strip a trailing slash from |url|, given a -// format flag including kFormatUrlOmitTrailingSlashOnBareHostname. -NET_EXPORT bool CanStripTrailingSlash(const GURL& url); - // Strip the portions of |url| that aren't core to the network request. // - user name / password // - reference section diff --git a/net/base/net_util_icu.cc b/net/base/net_util_icu.cc index 259baba..c174c92 100644 --- a/net/base/net_util_icu.cc +++ b/net/base/net_util_icu.cc @@ -4,594 +4,19 @@ #include "net/base/net_util.h" -#include <map> -#include <vector> - #include "base/i18n/time_formatting.h" #include "base/json/string_escape.h" -#include "base/lazy_instance.h" -#include "base/logging.h" -#include "base/memory/singleton.h" -#include "base/stl_util.h" -#include "base/strings/string_tokenizer.h" #include "base/strings/string_util.h" -#include "base/strings/utf_offset_string_conversions.h" #include "base/strings/utf_string_conversions.h" -#include "base/time/time.h" -#include "url/gurl.h" -#include "third_party/icu/source/common/unicode/uidna.h" -#include "third_party/icu/source/common/unicode/uniset.h" -#include "third_party/icu/source/common/unicode/uscript.h" -#include "third_party/icu/source/common/unicode/uset.h" -#include "third_party/icu/source/i18n/unicode/datefmt.h" -#include "third_party/icu/source/i18n/unicode/regex.h" -#include "third_party/icu/source/i18n/unicode/ulocdata.h" - -using base::Time; +#include "net/base/escape.h" namespace net { -namespace { - -typedef std::vector<size_t> Offsets; - -// Does some simple normalization of scripts so we can allow certain scripts -// to exist together. -// TODO(brettw) bug 880223: we should allow some other languages to be -// oombined such as Chinese and Latin. We will probably need a more -// complicated system of language pairs to have more fine-grained control. -UScriptCode NormalizeScript(UScriptCode code) { - switch (code) { - case USCRIPT_KATAKANA: - case USCRIPT_HIRAGANA: - case USCRIPT_KATAKANA_OR_HIRAGANA: - case USCRIPT_HANGUL: // This one is arguable. - return USCRIPT_HAN; - default: - return code; - } -} - -bool IsIDNComponentInSingleScript(const base::char16* str, int str_len) { - UScriptCode first_script = USCRIPT_INVALID_CODE; - bool is_first = true; - - int i = 0; - while (i < str_len) { - unsigned code_point; - U16_NEXT(str, i, str_len, code_point); - - UErrorCode err = U_ZERO_ERROR; - UScriptCode cur_script = uscript_getScript(code_point, &err); - if (err != U_ZERO_ERROR) - return false; // Report mixed on error. - cur_script = NormalizeScript(cur_script); - - // TODO(brettw) We may have to check for USCRIPT_INHERENT as well. - if (is_first && cur_script != USCRIPT_COMMON) { - first_script = cur_script; - is_first = false; - } else { - if (cur_script != USCRIPT_COMMON && cur_script != first_script) - return false; - } - } - return true; -} - -// Check if the script of a language can be 'safely' mixed with -// Latin letters in the ASCII range. -bool IsCompatibleWithASCIILetters(const std::string& lang) { - // For now, just list Chinese, Japanese and Korean (positive list). - // An alternative is negative-listing (languages using Greek and - // Cyrillic letters), but it can be more dangerous. - return !lang.substr(0, 2).compare("zh") || - !lang.substr(0, 2).compare("ja") || - !lang.substr(0, 2).compare("ko"); -} - -typedef std::map<std::string, icu::UnicodeSet*> LangToExemplarSetMap; - -class LangToExemplarSet { - public: - static LangToExemplarSet* GetInstance() { - return Singleton<LangToExemplarSet>::get(); - } - - private: - LangToExemplarSetMap map; - LangToExemplarSet() { } - ~LangToExemplarSet() { - STLDeleteContainerPairSecondPointers(map.begin(), map.end()); - } - - friend class Singleton<LangToExemplarSet>; - friend struct DefaultSingletonTraits<LangToExemplarSet>; - friend bool GetExemplarSetForLang(const std::string&, icu::UnicodeSet**); - friend void SetExemplarSetForLang(const std::string&, icu::UnicodeSet*); - - DISALLOW_COPY_AND_ASSIGN(LangToExemplarSet); -}; - -bool GetExemplarSetForLang(const std::string& lang, - icu::UnicodeSet** lang_set) { - const LangToExemplarSetMap& map = LangToExemplarSet::GetInstance()->map; - LangToExemplarSetMap::const_iterator pos = map.find(lang); - if (pos != map.end()) { - *lang_set = pos->second; - return true; - } - return false; -} - -void SetExemplarSetForLang(const std::string& lang, - icu::UnicodeSet* lang_set) { - LangToExemplarSetMap& map = LangToExemplarSet::GetInstance()->map; - map.insert(std::make_pair(lang, lang_set)); -} - -static base::LazyInstance<base::Lock>::Leaky - g_lang_set_lock = LAZY_INSTANCE_INITIALIZER; - -// Returns true if all the characters in component_characters are used by -// the language |lang|. -bool IsComponentCoveredByLang(const icu::UnicodeSet& component_characters, - const std::string& lang) { - CR_DEFINE_STATIC_LOCAL( - const icu::UnicodeSet, kASCIILetters, ('a', 'z')); - icu::UnicodeSet* lang_set = nullptr; - // We're called from both the UI thread and the history thread. - { - base::AutoLock lock(g_lang_set_lock.Get()); - if (!GetExemplarSetForLang(lang, &lang_set)) { - UErrorCode status = U_ZERO_ERROR; - ULocaleData* uld = ulocdata_open(lang.c_str(), &status); - // TODO(jungshik) Turn this check on when the ICU data file is - // rebuilt with the minimal subset of locale data for languages - // to which Chrome is not localized but which we offer in the list - // of languages selectable for Accept-Languages. With the rebuilt ICU - // data, ulocdata_open never should fall back to the default locale. - // (issue 2078) - // DCHECK(U_SUCCESS(status) && status != U_USING_DEFAULT_WARNING); - if (U_SUCCESS(status) && status != U_USING_DEFAULT_WARNING) { - lang_set = reinterpret_cast<icu::UnicodeSet*>(ulocdata_getExemplarSet( - uld, nullptr, 0, ULOCDATA_ES_STANDARD, &status)); - // On success, if |lang| is compatible with ASCII Latin letters, add - // them. - if (lang_set && IsCompatibleWithASCIILetters(lang)) - lang_set->addAll(kASCIILetters); - } - - if (!lang_set) - lang_set = new icu::UnicodeSet(1, 0); - - lang_set->freeze(); - SetExemplarSetForLang(lang, lang_set); - ulocdata_close(uld); - } - } - return !lang_set->isEmpty() && lang_set->containsAll(component_characters); -} - -// Returns true if the given Unicode host component is safe to display to the -// user. -bool IsIDNComponentSafe(const base::char16* str, - int str_len, - const std::string& languages) { - // Most common cases (non-IDN) do not reach here so that we don't - // need a fast return path. - // TODO(jungshik) : Check if there's any character inappropriate - // (although allowed) for domain names. - // See http://www.unicode.org/reports/tr39/#IDN_Security_Profiles and - // http://www.unicode.org/reports/tr39/data/xidmodifications.txt - // For now, we borrow the list from Mozilla and tweaked it slightly. - // (e.g. Characters like U+00A0, U+3000, U+3002 are omitted because - // they're gonna be canonicalized to U+0020 and full stop before - // reaching here.) - // The original list is available at - // http://kb.mozillazine.org/Network.IDN.blacklist_chars and - // at http://mxr.mozilla.org/seamonkey/source/modules/libpref/src/init/all.js#703 - - UErrorCode status = U_ZERO_ERROR; -#ifdef U_WCHAR_IS_UTF16 - icu::UnicodeSet dangerous_characters( - icu::UnicodeString( - L"[[\\ \u00ad\u00bc\u00bd\u01c3\u0337\u0338" - L"\u05c3\u05f4\u06d4\u0702\u115f\u1160][\u2000-\u200b]" - L"[\u2024\u2027\u2028\u2029\u2039\u203a\u2044\u205f]" - L"[\u2154-\u2156][\u2159-\u215b][\u215f\u2215\u23ae" - L"\u29f6\u29f8\u2afb\u2afd][\u2ff0-\u2ffb][\u3014" - L"\u3015\u3033\u3164\u321d\u321e\u33ae\u33af\u33c6\u33df\ufe14" - L"\ufe15\ufe3f\ufe5d\ufe5e\ufeff\uff0e\uff06\uff61\uffa0\ufff9]" - L"[\ufffa-\ufffd]\U0001f50f\U0001f510\U0001f512\U0001f513]"), - status); - DCHECK(U_SUCCESS(status)); - icu::RegexMatcher dangerous_patterns(icu::UnicodeString( - // Lone katakana no, so, or n - L"[^\\p{Katakana}][\u30ce\u30f3\u30bd][^\\p{Katakana}]" - // Repeating Japanese accent characters - L"|[\u3099\u309a\u309b\u309c][\u3099\u309a\u309b\u309c]"), - 0, status); -#else - icu::UnicodeSet dangerous_characters(icu::UnicodeString( - "[[\\u0020\\u00ad\\u00bc\\u00bd\\u01c3\\u0337\\u0338" - "\\u05c3\\u05f4\\u06d4\\u0702\\u115f\\u1160][\\u2000-\\u200b]" - "[\\u2024\\u2027\\u2028\\u2029\\u2039\\u203a\\u2044\\u205f]" - "[\\u2154-\\u2156][\\u2159-\\u215b][\\u215f\\u2215\\u23ae" - "\\u29f6\\u29f8\\u2afb\\u2afd][\\u2ff0-\\u2ffb][\\u3014" - "\\u3015\\u3033\\u3164\\u321d\\u321e\\u33ae\\u33af\\u33c6\\u33df\\ufe14" - "\\ufe15\\ufe3f\\ufe5d\\ufe5e\\ufeff\\uff0e\\uff06\\uff61\\uffa0\\ufff9]" - "[\\ufffa-\\ufffd]\\U0001f50f\\U0001f510\\U0001f512\\U0001f513]", -1, - US_INV), status); - DCHECK(U_SUCCESS(status)); - icu::RegexMatcher dangerous_patterns(icu::UnicodeString( - // Lone katakana no, so, or n - "[^\\p{Katakana}][\\u30ce\\u30f3\\u30bd][^\\p{Katakana}]" - // Repeating Japanese accent characters - "|[\\u3099\\u309a\\u309b\\u309c][\\u3099\\u309a\\u309b\\u309c]"), - 0, status); -#endif - DCHECK(U_SUCCESS(status)); - icu::UnicodeSet component_characters; - icu::UnicodeString component_string(str, str_len); - component_characters.addAll(component_string); - if (dangerous_characters.containsSome(component_characters)) - return false; - - DCHECK(U_SUCCESS(status)); - dangerous_patterns.reset(component_string); - if (dangerous_patterns.find()) - return false; - - // If the language list is empty, the result is completely determined - // by whether a component is a single script or not. This will block - // even "safe" script mixing cases like <Chinese, Latin-ASCII> that are - // allowed with |languages| (while it blocks Chinese + Latin letters with - // an accent as should be the case), but we want to err on the safe side - // when |languages| is empty. - if (languages.empty()) - return IsIDNComponentInSingleScript(str, str_len); - - // |common_characters| is made up of ASCII numbers, hyphen, plus and - // underscore that are used across scripts and allowed in domain names. - // (sync'd with characters allowed in url_canon_host with square - // brackets excluded.) See kHostCharLookup[] array in url_canon_host.cc. - icu::UnicodeSet common_characters(UNICODE_STRING_SIMPLE("[[0-9]\\-_+\\ ]"), - status); - DCHECK(U_SUCCESS(status)); - // Subtract common characters because they're always allowed so that - // we just have to check if a language-specific set contains - // the remainder. - component_characters.removeAll(common_characters); - - base::StringTokenizer t(languages, ","); - while (t.GetNext()) { - if (IsComponentCoveredByLang(component_characters, t.token())) - return true; - } - return false; -} - -// A wrapper to use LazyInstance<>::Leaky with ICU's UIDNA, a C pointer to -// a UTS46/IDNA 2008 handling object opened with uidna_openUTS46(). -// -// We use UTS46 with BiDiCheck to migrate from IDNA 2003 to IDNA 2008 with -// the backward compatibility in mind. What it does: -// -// 1. Use the up-to-date Unicode data. -// 2. Define a case folding/mapping with the up-to-date Unicode data as -// in IDNA 2003. -// 3. Use transitional mechanism for 4 deviation characters (sharp-s, -// final sigma, ZWJ and ZWNJ) for now. -// 4. Continue to allow symbols and punctuations. -// 5. Apply new BiDi check rules more permissive than the IDNA 2003 BiDI rules. -// 6. Do not apply STD3 rules -// 7. Do not allow unassigned code points. -// -// It also closely matches what IE 10 does except for the BiDi check ( -// http://goo.gl/3XBhqw ). -// See http://http://unicode.org/reports/tr46/ and references therein -// for more details. -struct UIDNAWrapper { - UIDNAWrapper() { - UErrorCode err = U_ZERO_ERROR; - // TODO(jungshik): Change options as different parties (browsers, - // registrars, search engines) converge toward a consensus. - value = uidna_openUTS46(UIDNA_CHECK_BIDI, &err); - if (U_FAILURE(err)) - value = NULL; - } - - UIDNA* value; -}; - -static base::LazyInstance<UIDNAWrapper>::Leaky - g_uidna = LAZY_INSTANCE_INITIALIZER; - -// Converts one component of a host (between dots) to IDN if safe. The result -// will be APPENDED to the given output string and will be the same as the input -// if it is not IDN or the IDN is unsafe to display. Returns whether any -// conversion was performed. -bool IDNToUnicodeOneComponent(const base::char16* comp, - size_t comp_len, - const std::string& languages, - base::string16* out) { - DCHECK(out); - if (comp_len == 0) - return false; - - // Only transform if the input can be an IDN component. - static const base::char16 kIdnPrefix[] = {'x', 'n', '-', '-'}; - if ((comp_len > arraysize(kIdnPrefix)) && - !memcmp(comp, kIdnPrefix, arraysize(kIdnPrefix) * sizeof(base::char16))) { - UIDNA* uidna = g_uidna.Get().value; - DCHECK(uidna != NULL); - size_t original_length = out->length(); - int output_length = 64; - UIDNAInfo info = UIDNA_INFO_INITIALIZER; - UErrorCode status; - do { - out->resize(original_length + output_length); - status = U_ZERO_ERROR; - // This returns the actual length required. If this is more than 64 - // code units, |status| will be U_BUFFER_OVERFLOW_ERROR and we'll try - // the conversion again, but with a sufficiently large buffer. - output_length = uidna_labelToUnicode( - uidna, comp, static_cast<int32_t>(comp_len), &(*out)[original_length], - output_length, &info, &status); - } while ((status == U_BUFFER_OVERFLOW_ERROR && info.errors == 0)); - - if (U_SUCCESS(status) && info.errors == 0) { - // Converted successfully. Ensure that the converted component - // can be safely displayed to the user. - out->resize(original_length + output_length); - if (IsIDNComponentSafe(out->data() + original_length, output_length, - languages)) - return true; - } - - // Something went wrong. Revert to original string. - out->resize(original_length); - } - - // We get here with no IDN or on error, in which case we just append the - // literal input. - out->append(comp, comp_len); - return false; -} - -// TODO(brettw) bug 734373: check the scripts for each host component and -// don't un-IDN-ize if there is more than one. Alternatively, only IDN for -// scripts that the user has installed. For now, just put the entire -// path through IDN. Maybe this feature can be implemented in ICU itself? -// -// We may want to skip this step in the case of file URLs to allow unicode -// UNC hostnames regardless of encodings. -base::string16 IDNToUnicodeWithAdjustments( - const std::string& host, - const std::string& languages, - base::OffsetAdjuster::Adjustments* adjustments) { - if (adjustments) - adjustments->clear(); - // Convert the ASCII input to a base::string16 for ICU. - base::string16 input16; - input16.reserve(host.length()); - input16.insert(input16.end(), host.begin(), host.end()); - - // Do each component of the host separately, since we enforce script matching - // on a per-component basis. - base::string16 out16; - { - for (size_t component_start = 0, component_end; - component_start < input16.length(); - component_start = component_end + 1) { - // Find the end of the component. - component_end = input16.find('.', component_start); - if (component_end == base::string16::npos) - component_end = input16.length(); // For getting the last component. - size_t component_length = component_end - component_start; - size_t new_component_start = out16.length(); - bool converted_idn = false; - if (component_end > component_start) { - // Add the substring that we just found. - converted_idn = IDNToUnicodeOneComponent( - input16.data() + component_start, component_length, languages, - &out16); - } - size_t new_component_length = out16.length() - new_component_start; - - if (converted_idn && adjustments) { - adjustments->push_back(base::OffsetAdjuster::Adjustment( - component_start, component_length, new_component_length)); - } - - // Need to add the dot we just found (if we found one). - if (component_end < input16.length()) - out16.push_back('.'); - } - } - return out16; -} - -// If |component| is valid, its begin is incremented by |delta|. -void AdjustComponent(int delta, url::Component* component) { - if (!component->is_valid()) - return; - - DCHECK(delta >= 0 || component->begin >= -delta); - component->begin += delta; -} - -// Adjusts all the components of |parsed| by |delta|, except for the scheme. -void AdjustAllComponentsButScheme(int delta, url::Parsed* parsed) { - AdjustComponent(delta, &(parsed->username)); - AdjustComponent(delta, &(parsed->password)); - AdjustComponent(delta, &(parsed->host)); - AdjustComponent(delta, &(parsed->port)); - AdjustComponent(delta, &(parsed->path)); - AdjustComponent(delta, &(parsed->query)); - AdjustComponent(delta, &(parsed->ref)); -} - -// Helper for FormatUrlWithOffsets(). -base::string16 FormatViewSourceUrl( - const GURL& url, - const std::string& languages, - FormatUrlTypes format_types, - UnescapeRule::Type unescape_rules, - url::Parsed* new_parsed, - size_t* prefix_end, - base::OffsetAdjuster::Adjustments* adjustments) { - DCHECK(new_parsed); - const char kViewSource[] = "view-source:"; - const size_t kViewSourceLength = arraysize(kViewSource) - 1; - - // Format the underlying URL and record adjustments. - const std::string& url_str(url.possibly_invalid_spec()); - adjustments->clear(); - base::string16 result(base::ASCIIToUTF16(kViewSource) + - FormatUrlWithAdjustments(GURL(url_str.substr(kViewSourceLength)), - languages, format_types, unescape_rules, - new_parsed, prefix_end, adjustments)); - // Revise |adjustments| by shifting to the offsets to prefix that the above - // call to FormatUrl didn't get to see. - for (base::OffsetAdjuster::Adjustments::iterator it = adjustments->begin(); - it != adjustments->end(); ++it) - it->original_offset += kViewSourceLength; - - // Adjust positions of the parsed components. - if (new_parsed->scheme.is_nonempty()) { - // Assume "view-source:real-scheme" as a scheme. - new_parsed->scheme.len += kViewSourceLength; - } else { - new_parsed->scheme.begin = 0; - new_parsed->scheme.len = kViewSourceLength - 1; - } - AdjustAllComponentsButScheme(kViewSourceLength, new_parsed); - - if (prefix_end) - *prefix_end += kViewSourceLength; - - return result; -} - -class AppendComponentTransform { - public: - AppendComponentTransform() {} - virtual ~AppendComponentTransform() {} - - virtual base::string16 Execute( - const std::string& component_text, - base::OffsetAdjuster::Adjustments* adjustments) const = 0; - - // NOTE: No DISALLOW_COPY_AND_ASSIGN here, since gcc < 4.3.0 requires an - // accessible copy constructor in order to call AppendFormattedComponent() - // with an inline temporary (see http://gcc.gnu.org/bugs/#cxx%5Frvalbind ). -}; - -class HostComponentTransform : public AppendComponentTransform { - public: - explicit HostComponentTransform(const std::string& languages) - : languages_(languages) { - } - - private: - base::string16 Execute( - const std::string& component_text, - base::OffsetAdjuster::Adjustments* adjustments) const override { - return IDNToUnicodeWithAdjustments(component_text, languages_, - adjustments); - } - - const std::string& languages_; -}; - -class NonHostComponentTransform : public AppendComponentTransform { - public: - explicit NonHostComponentTransform(UnescapeRule::Type unescape_rules) - : unescape_rules_(unescape_rules) { - } - - private: - base::string16 Execute( - const std::string& component_text, - base::OffsetAdjuster::Adjustments* adjustments) const override { - return (unescape_rules_ == UnescapeRule::NONE) ? - base::UTF8ToUTF16WithAdjustments(component_text, adjustments) : - UnescapeAndDecodeUTF8URLComponentWithAdjustments(component_text, - unescape_rules_, adjustments); - } - - const UnescapeRule::Type unescape_rules_; -}; - -// Transforms the portion of |spec| covered by |original_component| according to -// |transform|. Appends the result to |output|. If |output_component| is -// non-NULL, its start and length are set to the transformed component's new -// start and length. If |adjustments| is non-NULL, appends adjustments (if -// any) that reflect the transformation the original component underwent to -// become the transformed value appended to |output|. -void AppendFormattedComponent(const std::string& spec, - const url::Component& original_component, - const AppendComponentTransform& transform, - base::string16* output, - url::Component* output_component, - base::OffsetAdjuster::Adjustments* adjustments) { - DCHECK(output); - if (original_component.is_nonempty()) { - size_t original_component_begin = - static_cast<size_t>(original_component.begin); - size_t output_component_begin = output->length(); - std::string component_str(spec, original_component_begin, - static_cast<size_t>(original_component.len)); - - // Transform |component_str| and modify |adjustments| appropriately. - base::OffsetAdjuster::Adjustments component_transform_adjustments; - output->append( - transform.Execute(component_str, &component_transform_adjustments)); - - // Shift all the adjustments made for this component so the offsets are - // valid for the original string and add them to |adjustments|. - for (base::OffsetAdjuster::Adjustments::iterator comp_iter = - component_transform_adjustments.begin(); - comp_iter != component_transform_adjustments.end(); ++comp_iter) - comp_iter->original_offset += original_component_begin; - if (adjustments) { - adjustments->insert(adjustments->end(), - component_transform_adjustments.begin(), - component_transform_adjustments.end()); - } - - // Set positions of the parsed component. - if (output_component) { - output_component->begin = static_cast<int>(output_component_begin); - output_component->len = - static_cast<int>(output->length() - output_component_begin); - } - } else if (output_component) { - output_component->reset(); - } -} - -} // namespace - -const FormatUrlType kFormatUrlOmitNothing = 0; -const FormatUrlType kFormatUrlOmitUsernamePassword = 1 << 0; -const FormatUrlType kFormatUrlOmitHTTP = 1 << 1; -const FormatUrlType kFormatUrlOmitTrailingSlashOnBareHostname = 1 << 2; -const FormatUrlType kFormatUrlOmitAll = kFormatUrlOmitUsernamePassword | - kFormatUrlOmitHTTP | kFormatUrlOmitTrailingSlashOnBareHostname; - -base::string16 IDNToUnicode(const std::string& host, - const std::string& languages) { - return IDNToUnicodeWithAdjustments(host, languages, NULL); -} - std::string GetDirectoryListingEntry(const base::string16& name, const std::string& raw_bytes, bool is_dir, int64_t size, - Time modified) { + base::Time modified) { std::string result; result.append("<script>addRow("); base::EscapeJSONString(name, true, &result); @@ -601,6 +26,7 @@ std::string GetDirectoryListingEntry(const base::string16& name, } else { base::EscapeJSONString(EscapePath(raw_bytes), true, &result); } + if (is_dir) { result.append(",1,"); } else { @@ -617,9 +43,8 @@ std::string GetDirectoryListingEntry(const base::string16& name, base::string16 modified_str; // |modified| can be NULL in FTP listings. - if (!modified.is_null()) { + if (!modified.is_null()) modified_str = base::TimeFormatShortDateAndTime(modified); - } base::EscapeJSONString(modified_str, true, &result); result.append(");</script>\n"); @@ -627,213 +52,4 @@ std::string GetDirectoryListingEntry(const base::string16& name, return result; } -void AppendFormattedHost(const GURL& url, - const std::string& languages, - base::string16* output) { - AppendFormattedComponent(url.possibly_invalid_spec(), - url.parsed_for_possibly_invalid_spec().host, - HostComponentTransform(languages), output, NULL, NULL); -} - -base::string16 FormatUrlWithOffsets( - const GURL& url, - const std::string& languages, - FormatUrlTypes format_types, - UnescapeRule::Type unescape_rules, - url::Parsed* new_parsed, - size_t* prefix_end, - std::vector<size_t>* offsets_for_adjustment) { - base::OffsetAdjuster::Adjustments adjustments; - const base::string16& format_url_return_value = - FormatUrlWithAdjustments(url, languages, format_types, unescape_rules, - new_parsed, prefix_end, &adjustments); - base::OffsetAdjuster::AdjustOffsets(adjustments, offsets_for_adjustment); - if (offsets_for_adjustment) { - std::for_each( - offsets_for_adjustment->begin(), - offsets_for_adjustment->end(), - base::LimitOffset<std::string>(format_url_return_value.length())); - } - return format_url_return_value; -} - -base::string16 FormatUrlWithAdjustments( - const GURL& url, - const std::string& languages, - FormatUrlTypes format_types, - UnescapeRule::Type unescape_rules, - url::Parsed* new_parsed, - size_t* prefix_end, - base::OffsetAdjuster::Adjustments* adjustments) { - DCHECK(adjustments != NULL); - adjustments->clear(); - url::Parsed parsed_temp; - if (!new_parsed) - new_parsed = &parsed_temp; - else - *new_parsed = url::Parsed(); - - // Special handling for view-source:. Don't use content::kViewSourceScheme - // because this library shouldn't depend on chrome. - const char kViewSource[] = "view-source"; - // Reject "view-source:view-source:..." to avoid deep recursion. - const char kViewSourceTwice[] = "view-source:view-source:"; - if (url.SchemeIs(kViewSource) && - !base::StartsWith(url.possibly_invalid_spec(), kViewSourceTwice, - base::CompareCase::INSENSITIVE_ASCII)) { - return FormatViewSourceUrl(url, languages, format_types, - unescape_rules, new_parsed, prefix_end, - adjustments); - } - - // We handle both valid and invalid URLs (this will give us the spec - // regardless of validity). - const std::string& spec = url.possibly_invalid_spec(); - const url::Parsed& parsed = url.parsed_for_possibly_invalid_spec(); - - // Scheme & separators. These are ASCII. - base::string16 url_string; - url_string.insert( - url_string.end(), spec.begin(), - spec.begin() + parsed.CountCharactersBefore(url::Parsed::USERNAME, true)); - const char kHTTP[] = "http://"; - const char kFTP[] = "ftp."; - // url_fixer::FixupURL() treats "ftp.foo.com" as ftp://ftp.foo.com. This - // means that if we trim "http://" off a URL whose host starts with "ftp." and - // the user inputs this into any field subject to fixup (which is basically - // all input fields), the meaning would be changed. (In fact, often the - // formatted URL is directly pre-filled into an input field.) For this reason - // we avoid stripping "http://" in this case. - bool omit_http = - (format_types & kFormatUrlOmitHTTP) && - base::EqualsASCII(url_string, kHTTP) && - !base::StartsWith(url.host(), kFTP, base::CompareCase::SENSITIVE); - new_parsed->scheme = parsed.scheme; - - // Username & password. - if ((format_types & kFormatUrlOmitUsernamePassword) != 0) { - // Remove the username and password fields. We don't want to display those - // to the user since they can be used for attacks, - // e.g. "http://google.com:search@evil.ru/" - new_parsed->username.reset(); - new_parsed->password.reset(); - // Update the adjustments based on removed username and/or password. - if (parsed.username.is_nonempty() || parsed.password.is_nonempty()) { - if (parsed.username.is_nonempty() && parsed.password.is_nonempty()) { - // The seeming off-by-two is to account for the ':' after the username - // and '@' after the password. - adjustments->push_back(base::OffsetAdjuster::Adjustment( - static_cast<size_t>(parsed.username.begin), - static_cast<size_t>(parsed.username.len + parsed.password.len + 2), - 0)); - } else { - const url::Component* nonempty_component = - parsed.username.is_nonempty() ? &parsed.username : &parsed.password; - // The seeming off-by-one is to account for the '@' after the - // username/password. - adjustments->push_back(base::OffsetAdjuster::Adjustment( - static_cast<size_t>(nonempty_component->begin), - static_cast<size_t>(nonempty_component->len + 1), - 0)); - } - } - } else { - AppendFormattedComponent(spec, parsed.username, - NonHostComponentTransform(unescape_rules), - &url_string, &new_parsed->username, adjustments); - if (parsed.password.is_valid()) - url_string.push_back(':'); - AppendFormattedComponent(spec, parsed.password, - NonHostComponentTransform(unescape_rules), - &url_string, &new_parsed->password, adjustments); - if (parsed.username.is_valid() || parsed.password.is_valid()) - url_string.push_back('@'); - } - if (prefix_end) - *prefix_end = static_cast<size_t>(url_string.length()); - - // Host. - AppendFormattedComponent(spec, parsed.host, HostComponentTransform(languages), - &url_string, &new_parsed->host, adjustments); - - // Port. - if (parsed.port.is_nonempty()) { - url_string.push_back(':'); - new_parsed->port.begin = url_string.length(); - url_string.insert(url_string.end(), - spec.begin() + parsed.port.begin, - spec.begin() + parsed.port.end()); - new_parsed->port.len = url_string.length() - new_parsed->port.begin; - } else { - new_parsed->port.reset(); - } - - // Path & query. Both get the same general unescape & convert treatment. - if (!(format_types & kFormatUrlOmitTrailingSlashOnBareHostname) || - !CanStripTrailingSlash(url)) { - AppendFormattedComponent(spec, parsed.path, - NonHostComponentTransform(unescape_rules), - &url_string, &new_parsed->path, adjustments); - } else { - if (parsed.path.len > 0) { - adjustments->push_back(base::OffsetAdjuster::Adjustment( - parsed.path.begin, parsed.path.len, 0)); - } - } - if (parsed.query.is_valid()) - url_string.push_back('?'); - AppendFormattedComponent(spec, parsed.query, - NonHostComponentTransform(unescape_rules), - &url_string, &new_parsed->query, adjustments); - - // Ref. This is valid, unescaped UTF-8, so we can just convert. - if (parsed.ref.is_valid()) - url_string.push_back('#'); - AppendFormattedComponent(spec, parsed.ref, - NonHostComponentTransform(UnescapeRule::NONE), - &url_string, &new_parsed->ref, adjustments); - - // If we need to strip out http do it after the fact. - if (omit_http && - base::StartsWith(url_string, base::ASCIIToUTF16(kHTTP), - base::CompareCase::SENSITIVE)) { - const size_t kHTTPSize = arraysize(kHTTP) - 1; - url_string = url_string.substr(kHTTPSize); - // Because offsets in the |adjustments| are already calculated with respect - // to the string with the http:// prefix in it, those offsets remain correct - // 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)); - - if (prefix_end) - *prefix_end -= kHTTPSize; - - // Adjust new_parsed. - DCHECK(new_parsed->scheme.is_valid()); - int delta = -(new_parsed->scheme.len + 3); // +3 for ://. - new_parsed->scheme.reset(); - AdjustAllComponentsButScheme(delta, new_parsed); - } - - return url_string; -} - -base::string16 FormatUrl(const GURL& url, - const std::string& languages, - FormatUrlTypes format_types, - UnescapeRule::Type unescape_rules, - url::Parsed* new_parsed, - size_t* prefix_end, - size_t* offset_for_adjustment) { - Offsets offsets; - if (offset_for_adjustment) - offsets.push_back(*offset_for_adjustment); - base::string16 result = FormatUrlWithOffsets(url, languages, format_types, - unescape_rules, new_parsed, prefix_end, &offsets); - if (offset_for_adjustment) - *offset_for_adjustment = offsets[0]; - return result; -} - } // namespace net diff --git a/net/base/net_util_icu_unittest.cc b/net/base/net_util_icu_unittest.cc index f643426..cac922f 100644 --- a/net/base/net_util_icu_unittest.cc +++ b/net/base/net_util_icu_unittest.cc @@ -4,487 +4,19 @@ #include "net/base/net_util.h" -#include <string.h> +#include <stdint.h> -#include <vector> +#include <string> -#include "base/format_macros.h" -#include "base/strings/string_number_conversions.h" -#include "base/strings/stringprintf.h" #include "base/strings/utf_string_conversions.h" #include "base/time/time.h" #include "testing/gtest/include/gtest/gtest.h" #include "url/gurl.h" -using base::ASCIIToUTF16; -using base::WideToUTF16; - namespace net { namespace { -const size_t kNpos = base::string16::npos; - -const char* const kLanguages[] = { - "", "en", "zh-CN", "ja", "ko", - "he", "ar", "ru", "el", "fr", - "de", "pt", "sv", "th", "hi", - "de,en", "el,en", "zh-TW,en", "ko,ja", "he,ru,en", - "zh,ru,en" -}; - -struct IDNTestCase { - const char* const input; - const wchar_t* unicode_output; - const bool unicode_allowed[arraysize(kLanguages)]; -}; - -// TODO(jungshik) This is just a random sample of languages and is far -// from exhaustive. We may have to generate all the combinations -// of languages (powerset of a set of all the languages). -const IDNTestCase idn_cases[] = { - // No IDN - {"www.google.com", L"www.google.com", - {true, true, true, true, true, - true, true, true, true, true, - true, true, true, true, true, - true, true, true, true, true, - true}}, - {"www.google.com.", L"www.google.com.", - {true, true, true, true, true, - true, true, true, true, true, - true, true, true, true, true, - true, true, true, true, true, - true}}, - {".", L".", - {true, true, true, true, true, - true, true, true, true, true, - true, true, true, true, true, - true, true, true, true, true, - true}}, - {"", L"", - {true, true, true, true, true, - true, true, true, true, true, - true, true, true, true, true, - true, true, true, true, true, - true}}, - // IDN - // Hanzi (Traditional Chinese) - {"xn--1lq90ic7f1rc.cn", L"\x5317\x4eac\x5927\x5b78.cn", - {true, false, true, true, false, - false, false, false, false, false, - false, false, false, false, false, - false, false, true, true, false, - true}}, - // Hanzi ('video' in Simplified Chinese : will pass only in zh-CN,zh) - {"xn--cy2a840a.com", L"\x89c6\x9891.com", - {true, false, true, false, false, - false, false, false, false, false, - false, false, false, false, false, - false, false, false, false, false, - true}}, - // Hanzi + '123' - {"www.xn--123-p18d.com", L"www.\x4e00" L"123.com", - {true, false, true, true, false, - false, false, false, false, false, - false, false, false, false, false, - false, false, true, true, false, - true}}, - // Hanzi + Latin : U+56FD is simplified and is regarded - // as not supported in zh-TW. - {"www.xn--hello-9n1hm04c.com", L"www.hello\x4e2d\x56fd.com", - {false, false, true, true, false, - false, false, false, false, false, - false, false, false, false, false, - false, false, false, true, false, - true}}, - // Kanji + Kana (Japanese) - {"xn--l8jvb1ey91xtjb.jp", L"\x671d\x65e5\x3042\x3055\x3072.jp", - {true, false, false, true, false, - false, false, false, false, false, - false, false, false, false, false, - false, false, false, true, false, - false}}, - // Katakana including U+30FC - {"xn--tckm4i2e.jp", L"\x30b3\x30de\x30fc\x30b9.jp", - {true, false, false, true, false, - false, false, false, false, false, - false, false, false, false, false, - false, false, false, true, false, - }}, - {"xn--3ck7a7g.jp", L"\u30ce\u30f3\u30bd.jp", - {true, false, false, true, false, - false, false, false, false, false, - false, false, false, false, false, - false, false, false, true, false, - }}, - // Katakana + Latin (Japanese) - // TODO(jungshik): Change 'false' in the first element to 'true' - // after upgrading to ICU 4.2.1 to use new uspoof_* APIs instead - // of our IsIDNComponentInSingleScript(). - {"xn--e-efusa1mzf.jp", L"e\x30b3\x30de\x30fc\x30b9.jp", - {false, false, false, true, false, - false, false, false, false, false, - false, false, false, false, false, - false, false, false, true, false, - }}, - {"xn--3bkxe.jp", L"\x30c8\x309a.jp", - {false, false, false, true, false, - false, false, false, false, false, - false, false, false, false, false, - false, false, false, true, false, - }}, - // Hangul (Korean) - {"www.xn--or3b17p6jjc.kr", L"www.\xc804\xc790\xc815\xbd80.kr", - {true, false, false, false, true, - false, false, false, false, false, - false, false, false, false, false, - false, false, false, true, false, - false}}, - // b<u-umlaut>cher (German) - {"xn--bcher-kva.de", L"b\x00fc" L"cher.de", - {true, false, false, false, false, - false, false, false, false, true, - true, false, false, false, false, - true, false, false, false, false, - false}}, - // a with diaeresis - {"www.xn--frgbolaget-q5a.se", L"www.f\x00e4rgbolaget.se", - {true, false, false, false, false, - false, false, false, false, false, - true, false, true, false, false, - true, false, false, false, false, - false}}, - // c-cedilla (French) - {"www.xn--alliancefranaise-npb.fr", L"www.alliancefran\x00e7" L"aise.fr", - {true, false, false, false, false, - false, false, false, false, true, - false, true, false, false, false, - false, false, false, false, false, - false}}, - // caf'e with acute accent' (French) - {"xn--caf-dma.fr", L"caf\x00e9.fr", - {true, false, false, false, false, - false, false, false, false, true, - false, true, true, false, false, - false, false, false, false, false, - false}}, - // c-cedillla and a with tilde (Portuguese) - {"xn--poema-9qae5a.com.br", L"p\x00e3oema\x00e7\x00e3.com.br", - {true, false, false, false, false, - false, false, false, false, false, - false, true, false, false, false, - false, false, false, false, false, - false}}, - // s with caron - {"xn--achy-f6a.com", L"\x0161" L"achy.com", - {true, false, false, false, false, - false, false, false, false, false, - false, false, false, false, false, - false, false, false, false, false, - false}}, - // TODO(jungshik) : Add examples with Cyrillic letters - // only used in some languages written in Cyrillic. - // Eutopia (Greek) - {"xn--kxae4bafwg.gr", L"\x03bf\x03c5\x03c4\x03bf\x03c0\x03af\x03b1.gr", - {true, false, false, false, false, - false, false, false, true, false, - false, false, false, false, false, - false, true, false, false, false, - false}}, - // Eutopia + 123 (Greek) - {"xn---123-pldm0haj2bk.gr", - L"\x03bf\x03c5\x03c4\x03bf\x03c0\x03af\x03b1-123.gr", - {true, false, false, false, false, - false, false, false, true, false, - false, false, false, false, false, - false, true, false, false, false, - false}}, - // Cyrillic (Russian) - {"xn--n1aeec9b.ru", L"\x0442\x043e\x0440\x0442\x044b.ru", - {true, false, false, false, false, - false, false, true, false, false, - false, false, false, false, false, - false, false, false, false, true, - true}}, - // Cyrillic + 123 (Russian) - {"xn---123-45dmmc5f.ru", L"\x0442\x043e\x0440\x0442\x044b-123.ru", - {true, false, false, false, false, - false, false, true, false, false, - false, false, false, false, false, - false, false, false, false, true, - true}}, - // Arabic - {"xn--mgba1fmg.ar", L"\x0627\x0641\x0644\x0627\x0645.ar", - {true, false, false, false, false, - false, true, false, false, false, - false, false, false, false, false, - false, false, false, false, false, - false}}, - // Hebrew - {"xn--4dbib.he", L"\x05d5\x05d0\x05d4.he", - {true, false, false, false, false, - true, false, false, false, false, - false, false, false, false, false, - false, false, false, false, true, - false}}, - // Thai - {"xn--12c2cc4ag3b4ccu.th", - L"\x0e2a\x0e32\x0e22\x0e01\x0e32\x0e23\x0e1a\x0e34\x0e19.th", - {true, false, false, false, false, - false, false, false, false, false, - false, false, false, true, false, - false, false, false, false, false, - false}}, - // Devangari (Hindi) - {"www.xn--l1b6a9e1b7c.in", L"www.\x0905\x0915\x094b\x0932\x093e.in", - {true, false, false, false, false, - false, false, false, false, false, - false, false, false, false, true, - false, false, false, false, false, - false}}, - // Invalid IDN - {"xn--hello?world.com", NULL, - {false, false, false, false, false, - false, false, false, false, false, - false, false, false, false, false, - false, false, false, false, false, - false}}, - // Unsafe IDNs - // "payp<alpha>l.com" - {"www.xn--paypl-g9d.com", L"payp\x03b1l.com", - {false, false, false, false, false, - false, false, false, false, false, - false, false, false, false, false, - false, false, false, false, false, - false}}, - // google.gr with Greek omicron and epsilon - {"xn--ggl-6xc1ca.gr", L"g\x03bf\x03bfgl\x03b5.gr", - {false, false, false, false, false, - false, false, false, false, false, - false, false, false, false, false, - false, false, false, false, false, - false}}, - // google.ru with Cyrillic o - {"xn--ggl-tdd6ba.ru", L"g\x043e\x043egl\x0435.ru", - {false, false, false, false, false, - false, false, false, false, false, - false, false, false, false, false, - false, false, false, false, false, - false}}, - // h<e with acute>llo<China in Han>.cn - {"xn--hllo-bpa7979ih5m.cn", L"h\x00e9llo\x4e2d\x56fd.cn", - {false, false, false, false, false, - false, false, false, false, false, - false, false, false, false, false, - false, false, false, false, false, - false}}, - // <Greek rho><Cyrillic a><Cyrillic u>.ru - {"xn--2xa6t2b.ru", L"\x03c1\x0430\x0443.ru", - {false, false, false, false, false, - false, false, false, false, false, - false, false, false, false, false, - false, false, false, false, false, - false}}, - // One that's really long that will force a buffer realloc - {"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" - "aaaaaaa", - L"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" - L"aaaaaaaa", - {true, true, true, true, true, - true, true, true, true, true, - true, true, true, true, true, - true, true, true, true, true, - true}}, - // Test cases for characters we blacklisted although allowed in IDN. - // Embedded spaces will be turned to %20 in the display. - // TODO(jungshik): We need to have more cases. This is a typical - // data-driven trap. The following test cases need to be separated - // and tested only for a couple of languages. - {"xn--osd3820f24c.kr", L"\xac00\xb098\x115f.kr", - {false, false, false, false, false, - false, false, false, false, false, - false, false, false, false, false, - false, false, false, false, false, - false}}, - {"www.xn--google-ho0coa.com", L"www.\x2039google\x203a.com", - {false, false, false, false, false, - false, false, false, false, false, - false, false, false, false, false, - false, false, false, false, false, - }}, - {"google.xn--comabc-k8d", L"google.com\x0338" L"abc", - {false, false, false, false, false, - false, false, false, false, false, - false, false, false, false, false, - false, false, false, false, false, - }}, - {"google.xn--com-oh4ba.evil.jp", L"google.com\x309a\x309a.evil.jp", - {false, false, false, false, false, - false, false, false, false, false, - false, false, false, false, false, - false, false, false, false, false, - }}, - {"google.xn--comevil-v04f.jp", L"google.com\x30ce" L"evil.jp", - {false, false, false, false, false, - false, false, false, false, false, - false, false, false, false, false, - false, false, false, false, false, - }}, - // Padlock icon spoof. - {"xn--google-hj64e", L"\U0001f512google.com", - {false, false, false, false, false, - false, false, false, false, false, - false, false, false, false, false, - false, false, false, false, false, - }}, - // Ensure that blacklisting "\xd83d\xdd12" did not inadvertently blacklist - // all strings with the surrogate '\xdd12'. - {"xn--fk9c.com", L"\U00010912.com", - {true, false, false, false, false, - false, false, false, false, false, - false, false, false, false, false, - false, false, false, false, false, - }}, -#if 0 - // These two cases are special. We need a separate test. - // U+3000 and U+3002 are normalized to ASCII space and dot. - {"xn-- -kq6ay5z.cn", L"\x4e2d\x56fd\x3000.cn", - {false, false, true, false, false, - false, false, false, false, false, - false, false, false, false, false, - false, false, true, false, false, - true}}, - {"xn--fiqs8s.cn", L"\x4e2d\x56fd\x3002" L"cn", - {false, false, true, false, false, - false, false, false, false, false, - false, false, false, false, false, - false, false, true, false, false, - true}}, -#endif -}; - -struct AdjustOffsetCase { - size_t input_offset; - size_t output_offset; -}; - -struct UrlTestData { - const char* const description; - const char* const input; - const char* const languages; - FormatUrlTypes format_types; - UnescapeRule::Type escape_rules; - const wchar_t* output; // Use |wchar_t| to handle Unicode constants easily. - size_t prefix_len; -}; - -// 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. -void AppendLanguagesToOutputs(const char* languages, - base::string16* expected, - base::string16* actual) { - base::string16 to_append = ASCIIToUTF16("::") + ASCIIToUTF16(languages); - expected->append(to_append); - actual->append(to_append); -} - -// A pair of helpers for the FormatUrlWithOffsets() test. -void VerboseExpect(size_t expected, - size_t actual, - const std::string& original_url, - size_t position, - const base::string16& formatted_url) { - EXPECT_EQ(expected, actual) << "Original URL: " << original_url - << " (at char " << position << ")\nFormatted URL: " << formatted_url; -} - -void CheckAdjustedOffsets(const std::string& url_string, - const std::string& languages, - FormatUrlTypes format_types, - UnescapeRule::Type unescape_rules, - const size_t* output_offsets) { - GURL url(url_string); - size_t url_length = url_string.length(); - std::vector<size_t> offsets; - for (size_t i = 0; i <= url_length + 1; ++i) - offsets.push_back(i); - offsets.push_back(500000); // Something larger than any input length. - offsets.push_back(std::string::npos); - base::string16 formatted_url = FormatUrlWithOffsets(url, languages, - format_types, unescape_rules, NULL, NULL, &offsets); - for (size_t i = 0; i < url_length; ++i) - VerboseExpect(output_offsets[i], offsets[i], url_string, i, formatted_url); - VerboseExpect(formatted_url.length(), offsets[url_length], url_string, - url_length, formatted_url); - VerboseExpect(base::string16::npos, offsets[url_length + 1], url_string, - 500000, formatted_url); - VerboseExpect(base::string16::npos, offsets[url_length + 2], url_string, - std::string::npos, formatted_url); -} - -} // anonymous namespace - -TEST(NetUtilTest, IDNToUnicodeFast) { - for (size_t i = 0; i < arraysize(idn_cases); i++) { - for (size_t j = 0; j < arraysize(kLanguages); j++) { - // ja || zh-TW,en || ko,ja -> IDNToUnicodeSlow - if (j == 3 || j == 17 || j == 18) - continue; - base::string16 output(IDNToUnicode(idn_cases[i].input, kLanguages[j])); - base::string16 expected(idn_cases[i].unicode_allowed[j] ? - WideToUTF16(idn_cases[i].unicode_output) : - ASCIIToUTF16(idn_cases[i].input)); - AppendLanguagesToOutputs(kLanguages[j], &expected, &output); - EXPECT_EQ(expected, output) << "input: \"" << idn_cases[i].input - << "\", languages: \"" << kLanguages[j] - << "\""; - } - } -} - -TEST(NetUtilTest, IDNToUnicodeSlow) { - for (size_t i = 0; i < arraysize(idn_cases); i++) { - for (size_t j = 0; j < arraysize(kLanguages); j++) { - // !(ja || zh-TW,en || ko,ja) -> IDNToUnicodeFast - if (!(j == 3 || j == 17 || j == 18)) - continue; - base::string16 output(IDNToUnicode(idn_cases[i].input, kLanguages[j])); - base::string16 expected(idn_cases[i].unicode_allowed[j] ? - WideToUTF16(idn_cases[i].unicode_output) : - ASCIIToUTF16(idn_cases[i].input)); - AppendLanguagesToOutputs(kLanguages[j], &expected, &output); - EXPECT_EQ(expected, output) << "input: \"" << idn_cases[i].input - << "\", languages: \"" << kLanguages[j] - << "\""; - } - } -} - -// ulocdata_getExemplarSet may fail with some locales (currently bn, gu, and -// te), which was causing a crash (See http://crbug.com/510551). This may be an -// icu bug, but regardless, that should not cause a crash. -TEST(NetUtilTest, IDNToUnicodeNeverCrashes) { - for (char c1 = 'a'; c1 <= 'z'; c1++) { - for (char c2 = 'a'; c2 <= 'z'; c2++) { - std::string lang = base::StringPrintf("%c%c", c1, c2); - base::string16 output(IDNToUnicode("xn--74h", lang)); - } - } -} - -TEST(NetUtilTest, StripWWW) { - EXPECT_EQ(base::string16(), StripWWW(base::string16())); - EXPECT_EQ(base::string16(), StripWWW(ASCIIToUTF16("www."))); - EXPECT_EQ(ASCIIToUTF16("blah"), StripWWW(ASCIIToUTF16("www.blah"))); - EXPECT_EQ(ASCIIToUTF16("blah"), StripWWW(ASCIIToUTF16("blah"))); -} - -// This is currently a windows specific function. -#if defined(OS_WIN) -namespace { - struct GetDirectoryListingEntryCase { const wchar_t* name; const char* const raw_bytes; @@ -494,8 +26,6 @@ struct GetDirectoryListingEntryCase { const char* const expected; }; -} // namespace - TEST(NetUtilTest, GetDirectoryListingEntry) { const GetDirectoryListingEntryCase test_cases[] = { {L"Foo", @@ -540,564 +70,12 @@ TEST(NetUtilTest, GetDirectoryListingEntry) { for (size_t i = 0; i < arraysize(test_cases); ++i) { const std::string results = GetDirectoryListingEntry( - WideToUTF16(test_cases[i].name), - test_cases[i].raw_bytes, - test_cases[i].is_dir, - test_cases[i].filesize, - test_cases[i].time); + base::WideToUTF16(test_cases[i].name), test_cases[i].raw_bytes, + test_cases[i].is_dir, test_cases[i].filesize, test_cases[i].time); EXPECT_EQ(test_cases[i].expected, results); } } -#endif - -TEST(NetUtilTest, FormatUrl) { - FormatUrlTypes default_format_type = kFormatUrlOmitUsernamePassword; - const UrlTestData tests[] = { - {"Empty URL", "", "", default_format_type, UnescapeRule::NORMAL, L"", 0}, - - {"Simple URL", - "http://www.google.com/", "", default_format_type, UnescapeRule::NORMAL, - L"http://www.google.com/", 7}, - - {"With a port number and a reference", - "http://www.google.com:8080/#\xE3\x82\xB0", "", default_format_type, - UnescapeRule::NORMAL, - L"http://www.google.com:8080/#\x30B0", 7}, - - // -------- IDN tests -------- - {"Japanese IDN with ja", - "http://xn--l8jvb1ey91xtjb.jp", "ja", default_format_type, - UnescapeRule::NORMAL, L"http://\x671d\x65e5\x3042\x3055\x3072.jp/", 7}, - - {"Japanese IDN with en", - "http://xn--l8jvb1ey91xtjb.jp", "en", default_format_type, - UnescapeRule::NORMAL, L"http://xn--l8jvb1ey91xtjb.jp/", 7}, - - {"Japanese IDN without any languages", - "http://xn--l8jvb1ey91xtjb.jp", "", default_format_type, - UnescapeRule::NORMAL, - // Single script is safe for empty languages. - L"http://\x671d\x65e5\x3042\x3055\x3072.jp/", 7}, - - {"mailto: with Japanese IDN", - "mailto:foo@xn--l8jvb1ey91xtjb.jp", "ja", default_format_type, - UnescapeRule::NORMAL, - // GURL doesn't assume an email address's domain part as a host name. - L"mailto:foo@xn--l8jvb1ey91xtjb.jp", 7}, - - {"file: with Japanese IDN", - "file://xn--l8jvb1ey91xtjb.jp/config.sys", "ja", default_format_type, - UnescapeRule::NORMAL, - L"file://\x671d\x65e5\x3042\x3055\x3072.jp/config.sys", 7}, - - {"ftp: with Japanese IDN", - "ftp://xn--l8jvb1ey91xtjb.jp/config.sys", "ja", default_format_type, - UnescapeRule::NORMAL, - L"ftp://\x671d\x65e5\x3042\x3055\x3072.jp/config.sys", 6}, - - // -------- omit_username_password flag tests -------- - {"With username and password, omit_username_password=false", - "http://user:passwd@example.com/foo", "", - kFormatUrlOmitNothing, UnescapeRule::NORMAL, - L"http://user:passwd@example.com/foo", 19}, - - {"With username and password, omit_username_password=true", - "http://user:passwd@example.com/foo", "", default_format_type, - UnescapeRule::NORMAL, L"http://example.com/foo", 7}, - - {"With username and no password", - "http://user@example.com/foo", "", default_format_type, - UnescapeRule::NORMAL, L"http://example.com/foo", 7}, - - {"Just '@' without username and password", - "http://@example.com/foo", "", default_format_type, UnescapeRule::NORMAL, - L"http://example.com/foo", 7}, - - // GURL doesn't think local-part of an email address is username for URL. - {"mailto:, omit_username_password=true", - "mailto:foo@example.com", "", default_format_type, UnescapeRule::NORMAL, - L"mailto:foo@example.com", 7}, - - // -------- unescape flag tests -------- - {"Do not unescape", - "http://%E3%82%B0%E3%83%BC%E3%82%B0%E3%83%AB.jp/" - "%E3%82%B0%E3%83%BC%E3%82%B0%E3%83%AB" - "?q=%E3%82%B0%E3%83%BC%E3%82%B0%E3%83%AB", "en", default_format_type, - UnescapeRule::NONE, - // GURL parses %-encoded hostnames into Punycode. - L"http://xn--qcka1pmc.jp/%E3%82%B0%E3%83%BC%E3%82%B0%E3%83%AB" - L"?q=%E3%82%B0%E3%83%BC%E3%82%B0%E3%83%AB", 7}, - - {"Unescape normally", - "http://%E3%82%B0%E3%83%BC%E3%82%B0%E3%83%AB.jp/" - "%E3%82%B0%E3%83%BC%E3%82%B0%E3%83%AB" - "?q=%E3%82%B0%E3%83%BC%E3%82%B0%E3%83%AB", "en", default_format_type, - UnescapeRule::NORMAL, - L"http://xn--qcka1pmc.jp/\x30B0\x30FC\x30B0\x30EB" - L"?q=\x30B0\x30FC\x30B0\x30EB", 7}, - - {"Unescape normally with BiDi control character", - "http://example.com/%E2%80%AEabc?q=%E2%80%8Fxy", "en", default_format_type, - UnescapeRule::NORMAL, L"http://example.com/%E2%80%AEabc?q=%E2%80%8Fxy", 7}, - - {"Unescape normally including unescape spaces", - "http://www.google.com/search?q=Hello%20World", "en", default_format_type, - UnescapeRule::SPACES, L"http://www.google.com/search?q=Hello World", 7}, - - /* - {"unescape=true with some special characters", - "http://user%3A:%40passwd@example.com/foo%3Fbar?q=b%26z", "", - kFormatUrlOmitNothing, UnescapeRule::NORMAL, - L"http://user%3A:%40passwd@example.com/foo%3Fbar?q=b%26z", 25}, - */ - // Disabled: the resultant URL becomes "...user%253A:%2540passwd...". - - // -------- omit http: -------- - {"omit http with user name", - "http://user@example.com/foo", "", kFormatUrlOmitAll, - UnescapeRule::NORMAL, L"example.com/foo", 0}, - - {"omit http", - "http://www.google.com/", "en", kFormatUrlOmitHTTP, - UnescapeRule::NORMAL, L"www.google.com/", - 0}, - - {"omit http with https", - "https://www.google.com/", "en", kFormatUrlOmitHTTP, - UnescapeRule::NORMAL, L"https://www.google.com/", - 8}, - - {"omit http starts with ftp.", - "http://ftp.google.com/", "en", kFormatUrlOmitHTTP, - UnescapeRule::NORMAL, L"http://ftp.google.com/", - 7}, - - // -------- omit trailing slash on bare hostname -------- - {"omit slash when it's the entire path", - "http://www.google.com/", "en", - kFormatUrlOmitTrailingSlashOnBareHostname, UnescapeRule::NORMAL, - L"http://www.google.com", 7}, - {"omit slash when there's a ref", - "http://www.google.com/#ref", "en", - kFormatUrlOmitTrailingSlashOnBareHostname, UnescapeRule::NORMAL, - L"http://www.google.com/#ref", 7}, - {"omit slash when there's a query", - "http://www.google.com/?", "en", - kFormatUrlOmitTrailingSlashOnBareHostname, UnescapeRule::NORMAL, - L"http://www.google.com/?", 7}, - {"omit slash when it's not the entire path", - "http://www.google.com/foo", "en", - kFormatUrlOmitTrailingSlashOnBareHostname, UnescapeRule::NORMAL, - L"http://www.google.com/foo", 7}, - {"omit slash for nonstandard URLs", - "data:/", "en", kFormatUrlOmitTrailingSlashOnBareHostname, - UnescapeRule::NORMAL, L"data:/", 5}, - {"omit slash for file URLs", - "file:///", "en", kFormatUrlOmitTrailingSlashOnBareHostname, - UnescapeRule::NORMAL, L"file:///", 7}, - - // -------- view-source: -------- - {"view-source", - "view-source:http://xn--qcka1pmc.jp/", "ja", default_format_type, - UnescapeRule::NORMAL, L"view-source:http://\x30B0\x30FC\x30B0\x30EB.jp/", - 19}, - - {"view-source of view-source", - "view-source:view-source:http://xn--qcka1pmc.jp/", "ja", - default_format_type, UnescapeRule::NORMAL, - L"view-source:view-source:http://xn--qcka1pmc.jp/", 12}, - - // view-source should omit http and trailing slash where non-view-source - // would. - {"view-source omit http", - "view-source:http://a.b/c", "en", kFormatUrlOmitAll, - UnescapeRule::NORMAL, L"view-source:a.b/c", - 12}, - {"view-source omit http starts with ftp.", - "view-source:http://ftp.b/c", "en", kFormatUrlOmitAll, - UnescapeRule::NORMAL, L"view-source:http://ftp.b/c", - 19}, - {"view-source omit slash when it's the entire path", - "view-source:http://a.b/", "en", kFormatUrlOmitAll, - UnescapeRule::NORMAL, L"view-source:a.b", - 12}, - }; - - for (size_t i = 0; i < arraysize(tests); ++i) { - size_t prefix_len; - base::string16 formatted = FormatUrl( - GURL(tests[i].input), tests[i].languages, tests[i].format_types, - tests[i].escape_rules, NULL, &prefix_len, NULL); - EXPECT_EQ(WideToUTF16(tests[i].output), formatted) << tests[i].description; - EXPECT_EQ(tests[i].prefix_len, prefix_len) << tests[i].description; - } -} - -TEST(NetUtilTest, FormatUrlParsed) { - // No unescape case. - url::Parsed parsed; - base::string16 formatted = FormatUrl( - GURL("http://\xE3\x82\xB0:\xE3\x83\xBC@xn--qcka1pmc.jp:8080/" - "%E3%82%B0/?q=%E3%82%B0#\xE3\x82\xB0"), - "ja", kFormatUrlOmitNothing, UnescapeRule::NONE, &parsed, NULL, - NULL); - EXPECT_EQ(WideToUTF16( - L"http://%E3%82%B0:%E3%83%BC@\x30B0\x30FC\x30B0\x30EB.jp:8080" - L"/%E3%82%B0/?q=%E3%82%B0#\x30B0"), formatted); - EXPECT_EQ(WideToUTF16(L"%E3%82%B0"), - formatted.substr(parsed.username.begin, parsed.username.len)); - EXPECT_EQ(WideToUTF16(L"%E3%83%BC"), - formatted.substr(parsed.password.begin, parsed.password.len)); - EXPECT_EQ(WideToUTF16(L"\x30B0\x30FC\x30B0\x30EB.jp"), - formatted.substr(parsed.host.begin, parsed.host.len)); - EXPECT_EQ(WideToUTF16(L"8080"), - formatted.substr(parsed.port.begin, parsed.port.len)); - EXPECT_EQ(WideToUTF16(L"/%E3%82%B0/"), - formatted.substr(parsed.path.begin, parsed.path.len)); - EXPECT_EQ(WideToUTF16(L"q=%E3%82%B0"), - formatted.substr(parsed.query.begin, parsed.query.len)); - EXPECT_EQ(WideToUTF16(L"\x30B0"), - formatted.substr(parsed.ref.begin, parsed.ref.len)); - - // Unescape case. - formatted = FormatUrl( - GURL("http://\xE3\x82\xB0:\xE3\x83\xBC@xn--qcka1pmc.jp:8080/" - "%E3%82%B0/?q=%E3%82%B0#\xE3\x82\xB0"), - "ja", kFormatUrlOmitNothing, UnescapeRule::NORMAL, &parsed, NULL, - NULL); - EXPECT_EQ(WideToUTF16(L"http://\x30B0:\x30FC@\x30B0\x30FC\x30B0\x30EB.jp:8080" - L"/\x30B0/?q=\x30B0#\x30B0"), formatted); - EXPECT_EQ(WideToUTF16(L"\x30B0"), - formatted.substr(parsed.username.begin, parsed.username.len)); - EXPECT_EQ(WideToUTF16(L"\x30FC"), - formatted.substr(parsed.password.begin, parsed.password.len)); - EXPECT_EQ(WideToUTF16(L"\x30B0\x30FC\x30B0\x30EB.jp"), - formatted.substr(parsed.host.begin, parsed.host.len)); - EXPECT_EQ(WideToUTF16(L"8080"), - formatted.substr(parsed.port.begin, parsed.port.len)); - EXPECT_EQ(WideToUTF16(L"/\x30B0/"), - formatted.substr(parsed.path.begin, parsed.path.len)); - EXPECT_EQ(WideToUTF16(L"q=\x30B0"), - formatted.substr(parsed.query.begin, parsed.query.len)); - EXPECT_EQ(WideToUTF16(L"\x30B0"), - formatted.substr(parsed.ref.begin, parsed.ref.len)); - - // Omit_username_password + unescape case. - formatted = FormatUrl( - GURL("http://\xE3\x82\xB0:\xE3\x83\xBC@xn--qcka1pmc.jp:8080/" - "%E3%82%B0/?q=%E3%82%B0#\xE3\x82\xB0"), - "ja", kFormatUrlOmitUsernamePassword, UnescapeRule::NORMAL, &parsed, - NULL, NULL); - EXPECT_EQ(WideToUTF16(L"http://\x30B0\x30FC\x30B0\x30EB.jp:8080" - L"/\x30B0/?q=\x30B0#\x30B0"), formatted); - EXPECT_FALSE(parsed.username.is_valid()); - EXPECT_FALSE(parsed.password.is_valid()); - EXPECT_EQ(WideToUTF16(L"\x30B0\x30FC\x30B0\x30EB.jp"), - formatted.substr(parsed.host.begin, parsed.host.len)); - EXPECT_EQ(WideToUTF16(L"8080"), - formatted.substr(parsed.port.begin, parsed.port.len)); - EXPECT_EQ(WideToUTF16(L"/\x30B0/"), - formatted.substr(parsed.path.begin, parsed.path.len)); - EXPECT_EQ(WideToUTF16(L"q=\x30B0"), - formatted.substr(parsed.query.begin, parsed.query.len)); - EXPECT_EQ(WideToUTF16(L"\x30B0"), - formatted.substr(parsed.ref.begin, parsed.ref.len)); - - // View-source case. - formatted = - FormatUrl(GURL("view-source:http://user:passwd@host:81/path?query#ref"), - std::string(), - kFormatUrlOmitUsernamePassword, - UnescapeRule::NORMAL, - &parsed, - NULL, - NULL); - EXPECT_EQ(WideToUTF16(L"view-source:http://host:81/path?query#ref"), - formatted); - EXPECT_EQ(WideToUTF16(L"view-source:http"), - formatted.substr(parsed.scheme.begin, parsed.scheme.len)); - EXPECT_FALSE(parsed.username.is_valid()); - EXPECT_FALSE(parsed.password.is_valid()); - EXPECT_EQ(WideToUTF16(L"host"), - formatted.substr(parsed.host.begin, parsed.host.len)); - EXPECT_EQ(WideToUTF16(L"81"), - formatted.substr(parsed.port.begin, parsed.port.len)); - EXPECT_EQ(WideToUTF16(L"/path"), - formatted.substr(parsed.path.begin, parsed.path.len)); - EXPECT_EQ(WideToUTF16(L"query"), - formatted.substr(parsed.query.begin, parsed.query.len)); - EXPECT_EQ(WideToUTF16(L"ref"), - formatted.substr(parsed.ref.begin, parsed.ref.len)); - - // omit http case. - formatted = FormatUrl(GURL("http://host:8000/a?b=c#d"), - std::string(), - kFormatUrlOmitHTTP, - UnescapeRule::NORMAL, - &parsed, - NULL, - NULL); - EXPECT_EQ(WideToUTF16(L"host:8000/a?b=c#d"), formatted); - EXPECT_FALSE(parsed.scheme.is_valid()); - EXPECT_FALSE(parsed.username.is_valid()); - EXPECT_FALSE(parsed.password.is_valid()); - EXPECT_EQ(WideToUTF16(L"host"), - formatted.substr(parsed.host.begin, parsed.host.len)); - EXPECT_EQ(WideToUTF16(L"8000"), - formatted.substr(parsed.port.begin, parsed.port.len)); - EXPECT_EQ(WideToUTF16(L"/a"), - formatted.substr(parsed.path.begin, parsed.path.len)); - EXPECT_EQ(WideToUTF16(L"b=c"), - formatted.substr(parsed.query.begin, parsed.query.len)); - EXPECT_EQ(WideToUTF16(L"d"), - formatted.substr(parsed.ref.begin, parsed.ref.len)); - - // omit http starts with ftp case. - formatted = FormatUrl(GURL("http://ftp.host:8000/a?b=c#d"), - std::string(), - kFormatUrlOmitHTTP, - UnescapeRule::NORMAL, - &parsed, - NULL, - NULL); - EXPECT_EQ(WideToUTF16(L"http://ftp.host:8000/a?b=c#d"), formatted); - EXPECT_TRUE(parsed.scheme.is_valid()); - EXPECT_FALSE(parsed.username.is_valid()); - EXPECT_FALSE(parsed.password.is_valid()); - EXPECT_EQ(WideToUTF16(L"http"), - formatted.substr(parsed.scheme.begin, parsed.scheme.len)); - EXPECT_EQ(WideToUTF16(L"ftp.host"), - formatted.substr(parsed.host.begin, parsed.host.len)); - EXPECT_EQ(WideToUTF16(L"8000"), - formatted.substr(parsed.port.begin, parsed.port.len)); - EXPECT_EQ(WideToUTF16(L"/a"), - formatted.substr(parsed.path.begin, parsed.path.len)); - EXPECT_EQ(WideToUTF16(L"b=c"), - formatted.substr(parsed.query.begin, parsed.query.len)); - EXPECT_EQ(WideToUTF16(L"d"), - formatted.substr(parsed.ref.begin, parsed.ref.len)); - - // omit http starts with 'f' case. - formatted = FormatUrl(GURL("http://f/"), - std::string(), - kFormatUrlOmitHTTP, - UnescapeRule::NORMAL, - &parsed, - NULL, - NULL); - EXPECT_EQ(WideToUTF16(L"f/"), formatted); - EXPECT_FALSE(parsed.scheme.is_valid()); - EXPECT_FALSE(parsed.username.is_valid()); - EXPECT_FALSE(parsed.password.is_valid()); - EXPECT_FALSE(parsed.port.is_valid()); - EXPECT_TRUE(parsed.path.is_valid()); - EXPECT_FALSE(parsed.query.is_valid()); - EXPECT_FALSE(parsed.ref.is_valid()); - EXPECT_EQ(WideToUTF16(L"f"), - formatted.substr(parsed.host.begin, parsed.host.len)); - EXPECT_EQ(WideToUTF16(L"/"), - formatted.substr(parsed.path.begin, parsed.path.len)); -} - -// Make sure that calling FormatUrl on a GURL and then converting back to a GURL -// results in the original GURL, for each ASCII character in the path. -TEST(NetUtilTest, FormatUrlRoundTripPathASCII) { - for (unsigned char test_char = 32; test_char < 128; ++test_char) { - GURL url(std::string("http://www.google.com/") + - static_cast<char>(test_char)); - size_t prefix_len; - base::string16 formatted = FormatUrl(url, - std::string(), - kFormatUrlOmitUsernamePassword, - UnescapeRule::NORMAL, - NULL, - &prefix_len, - NULL); - EXPECT_EQ(url.spec(), GURL(formatted).spec()); - } -} - -// Make sure that calling FormatUrl on a GURL and then converting back to a GURL -// results in the original GURL, for each escaped ASCII character in the path. -TEST(NetUtilTest, FormatUrlRoundTripPathEscaped) { - for (unsigned char test_char = 32; test_char < 128; ++test_char) { - std::string original_url("http://www.google.com/"); - original_url.push_back('%'); - original_url.append(base::HexEncode(&test_char, 1)); - - GURL url(original_url); - size_t prefix_len; - base::string16 formatted = FormatUrl(url, - std::string(), - kFormatUrlOmitUsernamePassword, - UnescapeRule::NORMAL, - NULL, - &prefix_len, - NULL); - EXPECT_EQ(url.spec(), GURL(formatted).spec()); - } -} - -// Make sure that calling FormatUrl on a GURL and then converting back to a GURL -// results in the original GURL, for each ASCII character in the query. -TEST(NetUtilTest, FormatUrlRoundTripQueryASCII) { - for (unsigned char test_char = 32; test_char < 128; ++test_char) { - GURL url(std::string("http://www.google.com/?") + - static_cast<char>(test_char)); - size_t prefix_len; - base::string16 formatted = FormatUrl(url, - std::string(), - kFormatUrlOmitUsernamePassword, - UnescapeRule::NORMAL, - NULL, - &prefix_len, - NULL); - EXPECT_EQ(url.spec(), GURL(formatted).spec()); - } -} - -// Make sure that calling FormatUrl on a GURL and then converting back to a GURL -// only results in a different GURL for certain characters. -TEST(NetUtilTest, FormatUrlRoundTripQueryEscaped) { - // A full list of characters which FormatURL should unescape and GURL should - // not escape again, when they appear in a query string. - const char kUnescapedCharacters[] = - "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz-_~"; - for (unsigned char test_char = 0; test_char < 128; ++test_char) { - std::string original_url("http://www.google.com/?"); - original_url.push_back('%'); - original_url.append(base::HexEncode(&test_char, 1)); - - GURL url(original_url); - size_t prefix_len; - base::string16 formatted = FormatUrl(url, - std::string(), - kFormatUrlOmitUsernamePassword, - UnescapeRule::NORMAL, - NULL, - &prefix_len, - NULL); - - if (test_char && - strchr(kUnescapedCharacters, static_cast<char>(test_char))) { - EXPECT_NE(url.spec(), GURL(formatted).spec()); - } else { - EXPECT_EQ(url.spec(), GURL(formatted).spec()); - } - } -} - -TEST(NetUtilTest, FormatUrlWithOffsets) { - CheckAdjustedOffsets(std::string(), "en", kFormatUrlOmitNothing, - UnescapeRule::NORMAL, NULL); - - const size_t basic_offsets[] = { - 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, - 21, 22, 23, 24, 25 - }; - CheckAdjustedOffsets("http://www.google.com/foo/", "en", - kFormatUrlOmitNothing, UnescapeRule::NORMAL, - basic_offsets); - - const size_t omit_auth_offsets_1[] = { - 0, 1, 2, 3, 4, 5, 6, 7, kNpos, kNpos, kNpos, kNpos, kNpos, kNpos, kNpos, 7, - 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21 - }; - CheckAdjustedOffsets("http://foo:bar@www.google.com/", "en", - kFormatUrlOmitUsernamePassword, UnescapeRule::NORMAL, - omit_auth_offsets_1); - - const size_t omit_auth_offsets_2[] = { - 0, 1, 2, 3, 4, 5, 6, 7, kNpos, kNpos, kNpos, 7, 8, 9, 10, 11, 12, 13, 14, - 15, 16, 17, 18, 19, 20, 21 - }; - CheckAdjustedOffsets("http://foo@www.google.com/", "en", - kFormatUrlOmitUsernamePassword, UnescapeRule::NORMAL, - omit_auth_offsets_2); - - const size_t dont_omit_auth_offsets[] = { - 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, kNpos, kNpos, kNpos, kNpos, kNpos, kNpos, - kNpos, kNpos, 11, 12, kNpos, kNpos, kNpos, kNpos, kNpos, kNpos, kNpos, - kNpos, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, - 30, 31 - }; - // Unescape to "http://foo\x30B0:\x30B0bar@www.google.com". - CheckAdjustedOffsets("http://foo%E3%82%B0:%E3%82%B0bar@www.google.com/", "en", - kFormatUrlOmitNothing, UnescapeRule::NORMAL, - dont_omit_auth_offsets); - - const size_t view_source_offsets[] = { - 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, kNpos, - kNpos, kNpos, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33 - }; - CheckAdjustedOffsets("view-source:http://foo@www.google.com/", "en", - kFormatUrlOmitUsernamePassword, UnescapeRule::NORMAL, - view_source_offsets); - - const size_t idn_hostname_offsets_1[] = { - 0, 1, 2, 3, 4, 5, 6, 7, kNpos, kNpos, kNpos, kNpos, kNpos, kNpos, kNpos, - kNpos, kNpos, kNpos, kNpos, kNpos, kNpos, kNpos, kNpos, kNpos, kNpos, 12, - 13, 14, 15, 16, 17, 18, 19 - }; - // Convert punycode to "http://\x671d\x65e5\x3042\x3055\x3072.jp/foo/". - CheckAdjustedOffsets("http://xn--l8jvb1ey91xtjb.jp/foo/", "ja", - kFormatUrlOmitNothing, UnescapeRule::NORMAL, - idn_hostname_offsets_1); - - const size_t idn_hostname_offsets_2[] = { - 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, kNpos, kNpos, kNpos, kNpos, kNpos, - kNpos, kNpos, kNpos, kNpos, kNpos, kNpos, 14, 15, kNpos, kNpos, kNpos, - kNpos, kNpos, kNpos, kNpos, kNpos, kNpos, kNpos, kNpos, kNpos, kNpos, kNpos, - kNpos, 19, 20, 21, 22, 23, 24 - }; - // Convert punycode to - // "http://test.\x89c6\x9891.\x5317\x4eac\x5927\x5b78.test/". - CheckAdjustedOffsets("http://test.xn--cy2a840a.xn--1lq90ic7f1rc.test/", - "zh-CN", kFormatUrlOmitNothing, UnescapeRule::NORMAL, - idn_hostname_offsets_2); - - const size_t unescape_offsets[] = { - 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, - 21, 22, 23, 24, 25, kNpos, kNpos, 26, 27, 28, 29, 30, kNpos, kNpos, kNpos, - kNpos, kNpos, kNpos, kNpos, kNpos, 31, kNpos, kNpos, kNpos, kNpos, kNpos, - kNpos, kNpos, kNpos, 32, kNpos, kNpos, kNpos, kNpos, kNpos, kNpos, kNpos, - kNpos, 33, kNpos, kNpos, kNpos, kNpos, kNpos, kNpos, kNpos, kNpos - }; - // Unescape to "http://www.google.com/foo bar/\x30B0\x30FC\x30B0\x30EB". - CheckAdjustedOffsets( - "http://www.google.com/foo%20bar/%E3%82%B0%E3%83%BC%E3%82%B0%E3%83%AB", - "en", kFormatUrlOmitNothing, UnescapeRule::SPACES, unescape_offsets); - - const size_t ref_offsets[] = { - 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, - 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, kNpos, kNpos, 32, kNpos, kNpos, - 33 - }; - // Unescape to "http://www.google.com/foo.html#\x30B0\x30B0z". - CheckAdjustedOffsets( - "http://www.google.com/foo.html#\xE3\x82\xB0\xE3\x82\xB0z", "en", - kFormatUrlOmitNothing, UnescapeRule::NORMAL, ref_offsets); - - const size_t omit_http_offsets[] = { - 0, kNpos, kNpos, kNpos, kNpos, kNpos, kNpos, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, - 10, 11, 12, 13, 14 - }; - CheckAdjustedOffsets("http://www.google.com/", "en", kFormatUrlOmitHTTP, - UnescapeRule::NORMAL, omit_http_offsets); - - const size_t omit_http_start_with_ftp_offsets[] = { - 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21 - }; - CheckAdjustedOffsets("http://ftp.google.com/", "en", kFormatUrlOmitHTTP, - UnescapeRule::NORMAL, omit_http_start_with_ftp_offsets); - - const size_t omit_all_offsets[] = { - 0, kNpos, kNpos, kNpos, kNpos, kNpos, kNpos, 0, kNpos, kNpos, kNpos, kNpos, - 0, 1, 2, 3, 4, 5, 6, 7 - }; - CheckAdjustedOffsets("http://user@foo.com/", "en", kFormatUrlOmitAll, - UnescapeRule::NORMAL, omit_all_offsets); -} +} // namespace } // namespace net |