Chromium Code Reviews| OLD | NEW |
|---|---|
| 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 Loading... | |
| 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 Loading... | |
| 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 |
| OLD | NEW |