This source file includes following definitions.
- SetSelectControlValue
- FillNumericSelectControl
- FillStateSelectControl
- FillCountrySelectControl
- FillExpirationMonthSelectControl
- LastTwoDigitsMatch
- FillYearSelectControl
- FillCreditCardTypeSelectControl
- FillPhoneNumberField
- FillSelectControl
- FillMonthControl
- FillStreetAddress
- Hash32Bit
- phone_part_
- phone_part_
- set_heuristic_type
- set_server_type
- SetHtmlType
- IsEmpty
- FieldSignature
- IsFieldFillable
- FillFormField
#include "components/autofill/core/browser/autofill_field.h"
#include "base/logging.h"
#include "base/sha1.h"
#include "base/strings/string_number_conversions.h"
#include "base/strings/string_split.h"
#include "base/strings/string_util.h"
#include "base/strings/utf_string_conversions.h"
#include "components/autofill/core/browser/autofill_country.h"
#include "components/autofill/core/browser/autofill_type.h"
#include "components/autofill/core/browser/phone_number.h"
#include "components/autofill/core/browser/state_names.h"
#include "grit/component_strings.h"
#include "ui/base/l10n/l10n_util.h"
using base::ASCIIToUTF16;
using base::StringToInt;
namespace autofill {
namespace {
const char* const kMonthsAbbreviated[] = {
NULL,
"Jan", "Feb", "Mar", "Apr", "May", "Jun",
"Jul", "Aug", "Sep", "Oct", "Nov", "Dec",
};
const char* const kMonthsFull[] = {
NULL,
"January", "February", "March", "April", "May", "June",
"July", "August", "September", "October", "November", "December",
};
bool SetSelectControlValue(const base::string16& value,
FormFieldData* field) {
base::string16 value_lowercase = StringToLowerASCII(value);
DCHECK_EQ(field->option_values.size(), field->option_contents.size());
base::string16 best_match;
for (size_t i = 0; i < field->option_values.size(); ++i) {
if (value == field->option_values[i] ||
value == field->option_contents[i]) {
best_match = field->option_values[i];
break;
}
if (value_lowercase == StringToLowerASCII(field->option_values[i]) ||
value_lowercase == StringToLowerASCII(field->option_contents[i])) {
best_match = field->option_values[i];
}
}
if (best_match.empty())
return false;
field->value = best_match;
return true;
}
bool FillNumericSelectControl(int value,
FormFieldData* field) {
DCHECK_EQ(field->option_values.size(), field->option_contents.size());
for (size_t i = 0; i < field->option_values.size(); ++i) {
int option;
if ((StringToInt(field->option_values[i], &option) && option == value) ||
(StringToInt(field->option_contents[i], &option) && option == value)) {
field->value = field->option_values[i];
return true;
}
}
return false;
}
bool FillStateSelectControl(const base::string16& value,
FormFieldData* field) {
base::string16 full, abbreviation;
state_names::GetNameAndAbbreviation(value, &full, &abbreviation);
if (!abbreviation.empty() && SetSelectControlValue(abbreviation, field))
return true;
return !full.empty() && SetSelectControlValue(full, field);
}
bool FillCountrySelectControl(const base::string16& value,
const std::string& app_locale,
FormFieldData* field_data) {
std::string country_code = AutofillCountry::GetCountryCode(value, app_locale);
if (country_code.empty())
return false;
DCHECK_EQ(field_data->option_values.size(),
field_data->option_contents.size());
for (size_t i = 0; i < field_data->option_values.size(); ++i) {
base::string16 value = field_data->option_values[i];
base::string16 contents = field_data->option_contents[i];
if (country_code == AutofillCountry::GetCountryCode(value, app_locale) ||
country_code == AutofillCountry::GetCountryCode(contents, app_locale)) {
field_data->value = value;
return true;
}
}
return false;
}
bool FillExpirationMonthSelectControl(const base::string16& value,
FormFieldData* field) {
int index = 0;
if (!StringToInt(value, &index) ||
index <= 0 ||
static_cast<size_t>(index) >= arraysize(kMonthsFull))
return false;
bool filled =
SetSelectControlValue(ASCIIToUTF16(kMonthsAbbreviated[index]), field) ||
SetSelectControlValue(ASCIIToUTF16(kMonthsFull[index]), field) ||
FillNumericSelectControl(index, field);
return filled;
}
bool LastTwoDigitsMatch(const base::string16& year,
const base::string16& str) {
int year_int;
int str_int;
if (!StringToInt(year, &year_int) || !StringToInt(str, &str_int))
return false;
return (year_int % 100) == (str_int % 100);
}
bool FillYearSelectControl(const base::string16& value,
FormFieldData* field) {
if (value.size() != 2U && value.size() != 4U)
return false;
DCHECK_EQ(field->option_values.size(), field->option_contents.size());
for (size_t i = 0; i < field->option_values.size(); ++i) {
if (LastTwoDigitsMatch(value, field->option_values[i]) ||
LastTwoDigitsMatch(value, field->option_contents[i])) {
field->value = field->option_values[i];
return true;
}
}
return false;
}
bool FillCreditCardTypeSelectControl(const base::string16& value,
FormFieldData* field) {
base::string16 value_stripped;
base::RemoveChars(StringToLowerASCII(value), base::kWhitespaceUTF16,
&value_stripped);
for (size_t i = 0; i < field->option_values.size(); ++i) {
base::string16 option_value_lowercase;
base::RemoveChars(StringToLowerASCII(field->option_values[i]),
base::kWhitespaceUTF16, &option_value_lowercase);
base::string16 option_contents_lowercase;
base::RemoveChars(StringToLowerASCII(field->option_contents[i]),
base::kWhitespaceUTF16, &option_contents_lowercase);
if (value_stripped == option_value_lowercase ||
value_stripped == option_contents_lowercase) {
field->value = field->option_values[i];
return true;
}
}
if (value == l10n_util::GetStringUTF16(IDS_AUTOFILL_CC_AMEX))
return FillCreditCardTypeSelectControl(ASCIIToUTF16("AmEx"), field);
return false;
}
void FillPhoneNumberField(const AutofillField& field,
const base::string16& number,
FormFieldData* field_data) {
base::string16 value = number;
if (number.length() ==
PhoneNumber::kPrefixLength + PhoneNumber::kSuffixLength) {
if (field.phone_part() == AutofillField::PHONE_PREFIX ||
field_data->max_length == PhoneNumber::kPrefixLength) {
value = number.substr(PhoneNumber::kPrefixOffset,
PhoneNumber::kPrefixLength);
} else if (field.phone_part() == AutofillField::PHONE_SUFFIX ||
field_data->max_length == PhoneNumber::kSuffixLength) {
value = number.substr(PhoneNumber::kSuffixOffset,
PhoneNumber::kSuffixLength);
}
}
field_data->value = value;
}
bool FillSelectControl(const AutofillType& type,
const base::string16& value,
const std::string& app_locale,
FormFieldData* field) {
DCHECK_EQ("select-one", field->form_control_type);
if (field->option_values.size() != field->option_contents.size())
return false;
if (value.empty())
return false;
if (SetSelectControlValue(value, field))
return true;
ServerFieldType storable_type = type.GetStorableType();
if (storable_type == ADDRESS_HOME_STATE) {
return FillStateSelectControl(value, field);
} else if (storable_type == ADDRESS_HOME_COUNTRY) {
return FillCountrySelectControl(value, app_locale, field);
} else if (storable_type == CREDIT_CARD_EXP_MONTH) {
return FillExpirationMonthSelectControl(value, field);
} else if (storable_type == CREDIT_CARD_EXP_2_DIGIT_YEAR ||
storable_type == CREDIT_CARD_EXP_4_DIGIT_YEAR) {
return FillYearSelectControl(value, field);
} else if (storable_type == CREDIT_CARD_TYPE) {
return FillCreditCardTypeSelectControl(value, field);
}
return false;
}
bool FillMonthControl(const base::string16& value, FormFieldData* field) {
std::vector<base::string16> pieces;
base::SplitString(value, base::char16('/'), &pieces);
if (pieces.size() != 2)
return false;
base::string16 month = pieces[0];
base::string16 year = pieces[1];
if ((month.size() != 1 && month.size() != 2) || year.size() != 4)
return false;
if (month.size() == 1)
month = ASCIIToUTF16("0") + month;
field->value = year + ASCIIToUTF16("-") + month;
return true;
}
void FillStreetAddress(const base::string16& value,
FormFieldData* field) {
if (field->form_control_type == "textarea") {
field->value = value;
return;
}
base::string16 one_line_value;
const base::char16 kNewline[] = { '\n', 0 };
const base::string16 separator =
l10n_util::GetStringUTF16(IDS_AUTOFILL_ADDRESS_LINE_SEPARATOR);
base::ReplaceChars(value, kNewline, separator, &one_line_value);
field->value = one_line_value;
}
std::string Hash32Bit(const std::string& str) {
std::string hash_bin = base::SHA1HashString(str);
DCHECK_EQ(20U, hash_bin.length());
uint32 hash32 = ((hash_bin[0] & 0xFF) << 24) |
((hash_bin[1] & 0xFF) << 16) |
((hash_bin[2] & 0xFF) << 8) |
(hash_bin[3] & 0xFF);
return base::UintToString(hash32);
}
}
AutofillField::AutofillField()
: server_type_(NO_SERVER_DATA),
heuristic_type_(UNKNOWN_TYPE),
html_type_(HTML_TYPE_UNKNOWN),
html_mode_(HTML_MODE_NONE),
phone_part_(IGNORED) {
}
AutofillField::AutofillField(const FormFieldData& field,
const base::string16& unique_name)
: FormFieldData(field),
unique_name_(unique_name),
server_type_(NO_SERVER_DATA),
heuristic_type_(UNKNOWN_TYPE),
html_type_(HTML_TYPE_UNKNOWN),
html_mode_(HTML_MODE_NONE),
phone_part_(IGNORED) {
}
AutofillField::~AutofillField() {}
void AutofillField::set_heuristic_type(ServerFieldType type) {
if (type >= 0 && type < MAX_VALID_FIELD_TYPE &&
type != FIELD_WITH_DEFAULT_VALUE) {
heuristic_type_ = type;
} else {
NOTREACHED();
heuristic_type_ = UNKNOWN_TYPE;
}
}
void AutofillField::set_server_type(ServerFieldType type) {
if (type >= PHONE_FAX_NUMBER && type <= PHONE_FAX_WHOLE_NUMBER)
return;
server_type_ = type;
}
void AutofillField::SetHtmlType(HtmlFieldType type, HtmlFieldMode mode) {
html_type_ = type;
html_mode_ = mode;
if (type == HTML_TYPE_TEL_LOCAL_PREFIX)
phone_part_ = PHONE_PREFIX;
else if (type == HTML_TYPE_TEL_LOCAL_SUFFIX)
phone_part_ = PHONE_SUFFIX;
else
phone_part_ = IGNORED;
}
AutofillType AutofillField::Type() const {
if (html_type_ != HTML_TYPE_UNKNOWN)
return AutofillType(html_type_, html_mode_);
if (server_type_ != NO_SERVER_DATA)
return AutofillType(server_type_);
return AutofillType(heuristic_type_);
}
bool AutofillField::IsEmpty() const {
return value.empty();
}
std::string AutofillField::FieldSignature() const {
std::string field_name = base::UTF16ToUTF8(name);
std::string field_string = field_name + "&" + form_control_type;
return Hash32Bit(field_string);
}
bool AutofillField::IsFieldFillable() const {
return should_autocomplete && !Type().IsUnknown();
}
bool AutofillField::FillFormField(const AutofillField& field,
const base::string16& value,
const std::string& app_locale,
FormFieldData* field_data) {
AutofillType type = field.Type();
if (type.GetStorableType() == PHONE_HOME_NUMBER) {
FillPhoneNumberField(field, value, field_data);
return true;
} else if (field_data->form_control_type == "select-one") {
return FillSelectControl(type, value, app_locale, field_data);
} else if (field_data->form_control_type == "month") {
return FillMonthControl(value, field_data);
} else if (type.GetStorableType() == ADDRESS_HOME_STREET_ADDRESS) {
FillStreetAddress(value, field_data);
return true;
}
field_data->value = value;
return true;
}
}