summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorpritam.nikam <pritam.nikam@samsung.com>2014-08-25 12:15:00 -0700
committerCommit bot <commit-bot@chromium.org>2014-08-25 19:16:56 +0000
commit401f3492b9eaac6a3d964b7d5147f1e532fa95dc (patch)
tree264f9d23452e71955aea57bdcf12b2db58ab7d31
parent9b2d620f013ea943478c1bdca1f570df5ccab8ca (diff)
downloadchromium_src-401f3492b9eaac6a3d964b7d5147f1e532fa95dc.zip
chromium_src-401f3492b9eaac6a3d964b7d5147f1e532fa95dc.tar.gz
chromium_src-401f3492b9eaac6a3d964b7d5147f1e532fa95dc.tar.bz2
[Autofill] Autofill incorrectly fills credit card expiration year in 2-digit fields.
With current implementation the on parsing the credit card field heuristics matches to the autofill::kExpirationYearRe and apparently it's assumes that a 4-digit credit card field (i.e. ServerFieldType CREDIT_CARD_EXP_DATE_4_DIGIT_YEAR). This patch considers *maxlength* attribute in addition to see whether the feild is 2-digit input field or not. BUG=406247 Review URL: https://codereview.chromium.org/493393003 Cr-Commit-Position: refs/heads/master@{#291734}
-rw-r--r--components/autofill/core/browser/credit_card_field.cc70
-rw-r--r--components/autofill/core/browser/credit_card_field.h16
-rw-r--r--components/autofill/core/browser/credit_card_field_unittest.cc33
3 files changed, 81 insertions, 38 deletions
diff --git a/components/autofill/core/browser/credit_card_field.cc b/components/autofill/core/browser/credit_card_field.cc
index 09dab1e..73dc90d 100644
--- a/components/autofill/core/browser/credit_card_field.cc
+++ b/components/autofill/core/browser/credit_card_field.cc
@@ -60,7 +60,8 @@ FormField* CreditCardField::Parse(AutofillScanner* scanner) {
scanner->SaveCursor();
const AutofillField* first;
if (ParseField(scanner, base::ASCIIToUTF16("^cfnm"), &first) &&
- ParseField(scanner, base::ASCIIToUTF16("^clnm"),
+ ParseField(scanner,
+ base::ASCIIToUTF16("^clnm"),
&credit_card_field->cardholder_last_)) {
credit_card_field->cardholder_ = first;
continue;
@@ -71,7 +72,8 @@ FormField* CreditCardField::Parse(AutofillScanner* scanner) {
// Check for a credit card type (Visa, MasterCard, etc.) field.
base::string16 type_pattern = base::UTF8ToUTF16(autofill::kCardTypeRe);
if (!credit_card_field->type_ &&
- ParseFieldSpecifics(scanner, type_pattern,
+ ParseFieldSpecifics(scanner,
+ type_pattern,
MATCH_DEFAULT | MATCH_SELECT,
&credit_card_field->type_)) {
continue;
@@ -102,11 +104,15 @@ FormField* CreditCardField::Parse(AutofillScanner* scanner) {
scanner->SaveCursor();
pattern = base::UTF8ToUTF16(autofill::kExpirationMonthRe);
if (!credit_card_field->expiration_month_ &&
- ParseFieldSpecifics(scanner, pattern, MATCH_DEFAULT | MATCH_SELECT,
+ ParseFieldSpecifics(scanner,
+ pattern,
+ MATCH_DEFAULT | MATCH_SELECT,
&credit_card_field->expiration_month_)) {
pattern = base::UTF8ToUTF16(autofill::kExpirationYearRe);
- if (ParseFieldSpecifics(scanner, pattern, MATCH_DEFAULT | MATCH_SELECT,
- &credit_card_field->expiration_year_)) {
+ if (ParseFieldSpecifics(scanner,
+ pattern,
+ MATCH_DEFAULT | MATCH_SELECT,
+ &credit_card_field->expiration_year_)) {
continue;
}
}
@@ -117,19 +123,21 @@ FormField* CreditCardField::Parse(AutofillScanner* scanner) {
scanner->Rewind();
pattern = base::UTF8ToUTF16(autofill::kExpirationDate2DigitYearRe);
// We allow <select> fields, because they're used e.g. on qvc.com.
- if (ParseFieldSpecifics(scanner, pattern,
- MATCH_LABEL | MATCH_VALUE | MATCH_TEXT |
- MATCH_SELECT,
- &credit_card_field->expiration_date_)) {
- credit_card_field->is_two_digit_year_ = true;
+ if (ParseFieldSpecifics(
+ scanner,
+ pattern,
+ MATCH_LABEL | MATCH_VALUE | MATCH_TEXT | MATCH_SELECT,
+ &credit_card_field->expiration_date_)) {
+ credit_card_field->exp_year_type_ = CREDIT_CARD_EXP_DATE_2_DIGIT_YEAR;
continue;
}
pattern = base::UTF8ToUTF16(autofill::kExpirationDateRe);
- if (ParseFieldSpecifics(scanner, pattern,
- MATCH_LABEL | MATCH_VALUE | MATCH_TEXT |
- MATCH_SELECT,
- &credit_card_field->expiration_date_)) {
+ if (ParseFieldSpecifics(
+ scanner,
+ pattern,
+ MATCH_LABEL | MATCH_VALUE | MATCH_TEXT | MATCH_SELECT,
+ &credit_card_field->expiration_date_)) {
continue;
}
}
@@ -187,14 +195,14 @@ CreditCardField::CreditCardField()
expiration_month_(NULL),
expiration_year_(NULL),
expiration_date_(NULL),
- is_two_digit_year_(false) {
+ exp_year_type_(CREDIT_CARD_EXP_DATE_4_DIGIT_YEAR) {
}
bool CreditCardField::ClassifyField(ServerFieldTypeMap* map) const {
bool ok = AddClassification(number_, CREDIT_CARD_NUMBER, map);
ok = ok && AddClassification(type_, CREDIT_CARD_TYPE, map);
- ok = ok && AddClassification(verification_, CREDIT_CARD_VERIFICATION_CODE,
- map);
+ ok = ok &&
+ AddClassification(verification_, CREDIT_CARD_VERIFICATION_CODE, map);
// If the heuristics detected first and last name in separate fields,
// then ignore both fields. Putting them into separate fields is probably
@@ -204,27 +212,23 @@ bool CreditCardField::ClassifyField(ServerFieldTypeMap* map) const {
ok = ok && AddClassification(cardholder_, CREDIT_CARD_NAME, map);
if (expiration_date_) {
- if (is_two_digit_year_) {
- ok = ok && AddClassification(expiration_date_,
- CREDIT_CARD_EXP_DATE_2_DIGIT_YEAR, map);
- } else {
- ok = ok && AddClassification(expiration_date_,
- CREDIT_CARD_EXP_DATE_4_DIGIT_YEAR, map);
- }
+ ok =
+ ok && AddClassification(expiration_date_, GetExpirationYearType(), map);
} else {
ok = ok && AddClassification(expiration_month_, CREDIT_CARD_EXP_MONTH, map);
- if (is_two_digit_year_) {
- ok = ok && AddClassification(expiration_year_,
- CREDIT_CARD_EXP_2_DIGIT_YEAR,
- map);
- } else {
- ok = ok && AddClassification(expiration_year_,
- CREDIT_CARD_EXP_4_DIGIT_YEAR,
- map);
- }
+ ok =
+ ok && AddClassification(expiration_year_, GetExpirationYearType(), map);
}
return ok;
}
+ServerFieldType CreditCardField::GetExpirationYearType() const {
+ return (expiration_date_
+ ? exp_year_type_
+ : ((expiration_year_ && expiration_year_->max_length == 2)
+ ? CREDIT_CARD_EXP_2_DIGIT_YEAR
+ : CREDIT_CARD_EXP_4_DIGIT_YEAR));
+}
+
} // namespace autofill
diff --git a/components/autofill/core/browser/credit_card_field.h b/components/autofill/core/browser/credit_card_field.h
index bf45e7e..64fa4ed 100644
--- a/components/autofill/core/browser/credit_card_field.h
+++ b/components/autofill/core/browser/credit_card_field.h
@@ -31,12 +31,17 @@ class CreditCardField : public FormField {
CreditCardField();
+ // For the combined expiration field we return |exp_year_type_|; otherwise if
+ // |expiration_year_| is having year with |max_length| of 2-digits we return
+ // |CREDIT_CARD_EXP_2_DIGIT_YEAR|; otherwise |CREDIT_CARD_EXP_4_DIGIT_YEAR|.
+ ServerFieldType GetExpirationYearType() const;
+
const AutofillField* cardholder_; // Optional.
// Occasionally pages have separate fields for the cardholder's first and
- // last names; for such pages cardholder_ holds the first name field and
+ // last names; for such pages |cardholder_| holds the first name field and
// we store the last name field here.
- // (We could store an embedded NameField object here, but we don't do so
+ // (We could store an embedded |NameField| object here, but we don't do so
// because the text patterns for matching a cardholder name are different
// than for ordinary names, and because cardholder names never have titles,
// middle names or suffixes.)
@@ -55,9 +60,10 @@ class CreditCardField : public FormField {
const AutofillField* expiration_year_;
const AutofillField* expiration_date_;
- // True if the year is detected to be a 2-digit year; otherwise, we assume
- // a 4-digit year.
- bool is_two_digit_year_;
+ // For combined expiration field having year as 2-digits we store here
+ // |CREDIT_CARD_EXP_DATE_2_DIGIT_YEAR|; otherwise we store
+ // |CREDIT_CARD_EXP_DATE_4_DIGIT_YEAR|.
+ ServerFieldType exp_year_type_;
DISALLOW_COPY_AND_ASSIGN(CreditCardField);
};
diff --git a/components/autofill/core/browser/credit_card_field_unittest.cc b/components/autofill/core/browser/credit_card_field_unittest.cc
index 037a302..39e222f 100644
--- a/components/autofill/core/browser/credit_card_field_unittest.cc
+++ b/components/autofill/core/browser/credit_card_field_unittest.cc
@@ -347,4 +347,37 @@ TEST_F(CreditCardFieldTest, ParseMonthControl) {
field_type_map_[ASCIIToUTF16("date2")]);
}
+// Verify that heuristics <input name="ccyear" maxlength="2"/> considers
+// *maxlength* attribute while parsing 2 Digit expiration year.
+TEST_F(CreditCardFieldTest, ParseCreditCardExpYear_2DigitMaxLength) {
+ FormFieldData field;
+ field.form_control_type = "text";
+
+ field.label = ASCIIToUTF16("Card Number");
+ field.name = ASCIIToUTF16("card_number");
+ list_.push_back(new AutofillField(field, ASCIIToUTF16("number")));
+
+ field.label = ASCIIToUTF16("Expiration Date");
+ field.name = ASCIIToUTF16("ccmonth");
+ list_.push_back(new AutofillField(field, ASCIIToUTF16("month")));
+
+ field.name = ASCIIToUTF16("ccyear");
+ field.max_length = 2;
+ list_.push_back(new AutofillField(field, ASCIIToUTF16("year")));
+
+ Parse();
+ ASSERT_NE(static_cast<CreditCardField*>(NULL), field_.get());
+ EXPECT_TRUE(ClassifyField());
+ ASSERT_TRUE(field_type_map_.find(ASCIIToUTF16("number")) !=
+ field_type_map_.end());
+ EXPECT_EQ(CREDIT_CARD_NUMBER, field_type_map_[ASCIIToUTF16("number")]);
+ ASSERT_TRUE(field_type_map_.find(ASCIIToUTF16("month")) !=
+ field_type_map_.end());
+ EXPECT_EQ(CREDIT_CARD_EXP_MONTH, field_type_map_[ASCIIToUTF16("month")]);
+ ASSERT_TRUE(field_type_map_.find(ASCIIToUTF16("year")) !=
+ field_type_map_.end());
+ EXPECT_EQ(CREDIT_CARD_EXP_2_DIGIT_YEAR,
+ field_type_map_[ASCIIToUTF16("year")]);
+}
+
} // namespace autofill