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