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

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: fix browsertests compile error (sigh) Created 5 years, 5 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/i18n/time_formatting.h" 7 #include "base/i18n/time_formatting.h"
8 #include "base/logging.h" 8 #include "base/logging.h"
9 #include "base/strings/string16.h" 9 #include "base/strings/string16.h"
10 #include "base/strings/string_number_conversions.h" 10 #include "base/strings/string_number_conversions.h"
11 #include "base/strings/string_piece.h" 11 #include "base/strings/string_piece.h"
12 #include "base/strings/string_split.h" 12 #include "base/strings/string_split.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/suggestion_answer.h" 17 #include "components/omnibox/suggestion_answer.h"
18 #include "components/search_engines/template_url.h" 18 #include "components/search_engines/template_url.h"
19 #include "components/search_engines/template_url_service.h" 19 #include "components/search_engines/template_url_service.h"
20 #include "grit/components_scaled_resources.h" 20 #include "grit/components_scaled_resources.h"
21 #include "net/base/net_util.h"
21 22
22 namespace { 23 namespace {
23 24
24 bool IsTrivialClassification(const ACMatchClassifications& classifications) { 25 bool IsTrivialClassification(const ACMatchClassifications& classifications) {
25 return classifications.empty() || 26 return classifications.empty() ||
26 ((classifications.size() == 1) && 27 ((classifications.size() == 1) &&
27 (classifications.back().style == ACMatchClassification::NONE)); 28 (classifications.back().style == ACMatchClassification::NONE));
28 } 29 }
29 30
31 // Returns true if one of the |terms_prefixed_by_http_or_https| matches the
32 // beginning of the URL (sans scheme). (Recall that
33 // |terms_prefixed_by_http_or_https|, for the input "http://a b" will be
34 // ["a"].) This suggests that the user wants a particular URL with a scheme
35 // in mind, hence the caller should not consider another URL like this one
36 // but with a different scheme to be a duplicate. |languages| is used to
37 // format punycoded URLs to decide if they match.
38 bool WordMatchesURLContent(
39 const std::vector<base::string16>& terms_prefixed_by_http_or_https,
40 const std::string& languages,
41 const GURL& url) {
42 size_t prefix_length =
43 url.scheme().length() + strlen(url::kStandardSchemeSeparator);
44 DCHECK_GE(url.spec().length(), prefix_length);
45 const base::string16& formatted_url = net::FormatUrl(
46 url, languages, net::kFormatUrlOmitNothing, net::UnescapeRule::NORMAL,
47 NULL, NULL, &prefix_length);
48 if (prefix_length == base::string16::npos)
49 return false;
50 const base::string16& formatted_url_without_scheme =
51 formatted_url.substr(prefix_length);
52 for (const auto& term : terms_prefixed_by_http_or_https) {
53 if (base::StartsWith(formatted_url_without_scheme, term,
54 base::CompareCase::SENSITIVE))
55 return true;
56 }
57 return false;
58 }
59
30 } // namespace 60 } // namespace
31 61
32 // AutocompleteMatch ---------------------------------------------------------- 62 // AutocompleteMatch ----------------------------------------------------------
33 63
34 // static 64 // static
35 const base::char16 AutocompleteMatch::kInvalidChars[] = { 65 const base::char16 AutocompleteMatch::kInvalidChars[] = {
36 '\n', '\r', '\t', 66 '\n', '\r', '\t',
37 0x2028, // Line separator 67 0x2028, // Line separator
38 0x2029, // Paragraph separator 68 0x2029, // Paragraph separator
39 0 69 0
(...skipping 339 matching lines...) Expand 10 before | Expand all | Expand 10 after
379 return NULL; 409 return NULL;
380 TemplateURL* template_url = keyword.empty() ? 410 TemplateURL* template_url = keyword.empty() ?
381 NULL : template_url_service->GetTemplateURLForKeyword(keyword); 411 NULL : template_url_service->GetTemplateURLForKeyword(keyword);
382 return (template_url || host.empty()) ? 412 return (template_url || host.empty()) ?
383 template_url : template_url_service->GetTemplateURLForHost(host); 413 template_url : template_url_service->GetTemplateURLForHost(host);
384 } 414 }
385 415
386 // static 416 // static
387 GURL AutocompleteMatch::GURLToStrippedGURL( 417 GURL AutocompleteMatch::GURLToStrippedGURL(
388 const GURL& url, 418 const GURL& url,
419 const AutocompleteInput& input,
420 const std::string& languages,
389 TemplateURLService* template_url_service, 421 TemplateURLService* template_url_service,
390 const base::string16& keyword) { 422 const base::string16& keyword) {
391 if (!url.is_valid()) 423 if (!url.is_valid())
392 return url; 424 return url;
393 425
394 GURL stripped_destination_url = url; 426 GURL stripped_destination_url = url;
395 427
396 // If the destination URL looks like it was generated from a TemplateURL, 428 // If the destination URL looks like it was generated from a TemplateURL,
397 // remove all substitutions other than the search terms. This allows us 429 // remove all substitutions other than the search terms. This allows us
398 // to eliminate cases like past search URLs from history that differ only 430 // to eliminate cases like past search URLs from history that differ only
(...skipping 25 matching lines...) Expand all
424 456
425 // Remove the www. prefix from the host. 457 // Remove the www. prefix from the host.
426 static const char prefix[] = "www."; 458 static const char prefix[] = "www.";
427 static const size_t prefix_len = arraysize(prefix) - 1; 459 static const size_t prefix_len = arraysize(prefix) - 1;
428 std::string host = stripped_destination_url.host(); 460 std::string host = stripped_destination_url.host();
429 if (host.compare(0, prefix_len, prefix) == 0) { 461 if (host.compare(0, prefix_len, prefix) == 0) {
430 replacements.SetHostStr(base::StringPiece(host).substr(prefix_len)); 462 replacements.SetHostStr(base::StringPiece(host).substr(prefix_len));
431 needs_replacement = true; 463 needs_replacement = true;
432 } 464 }
433 465
434 // Replace https protocol with http protocol. 466 // Remove any trailing slash (if it's not a lone slash), or add a slash (to
435 if (stripped_destination_url.SchemeIs(url::kHttpsScheme)) { 467 // make a lone slash) if the path is empty. (We can't unconditionally
468 // remove even lone slashes because for some schemes the path must consist
469 // of at least a slash.)
470 const std::string& path = stripped_destination_url.path();
471 if ((path.length() > 1) && (path[path.length() - 1] == '/')) {
472 replacements.SetPathStr(
473 base::StringPiece(path).substr(0, path.length() - 1));
474 needs_replacement = true;
475 } else if (path.empty()) {
476 static const char slash[] = "/";
477 replacements.SetPathStr(base::StringPiece(slash));
478 needs_replacement = true;
479 }
480
481 // Replace https protocol with http, as long as the user didn't explicitly
482 // specify one of the two.
483 if (stripped_destination_url.SchemeIs(url::kHttpsScheme) &&
484 (input.terms_prefixed_by_http_or_https().empty() ||
485 !WordMatchesURLContent(
486 input.terms_prefixed_by_http_or_https(), languages, url))) {
436 replacements.SetScheme(url::kHttpScheme, 487 replacements.SetScheme(url::kHttpScheme,
437 url::Component(0, strlen(url::kHttpScheme))); 488 url::Component(0, strlen(url::kHttpScheme)));
438 needs_replacement = true; 489 needs_replacement = true;
439 } 490 }
440 491
441 if (needs_replacement) 492 if (needs_replacement)
442 stripped_destination_url = stripped_destination_url.ReplaceComponents( 493 stripped_destination_url = stripped_destination_url.ReplaceComponents(
443 replacements); 494 replacements);
444 return stripped_destination_url; 495 return stripped_destination_url;
445 } 496 }
446 497
447 void AutocompleteMatch::ComputeStrippedDestinationURL( 498 void AutocompleteMatch::ComputeStrippedDestinationURL(
499 const AutocompleteInput& input,
500 const std::string& languages,
448 TemplateURLService* template_url_service) { 501 TemplateURLService* template_url_service) {
449 stripped_destination_url = 502 stripped_destination_url = GURLToStrippedGURL(
450 GURLToStrippedGURL(destination_url, template_url_service, keyword); 503 destination_url, input, languages, template_url_service, keyword);
451 } 504 }
452 505
453 void AutocompleteMatch::EnsureUWYTIsAllowedToBeDefault( 506 void AutocompleteMatch::EnsureUWYTIsAllowedToBeDefault(
454 const GURL& canonical_input_url, 507 const AutocompleteInput& input,
508 const std::string& languages,
455 TemplateURLService* template_url_service) { 509 TemplateURLService* template_url_service) {
456 if (!allowed_to_be_default_match) { 510 if (!allowed_to_be_default_match) {
457 const GURL& stripped_canonical_input_url = 511 const GURL& stripped_canonical_input_url =
458 AutocompleteMatch::GURLToStrippedGURL( 512 AutocompleteMatch::GURLToStrippedGURL(
459 canonical_input_url, template_url_service, base::string16()); 513 input.canonicalized_url(), input, languages, template_url_service,
460 ComputeStrippedDestinationURL(template_url_service); 514 base::string16());
515 ComputeStrippedDestinationURL(input, languages, template_url_service);
461 allowed_to_be_default_match = 516 allowed_to_be_default_match =
462 stripped_canonical_input_url == stripped_destination_url; 517 stripped_canonical_input_url == stripped_destination_url;
463 } 518 }
464 } 519 }
465 520
466 void AutocompleteMatch::GetKeywordUIState( 521 void AutocompleteMatch::GetKeywordUIState(
467 TemplateURLService* template_url_service, 522 TemplateURLService* template_url_service,
468 base::string16* keyword, 523 base::string16* keyword,
469 bool* is_keyword_hint) const { 524 bool* is_keyword_hint) const {
470 *is_keyword_hint = associated_keyword.get() != NULL; 525 *is_keyword_hint = associated_keyword.get() != NULL;
(...skipping 109 matching lines...) Expand 10 before | Expand all | Expand 10 after
580 << " is unsorted in relation to last offset of " << last_offset 635 << " is unsorted in relation to last offset of " << last_offset
581 << ". Provider: " << provider_name << "."; 636 << ". Provider: " << provider_name << ".";
582 DCHECK_LT(i->offset, text.length()) 637 DCHECK_LT(i->offset, text.length())
583 << " Classification of [" << i->offset << "," << text.length() 638 << " Classification of [" << i->offset << "," << text.length()
584 << "] is out of bounds for \"" << text << "\". Provider: " 639 << "] is out of bounds for \"" << text << "\". Provider: "
585 << provider_name << "."; 640 << provider_name << ".";
586 last_offset = i->offset; 641 last_offset = i->offset;
587 } 642 }
588 } 643 }
589 #endif 644 #endif
OLDNEW
« no previous file with comments | « components/omnibox/autocomplete_match.h ('k') | components/omnibox/autocomplete_match_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698