• Home
  • History
  • Annotate
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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