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

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: More relaxed check for form tag 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_unowned_form,
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 size_t kThreshold = 3;
77 bool ignore_parsing = (count < kThreshold);
Evan Stade 2015/01/21 22:52:49 nit: no parens
78 // For <form> tags, make an exception for email fields, which are commonly the
79 // only recognized field on account registration sites.
80 if (!is_unowned_form)
Evan Stade 2015/01/21 22:52:49 &= is a confusing operator. How about: bool shoul
Lei Zhang 2015/01/22 08:07:37 Done.
81 ignore_parsing &= (email_count == 0);
82 if (ignore_parsing)
83 *map = saved_map;
67 } 84 }
68 85
69 // static 86 // static
70 bool FormField::ParseField(AutofillScanner* scanner, 87 bool FormField::ParseField(AutofillScanner* scanner,
71 const base::string16& pattern, 88 const base::string16& pattern,
72 AutofillField** match) { 89 AutofillField** match) {
73 return ParseFieldSpecifics(scanner, pattern, MATCH_DEFAULT, match); 90 return ParseFieldSpecifics(scanner, pattern, MATCH_DEFAULT, match);
74 } 91 }
75 92
76 // static 93 // static
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after
123 } 140 }
124 141
125 return false; 142 return false;
126 } 143 }
127 144
128 // static 145 // static
129 bool FormField::Match(const AutofillField* field, 146 bool FormField::Match(const AutofillField* field,
130 const base::string16& pattern, 147 const base::string16& pattern,
131 int match_type) { 148 int match_type) {
132 if ((match_type & FormField::MATCH_LABEL) && 149 if ((match_type & FormField::MATCH_LABEL) &&
133 autofill::MatchesPattern(field->label, pattern)) { 150 MatchesPattern(field->label, pattern)) {
134 return true; 151 return true;
135 } 152 }
136 153
137 if ((match_type & FormField::MATCH_NAME) && 154 if ((match_type & FormField::MATCH_NAME) &&
138 autofill::MatchesPattern(field->name, pattern)) { 155 MatchesPattern(field->name, pattern)) {
139 return true; 156 return true;
140 } 157 }
141 158
142 if ((match_type & FormField::MATCH_VALUE) && 159 if ((match_type & FormField::MATCH_VALUE) &&
143 autofill::MatchesPattern(field->value, pattern)) { 160 MatchesPattern(field->value, pattern)) {
144 return true; 161 return true;
145 } 162 }
146 163
147 return false; 164 return false;
148 } 165 }
149 166
150 // static 167 // static
151 void FormField::ParseFormFieldsPass(ParseFunction parse, 168 size_t FormField::ParseFormFieldsPass(ParseFunction parse,
152 std::vector<AutofillField*>* fields, 169 std::vector<AutofillField*>* fields,
153 ServerFieldTypeMap* map) { 170 ServerFieldTypeMap* map) {
154 // Store unmatched fields for further processing by the caller. 171 // Store unmatched fields for further processing by the caller.
155 std::vector<AutofillField*> remaining_fields; 172 std::vector<AutofillField*> remaining_fields;
156 173
174 ScopedVector<FormField> form_fields;
175 size_t field_count = 0;
157 AutofillScanner scanner(*fields); 176 AutofillScanner scanner(*fields);
158 while (!scanner.IsEnd()) { 177 while (!scanner.IsEnd()) {
159 scoped_ptr<FormField> form_field(parse(&scanner)); 178 scoped_ptr<FormField> form_field(parse(&scanner));
160 if (!form_field) { 179 if (!form_field) {
161 remaining_fields.push_back(scanner.Cursor()); 180 remaining_fields.push_back(scanner.Cursor());
162 scanner.Advance(); 181 scanner.Advance();
163 continue; 182 continue;
164 } 183 }
165 184
185 field_count += form_field->FieldCount();
Evan Stade 2015/01/21 22:52:49 instead of adding this function, couldn't you more
Lei Zhang 2015/01/22 08:07:37 Isn't it possible for functions like AddressField:
Evan Stade 2015/01/22 17:17:05 perhaps... but you could check the size of |map| a
Lei Zhang 2015/01/22 23:14:15 Sounds better, done.
186 form_fields.push_back(form_field.release());
187 }
188
189 for (const auto& form_field : form_fields) {
Evan Stade 2015/01/22 17:17:05 why is this a separate loop now? also, I think au
Lei Zhang 2015/01/22 23:14:15 I was experimenting with different ways to count f
166 // Add entries into the map for each field type found in |form_field|. 190 // Add entries into the map for each field type found in |form_field|.
167 bool ok = form_field->ClassifyField(map); 191 bool ok = form_field->ClassifyField(map);
168 DCHECK(ok); 192 DCHECK(ok);
169 } 193 }
170 194
171 std::swap(*fields, remaining_fields); 195 std::swap(*fields, remaining_fields);
196 return field_count;
172 } 197 }
173 198
174 bool FormField::MatchesFormControlType(const std::string& type, 199 bool FormField::MatchesFormControlType(const std::string& type,
175 int match_type) { 200 int match_type) {
176 if ((match_type & MATCH_TEXT) && type == "text") 201 if ((match_type & MATCH_TEXT) && type == "text")
177 return true; 202 return true;
178 203
179 if ((match_type & MATCH_EMAIL) && type == "email") 204 if ((match_type & MATCH_EMAIL) && type == "email")
180 return true; 205 return true;
181 206
182 if ((match_type & MATCH_TELEPHONE) && type == "tel") 207 if ((match_type & MATCH_TELEPHONE) && type == "tel")
183 return true; 208 return true;
184 209
185 if ((match_type & MATCH_SELECT) && type == "select-one") 210 if ((match_type & MATCH_SELECT) && type == "select-one")
186 return true; 211 return true;
187 212
188 if ((match_type & MATCH_TEXT_AREA) && type == "textarea") 213 if ((match_type & MATCH_TEXT_AREA) && type == "textarea")
189 return true; 214 return true;
190 215
191 if ((match_type & MATCH_PASSWORD) && type == "password") 216 if ((match_type & MATCH_PASSWORD) && type == "password")
192 return true; 217 return true;
193 218
194 return false; 219 return false;
195 } 220 }
196 221
197 } // namespace autofill 222 } // namespace autofill
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698