| OLD | NEW |
| 1 // Copyright 2016 The Chromium Authors. All rights reserved. | 1 // Copyright 2016 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/autofill/core/browser/autofill_profile_comparator.h" | 5 #include "components/autofill/core/browser/autofill_profile_comparator.h" |
| 6 | 6 |
| 7 #include <algorithm> | 7 #include <algorithm> |
| 8 #include <vector> | 8 #include <vector> |
| 9 | 9 |
| 10 #include "base/i18n/case_conversion.h" | 10 #include "base/i18n/case_conversion.h" |
| 11 #include "base/i18n/char_iterator.h" | 11 #include "base/i18n/char_iterator.h" |
| 12 #include "base/strings/string_piece.h" | |
| 13 #include "base/strings/string_split.h" | 12 #include "base/strings/string_split.h" |
| 14 #include "base/strings/string_util.h" | 13 #include "base/strings/string_util.h" |
| 15 #include "base/strings/utf_string_conversion_utils.h" | 14 #include "base/strings/utf_string_conversion_utils.h" |
| 16 #include "base/strings/utf_string_conversions.h" | 15 #include "base/strings/utf_string_conversions.h" |
| 17 #include "components/autofill/core/browser/address_rewriter.h" | 16 #include "components/autofill/core/browser/address_rewriter.h" |
| 18 #include "components/autofill/core/browser/autofill_country.h" | 17 #include "components/autofill/core/browser/autofill_country.h" |
| 19 #include "components/autofill/core/browser/autofill_data_util.h" | 18 #include "components/autofill/core/browser/autofill_data_util.h" |
| 20 #include "components/autofill/core/browser/state_names.h" | 19 #include "components/autofill/core/browser/state_names.h" |
| 21 #include "third_party/libphonenumber/phonenumber_api.h" | 20 #include "third_party/libphonenumber/phonenumber_api.h" |
| 22 | 21 |
| (...skipping 637 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 660 if (!s1.empty()) | 659 if (!s1.empty()) |
| 661 return s1; | 660 return s1; |
| 662 return p2.GetInfo(t, app_locale_); | 661 return p2.GetInfo(t, app_locale_); |
| 663 } | 662 } |
| 664 | 663 |
| 665 // static | 664 // static |
| 666 std::set<base::string16> AutofillProfileComparator::GetNamePartVariants( | 665 std::set<base::string16> AutofillProfileComparator::GetNamePartVariants( |
| 667 const base::string16& name_part) { | 666 const base::string16& name_part) { |
| 668 const size_t kMaxSupportedSubNames = 8; | 667 const size_t kMaxSupportedSubNames = 8; |
| 669 | 668 |
| 670 std::vector<base::string16> sub_names = base::SplitString( | 669 std::vector<base::StringPiece16> sub_names = base::SplitStringPiece( |
| 671 name_part, kSpace, base::TRIM_WHITESPACE, base::SPLIT_WANT_NONEMPTY); | 670 name_part, kSpace, base::TRIM_WHITESPACE, base::SPLIT_WANT_NONEMPTY); |
| 672 | 671 |
| 673 // Limit the number of sub-names we support (to constrain memory usage); | 672 // Limit the number of sub-names we support (to constrain memory usage); |
| 674 if (sub_names.size() > kMaxSupportedSubNames) | 673 if (sub_names.size() > kMaxSupportedSubNames) |
| 675 return {name_part}; | 674 return {name_part}; |
| 676 | 675 |
| 677 // Start with the empty string as a variant. | 676 // Start with the empty string as a variant. |
| 678 std::set<base::string16> variants = {base::EmptyString16()}; | 677 std::set<base::string16> variants = {base::EmptyString16()}; |
| 679 | 678 |
| 680 // For each sub-name, add a variant of all the already existing variants that | 679 // For each sub-name, add a variant of all the already existing variants that |
| 681 // appends this sub-name and one that appends the initial of this sub-name. | 680 // appends this sub-name and one that appends the initial of this sub-name. |
| 682 // Duplicates will be discarded when they're added to the variants set. | 681 // Duplicates will be discarded when they're added to the variants set. |
| 683 for (const base::string16& sub_name : sub_names) { | 682 for (auto sub_name : sub_names) { |
| 684 if (sub_name.empty()) | 683 if (sub_name.empty()) |
| 685 continue; | 684 continue; |
| 686 std::vector<base::string16> new_variants; | 685 std::vector<base::string16> new_variants; |
| 687 for (const base::string16& variant : variants) { | 686 for (const base::string16& variant : variants) { |
| 688 new_variants.push_back(base::CollapseWhitespace( | 687 new_variants.push_back(base::CollapseWhitespace( |
| 689 base::JoinString({variant, sub_name}, kSpace), true)); | 688 base::JoinString({variant, sub_name}, kSpace), true)); |
| 690 new_variants.push_back(base::CollapseWhitespace( | 689 new_variants.push_back(base::CollapseWhitespace( |
| 691 base::JoinString({variant, sub_name.substr(0, 1)}, kSpace), true)); | 690 base::JoinString({variant, sub_name.substr(0, 1)}, kSpace), true)); |
| 692 } | 691 } |
| 693 variants.insert(new_variants.begin(), new_variants.end()); | 692 variants.insert(new_variants.begin(), new_variants.end()); |
| 694 } | 693 } |
| 695 | 694 |
| 696 // As a common case, also add the variant that just concatenates all of the | 695 // As a common case, also add the variant that just concatenates all of the |
| 697 // initials. | 696 // initials. |
| 698 base::string16 initials; | 697 base::string16 initials; |
| 699 for (const base::string16& sub_name : sub_names) { | 698 for (auto sub_name : sub_names) { |
| 700 if (sub_name.empty()) | 699 if (sub_name.empty()) |
| 701 continue; | 700 continue; |
| 702 initials.push_back(sub_name[0]); | 701 initials.push_back(sub_name[0]); |
| 703 } | 702 } |
| 704 variants.insert(initials); | 703 variants.insert(initials); |
| 705 | 704 |
| 706 // And, we're done. | 705 // And, we're done. |
| 707 return variants; | 706 return variants; |
| 708 } | 707 } |
| 709 | 708 |
| 710 bool AutofillProfileComparator::IsNameVariantOf( | 709 bool AutofillProfileComparator::IsNameVariantOf( |
| 711 const base::string16& full_name_1, | 710 const base::string16& full_name_1, |
| 712 const base::string16& full_name_2) const { | 711 const base::string16& full_name_2) const { |
| 713 data_util::NameParts name_1_parts = data_util::SplitName(full_name_1); | 712 data_util::NameParts name_1_parts = data_util::SplitName(full_name_1); |
| 714 | 713 |
| 715 // Build the variants of full_name_1`s given, middle and family names. | 714 // Build the variants of full_name_1`s given, middle and family names. |
| 716 // | 715 // |
| 717 // TODO(rogerm): Figure out whether or not we should break apart a compound | 716 // TODO(rogerm): Figure out whether or not we should break apart a compound |
| 718 // family name into variants (crbug/619051) | 717 // family name into variants (crbug/619051) |
| 719 const std::set<base::string16> given_name_variants = | 718 const std::set<base::string16> given_name_variants = |
| 720 GetNamePartVariants(name_1_parts.given); | 719 GetNamePartVariants(name_1_parts.given); |
| 721 const std::set<base::string16> middle_name_variants = | 720 const std::set<base::string16> middle_name_variants = |
| 722 GetNamePartVariants(name_1_parts.middle); | 721 GetNamePartVariants(name_1_parts.middle); |
| 723 const base::string16& family_name = name_1_parts.family; | 722 base::StringPiece16 family_name = name_1_parts.family; |
| 724 | 723 |
| 725 // Iterate over all full name variants of profile 2 and see if any of them | 724 // Iterate over all full name variants of profile 2 and see if any of them |
| 726 // match the full name from profile 1. | 725 // match the full name from profile 1. |
| 727 for (const base::string16& given_name : given_name_variants) { | 726 for (base::StringPiece16 given_name : given_name_variants) { |
| 728 for (const base::string16& middle_name : middle_name_variants) { | 727 for (base::StringPiece16 middle_name : middle_name_variants) { |
| 729 base::string16 candidate = base::CollapseWhitespace( | 728 base::string16 candidate = base::CollapseWhitespace( |
| 730 base::JoinString({given_name, middle_name, family_name}, kSpace), | 729 base::JoinString({given_name, middle_name, family_name}, kSpace), |
| 731 true); | 730 true); |
| 732 if (candidate == full_name_2) | 731 if (candidate == full_name_2) |
| 733 return true; | 732 return true; |
| 734 } | 733 } |
| 735 } | 734 } |
| 736 | 735 |
| 737 // Also check if the name is just composed of the user's initials. For | 736 // Also check if the name is just composed of the user's initials. For |
| 738 // example, "thomas jefferson miller" could be composed as "tj miller". | 737 // example, "thomas jefferson miller" could be composed as "tj miller". |
| (...skipping 211 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 950 const base::string16& address2 = rewriter.Rewrite(NormalizeForComparison( | 949 const base::string16& address2 = rewriter.Rewrite(NormalizeForComparison( |
| 951 p2.GetInfo(AutofillType(ADDRESS_HOME_STREET_ADDRESS), app_locale_))); | 950 p2.GetInfo(AutofillType(ADDRESS_HOME_STREET_ADDRESS), app_locale_))); |
| 952 if (CompareTokens(address1, address2) == DIFFERENT_TOKENS) { | 951 if (CompareTokens(address1, address2) == DIFFERENT_TOKENS) { |
| 953 return false; | 952 return false; |
| 954 } | 953 } |
| 955 | 954 |
| 956 return true; | 955 return true; |
| 957 } | 956 } |
| 958 | 957 |
| 959 } // namespace autofill | 958 } // namespace autofill |
| OLD | NEW |