• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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