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

Side by Side Diff: components/autofill/core/browser/form_field.cc

Issue 853523004: Autofill: Set requirements for number of recognized fields in an autofillable form (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Address comments Created 5 years, 11 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 unified diff | Download patch
OLDNEW
1 // Copyright 2013 The Chromium Authors. All rights reserved. 1 // Copyright 2013 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "components/autofill/core/browser/form_field.h" 5 #include "components/autofill/core/browser/form_field.h"
6 6
7 #include <stddef.h> 7 #include <stddef.h>
8 #include <string> 8 #include <string>
9 #include <utility> 9 #include <utility>
10 10
(...skipping 22 matching lines...) Expand all
33 // Ignore fields marked as presentational. See 33 // Ignore fields marked as presentational. See
34 // http://www.w3.org/TR/wai-aria/roles#presentation 34 // http://www.w3.org/TR/wai-aria/roles#presentation
35 return field->is_checkable || 35 return field->is_checkable ||
36 field->role == FormFieldData::ROLE_ATTRIBUTE_PRESENTATION; 36 field->role == FormFieldData::ROLE_ATTRIBUTE_PRESENTATION;
37 } 37 }
38 38
39 } // namespace 39 } // namespace
40 40
41 // static 41 // static
42 void FormField::ParseFormFields(const std::vector<AutofillField*>& fields, 42 void FormField::ParseFormFields(const std::vector<AutofillField*>& fields,
43 bool is_in_form_tag,
43 ServerFieldTypeMap* map) { 44 ServerFieldTypeMap* map) {
44 // Set up a working copy of the fields to be processed. 45 // Set up a working copy of the fields to be processed.
45 std::vector<AutofillField*> remaining_fields(fields.size()); 46 std::vector<AutofillField*> remaining_fields(fields.size());
46 std::copy(fields.begin(), fields.end(), remaining_fields.begin()); 47 std::copy(fields.begin(), fields.end(), remaining_fields.begin());
47 48
48 remaining_fields.erase( 49 remaining_fields.erase(
49 std::remove_if(remaining_fields.begin(), remaining_fields.end(), 50 std::remove_if(remaining_fields.begin(), remaining_fields.end(),
50 ShouldBeIgnored), 51 ShouldBeIgnored),
51 remaining_fields.end()); 52 remaining_fields.end());
52 53
54 ServerFieldTypeMap saved_map = *map;
55 size_t email_count = 0;
56 size_t count = 0;
57
53 // Email pass. 58 // Email pass.
54 ParseFormFieldsPass(EmailField::Parse, &remaining_fields, map); 59 email_count += ParseFormFieldsPass(EmailField::Parse, &remaining_fields, map);
60 count += email_count;
55 61
56 // Phone pass. 62 // Phone pass.
57 ParseFormFieldsPass(PhoneField::Parse, &remaining_fields, map); 63 count += ParseFormFieldsPass(PhoneField::Parse, &remaining_fields, map);
58 64
59 // Address pass. 65 // Address pass.
60 ParseFormFieldsPass(AddressField::Parse, &remaining_fields, map); 66 count += ParseFormFieldsPass(AddressField::Parse, &remaining_fields, map);
61 67
62 // Credit card pass. 68 // Credit card pass.
63 ParseFormFieldsPass(CreditCardField::Parse, &remaining_fields, map); 69 count += ParseFormFieldsPass(CreditCardField::Parse, &remaining_fields, map);
64 70
65 // Name pass. 71 // Name pass.
66 ParseFormFieldsPass(NameField::Parse, &remaining_fields, map); 72 count += ParseFormFieldsPass(NameField::Parse, &remaining_fields, map);
73
74 // Do not autofill a form if there are less than 3 recognized fields.
75 // Otherwise it is very easy to have false positives. http://crbug.com/447332
76 // For <form> tags, make an exception for email fields, which are commonly the
77 // only recognized field on account registration sites.
78 size_t kThreshold = 3;
79 bool accept_parsing = (count >= kThreshold ||
80 (is_in_form_tag && email_count > 0));
81 if (!accept_parsing)
82 *map = saved_map;
67 } 83 }
68 84
69 // static 85 // static
70 bool FormField::ParseField(AutofillScanner* scanner, 86 bool FormField::ParseField(AutofillScanner* scanner,
71 const base::string16& pattern, 87 const base::string16& pattern,
72 AutofillField** match) { 88 AutofillField** match) {
73 return ParseFieldSpecifics(scanner, pattern, MATCH_DEFAULT, match); 89 return ParseFieldSpecifics(scanner, pattern, MATCH_DEFAULT, match);
74 } 90 }
75 91
76 // static 92 // static
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after
123 } 139 }
124 140
125 return false; 141 return false;
126 } 142 }
127 143
128 // static 144 // static
129 bool FormField::Match(const AutofillField* field, 145 bool FormField::Match(const AutofillField* field,
130 const base::string16& pattern, 146 const base::string16& pattern,
131 int match_type) { 147 int match_type) {
132 if ((match_type & FormField::MATCH_LABEL) && 148 if ((match_type & FormField::MATCH_LABEL) &&
133 autofill::MatchesPattern(field->label, pattern)) { 149 MatchesPattern(field->label, pattern)) {
134 return true; 150 return true;
135 } 151 }
136 152
137 if ((match_type & FormField::MATCH_NAME) && 153 if ((match_type & FormField::MATCH_NAME) &&
138 autofill::MatchesPattern(field->name, pattern)) { 154 MatchesPattern(field->name, pattern)) {
139 return true; 155 return true;
140 } 156 }
141 157
142 if ((match_type & FormField::MATCH_VALUE) && 158 if ((match_type & FormField::MATCH_VALUE) &&
143 autofill::MatchesPattern(field->value, pattern)) { 159 MatchesPattern(field->value, pattern)) {
144 return true; 160 return true;
145 } 161 }
146 162
147 return false; 163 return false;
148 } 164 }
149 165
150 // static 166 // static
151 void FormField::ParseFormFieldsPass(ParseFunction parse, 167 size_t FormField::ParseFormFieldsPass(ParseFunction parse,
152 std::vector<AutofillField*>* fields, 168 std::vector<AutofillField*>* fields,
153 ServerFieldTypeMap* map) { 169 ServerFieldTypeMap* map) {
154 // Store unmatched fields for further processing by the caller. 170 // Store unmatched fields for further processing by the caller.
155 std::vector<AutofillField*> remaining_fields; 171 std::vector<AutofillField*> remaining_fields;
156 172
173 size_t initial_field_count = map->size();
157 AutofillScanner scanner(*fields); 174 AutofillScanner scanner(*fields);
158 while (!scanner.IsEnd()) { 175 while (!scanner.IsEnd()) {
159 scoped_ptr<FormField> form_field(parse(&scanner)); 176 scoped_ptr<FormField> form_field(parse(&scanner));
160 if (!form_field) { 177 if (!form_field) {
161 remaining_fields.push_back(scanner.Cursor()); 178 remaining_fields.push_back(scanner.Cursor());
162 scanner.Advance(); 179 scanner.Advance();
163 continue; 180 continue;
164 } 181 }
165 182
166 // Add entries into the map for each field type found in |form_field|. 183 // Add entries into the map for each field type found in |form_field|.
167 bool ok = form_field->ClassifyField(map); 184 bool ok = form_field->ClassifyField(map);
168 DCHECK(ok); 185 DCHECK(ok);
169 } 186 }
170 187
171 std::swap(*fields, remaining_fields); 188 std::swap(*fields, remaining_fields);
189
190 DCHECK_GE(map->size(), initial_field_count);
191 return map->size() - initial_field_count;
Evan Stade 2015/01/22 23:17:04 this doesn't need to be part of ParseFormFieldsPas
Lei Zhang 2015/01/22 23:32:04 Done.
172 } 192 }
173 193
174 bool FormField::MatchesFormControlType(const std::string& type, 194 bool FormField::MatchesFormControlType(const std::string& type,
175 int match_type) { 195 int match_type) {
176 if ((match_type & MATCH_TEXT) && type == "text") 196 if ((match_type & MATCH_TEXT) && type == "text")
177 return true; 197 return true;
178 198
179 if ((match_type & MATCH_EMAIL) && type == "email") 199 if ((match_type & MATCH_EMAIL) && type == "email")
180 return true; 200 return true;
181 201
182 if ((match_type & MATCH_TELEPHONE) && type == "tel") 202 if ((match_type & MATCH_TELEPHONE) && type == "tel")
183 return true; 203 return true;
184 204
185 if ((match_type & MATCH_SELECT) && type == "select-one") 205 if ((match_type & MATCH_SELECT) && type == "select-one")
186 return true; 206 return true;
187 207
188 if ((match_type & MATCH_TEXT_AREA) && type == "textarea") 208 if ((match_type & MATCH_TEXT_AREA) && type == "textarea")
189 return true; 209 return true;
190 210
191 if ((match_type & MATCH_PASSWORD) && type == "password") 211 if ((match_type & MATCH_PASSWORD) && type == "password")
192 return true; 212 return true;
193 213
194 return false; 214 return false;
195 } 215 }
196 216
197 } // namespace autofill 217 } // namespace autofill
OLDNEW
« no previous file with comments | « components/autofill/core/browser/form_field.h ('k') | components/autofill/core/browser/form_field_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698