Home | History | Annotate | Download | only in browser
      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|.
     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".
     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".
    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|.
    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 
    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 
    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 
    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|.
    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.
    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|.
    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.
    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.
    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|.
    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.
    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|.
    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 
    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 
    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 
    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 
    418 AutofillField::~AutofillField() {}
    419 
    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 
    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 
    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 
    452 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 
    462 bool AutofillField::IsEmpty() const {
    463   return value.empty();
    464 }
    465 
    466 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 
    472 bool AutofillField::IsFieldFillable() const {
    473   return should_autocomplete && !Type().IsUnknown();
    474 }
    475 
    476 // static
    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 
    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