Chromium Code Reviews| 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 09dab1e48d796800fda5065ee6cb54075fd5697a..1d4b0ff5ee4bd064600583cfb917f3010e27ed4a 100644 |
| --- a/components/autofill/core/browser/credit_card_field.cc |
| +++ b/components/autofill/core/browser/credit_card_field.cc |
| @@ -6,6 +6,8 @@ |
| #include <stddef.h> |
| +#include <algorithm> |
| + |
| #include "base/logging.h" |
| #include "base/memory/scoped_ptr.h" |
| #include "base/strings/string16.h" |
| @@ -19,6 +21,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()) |
| @@ -58,7 +64,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"), |
| &credit_card_field->cardholder_last_)) { |
| @@ -89,8 +95,31 @@ 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_start_index() + |
| + credit_card_field->numbers_.back()->max_length; |
|
Evan Stade
2014/08/28 18:18:42
nit: \n
Pritam Nikam
2014/09/01 09:03:35
Done.
|
| + // 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. |
|
Evan Stade
2014/08/28 18:18:42
Not sure if this would happen in the wild, but it
Pritam Nikam
2014/09/01 09:03:35
This is already taken care with current logic.
Mod
|
| + if (last_number_field_size == 0U || |
| + last_number_field_size >= kMaxValidCardNumberSize) |
|
Evan Stade
2014/08/28 18:18:42
nit: curlies
Pritam Nikam
2014/09/01 09:03:35
Done.
|
| + // Mark that the credit card number splits are invalid. But keep |
| + // scanning HTML form so that cursor moves beyond related fields. |
| + credit_card_field->is_valid_card_number_split_ = false; |
| + |
| + start_index = last_number_field_size; |
| + } |
| + |
| + current_number_field->set_credit_card_number_start_index(start_index); |
| + credit_card_field->numbers_.push_back(current_number_field); |
| continue; |
| } |
| @@ -167,7 +196,8 @@ 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_) && |
| (credit_card_field->expiration_date_ || |
| (credit_card_field->expiration_month_ && |
| credit_card_field->expiration_year_))) { |
| @@ -182,16 +212,27 @@ CreditCardField::CreditCardField() |
| : cardholder_(NULL), |
| cardholder_last_(NULL), |
| type_(NULL), |
| - number_(NULL), |
| verification_(NULL), |
| expiration_month_(NULL), |
| expiration_year_(NULL), |
| expiration_date_(NULL), |
| - is_two_digit_year_(false) { |
| + is_two_digit_year_(false), |
| + is_valid_card_number_split_(true) { |
| +} |
| + |
| +CreditCardField::~CreditCardField() { |
| } |
| bool CreditCardField::ClassifyField(ServerFieldTypeMap* map) const { |
| - bool ok = AddClassification(number_, CREDIT_CARD_NUMBER, map); |
| + // Bail-out autofilling for invalid credit card number splits. |
| + if (!is_valid_card_number_split_) |
| + return false; |
| + |
| + bool ok = true; |
| + for (size_t index = 0; index < numbers_.size(); ++index) { |
| + ok = ok && AddClassification(numbers_.at(index), CREDIT_CARD_NUMBER, map); |
| + } |
| + |
| ok = ok && AddClassification(type_, CREDIT_CARD_TYPE, map); |
| ok = ok && AddClassification(verification_, CREDIT_CARD_VERIFICATION_CODE, |
| map); |