| Index: components/autofill/core/browser/credit_card_field.cc
|
| diff --git a/components/autofill/core/browser/credit_card_field.cc b/components/autofill/core/browser/credit_card_field.cc
|
| index 73dc90db9fc32658b470ec80b5d732fc5865e73d..f82dc063293ba3741b28ca440c6c907e4be366ad 100644
|
| --- a/components/autofill/core/browser/credit_card_field.cc
|
| +++ b/components/autofill/core/browser/credit_card_field.cc
|
| @@ -19,6 +19,10 @@
|
|
|
| namespace autofill {
|
|
|
| +// Credit card numbers are at most 19 digits in length.
|
| +// [Ref: http://en.wikipedia.org/wiki/Bank_card_number]
|
| +static const size_t kMaxValidCardNumberSize = 19;
|
| +
|
| // static
|
| FormField* CreditCardField::Parse(AutofillScanner* scanner) {
|
| if (scanner->IsEnd())
|
| @@ -26,6 +30,7 @@ FormField* CreditCardField::Parse(AutofillScanner* scanner) {
|
|
|
| scoped_ptr<CreditCardField> credit_card_field(new CreditCardField);
|
| size_t saved_cursor = scanner->SaveCursor();
|
| + bool form_has_valid_card_number_fields = true;
|
|
|
| // Credit card fields can appear in many different orders.
|
| // We loop until no more credit card related fields are found, see |break| at
|
| @@ -58,7 +63,7 @@ FormField* CreditCardField::Parse(AutofillScanner* scanner) {
|
| // for the cardholder's first and last name if they have the labels "cfnm"
|
| // and "clnm".
|
| scanner->SaveCursor();
|
| - const AutofillField* first;
|
| + AutofillField* first;
|
| if (ParseField(scanner, base::ASCIIToUTF16("^cfnm"), &first) &&
|
| ParseField(scanner,
|
| base::ASCIIToUTF16("^clnm"),
|
| @@ -91,8 +96,32 @@ FormField* CreditCardField::Parse(AutofillScanner* scanner) {
|
| }
|
|
|
| pattern = base::UTF8ToUTF16(autofill::kCardNumberRe);
|
| - if (!credit_card_field->number_ &&
|
| - ParseField(scanner, pattern, &credit_card_field->number_)) {
|
| + AutofillField* current_number_field;
|
| + if (ParseField(scanner, pattern, ¤t_number_field)) {
|
| + // Avoid autofilling any credit card number field having very low or high
|
| + // |start_index| on the HTML form.
|
| + size_t start_index = 0;
|
| + if (!credit_card_field->numbers_.empty()) {
|
| + size_t last_number_field_size =
|
| + credit_card_field->numbers_.back()->credit_card_number_offset() +
|
| + credit_card_field->numbers_.back()->max_length;
|
| +
|
| + // In some cases, HTML form may have credit card number split across
|
| + // multiple input fields and either one or cumulatively having
|
| + // |max_length| more than |kMaxValidCardNumberSize|, mark these input
|
| + // form fields as invalid and skip autofilling them.
|
| + if (last_number_field_size == 0U ||
|
| + last_number_field_size >= kMaxValidCardNumberSize) {
|
| + // Mark that the credit card number splits are invalid. But keep
|
| + // scanning HTML form so that cursor moves beyond related fields.
|
| + form_has_valid_card_number_fields = false;
|
| + }
|
| +
|
| + start_index = last_number_field_size;
|
| + }
|
| +
|
| + current_number_field->set_credit_card_number_offset(start_index);
|
| + credit_card_field->numbers_.push_back(current_number_field);
|
| continue;
|
| }
|
|
|
| @@ -162,6 +191,11 @@ FormField* CreditCardField::Parse(AutofillScanner* scanner) {
|
| break;
|
| }
|
|
|
| + // Cases where heuristic misinterprets input field as credit card number
|
| + // field, refuse to autofill credit card number fields.
|
| + if (!form_has_valid_card_number_fields)
|
| + credit_card_field->numbers_.clear();
|
| +
|
| // Some pages have a billing address field after the cardholder name field.
|
| // For that case, allow only just the cardholder name field. The remaining
|
| // CC fields will be picked up in a following CreditCardField.
|
| @@ -175,7 +209,9 @@ FormField* CreditCardField::Parse(AutofillScanner* scanner) {
|
| // a strong enough signal that this is a credit card. It is possible that
|
| // the number and name were parsed in a separate part of the form. So if
|
| // the cvc and date were found independently they are returned.
|
| - if ((credit_card_field->number_ || credit_card_field->verification_) &&
|
| + if ((!credit_card_field->numbers_.empty() ||
|
| + credit_card_field->verification_ ||
|
| + !form_has_valid_card_number_fields) &&
|
| (credit_card_field->expiration_date_ ||
|
| (credit_card_field->expiration_month_ &&
|
| credit_card_field->expiration_year_))) {
|
| @@ -190,7 +226,6 @@ CreditCardField::CreditCardField()
|
| : cardholder_(NULL),
|
| cardholder_last_(NULL),
|
| type_(NULL),
|
| - number_(NULL),
|
| verification_(NULL),
|
| expiration_month_(NULL),
|
| expiration_year_(NULL),
|
| @@ -198,8 +233,15 @@ CreditCardField::CreditCardField()
|
| exp_year_type_(CREDIT_CARD_EXP_DATE_4_DIGIT_YEAR) {
|
| }
|
|
|
| +CreditCardField::~CreditCardField() {
|
| +}
|
| +
|
| bool CreditCardField::ClassifyField(ServerFieldTypeMap* map) const {
|
| - bool ok = AddClassification(number_, CREDIT_CARD_NUMBER, map);
|
| + bool ok = true;
|
| + for (size_t index = 0; index < numbers_.size(); ++index) {
|
| + ok = ok && AddClassification(numbers_[index], CREDIT_CARD_NUMBER, map);
|
| + }
|
| +
|
| ok = ok && AddClassification(type_, CREDIT_CARD_TYPE, map);
|
| ok = ok &&
|
| AddClassification(verification_, CREDIT_CARD_VERIFICATION_CODE, map);
|
|
|