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