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

Side by Side 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: possible fix for mac code (cannot compile mac code myself) 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 unified diff | Download patch
OLDNEW
1 // Copyright 2014 The Chromium Authors. All rights reserved. 1 // Copyright 2014 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "components/omnibox/autocomplete_match.h" 5 #include "components/omnibox/autocomplete_match.h"
6 6
7 #include "base/command_line.h" 7 #include "base/command_line.h"
8 #include "base/i18n/time_formatting.h" 8 #include "base/i18n/time_formatting.h"
9 #include "base/logging.h" 9 #include "base/logging.h"
10 #include "base/strings/string16.h" 10 #include "base/strings/string16.h"
11 #include "base/strings/string_number_conversions.h" 11 #include "base/strings/string_number_conversions.h"
12 #include "base/strings/string_piece.h" 12 #include "base/strings/string_piece.h"
13 #include "base/strings/string_util.h" 13 #include "base/strings/string_util.h"
14 #include "base/strings/utf_string_conversions.h" 14 #include "base/strings/utf_string_conversions.h"
15 #include "base/time/time.h" 15 #include "base/time/time.h"
16 #include "components/omnibox/autocomplete_provider.h" 16 #include "components/omnibox/autocomplete_provider.h"
17 #include "components/omnibox/omnibox_switches.h" 17 #include "components/omnibox/omnibox_switches.h"
18 #include "components/omnibox/suggestion_answer.h" 18 #include "components/omnibox/suggestion_answer.h"
19 #include "components/search_engines/template_url.h" 19 #include "components/search_engines/template_url.h"
20 #include "components/search_engines/template_url_service.h" 20 #include "components/search_engines/template_url_service.h"
21 #include "grit/components_scaled_resources.h" 21 #include "grit/components_scaled_resources.h"
22 #include "net/base/net_util.h"
22 23
23 namespace { 24 namespace {
24 25
25 bool IsTrivialClassification(const ACMatchClassifications& classifications) { 26 bool IsTrivialClassification(const ACMatchClassifications& classifications) {
26 return classifications.empty() || 27 return classifications.empty() ||
27 ((classifications.size() == 1) && 28 ((classifications.size() == 1) &&
28 (classifications.back().style == ACMatchClassification::NONE)); 29 (classifications.back().style == ACMatchClassification::NONE));
29 } 30 }
30 31
32 // Returns true if one of the |terms_prefixed_by_http_or_https| matches the
33 // beginning of the URL (sans scheme). (Recall that
34 // |terms_prefixed_by_http_or_https|, for the input "http://a b" will be
35 // ["a"].) This suggests that the user wants a particular URL with a scheme
36 // in mind, hence the caller should not consider another URL like this one
37 // but with a different scheme to be a duplicate. |languages| is used to
38 // format punycoded URLs to decide if they match.
39 bool WordMatchesURLContent(
40 const std::vector<std::pair<std::string, base::string16> >&
41 terms_prefixed_by_http_or_https,
42 const std::string& languages,
43 const GURL& url) {
44 size_t prefix_length =
45 url.scheme().length() + strlen(url::kStandardSchemeSeparator);
46 DCHECK_GE(url.spec().length(), prefix_length);
47 const std::string& url_spec_without_scheme = url.spec().substr(prefix_length);
48 // In addition to checking the URL spec, check the formatted URL in order to
49 // detect a prefix match against a punycode-encoded hostname.
Peter Kasting 2015/06/29 05:04:59 How come you check both? Shouldn't the check agai
Mark P 2015/06/30 04:23:17 I thought I had a reason at the time but I don't r
50 const base::string16& formatted_url = net::FormatUrl(
51 url, languages, net::kFormatUrlOmitNothing, net::UnescapeRule::NORMAL,
52 NULL, NULL, &prefix_length);
53 base::string16 formatted_url_without_scheme;
54 if (prefix_length != base::string16::npos)
55 formatted_url_without_scheme = formatted_url.substr(prefix_length);
56 for (const auto& term_pair : terms_prefixed_by_http_or_https) {
57 // At the moment we do not support case-insensitive prefix matching
58 // for international (punycode) domain names.
59 if (base::StartsWith(url_spec_without_scheme, term_pair.first,
60 base::CompareCase::INSENSITIVE_ASCII) ||
61 ((prefix_length != base::string16::npos) &&
62 base::StartsWith(formatted_url_without_scheme, term_pair.second,
63 base::CompareCase::SENSITIVE)))
64 return true;
65 }
66 return false;
67 }
68
31 } // namespace 69 } // namespace
32 70
33 // AutocompleteMatch ---------------------------------------------------------- 71 // AutocompleteMatch ----------------------------------------------------------
34 72
35 // static 73 // static
36 const base::char16 AutocompleteMatch::kInvalidChars[] = { 74 const base::char16 AutocompleteMatch::kInvalidChars[] = {
37 '\n', '\r', '\t', 75 '\n', '\r', '\t',
38 0x2028, // Line separator 76 0x2028, // Line separator
39 0x2029, // Paragraph separator 77 0x2029, // Paragraph separator
40 0 78 0
(...skipping 324 matching lines...) Expand 10 before | Expand all | Expand 10 after
365 return NULL; 403 return NULL;
366 TemplateURL* template_url = keyword.empty() ? 404 TemplateURL* template_url = keyword.empty() ?
367 NULL : template_url_service->GetTemplateURLForKeyword(keyword); 405 NULL : template_url_service->GetTemplateURLForKeyword(keyword);
368 return (template_url || host.empty()) ? 406 return (template_url || host.empty()) ?
369 template_url : template_url_service->GetTemplateURLForHost(host); 407 template_url : template_url_service->GetTemplateURLForHost(host);
370 } 408 }
371 409
372 // static 410 // static
373 GURL AutocompleteMatch::GURLToStrippedGURL( 411 GURL AutocompleteMatch::GURLToStrippedGURL(
374 const GURL& url, 412 const GURL& url,
413 const AutocompleteInput& input,
414 const std::string& languages,
375 TemplateURLService* template_url_service, 415 TemplateURLService* template_url_service,
376 const base::string16& keyword) { 416 const base::string16& keyword) {
377 if (!url.is_valid()) 417 if (!url.is_valid())
378 return url; 418 return url;
379 419
380 GURL stripped_destination_url = url; 420 GURL stripped_destination_url = url;
381 421
382 // If the destination URL looks like it was generated from a TemplateURL, 422 // If the destination URL looks like it was generated from a TemplateURL,
383 // remove all substitutions other than the search terms. This allows us 423 // remove all substitutions other than the search terms. This allows us
384 // to eliminate cases like past search URLs from history that differ only 424 // to eliminate cases like past search URLs from history that differ only
(...skipping 25 matching lines...) Expand all
410 450
411 // Remove the www. prefix from the host. 451 // Remove the www. prefix from the host.
412 static const char prefix[] = "www."; 452 static const char prefix[] = "www.";
413 static const size_t prefix_len = arraysize(prefix) - 1; 453 static const size_t prefix_len = arraysize(prefix) - 1;
414 std::string host = stripped_destination_url.host(); 454 std::string host = stripped_destination_url.host();
415 if (host.compare(0, prefix_len, prefix) == 0) { 455 if (host.compare(0, prefix_len, prefix) == 0) {
416 replacements.SetHostStr(base::StringPiece(host).substr(prefix_len)); 456 replacements.SetHostStr(base::StringPiece(host).substr(prefix_len));
417 needs_replacement = true; 457 needs_replacement = true;
418 } 458 }
419 459
420 // Replace https protocol with http protocol. 460 // Remove any trailing slash (if it's not a lone slash), or add a slash (to
421 if (stripped_destination_url.SchemeIs(url::kHttpsScheme)) { 461 // make a lone slash) if the path is empty. (We can't unconditionally
462 // remove even lone slashes because for some schemes the path must consist
463 // of at least a slash.)
464 const std::string& path = stripped_destination_url.path();
465 if ((path.length() > 1) && (path[path.length() - 1] == '/')) {
466 replacements.SetPathStr(
467 base::StringPiece(path).substr(0, path.length() - 1));
468 needs_replacement = true;
469 } else if (path.empty()) {
470 static const char slash[] = "/";
471 replacements.SetPathStr(base::StringPiece(slash));
472 needs_replacement = true;
473 }
474
475 // Replace https protocol with http, as long as the user didn't explicitly
476 // specify one of the two.
477 if (stripped_destination_url.SchemeIs(url::kHttpsScheme) &&
478 (input.terms_prefixed_by_http_or_https().empty() ||
479 !WordMatchesURLContent(
480 input.terms_prefixed_by_http_or_https(), languages, url))) {
422 replacements.SetScheme(url::kHttpScheme, 481 replacements.SetScheme(url::kHttpScheme,
423 url::Component(0, strlen(url::kHttpScheme))); 482 url::Component(0, strlen(url::kHttpScheme)));
424 needs_replacement = true; 483 needs_replacement = true;
425 } 484 }
426 485
427 if (needs_replacement) 486 if (needs_replacement)
428 stripped_destination_url = stripped_destination_url.ReplaceComponents( 487 stripped_destination_url = stripped_destination_url.ReplaceComponents(
429 replacements); 488 replacements);
430 return stripped_destination_url; 489 return stripped_destination_url;
431 } 490 }
432 491
433 void AutocompleteMatch::ComputeStrippedDestinationURL( 492 void AutocompleteMatch::ComputeStrippedDestinationURL(
493 const AutocompleteInput& input,
494 const std::string& languages,
434 TemplateURLService* template_url_service) { 495 TemplateURLService* template_url_service) {
435 stripped_destination_url = 496 stripped_destination_url = GURLToStrippedGURL(
436 GURLToStrippedGURL(destination_url, template_url_service, keyword); 497 destination_url, input, languages, template_url_service, keyword);
437 } 498 }
438 499
439 void AutocompleteMatch::EnsureUWYTIsAllowedToBeDefault( 500 void AutocompleteMatch::EnsureUWYTIsAllowedToBeDefault(
440 const GURL& canonical_input_url, 501 const AutocompleteInput& input,
502 const std::string& languages,
441 TemplateURLService* template_url_service) { 503 TemplateURLService* template_url_service) {
442 if (!allowed_to_be_default_match) { 504 if (!allowed_to_be_default_match) {
443 const GURL& stripped_canonical_input_url = 505 const GURL& stripped_canonical_input_url =
444 AutocompleteMatch::GURLToStrippedGURL( 506 AutocompleteMatch::GURLToStrippedGURL(
445 canonical_input_url, template_url_service, base::string16()); 507 input.canonicalized_url(), input, languages, template_url_service,
446 ComputeStrippedDestinationURL(template_url_service); 508 base::string16());
509 ComputeStrippedDestinationURL(input, languages, template_url_service);
447 allowed_to_be_default_match = 510 allowed_to_be_default_match =
448 stripped_canonical_input_url == stripped_destination_url; 511 stripped_canonical_input_url == stripped_destination_url;
449 } 512 }
450 } 513 }
451 514
452 void AutocompleteMatch::GetKeywordUIState( 515 void AutocompleteMatch::GetKeywordUIState(
453 TemplateURLService* template_url_service, 516 TemplateURLService* template_url_service,
454 base::string16* keyword, 517 base::string16* keyword,
455 bool* is_keyword_hint) const { 518 bool* is_keyword_hint) const {
456 *is_keyword_hint = associated_keyword.get() != NULL; 519 *is_keyword_hint = associated_keyword.get() != NULL;
(...skipping 114 matching lines...) Expand 10 before | Expand all | Expand 10 after
571 << " is unsorted in relation to last offset of " << last_offset 634 << " is unsorted in relation to last offset of " << last_offset
572 << ". Provider: " << provider_name << "."; 635 << ". Provider: " << provider_name << ".";
573 DCHECK_LT(i->offset, text.length()) 636 DCHECK_LT(i->offset, text.length())
574 << " Classification of [" << i->offset << "," << text.length() 637 << " Classification of [" << i->offset << "," << text.length()
575 << "] is out of bounds for \"" << text << "\". Provider: " 638 << "] is out of bounds for \"" << text << "\". Provider: "
576 << provider_name << "."; 639 << provider_name << ".";
577 last_offset = i->offset; 640 last_offset = i->offset;
578 } 641 }
579 } 642 }
580 #endif 643 #endif
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698