Commit 86c02c5d authored by Matthias Körber's avatar Matthias Körber Committed by Commit Bot

[Autofill] Fixed requesting invalid country codes from CountryData.

Change-Id: Id0ce647400bdce2eb4cdd358432b7c647f880570
Bug: 1062861
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2122057Reviewed-by: default avatarMatthias Körber <koerber@google.com>
Reviewed-by: default avatarDominic Battré <battre@chromium.org>
Reviewed-by: default avatarVadym Doroshenko  <dvadym@chromium.org>
Commit-Queue: Matthias Körber <koerber@google.com>
Cr-Commit-Position: refs/heads/master@{#758887}
parent ede390a0
...@@ -25,13 +25,28 @@ const size_t kLocaleCapacity = ...@@ -25,13 +25,28 @@ const size_t kLocaleCapacity =
AutofillCountry::AutofillCountry(const std::string& country_code, AutofillCountry::AutofillCountry(const std::string& country_code,
const std::string& locale) { const std::string& locale) {
auto result = CountryDataMap* country_data_map = CountryDataMap::GetInstance();
CountryDataMap::GetInstance()->country_data().find(country_code);
DCHECK(result != CountryDataMap::GetInstance()->country_data().end());
const CountryData& data = result->second;
country_code_ = country_code; // If the country code is an alias (e.g. "GB" for "UK") expand the country
name_ = l10n_util::GetDisplayNameForCountry(country_code, locale); // code.
country_code_ = country_data_map->HasCountryCodeAlias(country_code)
? country_data_map->GetCountryCodeForAlias(country_code)
: country_code;
// If there is no entry in the |CountryDataMap| for the
// |country_code_for_country_data| use the country code derived from the
// locale. This reverts to US.
country_data_map->HasCountryData(country_code_)
? country_code_
: CountryCodeForLocale(locale);
// Acquire the country address data.
const CountryData& data = country_data_map->GetCountryData(country_code_);
// Translate the country name by the supplied local.
name_ = l10n_util::GetDisplayNameForCountry(country_code_, locale);
// Get the localized strings associate with the address fields.
postal_code_label_ = l10n_util::GetStringUTF16(data.postal_code_label_id); postal_code_label_ = l10n_util::GetStringUTF16(data.postal_code_label_id);
state_label_ = l10n_util::GetStringUTF16(data.state_label_id); state_label_ = l10n_util::GetStringUTF16(data.state_label_id);
address_required_fields_ = data.address_required_fields; address_required_fields_ = data.address_required_fields;
......
...@@ -14,6 +14,7 @@ ...@@ -14,6 +14,7 @@
#include "base/android/build_info.h" #include "base/android/build_info.h"
#endif #endif
using autofill::CountryDataMap;
using base::ASCIIToUTF16; using base::ASCIIToUTF16;
namespace autofill { namespace autofill {
...@@ -30,6 +31,11 @@ TEST(AutofillCountryTest, AutofillCountry) { ...@@ -30,6 +31,11 @@ TEST(AutofillCountryTest, AutofillCountry) {
EXPECT_EQ("US", united_states_es.country_code()); EXPECT_EQ("US", united_states_es.country_code());
EXPECT_EQ(ASCIIToUTF16("Estados Unidos"), united_states_es.name()); EXPECT_EQ(ASCIIToUTF16("Estados Unidos"), united_states_es.name());
AutofillCountry great_britain_uk_alias("UK", "en_GB");
EXPECT_EQ("GB", great_britain_uk_alias.country_code());
EXPECT_EQ("GB", great_britain_uk_alias.country_code());
EXPECT_EQ(ASCIIToUTF16("United Kingdom"), great_britain_uk_alias.name());
AutofillCountry canada_en("CA", "en_US"); AutofillCountry canada_en("CA", "en_US");
EXPECT_EQ("CA", canada_en.country_code()); EXPECT_EQ("CA", canada_en.country_code());
EXPECT_EQ(ASCIIToUTF16("Canada"), canada_en.name()); EXPECT_EQ(ASCIIToUTF16("Canada"), canada_en.name());
...@@ -74,4 +80,27 @@ TEST(AutofillCountryTest, AllCountryCodesHaveCountryName) { ...@@ -74,4 +80,27 @@ TEST(AutofillCountryTest, AllCountryCodesHaveCountryName) {
} }
} }
// Test alias mappings for falsely existing country codes.
TEST(AutofillCountryTest, AliasMappingsForCountryData) {
CountryDataMap* country_data_map = CountryDataMap::GetInstance();
// There should be country data for the "GB".
EXPECT_TRUE(country_data_map->HasCountryData("GB"));
// Check the correctness of the alias definitions.
EXPECT_TRUE(country_data_map->HasCountryCodeAlias("UK"));
EXPECT_FALSE(country_data_map->HasCountryCodeAlias("does_not_exist"));
// Query not existing mapping.
auto expected_country_code = std::string();
auto actual_country_code =
country_data_map->GetCountryCodeForAlias("does_not_exist");
EXPECT_EQ(expected_country_code, actual_country_code);
// GB should map the UK.
expected_country_code = "GB";
actual_country_code = country_data_map->GetCountryCodeForAlias("UK");
EXPECT_EQ(expected_country_code, actual_country_code);
}
} // namespace autofill } // namespace autofill
...@@ -19,6 +19,17 @@ struct StaticCountryData { ...@@ -19,6 +19,17 @@ struct StaticCountryData {
CountryData country_data; CountryData country_data;
}; };
// Alias definitions record for CountryData requests. A request for
// |country_code_alias| is served with the |CountryData| for
// |country_code_target|.
struct StaticCountryCodeAliasData {
char country_code_alias[3];
char country_code_target[3];
};
// Alias definitions.
const StaticCountryCodeAliasData kCountryCodeAliases[] = {{"UK", "GB"}};
// Maps country codes to localized label string identifiers. Keep this sorted // Maps country codes to localized label string identifiers. Keep this sorted
// by country code. // by country code.
// This list is comprized of countries appearing in both // This list is comprized of countries appearing in both
...@@ -790,7 +801,7 @@ std::vector<std::string> GetCountryCodes() { ...@@ -790,7 +801,7 @@ std::vector<std::string> GetCountryCodes() {
return country_codes; return country_codes;
} }
std::map<std::string, CountryData> GetCountryData() { std::map<std::string, CountryData> GetCountryDataMap() {
std::map<std::string, CountryData> country_data; std::map<std::string, CountryData> country_data;
// Add all the countries we have explicit data for. // Add all the countries we have explicit data for.
for (const auto& static_data : kCountryData) { for (const auto& static_data : kCountryData) {
...@@ -813,6 +824,18 @@ std::map<std::string, CountryData> GetCountryData() { ...@@ -813,6 +824,18 @@ std::map<std::string, CountryData> GetCountryData() {
return country_data; return country_data;
} }
std::map<std::string, std::string> GetCountryCodeAliasMap() {
std::map<std::string, std::string> country_code_aliases;
// Create mappings for the aliases defined in |kCountryCodeAliases|.
for (const auto& static_alias_data : kCountryCodeAliases) {
// Insert the alias.
country_code_aliases.insert(
std::make_pair(std::string(static_alias_data.country_code_alias),
std::string(static_alias_data.country_code_target)));
}
return country_code_aliases;
}
} // namespace } // namespace
// static // static
...@@ -821,8 +844,38 @@ CountryDataMap* CountryDataMap::GetInstance() { ...@@ -821,8 +844,38 @@ CountryDataMap* CountryDataMap::GetInstance() {
} }
CountryDataMap::CountryDataMap() CountryDataMap::CountryDataMap()
: country_data_(GetCountryData()), country_codes_(GetCountryCodes()) {} : country_data_(GetCountryDataMap()),
country_code_aliases_(GetCountryCodeAliasMap()),
country_codes_(GetCountryCodes()) {}
CountryDataMap::~CountryDataMap() = default; CountryDataMap::~CountryDataMap() = default;
bool CountryDataMap::HasCountryData(const std::string& country_code) const {
return country_data_.count(country_code) > 0;
}
const CountryData& CountryDataMap::GetCountryData(
const std::string& country_code) const {
auto lookup = country_data_.find(country_code);
if (lookup != country_data_.end())
return lookup->second;
// If there is no entry for country_code return the entry for the US.
return country_data_.find("US")->second;
}
bool CountryDataMap::HasCountryCodeAlias(
const std::string& country_code_alias) const {
return country_code_aliases_.count(country_code_alias) > 0;
}
const std::string CountryDataMap::GetCountryCodeForAlias(
const std::string& country_code_alias) const {
auto lookup = country_code_aliases_.find(country_code_alias);
if (lookup != country_code_aliases_.end()) {
DCHECK(HasCountryData(lookup->second));
return lookup->second;
}
return std::string();
}
} // namespace autofill } // namespace autofill
...@@ -58,10 +58,23 @@ class CountryDataMap { ...@@ -58,10 +58,23 @@ class CountryDataMap {
public: public:
static CountryDataMap* GetInstance(); static CountryDataMap* GetInstance();
const std::map<std::string, CountryData>& country_data() { // Returns true if a |CountryData| entry for the supplied |country_code|
return country_data_; // exists.
} bool HasCountryData(const std::string& country_code) const;
// Returns true if there is a country code alias for |country_code|.
bool HasCountryCodeAlias(const std::string& country_code_alias) const;
// Returns the country code for a country code alias. If no alias definition
// is present return an empty string.
const std::string GetCountryCodeForAlias(
const std::string& country_code_alias) const;
// Lookup the |CountryData| for the supplied |country_code|. If no entry
// exists, return the data for the US as a best guess.
const CountryData& GetCountryData(const std::string& country_code) const;
// Return a constant reference to a vector of all country codes.
const std::vector<std::string>& country_codes() { return country_codes_; } const std::vector<std::string>& country_codes() { return country_codes_; }
private: private:
...@@ -70,6 +83,7 @@ class CountryDataMap { ...@@ -70,6 +83,7 @@ class CountryDataMap {
friend struct base::DefaultSingletonTraits<CountryDataMap>; friend struct base::DefaultSingletonTraits<CountryDataMap>;
const std::map<std::string, CountryData> country_data_; const std::map<std::string, CountryData> country_data_;
const std::map<std::string, std::string> country_code_aliases_;
const std::vector<std::string> country_codes_; const std::vector<std::string> country_codes_;
DISALLOW_COPY_AND_ASSIGN(CountryDataMap); DISALLOW_COPY_AND_ASSIGN(CountryDataMap);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment