Commit 8622737d authored by Guillaume Jenkins's avatar Guillaume Jenkins Committed by Commit Bot

[Autofill] Add Price field as heuristic type.

This adds a new unfillable field type, PRICE, to the heuristics. The
idea is that by adding more specific field types instead of using
UNKNOWN, it will help reduce cases where fields are detected as the
wrong type.

For example, go to https://cydemind.bandcamp.com/album/erosion and
click "Buy Digital Album". In the popup, there is a "Name your price"
input, which gets incorrectly detected as NAME_FIRST.

Bug: crbug.com/807748
Change-Id: I8ee3ddbf7bc6928817c7c886e8431a338db1b5b6
Reviewed-on: https://chromium-review.googlesource.com/c/1495200
Commit-Queue: Guillaume Jenkins <gujen@google.com>
Reviewed-by: default avatarSebastien Seguin-Gagnon <sebsg@chromium.org>
Reviewed-by: default avatarParastoo Geranmayeh <parastoog@google.com>
Cr-Commit-Position: refs/heads/master@{#636958}
parent 30bac9e8
......@@ -175,6 +175,8 @@ jumbo_static_library("browser") {
"phone_number_i18n.h",
"popup_item_ids.h",
"popup_types.h",
"price_field.cc",
"price_field.h",
"randomized_encoder.cc",
"randomized_encoder.h",
"rationalization_util.cc",
......@@ -560,6 +562,7 @@ source_set("unit_tests") {
"phone_field_unittest.cc",
"phone_number_i18n_unittest.cc",
"phone_number_unittest.cc",
"price_field_unittest.cc",
"proto/legacy_proto_bridge_unittest.cc",
"randomized_encoder_unittest.cc",
"rationalization_util_unittest.cc",
......
......@@ -116,6 +116,7 @@ FieldTypeGroup GroupTypeOfServerFieldType(ServerFieldType field_type) {
case USERNAME:
return USERNAME_FIELD;
case PRICE:
case SEARCH_TERM:
return UNFILLABLE;
......@@ -774,6 +775,8 @@ std::string AutofillType::ServerFieldTypeToString(ServerFieldType type) {
return "CONFIRMATION_PASSWORD";
case SEARCH_TERM:
return "SEARCH_TERM";
case PRICE:
return "PRICE";
case AMBIGUOUS_TYPE:
return "AMBIGUOUS_TYPE";
......
......@@ -169,9 +169,12 @@ enum ServerFieldType {
// Search term fields are detected, but not filled.
SEARCH_TERM = 97,
// Price fields are detected, but not filled.
PRICE = 98,
// No new types can be added without a corresponding change to the Autofill
// server.
MAX_VALID_FIELD_TYPE = 98,
MAX_VALID_FIELD_TYPE = 99,
};
// The list of all HTML autocomplete field type hints supported by Chrome.
......
......@@ -23,6 +23,7 @@
#include "components/autofill/core/browser/form_structure.h"
#include "components/autofill/core/browser/name_field.h"
#include "components/autofill/core/browser/phone_field.h"
#include "components/autofill/core/browser/price_field.h"
#include "components/autofill/core/browser/search_field.h"
#include "components/autofill/core/browser/travel_field.h"
#include "components/autofill/core/common/autofill_constants.h"
......@@ -39,6 +40,7 @@ const float FormField::kBasePhoneParserScore = 1.3f;
const float FormField::kBaseTravelParserScore = 1.2f;
const float FormField::kBaseAddressParserScore = 1.1f;
const float FormField::kBaseCreditCardParserScore = 1.0f;
const float FormField::kBasePriceParserScore = 0.95f;
const float FormField::kBaseNameParserScore = 0.9f;
const float FormField::kBaseSearchParserScore = 0.8f;
......@@ -82,6 +84,9 @@ FieldCandidatesMap FormField::ParseFormFields(
ParseFormFieldsPass(CreditCardField::Parse, processed_fields,
&field_candidates);
// Price pass.
ParseFormFieldsPass(PriceField::Parse, processed_fields, &field_candidates);
// Name pass.
ParseFormFieldsPass(NameField::Parse, processed_fields, &field_candidates);
......
......@@ -63,6 +63,7 @@ class FormField {
static const float kBaseTravelParserScore;
static const float kBaseAddressParserScore;
static const float kBaseCreditCardParserScore;
static const float kBasePriceParserScore;
static const float kBaseNameParserScore;
static const float kBaseSearchParserScore;
......
// Copyright 2019 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/price_field.h"
#include "base/strings/utf_string_conversions.h"
#include "components/autofill/core/browser/autofill_field.h"
#include "components/autofill/core/browser/autofill_scanner.h"
#include "components/autofill/core/common/autofill_regex_constants.h"
namespace autofill {
// static
std::unique_ptr<FormField> PriceField::Parse(AutofillScanner* scanner) {
AutofillField* field;
if (ParseFieldSpecifics(
scanner, base::UTF8ToUTF16(kPriceRe),
MATCH_DEFAULT | MATCH_NUMBER | MATCH_SELECT | MATCH_TEXT_AREA,
&field)) {
return std::make_unique<PriceField>(field);
}
return nullptr;
}
PriceField::PriceField(const AutofillField* field) : field_(field) {}
void PriceField::AddClassifications(
FieldCandidatesMap* field_candidates) const {
AddClassification(field_, PRICE, kBasePriceParserScore, field_candidates);
}
} // namespace autofill
// Copyright 2019 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_PRICE_FIELD_H_
#define COMPONENTS_AUTOFILL_CORE_BROWSER_PRICE_FIELD_H_
#include <memory>
#include "base/compiler_specific.h"
#include "base/macros.h"
#include "components/autofill/core/browser/form_field.h"
namespace autofill {
class AutofillField;
class AutofillScanner;
// Price fields are not filled by autofill, but identifying them will help to
// reduce the number of false positives.
class PriceField : public FormField {
public:
static std::unique_ptr<FormField> Parse(AutofillScanner* scanner);
PriceField(const AutofillField* field);
protected:
void AddClassifications(FieldCandidatesMap* field_candidates) const override;
private:
FRIEND_TEST_ALL_PREFIXES(PriceFieldTest, ParsePrice);
FRIEND_TEST_ALL_PREFIXES(PriceFieldTest, ParseNonPrice);
const AutofillField* field_;
DISALLOW_COPY_AND_ASSIGN(PriceField);
};
} // namespace autofill
#endif // COMPONENTS_AUTOFILL_CORE_BROWSER_PRICE_FIELD_H_
// Copyright 2018 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/price_field.h"
#include <memory>
#include <vector>
#include "base/macros.h"
#include "base/memory/ptr_util.h"
#include "base/strings/string16.h"
#include "base/strings/utf_string_conversions.h"
#include "components/autofill/core/browser/autofill_field.h"
#include "components/autofill/core/browser/autofill_scanner.h"
#include "components/autofill/core/common/form_field_data.h"
#include "testing/gtest/include/gtest/gtest.h"
using base::ASCIIToUTF16;
namespace autofill {
class PriceFieldTest : public testing::Test {
public:
PriceFieldTest() {}
protected:
std::vector<std::unique_ptr<AutofillField>> list_;
std::unique_ptr<PriceField> field_;
FieldCandidatesMap field_candidates_map_;
// Downcast for tests.
static std::unique_ptr<PriceField> Parse(AutofillScanner* scanner) {
std::unique_ptr<FormField> field = PriceField::Parse(scanner);
return std::unique_ptr<PriceField>(
static_cast<PriceField*>(field.release()));
}
private:
DISALLOW_COPY_AND_ASSIGN(PriceFieldTest);
};
TEST_F(PriceFieldTest, ParsePrice) {
FormFieldData price_field;
price_field.form_control_type = "text";
price_field.label = ASCIIToUTF16("name your price");
price_field.name = ASCIIToUTF16("userPrice");
list_.push_back(
std::make_unique<AutofillField>(price_field, ASCIIToUTF16("price1")));
AutofillScanner scanner(list_);
field_ = Parse(&scanner);
ASSERT_NE(nullptr, field_.get());
field_->AddClassifications(&field_candidates_map_);
ASSERT_TRUE(field_candidates_map_.find(ASCIIToUTF16("price1")) !=
field_candidates_map_.end());
EXPECT_EQ(PRICE,
field_candidates_map_[ASCIIToUTF16("price1")].BestHeuristicType());
}
TEST_F(PriceFieldTest, ParseNonPrice) {
FormFieldData address_field;
address_field.form_control_type = "text";
address_field.label = ASCIIToUTF16("Name");
address_field.name = ASCIIToUTF16("firstName");
list_.push_back(
std::make_unique<AutofillField>(address_field, ASCIIToUTF16("name1")));
AutofillScanner scanner(list_);
field_ = Parse(&scanner);
ASSERT_EQ(nullptr, field_.get());
}
} // namespace autofill
......@@ -5,6 +5,7 @@
#include "components/autofill/core/browser/search_field.h"
#include "base/strings/utf_string_conversions.h"
#include "components/autofill/core/browser/autofill_field.h"
#include "components/autofill/core/browser/autofill_scanner.h"
#include "components/autofill/core/common/autofill_regex_constants.h"
......@@ -14,7 +15,8 @@ namespace autofill {
std::unique_ptr<FormField> SearchField::Parse(AutofillScanner* scanner) {
AutofillField* field;
if (ParseFieldSpecifics(scanner, base::UTF8ToUTF16(kSearchTermRe),
MATCH_DEFAULT | MATCH_SEARCH, &field)) {
MATCH_DEFAULT | MATCH_SEARCH | MATCH_TEXT_AREA,
&field)) {
return std::make_unique<SearchField>(field);
}
......
......@@ -13,6 +13,9 @@
namespace autofill {
class AutofillField;
class AutofillScanner;
// Search fields are not filled by autofill, but identifying them will help
// to reduce the number of false positives.
class SearchField : public FormField {
......
......@@ -143,6 +143,15 @@ const char kSearchTermRe[] =
"|جستجو" // fa
"|искать|найти|поиск"; // ru
/////////////////////////////////////////////////////////////////////////////
// field_price.cc
/////////////////////////////////////////////////////////////////////////////
const char kPriceRe[] =
"\\bprice\\b|\\brate\\b|\\bcost\\b"
"قیمة‎|سعر‎" // ar
"قیمت" // fa
"|\\bprix\\b|\\bcoût\\b|\\bcout\\b|\\btarif\\b"; // fr-CA
/////////////////////////////////////////////////////////////////////////////
// credit_card_field.cc
/////////////////////////////////////////////////////////////////////////////
......
......@@ -60,6 +60,7 @@ extern const char kPassportRe[];
extern const char kTravelOriginRe[];
extern const char kTravelDestinationRe[];
extern const char kFlightRe[];
extern const char kPriceRe[];
// Used to match field data that might be a UPI Virtual Payment Address.
// See:
......
UNKNOWN_TYPE | ctl00$ContentPlaceHolder1$ddlCategory | My Query Relates to * | 0 | ctl00$ContentPlaceHolder1$ddlCategory_1-default
UNKNOWN_TYPE | ctl00$ContentPlaceHolder1$txtQueryl | Mention Your Query * | | ctl00$ContentPlaceHolder1$ddlCategory_1-default
SEARCH_TERM | ctl00$ContentPlaceHolder1$txtQueryl | Mention Your Query * | | ctl00$ContentPlaceHolder1$ddlCategory_1-default
NAME_FULL | ctl00$ContentPlaceHolder1$txtName | Name * | | ctl00$ContentPlaceHolder1$ddlCategory_1-default
EMAIL_ADDRESS | ctl00$ContentPlaceHolder1$txtEmail | Email ID * | | ctl00$ContentPlaceHolder1$ddlCategory_1-default
PHONE_HOME_WHOLE_NUMBER | ctl00$ContentPlaceHolder1$txtContact | Contact Number * | | ctl00$ContentPlaceHolder1$ddlCategory_1-default
PRICE | userPrice | Name your price: | | userPrice_1-default
UNKNOWN_TYPE | purchase-note-input | Include a message to Alvvays. | | userPrice_1-default
UNKNOWN_TYPE | notify-me | Have a gift card? Redeem it here | on | userPrice_1-default
UNKNOWN_TYPE | notify-me-label | Have a gift card? Redeem it here | on | userPrice_1-default
EMAIL_ADDRESS | address | Email a link to my free download to: | | userPrice_1-default
ADDRESS_HOME_COUNTRY | country | Have a gift card? Redeem it here | US | userPrice_1-default
ADDRESS_HOME_ZIP | postcode | zip code | | userPrice_1-default
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