|
| 1 | +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 |
| 2 | +From: =?UTF-8?q?Matthias=20K=C3=B6rber?= <koerber@google.com> |
| 3 | +Date: Tue, 14 Apr 2020 16:55:14 +0000 |
| 4 | +Subject: Fixed requesting invalid country codes from CountryData. |
| 5 | +MIME-Version: 1.0 |
| 6 | +Content-Type: text/plain; charset=UTF-8 |
| 7 | +Content-Transfer-Encoding: 8bit |
| 8 | + |
| 9 | +Change-Id: Id0ce647400bdce2eb4cdd358432b7c647f880570 |
| 10 | +Bug: 1062861 |
| 11 | +Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2122057 |
| 12 | +Reviewed-by: Matthias Körber <koerber@google.com> |
| 13 | +Reviewed-by: Dominic Battré <battre@chromium.org> |
| 14 | +Reviewed-by: Vadym Doroshenko <dvadym@chromium.org> |
| 15 | +Commit-Queue: Matthias Körber <koerber@google.com> |
| 16 | +Cr-Commit-Position: refs/heads/master@{#758887} |
| 17 | + |
| 18 | +diff --git a/components/autofill/core/browser/geo/autofill_country.cc b/components/autofill/core/browser/geo/autofill_country.cc |
| 19 | +index 4eb8f2b1a609deb314efd9b37578be9fa803ac67..961b1dc7a19f23c6f2cf9f831f5d544cc19cd211 100644 |
| 20 | +--- a/components/autofill/core/browser/geo/autofill_country.cc |
| 21 | ++++ b/components/autofill/core/browser/geo/autofill_country.cc |
| 22 | +@@ -25,13 +25,28 @@ const size_t kLocaleCapacity = |
| 23 | + |
| 24 | + AutofillCountry::AutofillCountry(const std::string& country_code, |
| 25 | + const std::string& locale) { |
| 26 | +- auto result = |
| 27 | +- CountryDataMap::GetInstance()->country_data().find(country_code); |
| 28 | +- DCHECK(result != CountryDataMap::GetInstance()->country_data().end()); |
| 29 | +- const CountryData& data = result->second; |
| 30 | ++ CountryDataMap* country_data_map = CountryDataMap::GetInstance(); |
| 31 | + |
| 32 | +- country_code_ = country_code; |
| 33 | +- name_ = l10n_util::GetDisplayNameForCountry(country_code, locale); |
| 34 | ++ // If the country code is an alias (e.g. "GB" for "UK") expand the country |
| 35 | ++ // code. |
| 36 | ++ country_code_ = country_data_map->HasCountryCodeAlias(country_code) |
| 37 | ++ ? country_data_map->GetCountryCodeForAlias(country_code) |
| 38 | ++ : country_code; |
| 39 | ++ |
| 40 | ++ // If there is no entry in the |CountryDataMap| for the |
| 41 | ++ // |country_code_for_country_data| use the country code derived from the |
| 42 | ++ // locale. This reverts to US. |
| 43 | ++ country_data_map->HasCountryData(country_code_) |
| 44 | ++ ? country_code_ |
| 45 | ++ : CountryCodeForLocale(locale); |
| 46 | ++ |
| 47 | ++ // Acquire the country address data. |
| 48 | ++ const CountryData& data = country_data_map->GetCountryData(country_code_); |
| 49 | ++ |
| 50 | ++ // Translate the country name by the supplied local. |
| 51 | ++ name_ = l10n_util::GetDisplayNameForCountry(country_code_, locale); |
| 52 | ++ |
| 53 | ++ // Get the localized strings associate with the address fields. |
| 54 | + postal_code_label_ = l10n_util::GetStringUTF16(data.postal_code_label_id); |
| 55 | + state_label_ = l10n_util::GetStringUTF16(data.state_label_id); |
| 56 | + address_required_fields_ = data.address_required_fields; |
| 57 | +diff --git a/components/autofill/core/browser/geo/autofill_country_unittest.cc b/components/autofill/core/browser/geo/autofill_country_unittest.cc |
| 58 | +index 8f3994de4f5d8b924cc47a989d86676ed01bd760..94315c13967f1ce640bba01a555f8b418af97ad3 100644 |
| 59 | +--- a/components/autofill/core/browser/geo/autofill_country_unittest.cc |
| 60 | ++++ b/components/autofill/core/browser/geo/autofill_country_unittest.cc |
| 61 | +@@ -14,6 +14,7 @@ |
| 62 | + #include "base/android/build_info.h" |
| 63 | + #endif |
| 64 | + |
| 65 | ++using autofill::CountryDataMap; |
| 66 | + using base::ASCIIToUTF16; |
| 67 | + |
| 68 | + namespace autofill { |
| 69 | +@@ -30,6 +31,11 @@ TEST(AutofillCountryTest, AutofillCountry) { |
| 70 | + EXPECT_EQ("US", united_states_es.country_code()); |
| 71 | + EXPECT_EQ(ASCIIToUTF16("Estados Unidos"), united_states_es.name()); |
| 72 | + |
| 73 | ++ AutofillCountry great_britain_uk_alias("UK", "en_GB"); |
| 74 | ++ EXPECT_EQ("GB", great_britain_uk_alias.country_code()); |
| 75 | ++ EXPECT_EQ("GB", great_britain_uk_alias.country_code()); |
| 76 | ++ EXPECT_EQ(ASCIIToUTF16("United Kingdom"), great_britain_uk_alias.name()); |
| 77 | ++ |
| 78 | + AutofillCountry canada_en("CA", "en_US"); |
| 79 | + EXPECT_EQ("CA", canada_en.country_code()); |
| 80 | + EXPECT_EQ(ASCIIToUTF16("Canada"), canada_en.name()); |
| 81 | +@@ -74,4 +80,27 @@ TEST(AutofillCountryTest, AllCountryCodesHaveCountryName) { |
| 82 | + } |
| 83 | + } |
| 84 | + |
| 85 | ++// Test alias mappings for falsely existing country codes. |
| 86 | ++TEST(AutofillCountryTest, AliasMappingsForCountryData) { |
| 87 | ++ CountryDataMap* country_data_map = CountryDataMap::GetInstance(); |
| 88 | ++ |
| 89 | ++ // There should be country data for the "GB". |
| 90 | ++ EXPECT_TRUE(country_data_map->HasCountryData("GB")); |
| 91 | ++ |
| 92 | ++ // Check the correctness of the alias definitions. |
| 93 | ++ EXPECT_TRUE(country_data_map->HasCountryCodeAlias("UK")); |
| 94 | ++ EXPECT_FALSE(country_data_map->HasCountryCodeAlias("does_not_exist")); |
| 95 | ++ |
| 96 | ++ // Query not existing mapping. |
| 97 | ++ auto expected_country_code = std::string(); |
| 98 | ++ auto actual_country_code = |
| 99 | ++ country_data_map->GetCountryCodeForAlias("does_not_exist"); |
| 100 | ++ EXPECT_EQ(expected_country_code, actual_country_code); |
| 101 | ++ |
| 102 | ++ // GB should map the UK. |
| 103 | ++ expected_country_code = "GB"; |
| 104 | ++ actual_country_code = country_data_map->GetCountryCodeForAlias("UK"); |
| 105 | ++ EXPECT_EQ(expected_country_code, actual_country_code); |
| 106 | ++} |
| 107 | ++ |
| 108 | + } // namespace autofill |
| 109 | +diff --git a/components/autofill/core/browser/geo/country_data.cc b/components/autofill/core/browser/geo/country_data.cc |
| 110 | +index 1fe65ecf65323ce1917cb786b63d10ea4a7ac0b7..ec78e723ca71972d32ba00c2b46de9673fe91f46 100644 |
| 111 | +--- a/components/autofill/core/browser/geo/country_data.cc |
| 112 | ++++ b/components/autofill/core/browser/geo/country_data.cc |
| 113 | +@@ -19,6 +19,17 @@ struct StaticCountryData { |
| 114 | + CountryData country_data; |
| 115 | + }; |
| 116 | + |
| 117 | ++// Alias definitions record for CountryData requests. A request for |
| 118 | ++// |country_code_alias| is served with the |CountryData| for |
| 119 | ++// |country_code_target|. |
| 120 | ++struct StaticCountryCodeAliasData { |
| 121 | ++ char country_code_alias[3]; |
| 122 | ++ char country_code_target[3]; |
| 123 | ++}; |
| 124 | ++ |
| 125 | ++// Alias definitions. |
| 126 | ++const StaticCountryCodeAliasData kCountryCodeAliases[] = {{"UK", "GB"}}; |
| 127 | ++ |
| 128 | + // Maps country codes to localized label string identifiers. Keep this sorted |
| 129 | + // by country code. |
| 130 | + // This list is comprized of countries appearing in both |
| 131 | +@@ -790,7 +801,7 @@ std::vector<std::string> GetCountryCodes() { |
| 132 | + return country_codes; |
| 133 | + } |
| 134 | + |
| 135 | +-std::map<std::string, CountryData> GetCountryData() { |
| 136 | ++std::map<std::string, CountryData> GetCountryDataMap() { |
| 137 | + std::map<std::string, CountryData> country_data; |
| 138 | + // Add all the countries we have explicit data for. |
| 139 | + for (const auto& static_data : kCountryData) { |
| 140 | +@@ -813,6 +824,18 @@ std::map<std::string, CountryData> GetCountryData() { |
| 141 | + return country_data; |
| 142 | + } |
| 143 | + |
| 144 | ++std::map<std::string, std::string> GetCountryCodeAliasMap() { |
| 145 | ++ std::map<std::string, std::string> country_code_aliases; |
| 146 | ++ // Create mappings for the aliases defined in |kCountryCodeAliases|. |
| 147 | ++ for (const auto& static_alias_data : kCountryCodeAliases) { |
| 148 | ++ // Insert the alias. |
| 149 | ++ country_code_aliases.insert( |
| 150 | ++ std::make_pair(std::string(static_alias_data.country_code_alias), |
| 151 | ++ std::string(static_alias_data.country_code_target))); |
| 152 | ++ } |
| 153 | ++ return country_code_aliases; |
| 154 | ++} |
| 155 | ++ |
| 156 | + } // namespace |
| 157 | + |
| 158 | + // static |
| 159 | +@@ -821,8 +844,38 @@ CountryDataMap* CountryDataMap::GetInstance() { |
| 160 | + } |
| 161 | + |
| 162 | + CountryDataMap::CountryDataMap() |
| 163 | +- : country_data_(GetCountryData()), country_codes_(GetCountryCodes()) {} |
| 164 | ++ : country_data_(GetCountryDataMap()), |
| 165 | ++ country_code_aliases_(GetCountryCodeAliasMap()), |
| 166 | ++ country_codes_(GetCountryCodes()) {} |
| 167 | + |
| 168 | + CountryDataMap::~CountryDataMap() = default; |
| 169 | + |
| 170 | ++bool CountryDataMap::HasCountryData(const std::string& country_code) const { |
| 171 | ++ return country_data_.count(country_code) > 0; |
| 172 | ++} |
| 173 | ++ |
| 174 | ++const CountryData& CountryDataMap::GetCountryData( |
| 175 | ++ const std::string& country_code) const { |
| 176 | ++ auto lookup = country_data_.find(country_code); |
| 177 | ++ if (lookup != country_data_.end()) |
| 178 | ++ return lookup->second; |
| 179 | ++ // If there is no entry for country_code return the entry for the US. |
| 180 | ++ return country_data_.find("US")->second; |
| 181 | ++} |
| 182 | ++ |
| 183 | ++bool CountryDataMap::HasCountryCodeAlias( |
| 184 | ++ const std::string& country_code_alias) const { |
| 185 | ++ return country_code_aliases_.count(country_code_alias) > 0; |
| 186 | ++} |
| 187 | ++ |
| 188 | ++const std::string CountryDataMap::GetCountryCodeForAlias( |
| 189 | ++ const std::string& country_code_alias) const { |
| 190 | ++ auto lookup = country_code_aliases_.find(country_code_alias); |
| 191 | ++ if (lookup != country_code_aliases_.end()) { |
| 192 | ++ DCHECK(HasCountryData(lookup->second)); |
| 193 | ++ return lookup->second; |
| 194 | ++ } |
| 195 | ++ return std::string(); |
| 196 | ++} |
| 197 | ++ |
| 198 | + } // namespace autofill |
| 199 | +diff --git a/components/autofill/core/browser/geo/country_data.h b/components/autofill/core/browser/geo/country_data.h |
| 200 | +index b6a9497594b1c22a5521a9c40fab2decae449c3f..8266102deadd40e5f2b9b24703123f59034a9781 100644 |
| 201 | +--- a/components/autofill/core/browser/geo/country_data.h |
| 202 | ++++ b/components/autofill/core/browser/geo/country_data.h |
| 203 | +@@ -58,10 +58,23 @@ class CountryDataMap { |
| 204 | + public: |
| 205 | + static CountryDataMap* GetInstance(); |
| 206 | + |
| 207 | +- const std::map<std::string, CountryData>& country_data() { |
| 208 | +- return country_data_; |
| 209 | +- } |
| 210 | ++ // Returns true if a |CountryData| entry for the supplied |country_code| |
| 211 | ++ // exists. |
| 212 | ++ bool HasCountryData(const std::string& country_code) const; |
| 213 | + |
| 214 | ++ // Returns true if there is a country code alias for |country_code|. |
| 215 | ++ bool HasCountryCodeAlias(const std::string& country_code_alias) const; |
| 216 | ++ |
| 217 | ++ // Returns the country code for a country code alias. If no alias definition |
| 218 | ++ // is present return an empty string. |
| 219 | ++ const std::string GetCountryCodeForAlias( |
| 220 | ++ const std::string& country_code_alias) const; |
| 221 | ++ |
| 222 | ++ // Lookup the |CountryData| for the supplied |country_code|. If no entry |
| 223 | ++ // exists, return the data for the US as a best guess. |
| 224 | ++ const CountryData& GetCountryData(const std::string& country_code) const; |
| 225 | ++ |
| 226 | ++ // Return a constant reference to a vector of all country codes. |
| 227 | + const std::vector<std::string>& country_codes() { return country_codes_; } |
| 228 | + |
| 229 | + private: |
| 230 | +@@ -70,6 +83,7 @@ class CountryDataMap { |
| 231 | + friend struct base::DefaultSingletonTraits<CountryDataMap>; |
| 232 | + |
| 233 | + const std::map<std::string, CountryData> country_data_; |
| 234 | ++ const std::map<std::string, std::string> country_code_aliases_; |
| 235 | + const std::vector<std::string> country_codes_; |
| 236 | + |
| 237 | + DISALLOW_COPY_AND_ASSIGN(CountryDataMap); |
0 commit comments