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

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: final? API changes 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/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<base::string16>& terms_prefixed_by_http_or_https,
41 const std::string& languages,
42 const GURL& url) {
43 size_t prefix_length =
44 url.scheme().length() + strlen(url::kStandardSchemeSeparator);
45 DCHECK_GE(url.spec().length(), prefix_length);
46 const base::string16& formatted_url = net::FormatUrl(
47 url, languages, net::kFormatUrlOmitNothing, net::UnescapeRule::NORMAL,
48 NULL, NULL, &prefix_length);
49 if (prefix_length == base::string16::npos)
50 return false;
51 const base::string16& formatted_url_without_scheme =
52 formatted_url.substr(prefix_length);
53 for (const auto& term : terms_prefixed_by_http_or_https) {
54 // At the moment we do not support case-insensitive prefix matching
55 // 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
56 if (base::StartsWith(formatted_url_without_scheme, term,
57 base::CompareCase::SENSITIVE))
58 return true;
59 }
60 return false;
61 }
62
31 } // namespace 63 } // namespace
32 64
33 // AutocompleteMatch ---------------------------------------------------------- 65 // AutocompleteMatch ----------------------------------------------------------
34 66
35 // static 67 // static
36 const base::char16 AutocompleteMatch::kInvalidChars[] = { 68 const base::char16 AutocompleteMatch::kInvalidChars[] = {
37 '\n', '\r', '\t', 69 '\n', '\r', '\t',
38 0x2028, // Line separator 70 0x2028, // Line separator
39 0x2029, // Paragraph separator 71 0x2029, // Paragraph separator
40 0 72 0
(...skipping 324 matching lines...) Expand 10 before | Expand all | Expand 10 after
365 return NULL; 397 return NULL;
366 TemplateURL* template_url = keyword.empty() ? 398 TemplateURL* template_url = keyword.empty() ?
367 NULL : template_url_service->GetTemplateURLForKeyword(keyword); 399 NULL : template_url_service->GetTemplateURLForKeyword(keyword);
368 return (template_url || host.empty()) ? 400 return (template_url || host.empty()) ?
369 template_url : template_url_service->GetTemplateURLForHost(host); 401 template_url : template_url_service->GetTemplateURLForHost(host);
370 } 402 }
371 403
372 // static 404 // static
373 GURL AutocompleteMatch::GURLToStrippedGURL( 405 GURL AutocompleteMatch::GURLToStrippedGURL(
374 const GURL& url, 406 const GURL& url,
407 const AutocompleteInput& input,
408 const std::string& languages,
375 TemplateURLService* template_url_service, 409 TemplateURLService* template_url_service,
376 const base::string16& keyword) { 410 const base::string16& keyword) {
377 if (!url.is_valid()) 411 if (!url.is_valid())
378 return url; 412 return url;
379 413
380 GURL stripped_destination_url = url; 414 GURL stripped_destination_url = url;
381 415
382 // If the destination URL looks like it was generated from a TemplateURL, 416 // If the destination URL looks like it was generated from a TemplateURL,
383 // remove all substitutions other than the search terms. This allows us 417 // remove all substitutions other than the search terms. This allows us
384 // to eliminate cases like past search URLs from history that differ only 418 // to eliminate cases like past search URLs from history that differ only
(...skipping 25 matching lines...) Expand all
410 444
411 // Remove the www. prefix from the host. 445 // Remove the www. prefix from the host.
412 static const char prefix[] = "www."; 446 static const char prefix[] = "www.";
413 static const size_t prefix_len = arraysize(prefix) - 1; 447 static const size_t prefix_len = arraysize(prefix) - 1;
414 std::string host = stripped_destination_url.host(); 448 std::string host = stripped_destination_url.host();
415 if (host.compare(0, prefix_len, prefix) == 0) { 449 if (host.compare(0, prefix_len, prefix) == 0) {
416 replacements.SetHostStr(base::StringPiece(host).substr(prefix_len)); 450 replacements.SetHostStr(base::StringPiece(host).substr(prefix_len));
417 needs_replacement = true; 451 needs_replacement = true;
418 } 452 }
419 453
420 // Replace https protocol with http protocol. 454 // Remove any trailing slash (if it's not a lone slash), or add a slash (to
421 if (stripped_destination_url.SchemeIs(url::kHttpsScheme)) { 455 // make a lone slash) if the path is empty. (We can't unconditionally
456 // remove even lone slashes because for some schemes the path must consist
457 // of at least a slash.)
458 const std::string& path = stripped_destination_url.path();
459 if ((path.length() > 1) && (path[path.length() - 1] == '/')) {
460 replacements.SetPathStr(
461 base::StringPiece(path).substr(0, path.length() - 1));
462 needs_replacement = true;
463 } else if (path.empty()) {
464 static const char slash[] = "/";
465 replacements.SetPathStr(base::StringPiece(slash));
466 needs_replacement = true;
467 }
468
469 // Replace https protocol with http, as long as the user didn't explicitly
470 // specify one of the two.
471 if (stripped_destination_url.SchemeIs(url::kHttpsScheme) &&
472 (input.terms_prefixed_by_http_or_https().empty() ||
473 !WordMatchesURLContent(
474 input.terms_prefixed_by_http_or_https(), languages, url))) {
422 replacements.SetScheme(url::kHttpScheme, 475 replacements.SetScheme(url::kHttpScheme,
423 url::Component(0, strlen(url::kHttpScheme))); 476 url::Component(0, strlen(url::kHttpScheme)));
424 needs_replacement = true; 477 needs_replacement = true;
425 } 478 }
426 479
427 if (needs_replacement) 480 if (needs_replacement)
428 stripped_destination_url = stripped_destination_url.ReplaceComponents( 481 stripped_destination_url = stripped_destination_url.ReplaceComponents(
429 replacements); 482 replacements);
430 return stripped_destination_url; 483 return stripped_destination_url;
431 } 484 }
432 485
433 void AutocompleteMatch::ComputeStrippedDestinationURL( 486 void AutocompleteMatch::ComputeStrippedDestinationURL(
487 const AutocompleteInput& input,
488 const std::string& languages,
434 TemplateURLService* template_url_service) { 489 TemplateURLService* template_url_service) {
435 stripped_destination_url = 490 stripped_destination_url = GURLToStrippedGURL(
436 GURLToStrippedGURL(destination_url, template_url_service, keyword); 491 destination_url, input, languages, template_url_service, keyword);
437 } 492 }
438 493
439 void AutocompleteMatch::EnsureUWYTIsAllowedToBeDefault( 494 void AutocompleteMatch::EnsureUWYTIsAllowedToBeDefault(
440 const GURL& canonical_input_url, 495 const AutocompleteInput& input,
496 const std::string& languages,
441 TemplateURLService* template_url_service) { 497 TemplateURLService* template_url_service) {
442 if (!allowed_to_be_default_match) { 498 if (!allowed_to_be_default_match) {
443 const GURL& stripped_canonical_input_url = 499 const GURL& stripped_canonical_input_url =
444 AutocompleteMatch::GURLToStrippedGURL( 500 AutocompleteMatch::GURLToStrippedGURL(
445 canonical_input_url, template_url_service, base::string16()); 501 input.canonicalized_url(), input, languages, template_url_service,
446 ComputeStrippedDestinationURL(template_url_service); 502 base::string16());
503 ComputeStrippedDestinationURL(input, languages, template_url_service);
447 allowed_to_be_default_match = 504 allowed_to_be_default_match =
448 stripped_canonical_input_url == stripped_destination_url; 505 stripped_canonical_input_url == stripped_destination_url;
449 } 506 }
450 } 507 }
451 508
452 void AutocompleteMatch::GetKeywordUIState( 509 void AutocompleteMatch::GetKeywordUIState(
453 TemplateURLService* template_url_service, 510 TemplateURLService* template_url_service,
454 base::string16* keyword, 511 base::string16* keyword,
455 bool* is_keyword_hint) const { 512 bool* is_keyword_hint) const {
456 *is_keyword_hint = associated_keyword.get() != NULL; 513 *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 628 << " is unsorted in relation to last offset of " << last_offset
572 << ". Provider: " << provider_name << "."; 629 << ". Provider: " << provider_name << ".";
573 DCHECK_LT(i->offset, text.length()) 630 DCHECK_LT(i->offset, text.length())
574 << " Classification of [" << i->offset << "," << text.length() 631 << " Classification of [" << i->offset << "," << text.length()
575 << "] is out of bounds for \"" << text << "\". Provider: " 632 << "] is out of bounds for \"" << text << "\". Provider: "
576 << provider_name << "."; 633 << provider_name << ".";
577 last_offset = i->offset; 634 last_offset = i->offset;
578 } 635 }
579 } 636 }
580 #endif 637 #endif
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698