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 "ui/base/l10n/l10n_util.h"
     19 
     20 using base::ASCIIToUTF16;
     21 using base::StringToInt;
     22 
     23 namespace autofill {
     24 namespace {
     25 
     26 const char* const kMonthsAbbreviated[] = {
     27   NULL,  // Padding so index 1 = month 1 = January.
     28   "Jan", "Feb", "Mar", "Apr", "May", "Jun",
     29   "Jul", "Aug", "Sep", "Oct", "Nov", "Dec",
     30 };
     31 
     32 const char* const kMonthsFull[] = {
     33   NULL,  // Padding so index 1 = month 1 = January.
     34   "January", "February", "March", "April", "May", "June",
     35   "July", "August", "September", "October", "November", "December",
     36 };
     37 
     38 // Returns true if the value was successfully set, meaning |value| was found in
     39 // the list of select options in |field|.
     40 bool SetSelectControlValue(const base::string16& value,
     41                            FormFieldData* field) {
     42   base::string16 value_lowercase = StringToLowerASCII(value);
     43 
     44   DCHECK_EQ(field->option_values.size(), field->option_contents.size());
     45   base::string16 best_match;
     46   for (size_t i = 0; i < field->option_values.size(); ++i) {
     47     if (value == field->option_values[i] ||
     48         value == field->option_contents[i]) {
     49       // An exact match, use it.
     50       best_match = field->option_values[i];
     51       break;
     52     }
     53 
     54     if (value_lowercase == StringToLowerASCII(field->option_values[i]) ||
     55         value_lowercase == StringToLowerASCII(field->option_contents[i])) {
     56       // A match, but not in the same case. Save it in case an exact match is
     57       // not found.
     58       best_match = field->option_values[i];
     59     }
     60   }
     61 
     62   if (best_match.empty())
     63     return false;
     64 
     65   field->value = best_match;
     66   return true;
     67 }
     68 
     69 
     70 // Try to fill a numeric |value| into the given |field|.
     71 bool FillNumericSelectControl(int value,
     72                               FormFieldData* field) {
     73   DCHECK_EQ(field->option_values.size(), field->option_contents.size());
     74   for (size_t i = 0; i < field->option_values.size(); ++i) {
     75     int option;
     76     if ((StringToInt(field->option_values[i], &option) && option == value) ||
     77         (StringToInt(field->option_contents[i], &option) && option == value)) {
     78       field->value = field->option_values[i];
     79       return true;
     80     }
     81   }
     82 
     83   return false;
     84 }
     85 
     86 bool FillStateSelectControl(const base::string16& value,
     87                             FormFieldData* field) {
     88   base::string16 full, abbreviation;
     89   state_names::GetNameAndAbbreviation(value, &full, &abbreviation);
     90 
     91   // Try the abbreviation first.
     92   if (!abbreviation.empty() && SetSelectControlValue(abbreviation, field))
     93     return true;
     94 
     95   return !full.empty() && SetSelectControlValue(full, field);
     96 }
     97 
     98 bool FillCountrySelectControl(const base::string16& value,
     99                               const std::string& app_locale,
    100                               FormFieldData* field_data) {
    101   std::string country_code = AutofillCountry::GetCountryCode(value, app_locale);
    102   if (country_code.empty())
    103     return false;
    104 
    105   DCHECK_EQ(field_data->option_values.size(),
    106             field_data->option_contents.size());
    107   for (size_t i = 0; i < field_data->option_values.size(); ++i) {
    108     // Canonicalize each <option> value to a country code, and compare to the
    109     // target country code.
    110     base::string16 value = field_data->option_values[i];
    111     base::string16 contents = field_data->option_contents[i];
    112     if (country_code == AutofillCountry::GetCountryCode(value, app_locale) ||
    113         country_code == AutofillCountry::GetCountryCode(contents, app_locale)) {
    114       field_data->value = value;
    115       return true;
    116     }
    117   }
    118 
    119   return false;
    120 }
    121 
    122 bool FillExpirationMonthSelectControl(const base::string16& value,
    123                                       FormFieldData* field) {
    124   int index = 0;
    125   if (!StringToInt(value, &index) ||
    126       index <= 0 ||
    127       static_cast<size_t>(index) >= arraysize(kMonthsFull))
    128     return false;
    129 
    130   bool filled =
    131       SetSelectControlValue(ASCIIToUTF16(kMonthsAbbreviated[index]), field) ||
    132       SetSelectControlValue(ASCIIToUTF16(kMonthsFull[index]), field) ||
    133       FillNumericSelectControl(index, field);
    134   return filled;
    135 }
    136 
    137 // Returns true if the last two digits in |year| match those in |str|.
    138 bool LastTwoDigitsMatch(const base::string16& year,
    139                         const base::string16& str) {
    140   int year_int;
    141   int str_int;
    142   if (!StringToInt(year, &year_int) || !StringToInt(str, &str_int))
    143     return false;
    144 
    145   return (year_int % 100) == (str_int % 100);
    146 }
    147 
    148 // Try to fill a year |value| into the given |field| by comparing the last two
    149 // digits of the year to the field's options.
    150 bool FillYearSelectControl(const base::string16& value,
    151                            FormFieldData* field) {
    152   if (value.size() != 2U && value.size() != 4U)
    153     return false;
    154 
    155   DCHECK_EQ(field->option_values.size(), field->option_contents.size());
    156   for (size_t i = 0; i < field->option_values.size(); ++i) {
    157     if (LastTwoDigitsMatch(value, field->option_values[i]) ||
    158         LastTwoDigitsMatch(value, field->option_contents[i])) {
    159       field->value = field->option_values[i];
    160       return true;
    161     }
    162   }
    163 
    164   return false;
    165 }
    166 
    167 // Try to fill a credit card type |value| (Visa, MasterCard, etc.) into the
    168 // given |field|.
    169 bool FillCreditCardTypeSelectControl(const base::string16& value,
    170                                      FormFieldData* field) {
    171   // Try stripping off spaces.
    172   base::string16 value_stripped;
    173   base::RemoveChars(StringToLowerASCII(value), base::kWhitespaceUTF16,
    174                     &value_stripped);
    175 
    176   for (size_t i = 0; i < field->option_values.size(); ++i) {
    177     base::string16 option_value_lowercase;
    178     base::RemoveChars(StringToLowerASCII(field->option_values[i]),
    179                       base::kWhitespaceUTF16, &option_value_lowercase);
    180     base::string16 option_contents_lowercase;
    181     base::RemoveChars(StringToLowerASCII(field->option_contents[i]),
    182                       base::kWhitespaceUTF16, &option_contents_lowercase);
    183 
    184     // Perform a case-insensitive comparison; but fill the form with the
    185     // original text, not the lowercased version.
    186     if (value_stripped == option_value_lowercase ||
    187         value_stripped == option_contents_lowercase) {
    188       field->value = field->option_values[i];
    189       return true;
    190     }
    191   }
    192 
    193   // For American Express, also try filling as "AmEx".
    194   if (value == l10n_util::GetStringUTF16(IDS_AUTOFILL_CC_AMEX))
    195     return FillCreditCardTypeSelectControl(ASCIIToUTF16("AmEx"), field);
    196 
    197   return false;
    198 }
    199 
    200 // Set |field_data|'s value to |number|, or possibly an appropriate substring of
    201 // |number|.  The |field| specifies the type of the phone and whether this is a
    202 // phone prefix or suffix.
    203 void FillPhoneNumberField(const AutofillField& field,
    204                           const base::string16& number,
    205                           FormFieldData* field_data) {
    206   // Check to see if the size field matches the "prefix" or "suffix" sizes and
    207   // fill accordingly.
    208   base::string16 value = number;
    209   if (number.length() ==
    210           PhoneNumber::kPrefixLength + PhoneNumber::kSuffixLength) {
    211     if (field.phone_part() == AutofillField::PHONE_PREFIX ||
    212         field_data->max_length == PhoneNumber::kPrefixLength) {
    213       value = number.substr(PhoneNumber::kPrefixOffset,
    214                             PhoneNumber::kPrefixLength);
    215     } else if (field.phone_part() == AutofillField::PHONE_SUFFIX ||
    216                field_data->max_length == PhoneNumber::kSuffixLength) {
    217       value = number.substr(PhoneNumber::kSuffixOffset,
    218                             PhoneNumber::kSuffixLength);
    219     }
    220   }
    221 
    222   field_data->value = value;
    223 }
    224 
    225 // Fills in the select control |field| with |value|.  If an exact match is not
    226 // found, falls back to alternate filling strategies based on the |type|.
    227 bool FillSelectControl(const AutofillType& type,
    228                        const base::string16& value,
    229                        const std::string& app_locale,
    230                        FormFieldData* field) {
    231   DCHECK_EQ("select-one", field->form_control_type);
    232 
    233   // Guard against corrupted values passed over IPC.
    234   if (field->option_values.size() != field->option_contents.size())
    235     return false;
    236 
    237   if (value.empty())
    238     return false;
    239 
    240   // First, search for exact matches.
    241   if (SetSelectControlValue(value, field))
    242     return true;
    243 
    244   // If that fails, try specific fallbacks based on the field type.
    245   ServerFieldType storable_type = type.GetStorableType();
    246   if (storable_type == ADDRESS_HOME_STATE) {
    247     return FillStateSelectControl(value, field);
    248   } else if (storable_type == ADDRESS_HOME_COUNTRY) {
    249     return FillCountrySelectControl(value, app_locale, field);
    250   } else if (storable_type == CREDIT_CARD_EXP_MONTH) {
    251     return FillExpirationMonthSelectControl(value, field);
    252   } else if (storable_type == CREDIT_CARD_EXP_2_DIGIT_YEAR ||
    253              storable_type == CREDIT_CARD_EXP_4_DIGIT_YEAR) {
    254     return FillYearSelectControl(value, field);
    255   } else if (storable_type == CREDIT_CARD_TYPE) {
    256     return FillCreditCardTypeSelectControl(value, field);
    257   }
    258 
    259   return false;
    260 }
    261 
    262 // Fills in the month control |field| with |value|.  |value| should be a date
    263 // formatted as MM/YYYY.  If it isn't, filling will fail.
    264 bool FillMonthControl(const base::string16& value, FormFieldData* field) {
    265   // Autofill formats a combined date as month/year.
    266   std::vector<base::string16> pieces;
    267   base::SplitString(value, base::char16('/'), &pieces);
    268   if (pieces.size() != 2)
    269     return false;
    270 
    271   // HTML5 input="month" is formatted as year-month.
    272   base::string16 month = pieces[0];
    273   base::string16 year = pieces[1];
    274   if ((month.size() != 1 && month.size() != 2) || year.size() != 4)
    275     return false;
    276 
    277   // HTML5 input="month" expects zero-padded months.
    278   if (month.size() == 1)
    279     month = ASCIIToUTF16("0") + month;
    280 
    281   field->value = year + ASCIIToUTF16("-") + month;
    282   return true;
    283 }
    284 
    285 // Fills |field| with the street address in |value|.  Translates newlines into
    286 // equivalent separators when necessary, i.e. when filling a single-line field.
    287 void FillStreetAddress(const base::string16& value,
    288                        FormFieldData* field) {
    289   if (field->form_control_type == "textarea") {
    290     field->value = value;
    291     return;
    292   }
    293 
    294   const base::string16& separator =
    295       l10n_util::GetStringUTF16(IDS_AUTOFILL_ADDRESS_LINE_SEPARATOR);
    296   base::ReplaceChars(value, base::ASCIIToUTF16("\n"), separator, &field->value);
    297 }
    298 
    299 std::string Hash32Bit(const std::string& str) {
    300   std::string hash_bin = base::SHA1HashString(str);
    301   DCHECK_EQ(20U, hash_bin.length());
    302 
    303   uint32 hash32 = ((hash_bin[0] & 0xFF) << 24) |
    304                   ((hash_bin[1] & 0xFF) << 16) |
    305                   ((hash_bin[2] & 0xFF) << 8) |
    306                    (hash_bin[3] & 0xFF);
    307 
    308   return base::UintToString(hash32);
    309 }
    310 
    311 }  // namespace
    312 
    313 AutofillField::AutofillField()
    314     : server_type_(NO_SERVER_DATA),
    315       heuristic_type_(UNKNOWN_TYPE),
    316       html_type_(HTML_TYPE_UNKNOWN),
    317       html_mode_(HTML_MODE_NONE),
    318       phone_part_(IGNORED) {
    319 }
    320 
    321 AutofillField::AutofillField(const FormFieldData& field,
    322                              const base::string16& unique_name)
    323     : FormFieldData(field),
    324       unique_name_(unique_name),
    325       server_type_(NO_SERVER_DATA),
    326       heuristic_type_(UNKNOWN_TYPE),
    327       html_type_(HTML_TYPE_UNKNOWN),
    328       html_mode_(HTML_MODE_NONE),
    329       phone_part_(IGNORED) {
    330 }
    331 
    332 AutofillField::~AutofillField() {}
    333 
    334 void AutofillField::set_heuristic_type(ServerFieldType type) {
    335   if (type >= 0 && type < MAX_VALID_FIELD_TYPE &&
    336       type != FIELD_WITH_DEFAULT_VALUE) {
    337     heuristic_type_ = type;
    338   } else {
    339     NOTREACHED();
    340     // This case should not be reachable; but since this has potential
    341     // implications on data uploaded to the server, better safe than sorry.
    342     heuristic_type_ = UNKNOWN_TYPE;
    343   }
    344 }
    345 
    346 void AutofillField::set_server_type(ServerFieldType type) {
    347   // Chrome no longer supports fax numbers, but the server still does.
    348   if (type >= PHONE_FAX_NUMBER && type <= PHONE_FAX_WHOLE_NUMBER)
    349     return;
    350 
    351   server_type_ = type;
    352 }
    353 
    354 void AutofillField::SetHtmlType(HtmlFieldType type, HtmlFieldMode mode) {
    355   html_type_ = type;
    356   html_mode_ = mode;
    357 
    358   if (type == HTML_TYPE_TEL_LOCAL_PREFIX)
    359     phone_part_ = PHONE_PREFIX;
    360   else if (type == HTML_TYPE_TEL_LOCAL_SUFFIX)
    361     phone_part_ = PHONE_SUFFIX;
    362   else
    363     phone_part_ = IGNORED;
    364 }
    365 
    366 AutofillType AutofillField::Type() const {
    367   if (html_type_ != HTML_TYPE_UNKNOWN)
    368     return AutofillType(html_type_, html_mode_);
    369 
    370   if (server_type_ != NO_SERVER_DATA)
    371     return AutofillType(server_type_);
    372 
    373   return AutofillType(heuristic_type_);
    374 }
    375 
    376 bool AutofillField::IsEmpty() const {
    377   return value.empty();
    378 }
    379 
    380 std::string AutofillField::FieldSignature() const {
    381   std::string field_name = base::UTF16ToUTF8(name);
    382   std::string field_string = field_name + "&" + form_control_type;
    383   return Hash32Bit(field_string);
    384 }
    385 
    386 bool AutofillField::IsFieldFillable() const {
    387   return should_autocomplete && !Type().IsUnknown();
    388 }
    389 
    390 // static
    391 bool AutofillField::FillFormField(const AutofillField& field,
    392                                   const base::string16& value,
    393                                   const std::string& app_locale,
    394                                   FormFieldData* field_data) {
    395   AutofillType type = field.Type();
    396 
    397   if (type.GetStorableType() == PHONE_HOME_NUMBER) {
    398     FillPhoneNumberField(field, value, field_data);
    399     return true;
    400   } else if (field_data->form_control_type == "select-one") {
    401     return FillSelectControl(type, value, app_locale, field_data);
    402   } else if (field_data->form_control_type == "month") {
    403     return FillMonthControl(value, field_data);
    404   } else if (type.GetStorableType() == ADDRESS_HOME_STREET_ADDRESS) {
    405     FillStreetAddress(value, field_data);
    406     return true;
    407   }
    408 
    409   field_data->value = value;
    410   return true;
    411 }
    412 
    413 }  // namespace autofill
    414