Index: components/autofill/core/browser/autofill_field.cc |
diff --git a/components/autofill/core/browser/autofill_field.cc b/components/autofill/core/browser/autofill_field.cc |
index e7e5732e58c0918bcc96f53fa09ae85daab2127c..947a0368d01a5ce6e98a637097feb52176f3bb61 100644 |
--- a/components/autofill/core/browser/autofill_field.cc |
+++ b/components/autofill/core/browser/autofill_field.cc |
@@ -5,7 +5,7 @@ |
#include "components/autofill/core/browser/autofill_field.h" |
#include "base/command_line.h" |
-#include "base/i18n/string_compare.h" |
+#include "base/i18n/string_search.h" |
#include "base/logging.h" |
#include "base/metrics/field_trial.h" |
#include "base/sha1.h" |
@@ -15,6 +15,7 @@ |
#include "base/strings/utf_string_conversions.h" |
#include "components/autofill/core/browser/autofill_country.h" |
#include "components/autofill/core/browser/autofill_type.h" |
+#include "components/autofill/core/browser/credit_card.h" |
#include "components/autofill/core/browser/phone_number.h" |
#include "components/autofill/core/browser/state_names.h" |
#include "components/autofill/core/common/autofill_l10n_util.h" |
@@ -32,23 +33,11 @@ using base::StringToInt; |
namespace autofill { |
namespace { |
-const char* const kMonthsAbbreviated[] = { |
- NULL, // Padding so index 1 = month 1 = January. |
- "Jan", "Feb", "Mar", "Apr", "May", "Jun", |
- "Jul", "Aug", "Sep", "Oct", "Nov", "Dec", |
-}; |
- |
-const char* const kMonthsFull[] = { |
- NULL, // Padding so index 1 = month 1 = January. |
- "January", "February", "March", "April", "May", "June", |
- "July", "August", "September", "October", "November", "December", |
-}; |
- |
// Returns true if the value was successfully set, meaning |value| was found in |
// the list of select options in |field|. |
bool SetSelectControlValue(const base::string16& value, |
FormFieldData* field) { |
- base::string16 value_lowercase = base::StringToLowerASCII(value); |
+ l10n::CaseInsensitiveCompare compare; |
DCHECK_EQ(field->option_values.size(), field->option_contents.size()); |
base::string16 best_match; |
@@ -60,9 +49,8 @@ bool SetSelectControlValue(const base::string16& value, |
break; |
} |
- if (value_lowercase == base::StringToLowerASCII(field->option_values[i]) || |
- value_lowercase == |
- base::StringToLowerASCII(field->option_contents[i])) { |
+ if (compare.StringsEqual(value, field->option_values[i]) || |
+ compare.StringsEqual(value, field->option_contents[i])) { |
// A match, but not in the same case. Save it in case an exact match is |
// not found. |
best_match = field->option_values[i]; |
@@ -80,15 +68,13 @@ bool SetSelectControlValue(const base::string16& value, |
// for |value|. For example, "NC - North Carolina" would match "north carolina". |
bool SetSelectControlValueSubstringMatch(const base::string16& value, |
FormFieldData* field) { |
- base::string16 value_lowercase = base::StringToLowerASCII(value); |
DCHECK_EQ(field->option_values.size(), field->option_contents.size()); |
int best_match = -1; |
+ base::i18n::FixedPatternStringSearchIgnoringCaseAndAccents searcher(value); |
for (size_t i = 0; i < field->option_values.size(); ++i) { |
- if (base::StringToLowerASCII(field->option_values[i]).find(value_lowercase) != |
- std::string::npos || |
- base::StringToLowerASCII(field->option_contents[i]).find( |
- value_lowercase) != std::string::npos) { |
+ if (searcher.Search(field->option_values[i], nullptr, nullptr) || |
+ searcher.Search(field->option_contents[i], nullptr, nullptr)) { |
// The best match is the shortest one. |
if (best_match == -1 || |
field->option_values[best_match].size() > |
@@ -111,23 +97,25 @@ bool SetSelectControlValueSubstringMatch(const base::string16& value, |
// tokens. For example, "NC - North Carolina" would match "nc" but not "ca". |
bool SetSelectControlValueTokenMatch(const base::string16& value, |
FormFieldData* field) { |
- base::string16 value_lowercase = base::StringToLowerASCII(value); |
std::vector<base::string16> tokenized; |
DCHECK_EQ(field->option_values.size(), field->option_contents.size()); |
+ l10n::CaseInsensitiveCompare compare; |
for (size_t i = 0; i < field->option_values.size(); ++i) { |
- base::SplitStringAlongWhitespace( |
- base::StringToLowerASCII(field->option_values[i]), &tokenized); |
- if (std::find(tokenized.begin(), tokenized.end(), value_lowercase) != |
- tokenized.end()) { |
+ base::SplitStringAlongWhitespace(field->option_values[i], &tokenized); |
+ if (std::find_if(tokenized.begin(), tokenized.end(), |
+ [&compare, value](base::string16& rhs) { |
+ return compare.StringsEqual(value, rhs); |
+ }) != tokenized.end()) { |
field->value = field->option_values[i]; |
return true; |
} |
- base::SplitStringAlongWhitespace( |
- base::StringToLowerASCII(field->option_contents[i]), &tokenized); |
- if (std::find(tokenized.begin(), tokenized.end(), value_lowercase) != |
- tokenized.end()) { |
+ base::SplitStringAlongWhitespace(field->option_contents[i], &tokenized); |
+ if (std::find_if(tokenized.begin(), tokenized.end(), |
+ [&compare, value](base::string16& rhs) { |
+ return compare.StringsEqual(value, rhs); |
+ }) != tokenized.end()) { |
field->value = field->option_values[i]; |
return true; |
} |
@@ -202,18 +190,32 @@ bool FillCountrySelectControl(const base::string16& value, |
} |
bool FillExpirationMonthSelectControl(const base::string16& value, |
+ const std::string& app_locale, |
FormFieldData* field) { |
int index = 0; |
- if (!StringToInt(value, &index) || |
- index <= 0 || |
- static_cast<size_t>(index) >= arraysize(kMonthsFull)) |
+ if (!StringToInt(value, &index) || index <= 0 || index > 12) |
return false; |
- bool filled = |
- SetSelectControlValue(ASCIIToUTF16(kMonthsAbbreviated[index]), field) || |
- SetSelectControlValue(ASCIIToUTF16(kMonthsFull[index]), field) || |
- FillNumericSelectControl(index, field); |
- return filled; |
+ for (const base::string16& option_value : field->option_values) { |
+ int converted_value = 0; |
+ if (CreditCard::ConvertMonth(option_value, app_locale, &converted_value) && |
+ index == converted_value) { |
+ field->value = option_value; |
+ return true; |
+ } |
+ } |
+ |
+ for (const base::string16& option_contents : field->option_contents) { |
+ int converted_contents = 0; |
+ if (CreditCard::ConvertMonth(option_contents, app_locale, |
+ &converted_contents) && |
+ index == converted_contents) { |
+ field->value = option_contents; |
+ return true; |
+ } |
+ } |
+ |
+ return FillNumericSelectControl(index, field); |
} |
// Returns true if the last two digits in |year| match those in |str|. |
@@ -316,7 +318,7 @@ bool FillSelectControl(const AutofillType& type, |
} else if (storable_type == ADDRESS_HOME_COUNTRY) { |
return FillCountrySelectControl(value, app_locale, field); |
} else if (storable_type == CREDIT_CARD_EXP_MONTH) { |
- return FillExpirationMonthSelectControl(value, field); |
+ return FillExpirationMonthSelectControl(value, app_locale, field); |
} else if (storable_type == CREDIT_CARD_EXP_2_DIGIT_YEAR || |
storable_type == CREDIT_CARD_EXP_4_DIGIT_YEAR) { |
return FillYearSelectControl(value, field); |