Merge Chromium + Blink git repositories
[chromium-blink-merge.git] / components / autofill / core / browser / autofill_field.cc
blob5fd597d1d07141a1863d67355e30123c69896ab4
1 // Copyright 2013 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include "components/autofill/core/browser/autofill_field.h"
7 #include "base/command_line.h"
8 #include "base/i18n/string_search.h"
9 #include "base/logging.h"
10 #include "base/metrics/field_trial.h"
11 #include "base/sha1.h"
12 #include "base/strings/string_number_conversions.h"
13 #include "base/strings/string_split.h"
14 #include "base/strings/string_util.h"
15 #include "base/strings/utf_string_conversions.h"
16 #include "components/autofill/core/browser/autofill_country.h"
17 #include "components/autofill/core/browser/autofill_type.h"
18 #include "components/autofill/core/browser/credit_card.h"
19 #include "components/autofill/core/browser/phone_number.h"
20 #include "components/autofill/core/browser/state_names.h"
21 #include "components/autofill/core/common/autofill_l10n_util.h"
22 #include "components/autofill/core/common/autofill_switches.h"
23 #include "grit/components_strings.h"
24 #include "third_party/libaddressinput/src/cpp/include/libaddressinput/address_data.h"
25 #include "third_party/libaddressinput/src/cpp/include/libaddressinput/address_formatter.h"
26 #include "ui/base/l10n/l10n_util.h"
28 using ::i18n::addressinput::AddressData;
29 using ::i18n::addressinput::GetStreetAddressLinesAsSingleLine;
30 using base::ASCIIToUTF16;
31 using base::StringToInt;
33 namespace autofill {
34 namespace {
36 // Returns true if the value was successfully set, meaning |value| was found in
37 // the list of select options in |field|.
38 bool SetSelectControlValue(const base::string16& value,
39 FormFieldData* field) {
40 l10n::CaseInsensitiveCompare compare;
42 DCHECK_EQ(field->option_values.size(), field->option_contents.size());
43 base::string16 best_match;
44 for (size_t i = 0; i < field->option_values.size(); ++i) {
45 if (value == field->option_values[i] ||
46 value == field->option_contents[i]) {
47 // An exact match, use it.
48 best_match = field->option_values[i];
49 break;
52 if (compare.StringsEqual(value, field->option_values[i]) ||
53 compare.StringsEqual(value, field->option_contents[i])) {
54 // A match, but not in the same case. Save it in case an exact match is
55 // not found.
56 best_match = field->option_values[i];
60 if (best_match.empty())
61 return false;
63 field->value = best_match;
64 return true;
67 // Like SetSelectControlValue, but searches within the field values and options
68 // for |value|. For example, "NC - North Carolina" would match "north carolina".
69 bool SetSelectControlValueSubstringMatch(const base::string16& value,
70 FormFieldData* field) {
71 DCHECK_EQ(field->option_values.size(), field->option_contents.size());
72 int best_match = -1;
74 base::i18n::FixedPatternStringSearchIgnoringCaseAndAccents searcher(value);
75 for (size_t i = 0; i < field->option_values.size(); ++i) {
76 if (searcher.Search(field->option_values[i], nullptr, nullptr) ||
77 searcher.Search(field->option_contents[i], nullptr, nullptr)) {
78 // The best match is the shortest one.
79 if (best_match == -1 ||
80 field->option_values[best_match].size() >
81 field->option_values[i].size()) {
82 best_match = i;
87 if (best_match >= 0) {
88 field->value = field->option_values[best_match];
89 return true;
92 return false;
95 // Like SetSelectControlValue, but searches within the field values and options
96 // for |value|. First it tokenizes the options, then tries to match against
97 // tokens. For example, "NC - North Carolina" would match "nc" but not "ca".
98 bool SetSelectControlValueTokenMatch(const base::string16& value,
99 FormFieldData* field) {
100 std::vector<base::string16> tokenized;
101 DCHECK_EQ(field->option_values.size(), field->option_contents.size());
102 l10n::CaseInsensitiveCompare compare;
104 for (size_t i = 0; i < field->option_values.size(); ++i) {
105 tokenized = base::SplitString(
106 field->option_values[i], base::kWhitespaceASCIIAs16,
107 base::TRIM_WHITESPACE, base::SPLIT_WANT_NONEMPTY);
108 if (std::find_if(tokenized.begin(), tokenized.end(),
109 [&compare, value](base::string16& rhs) {
110 return compare.StringsEqual(value, rhs);
111 }) != tokenized.end()) {
112 field->value = field->option_values[i];
113 return true;
116 tokenized = base::SplitString(
117 field->option_contents[i], base::kWhitespaceASCIIAs16,
118 base::TRIM_WHITESPACE, base::SPLIT_WANT_NONEMPTY);
119 if (std::find_if(tokenized.begin(), tokenized.end(),
120 [&compare, value](base::string16& rhs) {
121 return compare.StringsEqual(value, rhs);
122 }) != tokenized.end()) {
123 field->value = field->option_values[i];
124 return true;
128 return false;
131 // Try to fill a numeric |value| into the given |field|.
132 bool FillNumericSelectControl(int value,
133 FormFieldData* field) {
134 DCHECK_EQ(field->option_values.size(), field->option_contents.size());
135 for (size_t i = 0; i < field->option_values.size(); ++i) {
136 int option;
137 if ((StringToInt(field->option_values[i], &option) && option == value) ||
138 (StringToInt(field->option_contents[i], &option) && option == value)) {
139 field->value = field->option_values[i];
140 return true;
144 return false;
147 bool FillStateSelectControl(const base::string16& value,
148 FormFieldData* field) {
149 base::string16 full, abbreviation;
150 state_names::GetNameAndAbbreviation(value, &full, &abbreviation);
152 // Try an exact match of the abbreviation first.
153 if (!abbreviation.empty() && SetSelectControlValue(abbreviation, field)) {
154 return true;
157 // Try an exact match of the full name.
158 if (!full.empty() && SetSelectControlValue(full, field)) {
159 return true;
162 // Then try an inexact match of the full name.
163 if (!full.empty() && SetSelectControlValueSubstringMatch(full, field)) {
164 return true;
167 // Then try an inexact match of the abbreviation name.
168 return !abbreviation.empty() &&
169 SetSelectControlValueTokenMatch(abbreviation, field);
172 bool FillCountrySelectControl(const base::string16& value,
173 const std::string& app_locale,
174 FormFieldData* field_data) {
175 std::string country_code = AutofillCountry::GetCountryCode(value, app_locale);
176 if (country_code.empty())
177 return false;
179 DCHECK_EQ(field_data->option_values.size(),
180 field_data->option_contents.size());
181 for (size_t i = 0; i < field_data->option_values.size(); ++i) {
182 // Canonicalize each <option> value to a country code, and compare to the
183 // target country code.
184 base::string16 value = field_data->option_values[i];
185 base::string16 contents = field_data->option_contents[i];
186 if (country_code == AutofillCountry::GetCountryCode(value, app_locale) ||
187 country_code == AutofillCountry::GetCountryCode(contents, app_locale)) {
188 field_data->value = value;
189 return true;
193 return false;
196 bool FillExpirationMonthSelectControl(const base::string16& value,
197 const std::string& app_locale,
198 FormFieldData* field) {
199 int index = 0;
200 if (!StringToInt(value, &index) || index <= 0 || index > 12)
201 return false;
203 for (const base::string16& option_value : field->option_values) {
204 int converted_value = 0;
205 if (CreditCard::ConvertMonth(option_value, app_locale, &converted_value) &&
206 index == converted_value) {
207 field->value = option_value;
208 return true;
212 for (const base::string16& option_contents : field->option_contents) {
213 int converted_contents = 0;
214 if (CreditCard::ConvertMonth(option_contents, app_locale,
215 &converted_contents) &&
216 index == converted_contents) {
217 field->value = option_contents;
218 return true;
222 return FillNumericSelectControl(index, field);
225 // Returns true if the last two digits in |year| match those in |str|.
226 bool LastTwoDigitsMatch(const base::string16& year,
227 const base::string16& str) {
228 int year_int;
229 int str_int;
230 if (!StringToInt(year, &year_int) || !StringToInt(str, &str_int))
231 return false;
233 return (year_int % 100) == (str_int % 100);
236 // Try to fill a year |value| into the given |field| by comparing the last two
237 // digits of the year to the field's options.
238 bool FillYearSelectControl(const base::string16& value,
239 FormFieldData* field) {
240 if (value.size() != 2U && value.size() != 4U)
241 return false;
243 DCHECK_EQ(field->option_values.size(), field->option_contents.size());
244 for (size_t i = 0; i < field->option_values.size(); ++i) {
245 if (LastTwoDigitsMatch(value, field->option_values[i]) ||
246 LastTwoDigitsMatch(value, field->option_contents[i])) {
247 field->value = field->option_values[i];
248 return true;
252 return false;
255 // Try to fill a credit card type |value| (Visa, MasterCard, etc.) into the
256 // given |field|.
257 bool FillCreditCardTypeSelectControl(const base::string16& value,
258 FormFieldData* field) {
259 size_t idx;
260 if (AutofillField::FindValueInSelectControl(*field, value, &idx)) {
261 field->value = field->option_values[idx];
262 return true;
265 // For American Express, also try filling as "AmEx".
266 if (value == l10n_util::GetStringUTF16(IDS_AUTOFILL_CC_AMEX))
267 return FillCreditCardTypeSelectControl(ASCIIToUTF16("AmEx"), field);
269 return false;
272 // Set |field_data|'s value to |number|, or possibly an appropriate substring of
273 // |number|. The |field| specifies the type of the phone and whether this is a
274 // phone prefix or suffix.
275 void FillPhoneNumberField(const AutofillField& field,
276 const base::string16& number,
277 FormFieldData* field_data) {
278 field_data->value =
279 AutofillField::GetPhoneNumberValue(field, number, *field_data);
282 // Set |field_data|'s value to |number|, or possibly an appropriate substring
283 // of |number| for cases where credit card number splits across multiple HTML
284 // form input fields.
285 // The |field| specifies the |credit_card_number_offset_| to the substring
286 // within credit card number.
287 void FillCreditCardNumberField(const AutofillField& field,
288 const base::string16& number,
289 FormFieldData* field_data) {
290 base::string16 value = number;
292 // |field|'s max_length truncates credit card number to fit within.
293 if (field.credit_card_number_offset() < value.length())
294 value = value.substr(field.credit_card_number_offset());
296 field_data->value = value;
299 // Fills in the select control |field| with |value|. If an exact match is not
300 // found, falls back to alternate filling strategies based on the |type|.
301 bool FillSelectControl(const AutofillType& type,
302 const base::string16& value,
303 const std::string& app_locale,
304 FormFieldData* field) {
305 DCHECK_EQ("select-one", field->form_control_type);
307 // Guard against corrupted values passed over IPC.
308 if (field->option_values.size() != field->option_contents.size())
309 return false;
311 if (value.empty())
312 return false;
314 // First, search for exact matches.
315 if (SetSelectControlValue(value, field))
316 return true;
318 // If that fails, try specific fallbacks based on the field type.
319 ServerFieldType storable_type = type.GetStorableType();
320 if (storable_type == ADDRESS_HOME_STATE) {
321 return FillStateSelectControl(value, field);
322 } else if (storable_type == ADDRESS_HOME_COUNTRY) {
323 return FillCountrySelectControl(value, app_locale, field);
324 } else if (storable_type == CREDIT_CARD_EXP_MONTH) {
325 return FillExpirationMonthSelectControl(value, app_locale, field);
326 } else if (storable_type == CREDIT_CARD_EXP_2_DIGIT_YEAR ||
327 storable_type == CREDIT_CARD_EXP_4_DIGIT_YEAR) {
328 return FillYearSelectControl(value, field);
329 } else if (storable_type == CREDIT_CARD_TYPE) {
330 return FillCreditCardTypeSelectControl(value, field);
333 return false;
336 // Fills in the month control |field| with |value|. |value| should be a date
337 // formatted as MM/YYYY. If it isn't, filling will fail.
338 bool FillMonthControl(const base::string16& value, FormFieldData* field) {
339 // Autofill formats a combined date as month/year.
340 std::vector<base::string16> pieces = base::SplitString(
341 value, base::ASCIIToUTF16("/"),
342 base::TRIM_WHITESPACE, base::SPLIT_WANT_ALL);
343 if (pieces.size() != 2)
344 return false;
346 // HTML5 input="month" is formatted as year-month.
347 base::string16 month = pieces[0];
348 base::string16 year = pieces[1];
349 if ((month.size() != 1 && month.size() != 2) || year.size() != 4)
350 return false;
352 // HTML5 input="month" expects zero-padded months.
353 if (month.size() == 1)
354 month = ASCIIToUTF16("0") + month;
356 field->value = year + ASCIIToUTF16("-") + month;
357 return true;
360 // Fills |field| with the street address in |value|. Translates newlines into
361 // equivalent separators when necessary, i.e. when filling a single-line field.
362 // The separators depend on |address_language_code|.
363 void FillStreetAddress(const base::string16& value,
364 const std::string& address_language_code,
365 FormFieldData* field) {
366 if (field->form_control_type == "textarea") {
367 field->value = value;
368 return;
371 AddressData address_data;
372 address_data.language_code = address_language_code;
373 address_data.address_line = base::SplitString(
374 base::UTF16ToUTF8(value), "\n",
375 base::TRIM_WHITESPACE, base::SPLIT_WANT_ALL);
376 std::string line;
377 GetStreetAddressLinesAsSingleLine(address_data, &line);
378 field->value = base::UTF8ToUTF16(line);
381 std::string Hash32Bit(const std::string& str) {
382 std::string hash_bin = base::SHA1HashString(str);
383 DCHECK_EQ(base::kSHA1Length, hash_bin.length());
385 uint32 hash32 = ((hash_bin[0] & 0xFF) << 24) |
386 ((hash_bin[1] & 0xFF) << 16) |
387 ((hash_bin[2] & 0xFF) << 8) |
388 (hash_bin[3] & 0xFF);
390 return base::UintToString(hash32);
393 base::string16 RemoveWhitespace(const base::string16& value) {
394 base::string16 stripped_value;
395 base::RemoveChars(value, base::kWhitespaceUTF16, &stripped_value);
396 return stripped_value;
399 } // namespace
401 AutofillField::AutofillField()
402 : server_type_(NO_SERVER_DATA),
403 heuristic_type_(UNKNOWN_TYPE),
404 html_type_(HTML_TYPE_UNKNOWN),
405 html_mode_(HTML_MODE_NONE),
406 phone_part_(IGNORED),
407 credit_card_number_offset_(0),
408 previously_autofilled_(false) {
411 AutofillField::AutofillField(const FormFieldData& field,
412 const base::string16& unique_name)
413 : FormFieldData(field),
414 unique_name_(unique_name),
415 server_type_(NO_SERVER_DATA),
416 heuristic_type_(UNKNOWN_TYPE),
417 html_type_(HTML_TYPE_UNKNOWN),
418 html_mode_(HTML_MODE_NONE),
419 phone_part_(IGNORED),
420 credit_card_number_offset_(0),
421 previously_autofilled_(false) {
424 AutofillField::~AutofillField() {}
426 void AutofillField::set_heuristic_type(ServerFieldType type) {
427 if (type >= 0 && type < MAX_VALID_FIELD_TYPE &&
428 type != FIELD_WITH_DEFAULT_VALUE) {
429 heuristic_type_ = type;
430 } else {
431 NOTREACHED();
432 // This case should not be reachable; but since this has potential
433 // implications on data uploaded to the server, better safe than sorry.
434 heuristic_type_ = UNKNOWN_TYPE;
438 void AutofillField::set_server_type(ServerFieldType type) {
439 // Chrome no longer supports fax numbers, but the server still does.
440 if (type >= PHONE_FAX_NUMBER && type <= PHONE_FAX_WHOLE_NUMBER)
441 return;
443 server_type_ = type;
446 void AutofillField::SetHtmlType(HtmlFieldType type, HtmlFieldMode mode) {
447 html_type_ = type;
448 html_mode_ = mode;
450 if (type == HTML_TYPE_TEL_LOCAL_PREFIX)
451 phone_part_ = PHONE_PREFIX;
452 else if (type == HTML_TYPE_TEL_LOCAL_SUFFIX)
453 phone_part_ = PHONE_SUFFIX;
454 else
455 phone_part_ = IGNORED;
458 AutofillType AutofillField::Type() const {
459 if (html_type_ != HTML_TYPE_UNKNOWN)
460 return AutofillType(html_type_, html_mode_);
462 if (server_type_ != NO_SERVER_DATA) {
463 // See http://crbug.com/429236 for background on why we might not always
464 // believe the server.
465 // See http://crbug.com/441488 for potential improvements to the server
466 // which may obviate the need for this logic.
467 bool believe_server =
468 !(server_type_ == NAME_FULL && heuristic_type_ == CREDIT_CARD_NAME) &&
469 !(server_type_ == CREDIT_CARD_NAME && heuristic_type_ == NAME_FULL) &&
470 // CVC is sometimes type="password", which tricks the server.
471 // See http://crbug.com/469007
472 !(AutofillType(server_type_).group() == PASSWORD_FIELD &&
473 heuristic_type_ == CREDIT_CARD_VERIFICATION_CODE);
474 if (believe_server)
475 return AutofillType(server_type_);
478 return AutofillType(heuristic_type_);
481 bool AutofillField::IsEmpty() const {
482 return value.empty();
485 std::string AutofillField::FieldSignature() const {
486 std::string field_name = base::UTF16ToUTF8(name);
487 std::string field_string = field_name + "&" + form_control_type;
488 return Hash32Bit(field_string);
491 bool AutofillField::IsFieldFillable() const {
492 return !Type().IsUnknown();
495 // static
496 bool AutofillField::FillFormField(const AutofillField& field,
497 const base::string16& value,
498 const std::string& address_language_code,
499 const std::string& app_locale,
500 FormFieldData* field_data) {
501 AutofillType type = field.Type();
503 if (type.GetStorableType() == PHONE_HOME_NUMBER) {
504 FillPhoneNumberField(field, value, field_data);
505 return true;
506 } else if (field_data->form_control_type == "select-one") {
507 return FillSelectControl(type, value, app_locale, field_data);
508 } else if (field_data->form_control_type == "month") {
509 return FillMonthControl(value, field_data);
510 } else if (type.GetStorableType() == ADDRESS_HOME_STREET_ADDRESS) {
511 FillStreetAddress(value, address_language_code, field_data);
512 return true;
513 } else if (type.GetStorableType() == CREDIT_CARD_NUMBER) {
514 FillCreditCardNumberField(field, value, field_data);
515 return true;
518 field_data->value = value;
519 return true;
522 base::string16 AutofillField::GetPhoneNumberValue(
523 const AutofillField& field,
524 const base::string16& number,
525 const FormFieldData& field_data) {
526 // Check to see if the size field matches the "prefix" or "suffix" size.
527 // If so, return the appropriate substring.
528 if (number.length() !=
529 PhoneNumber::kPrefixLength + PhoneNumber::kSuffixLength) {
530 return number;
533 if (field.phone_part() == AutofillField::PHONE_PREFIX ||
534 field_data.max_length == PhoneNumber::kPrefixLength) {
535 return
536 number.substr(PhoneNumber::kPrefixOffset, PhoneNumber::kPrefixLength);
539 if (field.phone_part() == AutofillField::PHONE_SUFFIX ||
540 field_data.max_length == PhoneNumber::kSuffixLength) {
541 return
542 number.substr(PhoneNumber::kSuffixOffset, PhoneNumber::kSuffixLength);
545 return number;
548 // static
549 bool AutofillField::FindValueInSelectControl(const FormFieldData& field,
550 const base::string16& value,
551 size_t* index) {
552 l10n::CaseInsensitiveCompare compare;
553 // Strip off spaces for all values in the comparisons.
554 const base::string16 value_stripped = RemoveWhitespace(value);
556 for (size_t i = 0; i < field.option_values.size(); ++i) {
557 base::string16 option_value = RemoveWhitespace(field.option_values[i]);
558 if (compare.StringsEqual(value_stripped, option_value)) {
559 if (index)
560 *index = i;
561 return true;
564 base::string16 option_contents = RemoveWhitespace(field.option_contents[i]);
565 if (compare.StringsEqual(value_stripped, option_contents)) {
566 if (index)
567 *index = i;
568 return true;
571 return false;
574 } // namespace autofill