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

Unified Diff: components/omnibox/autocomplete_match.cc

Issue 1098843004: Omnibox - Do Not Allow HTTP/HTTPS Equivalence if User Explicitly Entered A Scheme (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: final? API changes Created 5 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: components/omnibox/autocomplete_match.cc
diff --git a/components/omnibox/autocomplete_match.cc b/components/omnibox/autocomplete_match.cc
index 8bd091745b8ebf50fe4f9c7e7f8575776c44b157..0e1c0255078ca7ec61285a8d337adcf4f6cd6abc 100644
--- a/components/omnibox/autocomplete_match.cc
+++ b/components/omnibox/autocomplete_match.cc
@@ -19,6 +19,7 @@
#include "components/search_engines/template_url.h"
#include "components/search_engines/template_url_service.h"
#include "grit/components_scaled_resources.h"
+#include "net/base/net_util.h"
namespace {
@@ -28,6 +29,37 @@ bool IsTrivialClassification(const ACMatchClassifications& classifications) {
(classifications.back().style == ACMatchClassification::NONE));
}
+// Returns true if one of the |terms_prefixed_by_http_or_https| matches the
+// beginning of the URL (sans scheme). (Recall that
+// |terms_prefixed_by_http_or_https|, for the input "http://a b" will be
+// ["a"].) This suggests that the user wants a particular URL with a scheme
+// in mind, hence the caller should not consider another URL like this one
+// but with a different scheme to be a duplicate. |languages| is used to
+// format punycoded URLs to decide if they match.
+bool WordMatchesURLContent(
+ const std::vector<base::string16>& terms_prefixed_by_http_or_https,
+ const std::string& languages,
+ const GURL& url) {
+ 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);
+ if (prefix_length == base::string16::npos)
+ return false;
+ const base::string16& formatted_url_without_scheme =
+ formatted_url.substr(prefix_length);
+ for (const auto& term : terms_prefixed_by_http_or_https) {
+ // At the moment we do not support case-insensitive prefix matching
+ // for international (punycode) domain names.
Peter Kasting 2015/06/30 06:50:30 I bet I know why you did both comparisons. You we
Mark P 2015/06/30 17:29:20 Ah, that sounds like what I was thinking. Thanks
+ if (base::StartsWith(formatted_url_without_scheme, term,
+ base::CompareCase::SENSITIVE))
+ return true;
+ }
+ return false;
+}
+
} // namespace
// AutocompleteMatch ----------------------------------------------------------
@@ -372,6 +404,8 @@ TemplateURL* AutocompleteMatch::GetTemplateURLWithKeyword(
// static
GURL AutocompleteMatch::GURLToStrippedGURL(
const GURL& url,
+ const AutocompleteInput& input,
+ const std::string& languages,
TemplateURLService* template_url_service,
const base::string16& keyword) {
if (!url.is_valid())
@@ -417,8 +451,27 @@ GURL AutocompleteMatch::GURLToStrippedGURL(
needs_replacement = true;
}
- // Replace https protocol with http protocol.
- if (stripped_destination_url.SchemeIs(url::kHttpsScheme)) {
+ // Remove any trailing slash (if it's not a lone slash), or add a slash (to
+ // make a lone slash) if the path is empty. (We can't unconditionally
+ // remove even lone slashes because for some schemes the path must consist
+ // of at least a slash.)
+ const std::string& path = stripped_destination_url.path();
+ if ((path.length() > 1) && (path[path.length() - 1] == '/')) {
+ replacements.SetPathStr(
+ base::StringPiece(path).substr(0, path.length() - 1));
+ needs_replacement = true;
+ } else if (path.empty()) {
+ static const char slash[] = "/";
+ replacements.SetPathStr(base::StringPiece(slash));
+ needs_replacement = true;
+ }
+
+ // Replace https protocol with http, as long as the user didn't explicitly
+ // specify one of the two.
+ if (stripped_destination_url.SchemeIs(url::kHttpsScheme) &&
+ (input.terms_prefixed_by_http_or_https().empty() ||
+ !WordMatchesURLContent(
+ input.terms_prefixed_by_http_or_https(), languages, url))) {
replacements.SetScheme(url::kHttpScheme,
url::Component(0, strlen(url::kHttpScheme)));
needs_replacement = true;
@@ -431,19 +484,23 @@ GURL AutocompleteMatch::GURLToStrippedGURL(
}
void AutocompleteMatch::ComputeStrippedDestinationURL(
+ const AutocompleteInput& input,
+ const std::string& languages,
TemplateURLService* template_url_service) {
- stripped_destination_url =
- GURLToStrippedGURL(destination_url, template_url_service, keyword);
+ stripped_destination_url = GURLToStrippedGURL(
+ destination_url, input, languages, template_url_service, keyword);
}
void AutocompleteMatch::EnsureUWYTIsAllowedToBeDefault(
- const GURL& canonical_input_url,
+ const AutocompleteInput& input,
+ const std::string& languages,
TemplateURLService* template_url_service) {
if (!allowed_to_be_default_match) {
const GURL& stripped_canonical_input_url =
AutocompleteMatch::GURLToStrippedGURL(
- canonical_input_url, template_url_service, base::string16());
- ComputeStrippedDestinationURL(template_url_service);
+ input.canonicalized_url(), input, languages, template_url_service,
+ base::string16());
+ ComputeStrippedDestinationURL(input, languages, template_url_service);
allowed_to_be_default_match =
stripped_canonical_input_url == stripped_destination_url;
}

Powered by Google App Engine
This is Rietveld 408576698