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 3// found in the LICENSE file. 4 5#include "components/autofill/core/browser/form_field.h" 6 7#include <stddef.h> 8#include <string> 9#include <utility> 10 11#include "base/logging.h" 12#include "base/memory/scoped_ptr.h" 13#include "base/strings/string_util.h" 14#include "base/strings/stringprintf.h" 15#include "base/strings/utf_string_conversions.h" 16#include "components/autofill/core/browser/address_field.h" 17#include "components/autofill/core/browser/autofill_field.h" 18#include "components/autofill/core/browser/autofill_regexes.h" 19#include "components/autofill/core/browser/autofill_scanner.h" 20#include "components/autofill/core/browser/credit_card_field.h" 21#include "components/autofill/core/browser/email_field.h" 22#include "components/autofill/core/browser/form_structure.h" 23#include "components/autofill/core/browser/name_field.h" 24#include "components/autofill/core/browser/phone_field.h" 25#include "ui/base/l10n/l10n_util.h" 26 27namespace autofill { 28namespace { 29 30bool IsTextField(const std::string& type) { 31 return type == "text"; 32} 33 34bool IsEmailField(const std::string& type) { 35 return type == "email"; 36} 37 38bool IsTelephoneField(const std::string& type) { 39 return type == "tel"; 40} 41 42bool IsSelectField(const std::string& type) { 43 return type == "select-one"; 44} 45 46bool IsCheckable(const AutofillField* field) { 47 return field->is_checkable; 48} 49 50} // namespace 51 52// static 53void FormField::ParseFormFields(const std::vector<AutofillField*>& fields, 54 ServerFieldTypeMap* map) { 55 // Set up a working copy of the fields to be processed. 56 std::vector<const AutofillField*> remaining_fields(fields.size()); 57 std::copy(fields.begin(), fields.end(), remaining_fields.begin()); 58 59 // Ignore checkable fields as they interfere with parsers assuming context. 60 // Eg., while parsing address, "Is PO box" checkbox after ADDRESS_LINE1 61 // interferes with correctly understanding ADDRESS_LINE2. 62 remaining_fields.erase( 63 std::remove_if(remaining_fields.begin(), remaining_fields.end(), 64 IsCheckable), 65 remaining_fields.end()); 66 67 // Email pass. 68 ParseFormFieldsPass(EmailField::Parse, &remaining_fields, map); 69 70 // Phone pass. 71 ParseFormFieldsPass(PhoneField::Parse, &remaining_fields, map); 72 73 // Address pass. 74 ParseFormFieldsPass(AddressField::Parse, &remaining_fields, map); 75 76 // Credit card pass. 77 ParseFormFieldsPass(CreditCardField::Parse, &remaining_fields, map); 78 79 // Name pass. 80 ParseFormFieldsPass(NameField::Parse, &remaining_fields, map); 81} 82 83// static 84bool FormField::ParseField(AutofillScanner* scanner, 85 const base::string16& pattern, 86 const AutofillField** match) { 87 return ParseFieldSpecifics(scanner, pattern, MATCH_DEFAULT, match); 88} 89 90// static 91bool FormField::ParseFieldSpecifics(AutofillScanner* scanner, 92 const base::string16& pattern, 93 int match_type, 94 const AutofillField** match) { 95 if (scanner->IsEnd()) 96 return false; 97 98 const AutofillField* field = scanner->Cursor(); 99 100 if ((match_type & MATCH_TEXT) && IsTextField(field->form_control_type)) 101 return MatchAndAdvance(scanner, pattern, match_type, match); 102 103 if ((match_type & MATCH_EMAIL) && IsEmailField(field->form_control_type)) 104 return MatchAndAdvance(scanner, pattern, match_type, match); 105 106 if ((match_type & MATCH_TELEPHONE) && 107 IsTelephoneField(field->form_control_type)) { 108 return MatchAndAdvance(scanner, pattern, match_type, match); 109 } 110 111 if ((match_type & MATCH_SELECT) && IsSelectField(field->form_control_type)) 112 return MatchAndAdvance(scanner, pattern, match_type, match); 113 114 return false; 115} 116 117// static 118bool FormField::ParseEmptyLabel(AutofillScanner* scanner, 119 const AutofillField** match) { 120 return ParseFieldSpecifics(scanner, 121 ASCIIToUTF16("^$"), 122 MATCH_LABEL | MATCH_ALL_INPUTS, 123 match); 124} 125 126// static 127bool FormField::AddClassification(const AutofillField* field, 128 ServerFieldType type, 129 ServerFieldTypeMap* map) { 130 // Several fields are optional. 131 if (!field) 132 return true; 133 134 return map->insert(make_pair(field->unique_name(), type)).second; 135} 136 137// static. 138bool FormField::MatchAndAdvance(AutofillScanner* scanner, 139 const base::string16& pattern, 140 int match_type, 141 const AutofillField** match) { 142 const AutofillField* field = scanner->Cursor(); 143 if (FormField::Match(field, pattern, match_type)) { 144 if (match) 145 *match = field; 146 scanner->Advance(); 147 return true; 148 } 149 150 return false; 151} 152 153// static 154bool FormField::Match(const AutofillField* field, 155 const base::string16& pattern, 156 int match_type) { 157 if ((match_type & FormField::MATCH_LABEL) && 158 autofill::MatchesPattern(field->label, pattern)) { 159 return true; 160 } 161 162 if ((match_type & FormField::MATCH_NAME) && 163 autofill::MatchesPattern(field->name, pattern)) { 164 return true; 165 } 166 167 if ((match_type & FormField::MATCH_VALUE) && 168 autofill::MatchesPattern(field->value, pattern)) { 169 return true; 170 } 171 172 return false; 173} 174 175// static 176void FormField::ParseFormFieldsPass(ParseFunction parse, 177 std::vector<const AutofillField*>* fields, 178 ServerFieldTypeMap* map) { 179 // Store unmatched fields for further processing by the caller. 180 std::vector<const AutofillField*> remaining_fields; 181 182 AutofillScanner scanner(*fields); 183 while (!scanner.IsEnd()) { 184 scoped_ptr<FormField> form_field(parse(&scanner)); 185 if (!form_field.get()) { 186 remaining_fields.push_back(scanner.Cursor()); 187 scanner.Advance(); 188 continue; 189 } 190 191 // Add entries into the map for each field type found in |form_field|. 192 bool ok = form_field->ClassifyField(map); 193 DCHECK(ok); 194 } 195 196 std::swap(*fields, remaining_fields); 197} 198 199} // namespace autofill 200