Commit f1b689af authored by Mariia Shvedchenko's avatar Mariia Shvedchenko Committed by Commit Bot

[Autofill] Returns all patterns that match given language and fieldtype.

This CL provides new structure MatchingPattern that replace using
single regular expressions, but store more information about concret
pattern. Also it contains splitted MatchType into MactchFieldTypes
and MatchAttributes and sceleton of PatternProvider class.


Change-Id: I5acebf12aafaca67ae87260b2c897bdf35a38bea
Bug: 1121990
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2385282Reviewed-by: default avatarChristoph Schwering <schwering@google.com>
Reviewed-by: default avatarMatthias Körber <koerber@google.com>
Commit-Queue: Mariia Shvedchenko <mariiash@google.com>
Cr-Commit-Position: refs/heads/master@{#806125}
parent 6950e600
...@@ -123,6 +123,8 @@ static_library("browser") { ...@@ -123,6 +123,8 @@ static_library("browser") {
"form_data_importer.h", "form_data_importer.h",
"form_parsing/address_field.cc", "form_parsing/address_field.cc",
"form_parsing/address_field.h", "form_parsing/address_field.h",
"form_parsing/autofill_parsing_utils.cc",
"form_parsing/autofill_parsing_utils.h",
"form_parsing/autofill_scanner.cc", "form_parsing/autofill_scanner.cc",
"form_parsing/autofill_scanner.h", "form_parsing/autofill_scanner.h",
"form_parsing/credit_card_field.cc", "form_parsing/credit_card_field.cc",
...@@ -181,6 +183,8 @@ static_library("browser") { ...@@ -181,6 +183,8 @@ static_library("browser") {
"metrics/form_event_logger_base.cc", "metrics/form_event_logger_base.cc",
"metrics/form_event_logger_base.h", "metrics/form_event_logger_base.h",
"metrics/form_events.h", "metrics/form_events.h",
"pattern_provider/pattern_provider.cc",
"pattern_provider/pattern_provider.h",
"payments/account_info_getter.h", "payments/account_info_getter.h",
"payments/autofill_offer_manager.cc", "payments/autofill_offer_manager.cc",
"payments/autofill_offer_manager.h", "payments/autofill_offer_manager.h",
...@@ -612,6 +616,7 @@ source_set("unit_tests") { ...@@ -612,6 +616,7 @@ source_set("unit_tests") {
"logging/log_buffer_submitter_unittest.cc", "logging/log_buffer_submitter_unittest.cc",
"logging/log_manager_unittest.cc", "logging/log_manager_unittest.cc",
"logging/log_router_unittest.cc", "logging/log_router_unittest.cc",
"pattern_provider/pattern_provider_unittest.cc",
"payments/credit_card_access_manager_unittest.cc", "payments/credit_card_access_manager_unittest.cc",
"payments/credit_card_cvc_authenticator_unittest.cc", "payments/credit_card_cvc_authenticator_unittest.cc",
"payments/credit_card_save_manager_unittest.cc", "payments/credit_card_save_manager_unittest.cc",
......
// Copyright 2020 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "components/autofill/core/browser/form_parsing/autofill_parsing_utils.h"
namespace autofill {
MatchingPattern::MatchingPattern() = default;
MatchingPattern::MatchingPattern(const MatchingPattern& mp) = default;
MatchingPattern& MatchingPattern::operator=(const MatchingPattern& mp) =
default;
MatchingPattern::~MatchingPattern() = default;
autofill::MatchingPattern GetCompanyPatternEn() {
autofill::MatchingPattern m_p;
m_p.pattern_identifier = "kCompanyPatternEn";
m_p.positive_pattern = "company|business|organization|organisation";
m_p.positive_score = 1.1f;
m_p.negative_pattern = "";
m_p.match_field_attributes = autofill::MATCH_NAME;
m_p.match_field_input_types = autofill::MATCH_TEXT;
m_p.language = "en";
return m_p;
}
autofill::MatchingPattern GetCompanyPatternDe() {
autofill::MatchingPattern m_p;
m_p.pattern_identifier = "kCompanyPatternDe";
m_p.positive_pattern = "|(?<!con)firma|firmenname";
m_p.positive_score = 1.1f;
m_p.negative_pattern = "";
m_p.match_field_attributes = autofill::MATCH_LABEL | autofill::MATCH_NAME;
m_p.match_field_input_types = autofill::MATCH_TEXT;
m_p.language = "de";
return m_p;
}
} // namespace autofill
\ No newline at end of file
// Copyright 2020 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef COMPONENTS_AUTOFILL_CORE_BROWSER_FORM_PARSING_AUTOFILL_PARSING_UTILS_H_
#define COMPONENTS_AUTOFILL_CORE_BROWSER_FORM_PARSING_AUTOFILL_PARSING_UTILS_H_
#include <string>
namespace autofill {
// A bit-field used for matching specific parts of a field in question.
// Attributes.
enum MatchAttributes {
MATCH_LABEL = 1 << 0,
MATCH_NAME = 1 << 1,
MATCH_ATTRIBUTES_DEFAULT = MATCH_LABEL | MATCH_NAME,
};
// A bit-field used for matching specific parts of a field in question.
// Input types.
enum MatchFieldTypes {
MATCH_TEXT = 1 << 2,
MATCH_EMAIL = 1 << 3,
MATCH_TELEPHONE = 1 << 4,
MATCH_SELECT = 1 << 5,
MATCH_TEXT_AREA = 1 << 6,
MATCH_PASSWORD = 1 << 7,
MATCH_NUMBER = 1 << 8,
MATCH_SEARCH = 1 << 9,
MATCH_ALL_INPUTS = MATCH_TEXT | MATCH_EMAIL | MATCH_TELEPHONE | MATCH_SELECT |
MATCH_TEXT_AREA | MATCH_PASSWORD | MATCH_NUMBER |
MATCH_SEARCH,
// By default match label and name for input/text types.
MATCH_INPUTS_DEFAULT = MATCH_TEXT,
};
constexpr int MATCH_DEFAULT = MATCH_ATTRIBUTES_DEFAULT | MATCH_INPUTS_DEFAULT;
// Structure for a better organization of data and regular expressions
// for autofill regex_constants. In the future, to implement faster
// changes without global updates also for having a quick possibility
// to recognize incorrect matches.
struct MatchingPattern {
MatchingPattern();
MatchingPattern(const MatchingPattern& mp);
MatchingPattern& operator=(const MatchingPattern& mp);
~MatchingPattern();
std::string pattern_identifier;
std::string positive_pattern;
float positive_score = 1.1f;
std::string negative_pattern;
int match_field_attributes;
int match_field_input_types;
std::string language;
};
// Use these functions instead of storing "non standats type" constants that
// bots might complaining over.
MatchingPattern GetCompanyPatternEn();
MatchingPattern GetCompanyPatternDe();
} // namespace autofill
#endif // COMPONENTS_AUTOFILL_CORE_BROWSER_DATA_MODEL_AUTOFILL_PARSING_UTILS_H_
...@@ -159,10 +159,10 @@ bool FormField::ParseField(AutofillScanner* scanner, ...@@ -159,10 +159,10 @@ bool FormField::ParseField(AutofillScanner* scanner,
return ParseFieldSpecifics(scanner, pattern, MATCH_DEFAULT, match, logging); return ParseFieldSpecifics(scanner, pattern, MATCH_DEFAULT, match, logging);
} }
// static
bool FormField::ParseFieldSpecifics(AutofillScanner* scanner, bool FormField::ParseFieldSpecifics(AutofillScanner* scanner,
const base::string16& pattern, const base::string16& pattern,
int match_type, int match_field_attributes,
int match_field_input_types,
AutofillField** match, AutofillField** match,
const RegExLogging& logging) { const RegExLogging& logging) {
if (scanner->IsEnd()) if (scanner->IsEnd())
...@@ -170,10 +170,25 @@ bool FormField::ParseFieldSpecifics(AutofillScanner* scanner, ...@@ -170,10 +170,25 @@ bool FormField::ParseFieldSpecifics(AutofillScanner* scanner,
const AutofillField* field = scanner->Cursor(); const AutofillField* field = scanner->Cursor();
if (!MatchesFormControlType(field->form_control_type, match_type)) if (!MatchesFormControlType(field->form_control_type,
match_field_input_types))
return false; return false;
return MatchAndAdvance(scanner, pattern, match_type, match, logging); return MatchAndAdvance(scanner, pattern, match_field_attributes,
match_field_input_types, match, logging);
}
// static
bool FormField::ParseFieldSpecifics(AutofillScanner* scanner,
const base::string16& pattern,
int match_type,
AutofillField** match,
const RegExLogging& logging) {
int match_field_attributes = match_type & 0b11;
int match_field_types = match_type & ~0b11;
return ParseFieldSpecifics(scanner, pattern, match_field_attributes,
match_field_types, match, logging);
} }
// static // static
...@@ -196,14 +211,15 @@ void FormField::AddClassification(const AutofillField* field, ...@@ -196,14 +211,15 @@ void FormField::AddClassification(const AutofillField* field,
candidates.AddFieldCandidate(type, score); candidates.AddFieldCandidate(type, score);
} }
// static.
bool FormField::MatchAndAdvance(AutofillScanner* scanner, bool FormField::MatchAndAdvance(AutofillScanner* scanner,
const base::string16& pattern, const base::string16& pattern,
int match_type, int match_field_attributes,
int match_field_input_types,
AutofillField** match, AutofillField** match,
const RegExLogging& logging) { const RegExLogging& logging) {
AutofillField* field = scanner->Cursor(); AutofillField* field = scanner->Cursor();
if (FormField::Match(field, pattern, match_type, logging)) { if (FormField::Match(field, pattern, match_field_attributes,
match_field_input_types, logging)) {
if (match) if (match)
*match = field; *match = field;
scanner->Advance(); scanner->Advance();
...@@ -213,22 +229,35 @@ bool FormField::MatchAndAdvance(AutofillScanner* scanner, ...@@ -213,22 +229,35 @@ bool FormField::MatchAndAdvance(AutofillScanner* scanner,
return false; return false;
} }
// static // static.
bool FormField::MatchAndAdvance(AutofillScanner* scanner,
const base::string16& pattern,
int match_type,
AutofillField** match,
const RegExLogging& logging) {
int match_field_attributes = match_type & 0b11;
int match_field_types = match_type & ~0b11;
return MatchAndAdvance(scanner, pattern, match_field_attributes,
match_field_types, match, logging);
}
bool FormField::Match(const AutofillField* field, bool FormField::Match(const AutofillField* field,
const base::string16& pattern, const base::string16& pattern,
int match_type, int match_field_attributes,
int match_field_input_types,
const RegExLogging& logging) { const RegExLogging& logging) {
bool found_match = false; bool found_match = false;
base::StringPiece match_type_string; base::StringPiece match_type_string;
base::StringPiece16 value; base::StringPiece16 value;
base::string16 match; base::string16 match;
if ((match_type & FormField::MATCH_LABEL) && if ((match_field_attributes & MATCH_LABEL) &&
MatchesPattern(field->label, pattern, &match)) { MatchesPattern(field->label, pattern, &match)) {
found_match = true; found_match = true;
match_type_string = "Match in label"; match_type_string = "Match in label";
value = field->label; value = field->label;
} else if ((match_type & FormField::MATCH_NAME) && } else if ((match_field_attributes & MATCH_NAME) &&
MatchesPattern(field->parseable_name(), pattern, &match)) { MatchesPattern(field->parseable_name(), pattern, &match)) {
found_match = true; found_match = true;
match_type_string = "Match in name"; match_type_string = "Match in name";
...@@ -251,6 +280,18 @@ bool FormField::Match(const AutofillField* field, ...@@ -251,6 +280,18 @@ bool FormField::Match(const AutofillField* field,
return found_match; return found_match;
} }
// static
bool FormField::Match(const AutofillField* field,
const base::string16& pattern,
int match_type,
const RegExLogging& logging) {
int match_field_attributes = match_type & 0b11;
int match_field_types = match_type & ~0b11;
return Match(field, pattern, match_field_attributes, match_field_types,
logging);
}
// static // static
void FormField::ParseFormFieldsPass(ParseFunction parse, void FormField::ParseFormFieldsPass(ParseFunction parse,
const std::vector<AutofillField*>& fields, const std::vector<AutofillField*>& fields,
......
...@@ -12,6 +12,7 @@ ...@@ -12,6 +12,7 @@
#include "base/macros.h" #include "base/macros.h"
#include "base/strings/string16.h" #include "base/strings/string16.h"
#include "components/autofill/core/browser/field_types.h" #include "components/autofill/core/browser/field_types.h"
#include "components/autofill/core/browser/form_parsing/autofill_parsing_utils.h"
#include "components/autofill/core/browser/form_parsing/field_candidates.h" #include "components/autofill/core/browser/form_parsing/field_candidates.h"
namespace autofill { namespace autofill {
...@@ -45,29 +46,6 @@ class FormField { ...@@ -45,29 +46,6 @@ class FormField {
LogManager* log_manager = nullptr); LogManager* log_manager = nullptr);
protected: protected:
// A bit-field used for matching specific parts of a field in question.
enum MatchType {
// Attributes.
MATCH_LABEL = 1 << 0,
MATCH_NAME = 1 << 1,
// Input types.
MATCH_TEXT = 1 << 2,
MATCH_EMAIL = 1 << 3,
MATCH_TELEPHONE = 1 << 4,
MATCH_SELECT = 1 << 5,
MATCH_TEXT_AREA = 1 << 6,
MATCH_PASSWORD = 1 << 7,
MATCH_NUMBER = 1 << 8,
MATCH_SEARCH = 1 << 9,
MATCH_ALL_INPUTS = MATCH_TEXT | MATCH_EMAIL | MATCH_TELEPHONE |
MATCH_SELECT | MATCH_TEXT_AREA | MATCH_PASSWORD |
MATCH_NUMBER | MATCH_SEARCH,
// By default match label and name for input/text types.
MATCH_DEFAULT = MATCH_LABEL | MATCH_NAME | MATCH_TEXT,
};
// Initial values assigned to FieldCandidates by their corresponding parsers. // Initial values assigned to FieldCandidates by their corresponding parsers.
static const float kBaseEmailParserScore; static const float kBaseEmailParserScore;
static const float kBasePhoneParserScore; static const float kBasePhoneParserScore;
...@@ -99,6 +77,15 @@ class FormField { ...@@ -99,6 +77,15 @@ class FormField {
AutofillField** match, AutofillField** match,
const RegExLogging& logging = {}); const RegExLogging& logging = {});
// The same as ParseFieldSpecifics but with splitted match_types into
// MatchAttributes and MatchFieldTypes.
static bool ParseFieldSpecifics(AutofillScanner* scanner,
const base::string16& pattern,
int match_field_attributes,
int match_field_input_types,
AutofillField** match,
const RegExLogging& logging = {});
// Attempts to parse a field with an empty label. Returns true // Attempts to parse a field with an empty label. Returns true
// on success and fills |match| with a pointer to the field. // on success and fills |match| with a pointer to the field.
static bool ParseEmptyLabel(AutofillScanner* scanner, AutofillField** match); static bool ParseEmptyLabel(AutofillScanner* scanner, AutofillField** match);
...@@ -139,13 +126,30 @@ class FormField { ...@@ -139,13 +126,30 @@ class FormField {
AutofillField** match, AutofillField** match,
const RegExLogging& logging = {}); const RegExLogging& logging = {});
// Matches the regular expression |pattern| against the components of |field| // The same as MatchAndAdvance but with splitted match_types into
// as specified in the |match_type| bit field (see |MatchType|). // MatchAttributes and MatchFieldTypes.
static bool MatchAndAdvance(AutofillScanner* scanner,
const base::string16& pattern,
int match_field_attributes,
int match_field_input_types,
AutofillField** match,
const RegExLogging& logging = {});
// Matches the regular expression |pattern| against the components of
// |field| as specified in the |match_type| bit field (see |MatchType|).
static bool Match(const AutofillField* field, static bool Match(const AutofillField* field,
const base::string16& pattern, const base::string16& pattern,
int match_type, int match_type,
const RegExLogging& logging = {}); const RegExLogging& logging = {});
// The same as Match but with splitted match_types into MatchAttributes
// and MatchFieldTypes.
static bool Match(const AutofillField* field,
const base::string16& pattern,
int match_field_attributes,
int match_field_input_types,
const RegExLogging& logging = {});
// Perform a "pass" over the |fields| where each pass uses the supplied // Perform a "pass" over the |fields| where each pass uses the supplied
// |parse| method to match content to a given field type. // |parse| method to match content to a given field type.
// |fields| is both an input and an output parameter. Upon exit |fields| // |fields| is both an input and an output parameter. Upon exit |fields|
......
...@@ -23,109 +23,91 @@ TEST(FormFieldTest, Match) { ...@@ -23,109 +23,91 @@ TEST(FormFieldTest, Match) {
AutofillField field; AutofillField field;
// Empty strings match. // Empty strings match.
EXPECT_TRUE( EXPECT_TRUE(FormField::Match(&field, base::string16(), MATCH_LABEL));
FormField::Match(&field, base::string16(), FormField::MATCH_LABEL));
// Empty pattern matches non-empty string. // Empty pattern matches non-empty string.
field.label = ASCIIToUTF16("a"); field.label = ASCIIToUTF16("a");
EXPECT_TRUE( EXPECT_TRUE(FormField::Match(&field, base::string16(), MATCH_LABEL));
FormField::Match(&field, base::string16(), FormField::MATCH_LABEL));
// Strictly empty pattern matches empty string. // Strictly empty pattern matches empty string.
field.label = base::string16(); field.label = base::string16();
EXPECT_TRUE( EXPECT_TRUE(FormField::Match(&field, ASCIIToUTF16("^$"), MATCH_LABEL));
FormField::Match(&field, ASCIIToUTF16("^$"), FormField::MATCH_LABEL));
// Strictly empty pattern does not match non-empty string. // Strictly empty pattern does not match non-empty string.
field.label = ASCIIToUTF16("a"); field.label = ASCIIToUTF16("a");
EXPECT_FALSE( EXPECT_FALSE(FormField::Match(&field, ASCIIToUTF16("^$"), MATCH_LABEL));
FormField::Match(&field, ASCIIToUTF16("^$"), FormField::MATCH_LABEL));
// Non-empty pattern doesn't match empty string. // Non-empty pattern doesn't match empty string.
field.label = base::string16(); field.label = base::string16();
EXPECT_FALSE( EXPECT_FALSE(FormField::Match(&field, ASCIIToUTF16("a"), MATCH_LABEL));
FormField::Match(&field, ASCIIToUTF16("a"), FormField::MATCH_LABEL));
// Beginning of line. // Beginning of line.
field.label = ASCIIToUTF16("head_tail"); field.label = ASCIIToUTF16("head_tail");
EXPECT_TRUE( EXPECT_TRUE(FormField::Match(&field, ASCIIToUTF16("^head"), MATCH_LABEL));
FormField::Match(&field, ASCIIToUTF16("^head"), FormField::MATCH_LABEL)); EXPECT_FALSE(FormField::Match(&field, ASCIIToUTF16("^tail"), MATCH_LABEL));
EXPECT_FALSE(
FormField::Match(&field, ASCIIToUTF16("^tail"), FormField::MATCH_LABEL));
// End of line. // End of line.
field.label = ASCIIToUTF16("head_tail"); field.label = ASCIIToUTF16("head_tail");
EXPECT_FALSE( EXPECT_FALSE(FormField::Match(&field, ASCIIToUTF16("head$"), MATCH_LABEL));
FormField::Match(&field, ASCIIToUTF16("head$"), FormField::MATCH_LABEL)); EXPECT_TRUE(FormField::Match(&field, ASCIIToUTF16("tail$"), MATCH_LABEL));
EXPECT_TRUE(
FormField::Match(&field, ASCIIToUTF16("tail$"), FormField::MATCH_LABEL));
// Exact. // Exact.
field.label = ASCIIToUTF16("head_tail"); field.label = ASCIIToUTF16("head_tail");
EXPECT_FALSE( EXPECT_FALSE(FormField::Match(&field, ASCIIToUTF16("^head$"), MATCH_LABEL));
FormField::Match(&field, ASCIIToUTF16("^head$"), FormField::MATCH_LABEL)); EXPECT_FALSE(FormField::Match(&field, ASCIIToUTF16("^tail$"), MATCH_LABEL));
EXPECT_FALSE( EXPECT_TRUE(
FormField::Match(&field, ASCIIToUTF16("^tail$"), FormField::MATCH_LABEL)); FormField::Match(&field, ASCIIToUTF16("^head_tail$"), MATCH_LABEL));
EXPECT_TRUE(FormField::Match(&field, ASCIIToUTF16("^head_tail$"),
FormField::MATCH_LABEL));
// Escaped dots. // Escaped dots.
field.label = ASCIIToUTF16("m.i."); field.label = ASCIIToUTF16("m.i.");
// Note: This pattern is misleading as the "." characters are wild cards. // Note: This pattern is misleading as the "." characters are wild cards.
EXPECT_TRUE( EXPECT_TRUE(FormField::Match(&field, ASCIIToUTF16("m.i."), MATCH_LABEL));
FormField::Match(&field, ASCIIToUTF16("m.i."), FormField::MATCH_LABEL)); EXPECT_TRUE(FormField::Match(&field, ASCIIToUTF16("m\\.i\\."), MATCH_LABEL));
EXPECT_TRUE(FormField::Match(&field, ASCIIToUTF16("m\\.i\\."),
FormField::MATCH_LABEL));
field.label = ASCIIToUTF16("mXiX"); field.label = ASCIIToUTF16("mXiX");
EXPECT_TRUE( EXPECT_TRUE(FormField::Match(&field, ASCIIToUTF16("m.i."), MATCH_LABEL));
FormField::Match(&field, ASCIIToUTF16("m.i."), FormField::MATCH_LABEL)); EXPECT_FALSE(FormField::Match(&field, ASCIIToUTF16("m\\.i\\."), MATCH_LABEL));
EXPECT_FALSE(FormField::Match(&field, ASCIIToUTF16("m\\.i\\."),
FormField::MATCH_LABEL));
// Repetition. // Repetition.
field.label = ASCIIToUTF16("headtail"); field.label = ASCIIToUTF16("headtail");
EXPECT_TRUE(FormField::Match(&field, ASCIIToUTF16("head.*tail"), EXPECT_TRUE(
FormField::MATCH_LABEL)); FormField::Match(&field, ASCIIToUTF16("head.*tail"), MATCH_LABEL));
field.label = ASCIIToUTF16("headXtail"); field.label = ASCIIToUTF16("headXtail");
EXPECT_TRUE(FormField::Match(&field, ASCIIToUTF16("head.*tail"), EXPECT_TRUE(
FormField::MATCH_LABEL)); FormField::Match(&field, ASCIIToUTF16("head.*tail"), MATCH_LABEL));
field.label = ASCIIToUTF16("headXXXtail"); field.label = ASCIIToUTF16("headXXXtail");
EXPECT_TRUE(FormField::Match(&field, ASCIIToUTF16("head.*tail"), EXPECT_TRUE(
FormField::MATCH_LABEL)); FormField::Match(&field, ASCIIToUTF16("head.*tail"), MATCH_LABEL));
field.label = ASCIIToUTF16("headtail"); field.label = ASCIIToUTF16("headtail");
EXPECT_FALSE(FormField::Match(&field, ASCIIToUTF16("head.+tail"), EXPECT_FALSE(
FormField::MATCH_LABEL)); FormField::Match(&field, ASCIIToUTF16("head.+tail"), MATCH_LABEL));
field.label = ASCIIToUTF16("headXtail"); field.label = ASCIIToUTF16("headXtail");
EXPECT_TRUE(FormField::Match(&field, ASCIIToUTF16("head.+tail"), EXPECT_TRUE(
FormField::MATCH_LABEL)); FormField::Match(&field, ASCIIToUTF16("head.+tail"), MATCH_LABEL));
field.label = ASCIIToUTF16("headXXXtail"); field.label = ASCIIToUTF16("headXXXtail");
EXPECT_TRUE(FormField::Match(&field, ASCIIToUTF16("head.+tail"), EXPECT_TRUE(
FormField::MATCH_LABEL)); FormField::Match(&field, ASCIIToUTF16("head.+tail"), MATCH_LABEL));
// Alternation. // Alternation.
field.label = ASCIIToUTF16("head_tail"); field.label = ASCIIToUTF16("head_tail");
EXPECT_TRUE(FormField::Match(&field, ASCIIToUTF16("head|other"), EXPECT_TRUE(
FormField::MATCH_LABEL)); FormField::Match(&field, ASCIIToUTF16("head|other"), MATCH_LABEL));
EXPECT_TRUE(FormField::Match(&field, ASCIIToUTF16("tail|other"), EXPECT_TRUE(
FormField::MATCH_LABEL)); FormField::Match(&field, ASCIIToUTF16("tail|other"), MATCH_LABEL));
EXPECT_FALSE(FormField::Match(&field, ASCIIToUTF16("bad|good"), EXPECT_FALSE(FormField::Match(&field, ASCIIToUTF16("bad|good"), MATCH_LABEL));
FormField::MATCH_LABEL));
// Case sensitivity. // Case sensitivity.
field.label = ASCIIToUTF16("xxxHeAd_tAiLxxx"); field.label = ASCIIToUTF16("xxxHeAd_tAiLxxx");
EXPECT_TRUE(FormField::Match(&field, ASCIIToUTF16("head_tail"), EXPECT_TRUE(FormField::Match(&field, ASCIIToUTF16("head_tail"), MATCH_LABEL));
FormField::MATCH_LABEL));
// Word boundaries. // Word boundaries.
field.label = ASCIIToUTF16("contains word:"); field.label = ASCIIToUTF16("contains word:");
EXPECT_TRUE(FormField::Match(&field, ASCIIToUTF16("\\bword\\b"), EXPECT_TRUE(
FormField::MATCH_LABEL)); FormField::Match(&field, ASCIIToUTF16("\\bword\\b"), MATCH_LABEL));
EXPECT_FALSE(FormField::Match(&field, ASCIIToUTF16("\\bcon\\b"), EXPECT_FALSE(
FormField::MATCH_LABEL)); FormField::Match(&field, ASCIIToUTF16("\\bcon\\b"), MATCH_LABEL));
// Make sure the circumflex in 'crepe' is not treated as a word boundary. // Make sure the circumflex in 'crepe' is not treated as a word boundary.
field.label = base::UTF8ToUTF16("cr\xC3\xAApe"); field.label = base::UTF8ToUTF16("cr\xC3\xAApe");
EXPECT_FALSE(FormField::Match(&field, ASCIIToUTF16("\\bcr\\b"), EXPECT_FALSE(FormField::Match(&field, ASCIIToUTF16("\\bcr\\b"), MATCH_LABEL));
FormField::MATCH_LABEL));
} }
// Test that we ignore checkable elements. // Test that we ignore checkable elements.
......
// Copyright 2020 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "components/autofill/core/browser/pattern_provider/pattern_provider.h"
#include <algorithm>
#include <iostream>
#include <string>
#include "components/autofill/core/browser/autofill_type.h"
namespace autofill {
PatternProvider::PatternProvider(autofill::ServerFieldType type) {
autofill::MatchingPattern kCompanyPatternEn = autofill::GetCompanyPatternEn();
autofill::MatchingPattern kCompanyPatternDe = autofill::GetCompanyPatternDe();
patterns_[AutofillType(COMPANY_NAME).ToString()]["en"] = kCompanyPatternEn;
patterns_[AutofillType(COMPANY_NAME).ToString()]["de"] = kCompanyPatternDe;
}
PatternProvider::~PatternProvider() {
patterns_.clear();
}
autofill::MatchingPattern PatternProvider::GetSingleMatchPattern(
autofill::ServerFieldType type,
const std::string& page_language) {
base::StringPiece type_s = autofill::FieldTypeToStringPiece(type);
return patterns_[type_s.as_string()][page_language];
}
} // namespace autofill
// Copyright 2020 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef COMPONENTS_AUTOFILL_CORE_BROWSER_PATTERN_PROVIDER_PATTERN_PROVIDER_H_
#define COMPONENTS_AUTOFILL_CORE_BROWSER_PATTERN_PROVIDER_PATTERN_PROVIDER_H_
#include <string>
#include "base/macros.h"
#include "base/synchronization/lock.h"
#include "components/autofill/core/browser/field_types.h"
#include "components/autofill/core/browser/form_parsing/autofill_parsing_utils.h"
#include "components/autofill/core/common/autofill_regex_constants.h"
#include "third_party/re2/src/re2/re2.h"
namespace autofill {
class PatternProvider {
public:
PatternProvider();
PatternProvider(ServerFieldType type, const std::string& page_language);
explicit PatternProvider(ServerFieldType type);
~PatternProvider();
// Provides us with all patterns that can match our field type and page
// language.
const std::vector<MatchingPattern>& GetMatchPatterns(
ServerFieldType type,
const std::string& page_language);
const std::vector<MatchingPattern>& GetMatchPatterns(
const std::string& pattern_name,
const std::string& page_launguage);
// Provides us with all patterns that can match our field type.
const std::vector<MatchingPattern>& GetAllPatternsBaseOnType(
ServerFieldType type);
// Function that returns pattern that match our field type and page language.
MatchingPattern GetSingleMatchPattern(ServerFieldType type,
const std::string& page_language);
private:
// Func to sort the incoming map by score.
void SortPatternsByScore(std::vector<MatchingPattern>& patterns);
// Local map to store patterns keyed by field type and page language.
std::map<std::string, std::map<std::string, MatchingPattern>> patterns_;
};
} // namespace autofill
#endif // COMPONENTS_AUTOFILL_CORE_BROWSER_PATTERN_PROVIDER_PATTERN_PROVIDER_H_
\ No newline at end of file
// Copyright 2020 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "components/autofill/core/browser/pattern_provider/pattern_provider.h"
#include <stddef.h>
#include <map>
#include <string>
#include <vector>
#include "base/test/gtest_util.h"
#include "testing/gtest/include/gtest/gtest.h"
namespace autofill {
bool operator==(const MatchingPattern& mp1, const MatchingPattern& mp2) {
return (mp1.language == mp2.language &&
mp1.match_field_attributes == mp2.match_field_attributes &&
mp1.match_field_input_types == mp2.match_field_input_types &&
mp1.negative_pattern == mp2.negative_pattern &&
mp1.pattern_identifier == mp2.pattern_identifier &&
mp1.positive_pattern == mp2.positive_pattern &&
mp1.positive_score == mp2.positive_score);
}
TEST(AutofillPatternProvider, Single_Match) {
MatchingPattern kCompanyPatternEn = GetCompanyPatternEn();
MatchingPattern kCompanyPatternDe = GetCompanyPatternDe();
PatternProvider pattern_provider(COMPANY_NAME);
EXPECT_EQ(pattern_provider.GetSingleMatchPattern(COMPANY_NAME, "en"),
kCompanyPatternEn);
EXPECT_EQ(pattern_provider.GetSingleMatchPattern(COMPANY_NAME, "de"),
kCompanyPatternDe);
}
} // namespace autofill
\ No newline at end of file
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