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.
4
5 #include "components/autofill/core/browser/autofill_field.h"
6
7 #include "base/logging.h"
8 #include "base/sha1.h"
9 #include "base/strings/string_number_conversions.h"
10 #include "base/strings/string_split.h"
11 #include "base/strings/string_util.h"
12 #include "base/strings/utf_string_conversions.h"
13 #include "components/autofill/core/browser/autofill_country.h"
14 #include "components/autofill/core/browser/autofill_type.h"
15 #include "components/autofill/core/browser/phone_number.h"
16 #include "components/autofill/core/browser/state_names.h"
17 #include "grit/components_strings.h"
18 #include "third_party/libaddressinput/src/cpp/include/libaddressinput/address_data.h"
19 #include "third_party/libaddressinput/src/cpp/include/libaddressinput/address_formatter.h"
20 #include "ui/base/l10n/l10n_util.h"
21
22 using ::i18n::addressinput::AddressData;
23 using ::i18n::addressinput::GetStreetAddressLinesAsSingleLine;
24 using base::ASCIIToUTF16;
25 using base::StringToInt;
26
27 namespace autofill {
28 namespace {
29
30 const char* const kMonthsAbbreviated[] = {
31 NULL, // Padding so index 1 = month 1 = January.
32 "Jan", "Feb", "Mar", "Apr", "May", "Jun",
33 "Jul", "Aug", "Sep", "Oct", "Nov", "Dec",
34 };
35
36 const char* const kMonthsFull[] = {
37 NULL, // Padding so index 1 = month 1 = January.
38 "January", "February", "March", "April", "May", "June",
39 "July", "August", "September", "October", "November", "December",
40 };
41
42 // Returns true if the value was successfully set, meaning |value| was found in
43 // the list of select options in |field|.
SetSelectControlValue(const base::string16 & value,FormFieldData * field)44 bool SetSelectControlValue(const base::string16& value,
45 FormFieldData* field) {
46 base::string16 value_lowercase = base::StringToLowerASCII(value);
47
48 DCHECK_EQ(field->option_values.size(), field->option_contents.size());
49 base::string16 best_match;
50 for (size_t i = 0; i < field->option_values.size(); ++i) {
51 if (value == field->option_values[i] ||
52 value == field->option_contents[i]) {
53 // An exact match, use it.
54 best_match = field->option_values[i];
55 break;
56 }
57
58 if (value_lowercase == base::StringToLowerASCII(field->option_values[i]) ||
59 value_lowercase ==
60 base::StringToLowerASCII(field->option_contents[i])) {
61 // A match, but not in the same case. Save it in case an exact match is
62 // not found.
63 best_match = field->option_values[i];
64 }
65 }
66
67 if (best_match.empty())
68 return false;
69
70 field->value = best_match;
71 return true;
72 }
73
74 // Like SetSelectControlValue, but searches within the field values and options
75 // for |value|. For example, "NC - North Carolina" would match "north carolina".
SetSelectControlValueSubstringMatch(const base::string16 & value,FormFieldData * field)76 bool SetSelectControlValueSubstringMatch(const base::string16& value,
77 FormFieldData* field) {
78 base::string16 value_lowercase = base::StringToLowerASCII(value);
79 DCHECK_EQ(field->option_values.size(), field->option_contents.size());
80 int best_match = -1;
81
82 for (size_t i = 0; i < field->option_values.size(); ++i) {
83 if (base::StringToLowerASCII(field->option_values[i]).find(value_lowercase) !=
84 std::string::npos ||
85 base::StringToLowerASCII(field->option_contents[i]).find(
86 value_lowercase) != std::string::npos) {
87 // The best match is the shortest one.
88 if (best_match == -1 ||
89 field->option_values[best_match].size() >
90 field->option_values[i].size()) {
91 best_match = i;
92 }
93 }
94 }
95
96 if (best_match >= 0) {
97 field->value = field->option_values[best_match];
98 return true;
99 }
100
101 return false;
102 }
103
104 // Like SetSelectControlValue, but searches within the field values and options
105 // for |value|. First it tokenizes the options, then tries to match against
106 // tokens. For example, "NC - North Carolina" would match "nc" but not "ca".
SetSelectControlValueTokenMatch(const base::string16 & value,FormFieldData * field)107 bool SetSelectControlValueTokenMatch(const base::string16& value,
108 FormFieldData* field) {
109 base::string16 value_lowercase = base::StringToLowerASCII(value);
110 std::vector<base::string16> tokenized;
111 DCHECK_EQ(field->option_values.size(), field->option_contents.size());
112
113 for (size_t i = 0; i < field->option_values.size(); ++i) {
114 base::SplitStringAlongWhitespace(
115 base::StringToLowerASCII(field->option_values[i]), &tokenized);
116 if (std::find(tokenized.begin(), tokenized.end(), value_lowercase) !=
117 tokenized.end()) {
118 field->value = field->option_values[i];
119 return true;
120 }
121
122 base::SplitStringAlongWhitespace(
123 base::StringToLowerASCII(field->option_contents[i]), &tokenized);
124 if (std::find(tokenized.begin(), tokenized.end(), value_lowercase) !=
125 tokenized.end()) {
126 field->value = field->option_values[i];
127 return true;
128 }
129 }
130
131 return false;
132 }
133
134 // Try to fill a numeric |value| into the given |field|.
FillNumericSelectControl(int value,FormFieldData * field)135 bool FillNumericSelectControl(int value,
136 FormFieldData* field) {
137 DCHECK_EQ(field->option_values.size(), field->option_contents.size());
138 for (size_t i = 0; i < field->option_values.size(); ++i) {
139 int option;
140 if ((StringToInt(field->option_values[i], &option) && option == value) ||
141 (StringToInt(field->option_contents[i], &option) && option == value)) {
142 field->value = field->option_values[i];
143 return true;
144 }
145 }
146
147 return false;
148 }
149
FillStateSelectControl(const base::string16 & value,FormFieldData * field)150 bool FillStateSelectControl(const base::string16& value,
151 FormFieldData* field) {
152 base::string16 full, abbreviation;
153 state_names::GetNameAndAbbreviation(value, &full, &abbreviation);
154
155 // Try an exact match of the abbreviation first.
156 if (!abbreviation.empty() && SetSelectControlValue(abbreviation, field)) {
157 return true;
158 }
159
160 // Try an exact match of the full name.
161 if (!full.empty() && SetSelectControlValue(full, field)) {
162 return true;
163 }
164
165 // Then try an inexact match of the full name.
166 if (!full.empty() && SetSelectControlValueSubstringMatch(full, field)) {
167 return true;
168 }
169
170 // Then try an inexact match of the abbreviation name.
171 return !abbreviation.empty() &&
172 SetSelectControlValueTokenMatch(abbreviation, field);
173 }
174
FillCountrySelectControl(const base::string16 & value,const std::string & app_locale,FormFieldData * field_data)175 bool FillCountrySelectControl(const base::string16& value,
176 const std::string& app_locale,
177 FormFieldData* field_data) {
178 std::string country_code = AutofillCountry::GetCountryCode(value, app_locale);
179 if (country_code.empty())
180 return false;
181
182 DCHECK_EQ(field_data->option_values.size(),
183 field_data->option_contents.size());
184 for (size_t i = 0; i < field_data->option_values.size(); ++i) {
185 // Canonicalize each <option> value to a country code, and compare to the
186 // target country code.
187 base::string16 value = field_data->option_values[i];
188 base::string16 contents = field_data->option_contents[i];
189 if (country_code == AutofillCountry::GetCountryCode(value, app_locale) ||
190 country_code == AutofillCountry::GetCountryCode(contents, app_locale)) {
191 field_data->value = value;
192 return true;
193 }
194 }
195
196 return false;
197 }
198
FillExpirationMonthSelectControl(const base::string16 & value,FormFieldData * field)199 bool FillExpirationMonthSelectControl(const base::string16& value,
200 FormFieldData* field) {
201 int index = 0;
202 if (!StringToInt(value, &index) ||
203 index <= 0 ||
204 static_cast<size_t>(index) >= arraysize(kMonthsFull))
205 return false;
206
207 bool filled =
208 SetSelectControlValue(ASCIIToUTF16(kMonthsAbbreviated[index]), field) ||
209 SetSelectControlValue(ASCIIToUTF16(kMonthsFull[index]), field) ||
210 FillNumericSelectControl(index, field);
211 return filled;
212 }
213
214 // Returns true if the last two digits in |year| match those in |str|.
LastTwoDigitsMatch(const base::string16 & year,const base::string16 & str)215 bool LastTwoDigitsMatch(const base::string16& year,
216 const base::string16& str) {
217 int year_int;
218 int str_int;
219 if (!StringToInt(year, &year_int) || !StringToInt(str, &str_int))
220 return false;
221
222 return (year_int % 100) == (str_int % 100);
223 }
224
225 // Try to fill a year |value| into the given |field| by comparing the last two
226 // digits of the year to the field's options.
FillYearSelectControl(const base::string16 & value,FormFieldData * field)227 bool FillYearSelectControl(const base::string16& value,
228 FormFieldData* field) {
229 if (value.size() != 2U && value.size() != 4U)
230 return false;
231
232 DCHECK_EQ(field->option_values.size(), field->option_contents.size());
233 for (size_t i = 0; i < field->option_values.size(); ++i) {
234 if (LastTwoDigitsMatch(value, field->option_values[i]) ||
235 LastTwoDigitsMatch(value, field->option_contents[i])) {
236 field->value = field->option_values[i];
237 return true;
238 }
239 }
240
241 return false;
242 }
243
244 // Try to fill a credit card type |value| (Visa, MasterCard, etc.) into the
245 // given |field|.
FillCreditCardTypeSelectControl(const base::string16 & value,FormFieldData * field)246 bool FillCreditCardTypeSelectControl(const base::string16& value,
247 FormFieldData* field) {
248 // Try stripping off spaces.
249 base::string16 value_stripped;
250 base::RemoveChars(base::StringToLowerASCII(value), base::kWhitespaceUTF16,
251 &value_stripped);
252
253 for (size_t i = 0; i < field->option_values.size(); ++i) {
254 base::string16 option_value_lowercase;
255 base::RemoveChars(base::StringToLowerASCII(field->option_values[i]),
256 base::kWhitespaceUTF16, &option_value_lowercase);
257 base::string16 option_contents_lowercase;
258 base::RemoveChars(base::StringToLowerASCII(field->option_contents[i]),
259 base::kWhitespaceUTF16, &option_contents_lowercase);
260
261 // Perform a case-insensitive comparison; but fill the form with the
262 // original text, not the lowercased version.
263 if (value_stripped == option_value_lowercase ||
264 value_stripped == option_contents_lowercase) {
265 field->value = field->option_values[i];
266 return true;
267 }
268 }
269
270 // For American Express, also try filling as "AmEx".
271 if (value == l10n_util::GetStringUTF16(IDS_AUTOFILL_CC_AMEX))
272 return FillCreditCardTypeSelectControl(ASCIIToUTF16("AmEx"), field);
273
274 return false;
275 }
276
277 // Set |field_data|'s value to |number|, or possibly an appropriate substring of
278 // |number|. The |field| specifies the type of the phone and whether this is a
279 // phone prefix or suffix.
FillPhoneNumberField(const AutofillField & field,const base::string16 & number,FormFieldData * field_data)280 void FillPhoneNumberField(const AutofillField& field,
281 const base::string16& number,
282 FormFieldData* field_data) {
283 field_data->value =
284 AutofillField::GetPhoneNumberValue(field, number, *field_data);
285 }
286
287 // Set |field_data|'s value to |number|, or possibly an appropriate substring
288 // of |number| for cases where credit card number splits across multiple HTML
289 // form input fields.
290 // The |field| specifies the |credit_card_number_offset_| to the substring
291 // within credit card number.
FillCreditCardNumberField(const AutofillField & field,const base::string16 & number,FormFieldData * field_data)292 void FillCreditCardNumberField(const AutofillField& field,
293 const base::string16& number,
294 FormFieldData* field_data) {
295 base::string16 value = number;
296
297 // |field|'s max_length truncates credit card number to fit within.
298 if (field.credit_card_number_offset() < value.length())
299 value = value.substr(field.credit_card_number_offset());
300
301 field_data->value = value;
302 }
303
304 // Fills in the select control |field| with |value|. If an exact match is not
305 // found, falls back to alternate filling strategies based on the |type|.
FillSelectControl(const AutofillType & type,const base::string16 & value,const std::string & app_locale,FormFieldData * field)306 bool FillSelectControl(const AutofillType& type,
307 const base::string16& value,
308 const std::string& app_locale,
309 FormFieldData* field) {
310 DCHECK_EQ("select-one", field->form_control_type);
311
312 // Guard against corrupted values passed over IPC.
313 if (field->option_values.size() != field->option_contents.size())
314 return false;
315
316 if (value.empty())
317 return false;
318
319 // First, search for exact matches.
320 if (SetSelectControlValue(value, field))
321 return true;
322
323 // If that fails, try specific fallbacks based on the field type.
324 ServerFieldType storable_type = type.GetStorableType();
325 if (storable_type == ADDRESS_HOME_STATE) {
326 return FillStateSelectControl(value, field);
327 } else if (storable_type == ADDRESS_HOME_COUNTRY) {
328 return FillCountrySelectControl(value, app_locale, field);
329 } else if (storable_type == CREDIT_CARD_EXP_MONTH) {
330 return FillExpirationMonthSelectControl(value, field);
331 } else if (storable_type == CREDIT_CARD_EXP_2_DIGIT_YEAR ||
332 storable_type == CREDIT_CARD_EXP_4_DIGIT_YEAR) {
333 return FillYearSelectControl(value, field);
334 } else if (storable_type == CREDIT_CARD_TYPE) {
335 return FillCreditCardTypeSelectControl(value, field);
336 }
337
338 return false;
339 }
340
341 // Fills in the month control |field| with |value|. |value| should be a date
342 // formatted as MM/YYYY. If it isn't, filling will fail.
FillMonthControl(const base::string16 & value,FormFieldData * field)343 bool FillMonthControl(const base::string16& value, FormFieldData* field) {
344 // Autofill formats a combined date as month/year.
345 std::vector<base::string16> pieces;
346 base::SplitString(value, base::char16('/'), &pieces);
347 if (pieces.size() != 2)
348 return false;
349
350 // HTML5 input="month" is formatted as year-month.
351 base::string16 month = pieces[0];
352 base::string16 year = pieces[1];
353 if ((month.size() != 1 && month.size() != 2) || year.size() != 4)
354 return false;
355
356 // HTML5 input="month" expects zero-padded months.
357 if (month.size() == 1)
358 month = ASCIIToUTF16("0") + month;
359
360 field->value = year + ASCIIToUTF16("-") + month;
361 return true;
362 }
363
364 // Fills |field| with the street address in |value|. Translates newlines into
365 // equivalent separators when necessary, i.e. when filling a single-line field.
366 // The separators depend on |address_language_code|.
FillStreetAddress(const base::string16 & value,const std::string & address_language_code,FormFieldData * field)367 void FillStreetAddress(const base::string16& value,
368 const std::string& address_language_code,
369 FormFieldData* field) {
370 if (field->form_control_type == "textarea") {
371 field->value = value;
372 return;
373 }
374
375 AddressData address_data;
376 address_data.language_code = address_language_code;
377 base::SplitString(base::UTF16ToUTF8(value), '\n', &address_data.address_line);
378 std::string line;
379 GetStreetAddressLinesAsSingleLine(address_data, &line);
380 field->value = base::UTF8ToUTF16(line);
381 }
382
Hash32Bit(const std::string & str)383 std::string Hash32Bit(const std::string& str) {
384 std::string hash_bin = base::SHA1HashString(str);
385 DCHECK_EQ(20U, hash_bin.length());
386
387 uint32 hash32 = ((hash_bin[0] & 0xFF) << 24) |
388 ((hash_bin[1] & 0xFF) << 16) |
389 ((hash_bin[2] & 0xFF) << 8) |
390 (hash_bin[3] & 0xFF);
391
392 return base::UintToString(hash32);
393 }
394
395 } // namespace
396
AutofillField()397 AutofillField::AutofillField()
398 : server_type_(NO_SERVER_DATA),
399 heuristic_type_(UNKNOWN_TYPE),
400 html_type_(HTML_TYPE_UNKNOWN),
401 html_mode_(HTML_MODE_NONE),
402 phone_part_(IGNORED),
403 credit_card_number_offset_(0) {
404 }
405
AutofillField(const FormFieldData & field,const base::string16 & unique_name)406 AutofillField::AutofillField(const FormFieldData& field,
407 const base::string16& unique_name)
408 : FormFieldData(field),
409 unique_name_(unique_name),
410 server_type_(NO_SERVER_DATA),
411 heuristic_type_(UNKNOWN_TYPE),
412 html_type_(HTML_TYPE_UNKNOWN),
413 html_mode_(HTML_MODE_NONE),
414 phone_part_(IGNORED),
415 credit_card_number_offset_(0) {
416 }
417
~AutofillField()418 AutofillField::~AutofillField() {}
419
set_heuristic_type(ServerFieldType type)420 void AutofillField::set_heuristic_type(ServerFieldType type) {
421 if (type >= 0 && type < MAX_VALID_FIELD_TYPE &&
422 type != FIELD_WITH_DEFAULT_VALUE) {
423 heuristic_type_ = type;
424 } else {
425 NOTREACHED();
426 // This case should not be reachable; but since this has potential
427 // implications on data uploaded to the server, better safe than sorry.
428 heuristic_type_ = UNKNOWN_TYPE;
429 }
430 }
431
set_server_type(ServerFieldType type)432 void AutofillField::set_server_type(ServerFieldType type) {
433 // Chrome no longer supports fax numbers, but the server still does.
434 if (type >= PHONE_FAX_NUMBER && type <= PHONE_FAX_WHOLE_NUMBER)
435 return;
436
437 server_type_ = type;
438 }
439
SetHtmlType(HtmlFieldType type,HtmlFieldMode mode)440 void AutofillField::SetHtmlType(HtmlFieldType type, HtmlFieldMode mode) {
441 html_type_ = type;
442 html_mode_ = mode;
443
444 if (type == HTML_TYPE_TEL_LOCAL_PREFIX)
445 phone_part_ = PHONE_PREFIX;
446 else if (type == HTML_TYPE_TEL_LOCAL_SUFFIX)
447 phone_part_ = PHONE_SUFFIX;
448 else
449 phone_part_ = IGNORED;
450 }
451
Type() const452 AutofillType AutofillField::Type() const {
453 if (html_type_ != HTML_TYPE_UNKNOWN)
454 return AutofillType(html_type_, html_mode_);
455
456 if (server_type_ != NO_SERVER_DATA)
457 return AutofillType(server_type_);
458
459 return AutofillType(heuristic_type_);
460 }
461
IsEmpty() const462 bool AutofillField::IsEmpty() const {
463 return value.empty();
464 }
465
FieldSignature() const466 std::string AutofillField::FieldSignature() const {
467 std::string field_name = base::UTF16ToUTF8(name);
468 std::string field_string = field_name + "&" + form_control_type;
469 return Hash32Bit(field_string);
470 }
471
IsFieldFillable() const472 bool AutofillField::IsFieldFillable() const {
473 return should_autocomplete && !Type().IsUnknown();
474 }
475
476 // static
FillFormField(const AutofillField & field,const base::string16 & value,const std::string & address_language_code,const std::string & app_locale,FormFieldData * field_data)477 bool AutofillField::FillFormField(const AutofillField& field,
478 const base::string16& value,
479 const std::string& address_language_code,
480 const std::string& app_locale,
481 FormFieldData* field_data) {
482 AutofillType type = field.Type();
483
484 if (type.GetStorableType() == PHONE_HOME_NUMBER) {
485 FillPhoneNumberField(field, value, field_data);
486 return true;
487 } else if (field_data->form_control_type == "select-one") {
488 return FillSelectControl(type, value, app_locale, field_data);
489 } else if (field_data->form_control_type == "month") {
490 return FillMonthControl(value, field_data);
491 } else if (type.GetStorableType() == ADDRESS_HOME_STREET_ADDRESS) {
492 FillStreetAddress(value, address_language_code, field_data);
493 return true;
494 } else if (type.GetStorableType() == CREDIT_CARD_NUMBER) {
495 FillCreditCardNumberField(field, value, field_data);
496 return true;
497 }
498
499 field_data->value = value;
500 return true;
501 }
502
GetPhoneNumberValue(const AutofillField & field,const base::string16 & number,const FormFieldData & field_data)503 base::string16 AutofillField::GetPhoneNumberValue(
504 const AutofillField& field,
505 const base::string16& number,
506 const FormFieldData& field_data) {
507 // Check to see if the size field matches the "prefix" or "suffix" size.
508 // If so, return the appropriate substring.
509 if (number.length() !=
510 PhoneNumber::kPrefixLength + PhoneNumber::kSuffixLength) {
511 return number;
512 }
513
514 if (field.phone_part() == AutofillField::PHONE_PREFIX ||
515 field_data.max_length == PhoneNumber::kPrefixLength) {
516 return
517 number.substr(PhoneNumber::kPrefixOffset, PhoneNumber::kPrefixLength);
518 }
519
520 if (field.phone_part() == AutofillField::PHONE_SUFFIX ||
521 field_data.max_length == PhoneNumber::kSuffixLength) {
522 return
523 number.substr(PhoneNumber::kSuffixOffset, PhoneNumber::kSuffixLength);
524 }
525
526 return number;
527 }
528
529 } // namespace autofill
530