Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(8390)

Unified Diff: components/autofill/core/browser/credit_card_field.cc

Issue 381613005: [Autofill] Autofill fails to fill credit card number when split across fields. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Incorporated review inputs. Created 6 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
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, &current_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);
« no previous file with comments | « components/autofill/core/browser/credit_card_field.h ('k') | components/autofill/core/browser/credit_card_field_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698