Commit c011630e authored by pritam.nikam's avatar pritam.nikam Committed by Commit bot

[Autofill] Autofill fails to fill credit card number when split across fields.

With current autofill implementaion for credit card number field on a secure form that splits up the credit card number across multiple fields fails to fill all fields, and instead it just fills first of the credit card number field.

With this patch it solves the problem by book-keeping spilt information to hold the credit card number grouping.

BUG=90280

Review URL: https://codereview.chromium.org/381613005

Cr-Commit-Position: refs/heads/master@{#295200}
parent 12bec174
......@@ -49,15 +49,15 @@ class AddressField : public FormField {
bool ParseCity(AutofillScanner* scanner);
bool ParseState(AutofillScanner* scanner);
const AutofillField* company_;
const AutofillField* address1_;
const AutofillField* address2_;
const AutofillField* street_address_;
const AutofillField* city_;
const AutofillField* state_;
const AutofillField* zip_;
const AutofillField* zip4_; // optional ZIP+4; we don't fill this yet.
const AutofillField* country_;
AutofillField* company_;
AutofillField* address1_;
AutofillField* address2_;
AutofillField* street_address_;
AutofillField* city_;
AutofillField* state_;
AutofillField* zip_;
AutofillField* zip4_; // optional ZIP+4; we don't fill this yet.
AutofillField* country_;
DISALLOW_COPY_AND_ASSIGN(AddressField);
};
......
......@@ -21,7 +21,7 @@ class AddressFieldTest : public testing::Test {
AddressFieldTest() {}
protected:
ScopedVector<const AutofillField> list_;
ScopedVector<AutofillField> list_;
scoped_ptr<AddressField> field_;
ServerFieldTypeMap field_type_map_;
......
......@@ -299,6 +299,23 @@ void FillPhoneNumberField(const AutofillField& field,
field_data->value = value;
}
// Set |field_data|'s value to |number|, or possibly an appropriate substring
// of |number| for cases where credit card number splits across multiple HTML
// form input fields.
// The |field| specifies the |credit_card_number_offset_| to the substring
// within credit card number.
void FillCreditCardNumberField(const AutofillField& field,
const base::string16& number,
FormFieldData* field_data) {
base::string16 value = number;
// |field|'s max_length truncates credit card number to fit within.
if (field.credit_card_number_offset() < value.length())
value = value.substr(field.credit_card_number_offset());
field_data->value = value;
}
// Fills in the select control |field| with |value|. If an exact match is not
// found, falls back to alternate filling strategies based on the |type|.
bool FillSelectControl(const AutofillType& type,
......@@ -397,7 +414,8 @@ AutofillField::AutofillField()
heuristic_type_(UNKNOWN_TYPE),
html_type_(HTML_TYPE_UNKNOWN),
html_mode_(HTML_MODE_NONE),
phone_part_(IGNORED) {
phone_part_(IGNORED),
credit_card_number_offset_(0) {
}
AutofillField::AutofillField(const FormFieldData& field,
......@@ -408,7 +426,8 @@ AutofillField::AutofillField(const FormFieldData& field,
heuristic_type_(UNKNOWN_TYPE),
html_type_(HTML_TYPE_UNKNOWN),
html_mode_(HTML_MODE_NONE),
phone_part_(IGNORED) {
phone_part_(IGNORED),
credit_card_number_offset_(0) {
}
AutofillField::~AutofillField() {}
......@@ -487,6 +506,9 @@ bool AutofillField::FillFormField(const AutofillField& field,
} else if (type.GetStorableType() == ADDRESS_HOME_STREET_ADDRESS) {
FillStreetAddress(value, address_language_code, field_data);
return true;
} else if (type.GetStorableType() == CREDIT_CARD_NUMBER) {
FillCreditCardNumberField(field, value, field_data);
return true;
}
field_data->value = value;
......
......@@ -65,6 +65,13 @@ class AutofillField : public FormFieldData {
void set_default_value(const std::string& value) { default_value_ = value; }
const std::string& default_value() const { return default_value_; }
void set_credit_card_number_offset(size_t position) {
credit_card_number_offset_ = position;
}
size_t credit_card_number_offset() const {
return credit_card_number_offset_;
}
// Set |field_data|'s value to |value|. Uses |field|, |address_language_code|,
// and |app_locale| as hints when filling exceptional cases like phone number
// values and <select> fields. Returns |true| if the field has been filled,
......@@ -105,6 +112,10 @@ class AutofillField : public FormFieldData {
// The default value returned by the Autofill server.
std::string default_value_;
// Used to hold the position of the first digit to be copied as a substring
// from credit card number.
size_t credit_card_number_offset_;
DISALLOW_COPY_AND_ASSIGN(AutofillField);
};
......
......@@ -34,6 +34,21 @@ FormFieldData GenerateSelectFieldWithOptions(const char* const* options,
return form_field;
}
struct TestCase {
std::string card_number_;
size_t total_spilts_;
std::vector<int> splits_;
std::vector<std::string> expected_results_;
};
// Returns the offset to be set within the credit card number field.
size_t GetNumberOffset(size_t index, const TestCase& test) {
size_t result = 0;
for (size_t i = 0; i < index; ++i)
result += test.splits_[i];
return result;
}
TEST(AutofillFieldTest, Type) {
AutofillField field;
ASSERT_EQ(NO_SERVER_DATA, field.server_type());
......@@ -503,5 +518,109 @@ TEST(AutofillFieldTest, FillStreetAddressTextField) {
EXPECT_EQ(UTF8ToUTF16("桜丘町26-1セルリアンタワー6階"), field.value);
}
TEST(AutofillFieldTest, FillCreditCardNumberWithoutSplits) {
// Case 1: card number without any spilt.
AutofillField cc_number_full;
cc_number_full.set_heuristic_type(CREDIT_CARD_NUMBER);
AutofillField::FillFormField(cc_number_full,
ASCIIToUTF16("4111111111111111"),
"en-US",
"en-US",
&cc_number_full);
// Verify that full card-number shall get fill properly.
EXPECT_EQ(ASCIIToUTF16("4111111111111111"), cc_number_full.value);
EXPECT_EQ(0U, cc_number_full.credit_card_number_offset());
}
TEST(AutofillFieldTest, FillCreditCardNumberWithEqualSizeSplits) {
// Case 2: card number broken up into four equal groups, of length 4.
TestCase test;
test.card_number_ = "5187654321098765";
test.total_spilts_ = 4;
int splits[] = {4, 4, 4, 4};
test.splits_ = std::vector<int>(splits, splits + arraysize(splits));
std::string results[] = {"5187", "6543", "2109", "8765"};
test.expected_results_ =
std::vector<std::string>(results, results + arraysize(results));
for (size_t i = 0; i < test.total_spilts_; ++i) {
AutofillField cc_number_part;
cc_number_part.set_heuristic_type(CREDIT_CARD_NUMBER);
cc_number_part.max_length = test.splits_[i];
cc_number_part.set_credit_card_number_offset(4 * i);
// Fill with a card-number; should fill just the card_number_part.
AutofillField::FillFormField(cc_number_part,
ASCIIToUTF16(test.card_number_),
"en-US",
"en-US",
&cc_number_part);
// Verify for expected results.
EXPECT_EQ(ASCIIToUTF16(test.expected_results_[i]),
cc_number_part.value.substr(0, cc_number_part.max_length));
EXPECT_EQ(4 * i, cc_number_part.credit_card_number_offset());
}
// Verify that full card-number shall get fill properly as well.
AutofillField cc_number_full;
cc_number_full.set_heuristic_type(CREDIT_CARD_NUMBER);
AutofillField::FillFormField(cc_number_full,
ASCIIToUTF16(test.card_number_),
"en-US",
"en-US",
&cc_number_full);
// Verify for expected results.
EXPECT_EQ(ASCIIToUTF16(test.card_number_), cc_number_full.value);
}
TEST(AutofillFieldTest, FillCreditCardNumberWithUnequalSizeSplits) {
// Case 3: card with 15 digits number, broken up into three unequal groups, of
// lengths 4, 6, and 5.
TestCase test;
test.card_number_ = "423456789012345";
test.total_spilts_ = 3;
int splits[] = {4, 6, 5};
test.splits_ = std::vector<int>(splits, splits + arraysize(splits));
std::string results[] = {"4234", "567890", "12345"};
test.expected_results_ =
std::vector<std::string>(results, results + arraysize(results));
// Start executing test cases to verify parts and full credit card number.
for (size_t i = 0; i < test.total_spilts_; ++i) {
AutofillField cc_number_part;
cc_number_part.set_heuristic_type(CREDIT_CARD_NUMBER);
cc_number_part.max_length = test.splits_[i];
cc_number_part.set_credit_card_number_offset(GetNumberOffset(i, test));
// Fill with a card-number; should fill just the card_number_part.
AutofillField::FillFormField(cc_number_part,
ASCIIToUTF16(test.card_number_),
"en-US",
"en-US",
&cc_number_part);
// Verify for expected results.
EXPECT_EQ(ASCIIToUTF16(test.expected_results_[i]),
cc_number_part.value.substr(0, cc_number_part.max_length));
EXPECT_EQ(GetNumberOffset(i, test),
cc_number_part.credit_card_number_offset());
}
// Verify that full card-number shall get fill properly as well.
AutofillField cc_number_full;
cc_number_full.set_heuristic_type(CREDIT_CARD_NUMBER);
AutofillField::FillFormField(cc_number_full,
ASCIIToUTF16(test.card_number_),
"en-US",
"en-US",
&cc_number_full);
// Verify for expected results.
EXPECT_EQ(ASCIIToUTF16(test.card_number_), cc_number_full.value);
}
} // namespace
} // namespace autofill
......@@ -9,8 +9,7 @@
namespace autofill {
AutofillScanner::AutofillScanner(
const std::vector<const AutofillField*>& fields)
AutofillScanner::AutofillScanner(std::vector<AutofillField*>& fields)
: cursor_(fields.begin()),
saved_cursor_(fields.begin()),
begin_(fields.begin()),
......@@ -25,7 +24,7 @@ void AutofillScanner::Advance() {
++cursor_;
}
const AutofillField* AutofillScanner::Cursor() const {
AutofillField* AutofillScanner::Cursor() const {
if (IsEnd()) {
NOTREACHED();
return NULL;
......
......@@ -17,7 +17,7 @@ class AutofillField;
// A helper class for parsing a stream of |AutofillField|'s with lookahead.
class AutofillScanner {
public:
explicit AutofillScanner(const std::vector<const AutofillField*>& fields);
explicit AutofillScanner(std::vector<AutofillField*>& fields);
~AutofillScanner();
// Advances the cursor by one step, if possible.
......@@ -25,7 +25,7 @@ class AutofillScanner {
// Returns the current field in the stream, or |NULL| if there are no more
// fields in the stream.
const AutofillField* Cursor() const;
AutofillField* Cursor() const;
// Returns |true| if the cursor has reached the end of the stream.
bool IsEnd() const;
......@@ -42,16 +42,16 @@ class AutofillScanner {
private:
// Indicates the current position in the stream, represented as a vector.
std::vector<const AutofillField*>::const_iterator cursor_;
std::vector<AutofillField*>::const_iterator cursor_;
// The most recently saved cursor.
std::vector<const AutofillField*>::const_iterator saved_cursor_;
std::vector<AutofillField*>::const_iterator saved_cursor_;
// The beginning pointer for the stream.
const std::vector<const AutofillField*>::const_iterator begin_;
const std::vector<AutofillField*>::iterator begin_;
// The past-the-end pointer for the stream.
const std::vector<const AutofillField*>::const_iterator end_;
const std::vector<AutofillField*>::iterator end_;
DISALLOW_COPY_AND_ASSIGN(AutofillScanner);
};
......
......@@ -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);
......
......@@ -20,6 +20,7 @@ class AutofillScanner;
class CreditCardField : public FormField {
public:
virtual ~CreditCardField();
static FormField* Parse(AutofillScanner* scanner);
protected:
......@@ -36,7 +37,7 @@ class CreditCardField : public FormField {
// |CREDIT_CARD_EXP_2_DIGIT_YEAR|; otherwise |CREDIT_CARD_EXP_4_DIGIT_YEAR|.
ServerFieldType GetExpirationYearType() const;
const AutofillField* cardholder_; // Optional.
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
......@@ -45,20 +46,20 @@ class CreditCardField : public FormField {
// 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.)
const AutofillField* cardholder_last_;
AutofillField* cardholder_last_;
// TODO(jhawkins): Parse the select control.
const AutofillField* type_; // Optional.
const AutofillField* number_; // Required.
AutofillField* type_; // Optional.
std::vector<AutofillField*> numbers_; // Required.
// The 3-digit card verification number; we don't currently fill this.
const AutofillField* verification_;
AutofillField* verification_;
// Either |expiration_date_| or both |expiration_month_| and
// |expiration_year_| are required.
const AutofillField* expiration_month_;
const AutofillField* expiration_year_;
const AutofillField* expiration_date_;
AutofillField* expiration_month_;
AutofillField* expiration_year_;
AutofillField* expiration_date_;
// For combined expiration field having year as 2-digits we store here
// |CREDIT_CARD_EXP_DATE_2_DIGIT_YEAR|; otherwise we store
......
......@@ -21,7 +21,7 @@ class CreditCardFieldTest : public testing::Test {
virtual ~CreditCardFieldTest() {}
protected:
ScopedVector<const AutofillField> list_;
ScopedVector<AutofillField> list_;
scoped_ptr<const CreditCardField> field_;
ServerFieldTypeMap field_type_map_;
......@@ -380,4 +380,116 @@ TEST_F(CreditCardFieldTest, ParseCreditCardExpYear_2DigitMaxLength) {
field_type_map_[ASCIIToUTF16("year")]);
}
TEST_F(CreditCardFieldTest, ParseCreditCardNumberWithSplit) {
FormFieldData field;
field.form_control_type = "text";
field.label = ASCIIToUTF16("Card Number");
field.name = ASCIIToUTF16("card_number_q1");
field.max_length = 4;
list_.push_back(new AutofillField(field, ASCIIToUTF16("number1")));
field.label = ASCIIToUTF16("Card Number");
field.name = ASCIIToUTF16("card_number_q2");
field.max_length = 4;
list_.push_back(new AutofillField(field, ASCIIToUTF16("number2")));
field.label = ASCIIToUTF16("Card Number");
field.name = ASCIIToUTF16("card_number_q3");
field.max_length = 4;
list_.push_back(new AutofillField(field, ASCIIToUTF16("number3")));
// For last credit card number input field it simply ignores the |max_length|
// attribute. So even having a very big number, does not conside it an invalid
// split for autofilling.
field.label = ASCIIToUTF16("Card Number");
field.name = ASCIIToUTF16("card_number_q4");
field.max_length = 20;
list_.push_back(new AutofillField(field, ASCIIToUTF16("number4")));
field.label = ASCIIToUTF16("Exp Month");
field.name = ASCIIToUTF16("ccmonth");
list_.push_back(new AutofillField(field, ASCIIToUTF16("month5")));
field.label = ASCIIToUTF16("Exp Year");
field.name = ASCIIToUTF16("ccyear");
list_.push_back(new AutofillField(field, ASCIIToUTF16("year6")));
Parse();
ASSERT_NE(static_cast<CreditCardField*>(NULL), field_.get());
EXPECT_TRUE(ClassifyField());
ASSERT_TRUE(field_type_map_.find(ASCIIToUTF16("number1")) !=
field_type_map_.end());
EXPECT_EQ(CREDIT_CARD_NUMBER, field_type_map_[ASCIIToUTF16("number1")]);
EXPECT_EQ(0U, list_[0]->credit_card_number_offset());
ASSERT_TRUE(field_type_map_.find(ASCIIToUTF16("number2")) !=
field_type_map_.end());
EXPECT_EQ(CREDIT_CARD_NUMBER, field_type_map_[ASCIIToUTF16("number2")]);
EXPECT_EQ(4U, list_[1]->credit_card_number_offset());
ASSERT_TRUE(field_type_map_.find(ASCIIToUTF16("number3")) !=
field_type_map_.end());
EXPECT_EQ(CREDIT_CARD_NUMBER, field_type_map_[ASCIIToUTF16("number3")]);
EXPECT_EQ(8U, list_[2]->credit_card_number_offset());
ASSERT_TRUE(field_type_map_.find(ASCIIToUTF16("number4")) !=
field_type_map_.end());
EXPECT_EQ(CREDIT_CARD_NUMBER, field_type_map_[ASCIIToUTF16("number4")]);
EXPECT_EQ(12U, list_[3]->credit_card_number_offset());
ASSERT_TRUE(field_type_map_.find(ASCIIToUTF16("month5")) !=
field_type_map_.end());
EXPECT_EQ(CREDIT_CARD_EXP_MONTH, field_type_map_[ASCIIToUTF16("month5")]);
ASSERT_TRUE(field_type_map_.find(ASCIIToUTF16("year6")) !=
field_type_map_.end());
EXPECT_EQ(CREDIT_CARD_EXP_4_DIGIT_YEAR,
field_type_map_[ASCIIToUTF16("year6")]);
}
TEST_F(CreditCardFieldTest, ParseCreditCardNumberWithInvalidSplit) {
FormFieldData field;
field.form_control_type = "text";
field.label = ASCIIToUTF16("Name on Card");
field.name = ASCIIToUTF16("name_on_card");
list_.push_back(new AutofillField(field, ASCIIToUTF16("name1")));
field.label = ASCIIToUTF16("Card Number");
field.name = ASCIIToUTF16("card_number");
list_.push_back(new AutofillField(field, ASCIIToUTF16("number2")));
field.label = ASCIIToUTF16("Not Card Number");
field.name = ASCIIToUTF16("not_card_number");
list_.push_back(new AutofillField(field, ASCIIToUTF16("number3")));
field.label = ASCIIToUTF16("Exp Month");
field.name = ASCIIToUTF16("ccmonth");
list_.push_back(new AutofillField(field, ASCIIToUTF16("month4")));
field.label = ASCIIToUTF16("Exp Year");
field.name = ASCIIToUTF16("ccyear");
list_.push_back(new AutofillField(field, ASCIIToUTF16("year5")));
Parse();
ASSERT_NE(static_cast<CreditCardField*>(NULL), field_.get());
EXPECT_TRUE(ClassifyField());
ASSERT_TRUE(field_type_map_.find(ASCIIToUTF16("name1")) !=
field_type_map_.end());
EXPECT_EQ(CREDIT_CARD_NAME, field_type_map_[ASCIIToUTF16("name1")]);
ASSERT_TRUE(field_type_map_.find(ASCIIToUTF16("number2")) ==
field_type_map_.end());
ASSERT_TRUE(field_type_map_.find(ASCIIToUTF16("number3")) ==
field_type_map_.end());
ASSERT_TRUE(field_type_map_.find(ASCIIToUTF16("month4")) !=
field_type_map_.end());
EXPECT_EQ(CREDIT_CARD_EXP_MONTH, field_type_map_[ASCIIToUTF16("month4")]);
ASSERT_TRUE(field_type_map_.find(ASCIIToUTF16("year5")) !=
field_type_map_.end());
EXPECT_EQ(CREDIT_CARD_EXP_4_DIGIT_YEAR,
field_type_map_[ASCIIToUTF16("year5")]);
}
} // namespace autofill
......@@ -13,7 +13,7 @@ namespace autofill {
// static
FormField* EmailField::Parse(AutofillScanner* scanner) {
const AutofillField* field;
AutofillField* field;
if (ParseFieldSpecifics(scanner, base::UTF8ToUTF16(autofill::kEmailRe),
MATCH_DEFAULT | MATCH_EMAIL, &field)) {
return new EmailField(field);
......
......@@ -37,7 +37,7 @@ bool IsCheckable(const AutofillField* field) {
void FormField::ParseFormFields(const std::vector<AutofillField*>& fields,
ServerFieldTypeMap* map) {
// Set up a working copy of the fields to be processed.
std::vector<const AutofillField*> remaining_fields(fields.size());
std::vector<AutofillField*> remaining_fields(fields.size());
std::copy(fields.begin(), fields.end(), remaining_fields.begin());
// Ignore checkable fields as they interfere with parsers assuming context.
......@@ -67,7 +67,7 @@ void FormField::ParseFormFields(const std::vector<AutofillField*>& fields,
// static
bool FormField::ParseField(AutofillScanner* scanner,
const base::string16& pattern,
const AutofillField** match) {
AutofillField** match) {
return ParseFieldSpecifics(scanner, pattern, MATCH_DEFAULT, match);
}
......@@ -75,7 +75,7 @@ bool FormField::ParseField(AutofillScanner* scanner,
bool FormField::ParseFieldSpecifics(AutofillScanner* scanner,
const base::string16& pattern,
int match_type,
const AutofillField** match) {
AutofillField** match) {
if (scanner->IsEnd())
return false;
......@@ -89,7 +89,7 @@ bool FormField::ParseFieldSpecifics(AutofillScanner* scanner,
// static
bool FormField::ParseEmptyLabel(AutofillScanner* scanner,
const AutofillField** match) {
AutofillField** match) {
return ParseFieldSpecifics(scanner,
base::ASCIIToUTF16("^$"),
MATCH_LABEL | MATCH_ALL_INPUTS,
......@@ -111,8 +111,8 @@ bool FormField::AddClassification(const AutofillField* field,
bool FormField::MatchAndAdvance(AutofillScanner* scanner,
const base::string16& pattern,
int match_type,
const AutofillField** match) {
const AutofillField* field = scanner->Cursor();
AutofillField** match) {
AutofillField* field = scanner->Cursor();
if (FormField::Match(field, pattern, match_type)) {
if (match)
*match = field;
......@@ -147,10 +147,10 @@ bool FormField::Match(const AutofillField* field,
// static
void FormField::ParseFormFieldsPass(ParseFunction parse,
std::vector<const AutofillField*>* fields,
std::vector<AutofillField*>* fields,
ServerFieldTypeMap* map) {
// Store unmatched fields for further processing by the caller.
std::vector<const AutofillField*> remaining_fields;
std::vector<AutofillField*> remaining_fields;
AutofillScanner scanner(*fields);
while (!scanner.IsEnd()) {
......
......@@ -59,7 +59,7 @@ class FormField {
// success and fills |match| with a pointer to the field.
static bool ParseField(AutofillScanner* scanner,
const base::string16& pattern,
const AutofillField** match);
AutofillField** match);
// Parses the stream of fields in |scanner| with regular expression |pattern|
// as specified in the |match_type| bit field (see |MatchType|). If |match|
......@@ -69,12 +69,11 @@ class FormField {
static bool ParseFieldSpecifics(AutofillScanner* scanner,
const base::string16& pattern,
int match_type,
const AutofillField** match);
AutofillField** match);
// Attempts to parse a field with an empty label. Returns true
// on success and fills |match| with a pointer to the field.
static bool ParseEmptyLabel(AutofillScanner* scanner,
const AutofillField** match);
static bool ParseEmptyLabel(AutofillScanner* scanner, AutofillField** match);
// Adds an association between a field and a type to |map|.
static bool AddClassification(const AutofillField* field,
......@@ -101,7 +100,7 @@ class FormField {
static bool MatchAndAdvance(AutofillScanner* scanner,
const base::string16& pattern,
int match_type,
const AutofillField** match);
AutofillField** match);
// Matches the regular expression |pattern| against the components of |field|
// as specified in the |match_type| bit field (see |MatchType|).
......@@ -115,7 +114,7 @@ class FormField {
// holds any remaining unclassified fields for further processing.
// Classification results of the processed fields are stored in |map|.
static void ParseFormFieldsPass(ParseFunction parse,
std::vector<const AutofillField*>* fields,
std::vector<AutofillField*>* fields,
ServerFieldTypeMap* map);
// Returns true iff |type| matches |match_type|.
......
......@@ -28,9 +28,9 @@ class FullNameField : public NameField {
virtual bool ClassifyField(ServerFieldTypeMap* map) const OVERRIDE;
private:
explicit FullNameField(const AutofillField* field);
explicit FullNameField(AutofillField* field);
const AutofillField* field_;
AutofillField* field_;
DISALLOW_COPY_AND_ASSIGN(FullNameField);
};
......@@ -49,9 +49,9 @@ class FirstLastNameField : public NameField {
private:
FirstLastNameField();
const AutofillField* first_name_;
const AutofillField* middle_name_; // Optional.
const AutofillField* last_name_;
AutofillField* first_name_;
AutofillField* middle_name_; // Optional.
AutofillField* last_name_;
bool middle_initial_; // True if middle_name_ is a middle initial.
DISALLOW_COPY_AND_ASSIGN(FirstLastNameField);
......@@ -87,7 +87,7 @@ FullNameField* FullNameField::Parse(AutofillScanner* scanner) {
// Searching for any label containing the word "name" is too general;
// for example, Travelocity_Edit travel profile.html contains a field
// "Travel Profile Name".
const AutofillField* field = NULL;
AutofillField* field = NULL;
if (ParseField(scanner, UTF8ToUTF16(autofill::kNameRe), &field))
return new FullNameField(field);
......@@ -98,8 +98,7 @@ bool FullNameField::ClassifyField(ServerFieldTypeMap* map) const {
return AddClassification(field_, NAME_FULL, map);
}
FullNameField::FullNameField(const AutofillField* field)
: field_(field) {
FullNameField::FullNameField(AutofillField* field) : field_(field) {
}
FirstLastNameField* FirstLastNameField::ParseSpecificName(
......@@ -109,7 +108,7 @@ FirstLastNameField* FirstLastNameField::ParseSpecificName(
scoped_ptr<FirstLastNameField> v(new FirstLastNameField);
scanner->SaveCursor();
const AutofillField* next = NULL;
AutofillField* next = NULL;
if (ParseField(scanner,
UTF8ToUTF16(autofill::kNameSpecificRe), &v->first_name_) &&
ParseEmptyLabel(scanner, &next)) {
......
......@@ -20,7 +20,7 @@ class NameFieldTest : public testing::Test {
NameFieldTest() {}
protected:
ScopedVector<const AutofillField> list_;
ScopedVector<AutofillField> list_;
scoped_ptr<NameField> field_;
ServerFieldTypeMap field_type_map_;
......
......@@ -125,7 +125,7 @@ FormField* PhoneField::Parse(AutofillScanner* scanner) {
scanner->SaveCursor();
// The form owns the following variables, so they should not be deleted.
const AutofillField* parsed_fields[FIELD_MAX];
AutofillField* parsed_fields[FIELD_MAX];
for (size_t i = 0; i < arraysize(kPhoneFieldGrammars); ++i) {
memset(parsed_fields, 0, sizeof(parsed_fields));
......
......@@ -83,7 +83,7 @@ class PhoneField : public FormField {
// FIELD_PHONE is always present; holds suffix if prefix is present.
// The rest could be NULL.
const AutofillField* parsed_phone_fields_[FIELD_MAX];
AutofillField* parsed_phone_fields_[FIELD_MAX];
DISALLOW_COPY_AND_ASSIGN(PhoneField);
};
......
......@@ -20,7 +20,7 @@ class PhoneFieldTest : public testing::Test {
PhoneFieldTest() {}
protected:
ScopedVector<const AutofillField> list_;
ScopedVector<AutofillField> list_;
scoped_ptr<PhoneField> field_;
ServerFieldTypeMap field_type_map_;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment