1 // Copyright (c) 2011 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 "chrome/browser/autofill/form_field.h"
6
7 #include <stddef.h>
8 #include <string>
9 #include <utility>
10
11 #include "base/logging.h"
12 #include "base/string_util.h"
13 #include "base/stringprintf.h"
14 #include "base/utf_string_conversions.h"
15 #include "chrome/browser/autofill/address_field.h"
16 #include "chrome/browser/autofill/autofill_field.h"
17 #include "chrome/browser/autofill/credit_card_field.h"
18 #include "chrome/browser/autofill/field_types.h"
19 #include "chrome/browser/autofill/form_structure.h"
20 #include "chrome/browser/autofill/name_field.h"
21 #include "chrome/browser/autofill/phone_field.h"
22 #include "grit/autofill_resources.h"
23 #include "ui/base/l10n/l10n_util.h"
24 #include "unicode/regex.h"
25
26 // Field names from the ECML specification; see RFC 3106. We've
27 // made these names lowercase since we convert labels and field names to
28 // lowercase before searching.
29
30 // shipping name/address fields
31 const char kEcmlShipToTitle[] = "ecom_shipto_postal_name_prefix";
32 const char kEcmlShipToFirstName[] = "ecom_shipto_postal_name_first";
33 const char kEcmlShipToMiddleName[] = "ecom_shipto_postal_name_middle";
34 const char kEcmlShipToLastName[] = "ecom_shipto_postal_name_last";
35 const char kEcmlShipToNameSuffix[] = "ecom_shipto_postal_name_suffix";
36 const char kEcmlShipToCompanyName[] = "ecom_shipto_postal_company";
37 const char kEcmlShipToAddress1[] = "ecom_shipto_postal_street_line1";
38 const char kEcmlShipToAddress2[] = "ecom_shipto_postal_street_line2";
39 const char kEcmlShipToAddress3[] = "ecom_shipto_postal_street_line3";
40 const char kEcmlShipToCity[] = "ecom_shipto_postal_city";
41 const char kEcmlShipToStateProv[] = "ecom_shipto_postal_stateprov";
42 const char kEcmlShipToPostalCode[] = "ecom_shipto_postal_postalcode";
43 const char kEcmlShipToCountry[] = "ecom_shipto_postal_countrycode";
44 const char kEcmlShipToPhone[] = "ecom_shipto_telecom_phone_number";
45 const char kEcmlShipToEmail[] = "ecom_shipto_online_email";
46
47 // billing name/address fields
48 const char kEcmlBillToTitle[] = "ecom_billto_postal_name_prefix";
49 const char kEcmlBillToFirstName[] = "ecom_billto_postal_name_first";
50 const char kEcmlBillToMiddleName[] = "ecom_billto_postal_name_middle";
51 const char kEcmlBillToLastName[] = "ecom_billto_postal_name_last";
52 const char kEcmlBillToNameSuffix[] = "ecom_billto_postal_name_suffix";
53 const char kEcmlBillToCompanyName[] = "ecom_billto_postal_company";
54 const char kEcmlBillToAddress1[] = "ecom_billto_postal_street_line1";
55 const char kEcmlBillToAddress2[] = "ecom_billto_postal_street_line2";
56 const char kEcmlBillToAddress3[] = "ecom_billto_postal_street_line3";
57 const char kEcmlBillToCity[] = "ecom_billto_postal_city";
58 const char kEcmlBillToStateProv[] = "ecom_billto_postal_stateprov";
59 const char kEcmlBillToPostalCode[] = "ecom_billto_postal_postalcode";
60 const char kEcmlBillToCountry[] = "ecom_billto_postal_countrycode";
61 const char kEcmlBillToPhone[] = "ecom_billto_telecom_phone_number";
62 const char kEcmlBillToEmail[] = "ecom_billto_online_email";
63
64 // credit card fields
65 const char kEcmlCardHolder[] = "ecom_payment_card_name";
66 const char kEcmlCardType[] = "ecom_payment_card_type";
67 const char kEcmlCardNumber[] = "ecom_payment_card_number";
68 const char kEcmlCardVerification[] = "ecom_payment_card_verification";
69 const char kEcmlCardExpireDay[] = "ecom_payment_card_expdate_day";
70 const char kEcmlCardExpireMonth[] = "ecom_payment_card_expdate_month";
71 const char kEcmlCardExpireYear[] = "ecom_payment_card_expdate_year";
72
73 namespace autofill {
74
MatchString(const string16 & input,const string16 & pattern)75 bool MatchString(const string16& input, const string16& pattern) {
76 UErrorCode status = U_ZERO_ERROR;
77 icu::UnicodeString icu_pattern(pattern.data(), pattern.length());
78 icu::UnicodeString icu_input(input.data(), input.length());
79 icu::RegexMatcher matcher(icu_pattern, icu_input,
80 UREGEX_CASE_INSENSITIVE, status);
81 DCHECK(U_SUCCESS(status));
82
83 UBool match = matcher.find(0, status);
84 DCHECK(U_SUCCESS(status));
85 return !!match;
86 }
87
88 } // namespace autofill
89
90 class EmailField : public FormField {
91 public:
GetFieldInfo(FieldTypeMap * field_type_map) const92 virtual bool GetFieldInfo(FieldTypeMap* field_type_map) const {
93 bool ok = Add(field_type_map, field_, AutofillType(EMAIL_ADDRESS));
94 DCHECK(ok);
95 return true;
96 }
97
Parse(std::vector<AutofillField * >::const_iterator * iter,bool is_ecml)98 static EmailField* Parse(std::vector<AutofillField*>::const_iterator* iter,
99 bool is_ecml) {
100 string16 pattern;
101 if (is_ecml) {
102 pattern = GetEcmlPattern(kEcmlShipToEmail, kEcmlBillToEmail, '|');
103 } else {
104 pattern = l10n_util::GetStringUTF16(IDS_AUTOFILL_EMAIL_RE);
105 }
106
107 AutofillField* field;
108 if (ParseText(iter, pattern, &field))
109 return new EmailField(field);
110
111 return NULL;
112 }
113
114 private:
EmailField(AutofillField * field)115 explicit EmailField(AutofillField *field) : field_(field) {}
116
117 AutofillField* field_;
118 };
119
GetFormFieldType() const120 FormFieldType FormField::GetFormFieldType() const {
121 return kOtherFieldType;
122 }
123
124 // static
Match(AutofillField * field,const string16 & pattern,bool match_label_only)125 bool FormField::Match(AutofillField* field,
126 const string16& pattern,
127 bool match_label_only) {
128 if (match_label_only) {
129 if (autofill::MatchString(field->label, pattern)) {
130 return true;
131 }
132 } else {
133 // For now, we apply the same pattern to the field's label and the field's
134 // name. Matching the name is a bit of a long shot for many patterns, but
135 // it generally doesn't hurt to try.
136 if (autofill::MatchString(field->label, pattern) ||
137 autofill::MatchString(field->name, pattern)) {
138 return true;
139 }
140 }
141 return false;
142 }
143
144
145
146 // static
ParseFormField(std::vector<AutofillField * >::const_iterator * iter,bool is_ecml)147 FormField* FormField::ParseFormField(
148 std::vector<AutofillField*>::const_iterator* iter,
149 bool is_ecml) {
150 FormField *field;
151 field = EmailField::Parse(iter, is_ecml);
152 if (field != NULL)
153 return field;
154 // Parses both phone and fax.
155 field = PhoneField::Parse(iter, is_ecml);
156 if (field != NULL)
157 return field;
158 field = AddressField::Parse(iter, is_ecml);
159 if (field != NULL)
160 return field;
161 field = CreditCardField::Parse(iter, is_ecml);
162 if (field != NULL)
163 return field;
164
165 // We search for a NameField last since it matches the word "name", which is
166 // relatively general.
167 return NameField::Parse(iter, is_ecml);
168 }
169
170 // static
ParseText(std::vector<AutofillField * >::const_iterator * iter,const string16 & pattern)171 bool FormField::ParseText(std::vector<AutofillField*>::const_iterator* iter,
172 const string16& pattern) {
173 AutofillField* field;
174 return ParseText(iter, pattern, &field);
175 }
176
177 // static
ParseText(std::vector<AutofillField * >::const_iterator * iter,const string16 & pattern,AutofillField ** dest)178 bool FormField::ParseText(std::vector<AutofillField*>::const_iterator* iter,
179 const string16& pattern,
180 AutofillField** dest) {
181 return ParseText(iter, pattern, dest, false);
182 }
183
184 // static
ParseEmptyText(std::vector<AutofillField * >::const_iterator * iter,AutofillField ** dest)185 bool FormField::ParseEmptyText(
186 std::vector<AutofillField*>::const_iterator* iter,
187 AutofillField** dest) {
188 return ParseLabelText(iter, ASCIIToUTF16("^$"), dest);
189 }
190
191 // static
ParseLabelText(std::vector<AutofillField * >::const_iterator * iter,const string16 & pattern,AutofillField ** dest)192 bool FormField::ParseLabelText(
193 std::vector<AutofillField*>::const_iterator* iter,
194 const string16& pattern,
195 AutofillField** dest) {
196 return ParseText(iter, pattern, dest, true);
197 }
198
199 // static
ParseText(std::vector<AutofillField * >::const_iterator * iter,const string16 & pattern,AutofillField ** dest,bool match_label_only)200 bool FormField::ParseText(std::vector<AutofillField*>::const_iterator* iter,
201 const string16& pattern,
202 AutofillField** dest,
203 bool match_label_only) {
204 AutofillField* field = **iter;
205 if (!field)
206 return false;
207
208 if (Match(field, pattern, match_label_only)) {
209 if (dest)
210 *dest = field;
211 (*iter)++;
212 return true;
213 }
214
215 return false;
216 }
217
218 // static
ParseLabelAndName(std::vector<AutofillField * >::const_iterator * iter,const string16 & pattern,AutofillField ** dest)219 bool FormField::ParseLabelAndName(
220 std::vector<AutofillField*>::const_iterator* iter,
221 const string16& pattern,
222 AutofillField** dest) {
223 AutofillField* field = **iter;
224 if (!field)
225 return false;
226
227 if (autofill::MatchString(field->label, pattern) &&
228 autofill::MatchString(field->name, pattern)) {
229 if (dest)
230 *dest = field;
231 (*iter)++;
232 return true;
233 }
234
235 return false;
236 }
237
238 // static
ParseEmpty(std::vector<AutofillField * >::const_iterator * iter)239 bool FormField::ParseEmpty(std::vector<AutofillField*>::const_iterator* iter) {
240 // TODO(jhawkins): Handle select fields.
241 return ParseLabelAndName(iter, ASCIIToUTF16("^$"), NULL);
242 }
243
244 // static
Add(FieldTypeMap * field_type_map,AutofillField * field,const AutofillType & type)245 bool FormField::Add(FieldTypeMap* field_type_map, AutofillField* field,
246 const AutofillType& type) {
247 // Several fields are optional.
248 if (field)
249 field_type_map->insert(make_pair(field->unique_name(), type.field_type()));
250
251 return true;
252 }
253
GetEcmlPattern(const char * ecml_name)254 string16 FormField::GetEcmlPattern(const char* ecml_name) {
255 return ASCIIToUTF16(std::string("^") + ecml_name);
256 }
257
GetEcmlPattern(const char * ecml_name1,const char * ecml_name2,char pattern_operator)258 string16 FormField::GetEcmlPattern(const char* ecml_name1,
259 const char* ecml_name2,
260 char pattern_operator) {
261 return ASCIIToUTF16(StringPrintf("^%s%c^%s",
262 ecml_name1, pattern_operator, ecml_name2));
263 }
264
FormFieldSet(FormStructure * fields)265 FormFieldSet::FormFieldSet(FormStructure* fields) {
266 std::vector<AddressField*> addresses;
267
268 // First, find if there is one form field with an ECML name. If there is,
269 // then we will match an element only if it is in the standard.
270 bool is_ecml = CheckECML(fields);
271
272 // Parse fields.
273 std::vector<AutofillField*>::const_iterator field = fields->begin();
274 while (field != fields->end() && *field != NULL) {
275 FormField* form_field = FormField::ParseFormField(&field, is_ecml);
276 if (!form_field) {
277 field++;
278 continue;
279 }
280
281 push_back(form_field);
282
283 if (form_field->GetFormFieldType() == kAddressType) {
284 AddressField* address = static_cast<AddressField*>(form_field);
285 if (address->IsFullAddress())
286 addresses.push_back(address);
287 }
288 }
289
290 // Now determine an address type for each address. Note, if this is an ECML
291 // form, then we already got this info from the field names.
292 if (!is_ecml && !addresses.empty()) {
293 if (addresses.size() == 1) {
294 addresses[0]->SetType(addresses[0]->FindType());
295 } else {
296 AddressType type0 = addresses[0]->FindType();
297 AddressType type1 = addresses[1]->FindType();
298
299 // When there are two addresses on a page, they almost always appear in
300 // the order (billing, shipping).
301 bool reversed = (type0 == kShippingAddress && type1 == kBillingAddress);
302 addresses[0]->SetType(reversed ? kShippingAddress : kBillingAddress);
303 addresses[1]->SetType(reversed ? kBillingAddress : kShippingAddress);
304 }
305 }
306 }
307
CheckECML(FormStructure * fields)308 bool FormFieldSet::CheckECML(FormStructure* fields) {
309 size_t num_fields = fields->field_count();
310 struct EcmlField {
311 const char* name_;
312 const int length_;
313 } form_fields[] = {
314 #define ECML_STRING_ENTRY(x) { x, arraysize(x) - 1 },
315 ECML_STRING_ENTRY(kEcmlShipToTitle)
316 ECML_STRING_ENTRY(kEcmlShipToFirstName)
317 ECML_STRING_ENTRY(kEcmlShipToMiddleName)
318 ECML_STRING_ENTRY(kEcmlShipToLastName)
319 ECML_STRING_ENTRY(kEcmlShipToNameSuffix)
320 ECML_STRING_ENTRY(kEcmlShipToCompanyName)
321 ECML_STRING_ENTRY(kEcmlShipToAddress1)
322 ECML_STRING_ENTRY(kEcmlShipToAddress2)
323 ECML_STRING_ENTRY(kEcmlShipToAddress3)
324 ECML_STRING_ENTRY(kEcmlShipToCity)
325 ECML_STRING_ENTRY(kEcmlShipToStateProv)
326 ECML_STRING_ENTRY(kEcmlShipToPostalCode)
327 ECML_STRING_ENTRY(kEcmlShipToCountry)
328 ECML_STRING_ENTRY(kEcmlShipToPhone)
329 ECML_STRING_ENTRY(kEcmlShipToPhone)
330 ECML_STRING_ENTRY(kEcmlShipToEmail)
331 ECML_STRING_ENTRY(kEcmlBillToTitle)
332 ECML_STRING_ENTRY(kEcmlBillToFirstName)
333 ECML_STRING_ENTRY(kEcmlBillToMiddleName)
334 ECML_STRING_ENTRY(kEcmlBillToLastName)
335 ECML_STRING_ENTRY(kEcmlBillToNameSuffix)
336 ECML_STRING_ENTRY(kEcmlBillToCompanyName)
337 ECML_STRING_ENTRY(kEcmlBillToAddress1)
338 ECML_STRING_ENTRY(kEcmlBillToAddress2)
339 ECML_STRING_ENTRY(kEcmlBillToAddress3)
340 ECML_STRING_ENTRY(kEcmlBillToCity)
341 ECML_STRING_ENTRY(kEcmlBillToStateProv)
342 ECML_STRING_ENTRY(kEcmlBillToPostalCode)
343 ECML_STRING_ENTRY(kEcmlBillToCountry)
344 ECML_STRING_ENTRY(kEcmlBillToPhone)
345 ECML_STRING_ENTRY(kEcmlBillToPhone)
346 ECML_STRING_ENTRY(kEcmlBillToEmail)
347 ECML_STRING_ENTRY(kEcmlCardHolder)
348 ECML_STRING_ENTRY(kEcmlCardType)
349 ECML_STRING_ENTRY(kEcmlCardNumber)
350 ECML_STRING_ENTRY(kEcmlCardVerification)
351 ECML_STRING_ENTRY(kEcmlCardExpireMonth)
352 ECML_STRING_ENTRY(kEcmlCardExpireYear)
353 #undef ECML_STRING_ENTRY
354 };
355
356 const string16 ecom(ASCIIToUTF16("ecom"));
357 for (size_t index = 0; index < num_fields; ++index) {
358 const string16& utf16_name = fields->field(index)->name;
359 if (StartsWith(utf16_name, ecom, true)) {
360 std::string name(UTF16ToASCII(utf16_name));
361 for (size_t i = 0; i < ARRAYSIZE_UNSAFE(form_fields); ++i) {
362 if (base::strncasecmp(name.c_str(), form_fields[i].name_,
363 form_fields[i].length_) == 0) {
364 return true;
365 }
366 }
367 }
368 }
369
370 return false;
371 }
372