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
31const char kEcmlShipToTitle[] = "ecom_shipto_postal_name_prefix";
32const char kEcmlShipToFirstName[] = "ecom_shipto_postal_name_first";
33const char kEcmlShipToMiddleName[] = "ecom_shipto_postal_name_middle";
34const char kEcmlShipToLastName[] = "ecom_shipto_postal_name_last";
35const char kEcmlShipToNameSuffix[] = "ecom_shipto_postal_name_suffix";
36const char kEcmlShipToCompanyName[] = "ecom_shipto_postal_company";
37const char kEcmlShipToAddress1[] = "ecom_shipto_postal_street_line1";
38const char kEcmlShipToAddress2[] = "ecom_shipto_postal_street_line2";
39const char kEcmlShipToAddress3[] = "ecom_shipto_postal_street_line3";
40const char kEcmlShipToCity[] = "ecom_shipto_postal_city";
41const char kEcmlShipToStateProv[] = "ecom_shipto_postal_stateprov";
42const char kEcmlShipToPostalCode[] = "ecom_shipto_postal_postalcode";
43const char kEcmlShipToCountry[] = "ecom_shipto_postal_countrycode";
44const char kEcmlShipToPhone[] = "ecom_shipto_telecom_phone_number";
45const char kEcmlShipToEmail[] = "ecom_shipto_online_email";
46
47// billing name/address fields
48const char kEcmlBillToTitle[] = "ecom_billto_postal_name_prefix";
49const char kEcmlBillToFirstName[] = "ecom_billto_postal_name_first";
50const char kEcmlBillToMiddleName[] = "ecom_billto_postal_name_middle";
51const char kEcmlBillToLastName[] = "ecom_billto_postal_name_last";
52const char kEcmlBillToNameSuffix[] = "ecom_billto_postal_name_suffix";
53const char kEcmlBillToCompanyName[] = "ecom_billto_postal_company";
54const char kEcmlBillToAddress1[] = "ecom_billto_postal_street_line1";
55const char kEcmlBillToAddress2[] = "ecom_billto_postal_street_line2";
56const char kEcmlBillToAddress3[] = "ecom_billto_postal_street_line3";
57const char kEcmlBillToCity[] = "ecom_billto_postal_city";
58const char kEcmlBillToStateProv[] = "ecom_billto_postal_stateprov";
59const char kEcmlBillToPostalCode[] = "ecom_billto_postal_postalcode";
60const char kEcmlBillToCountry[] = "ecom_billto_postal_countrycode";
61const char kEcmlBillToPhone[] = "ecom_billto_telecom_phone_number";
62const char kEcmlBillToEmail[] = "ecom_billto_online_email";
63
64// credit card fields
65const char kEcmlCardHolder[] = "ecom_payment_card_name";
66const char kEcmlCardType[] = "ecom_payment_card_type";
67const char kEcmlCardNumber[] = "ecom_payment_card_number";
68const char kEcmlCardVerification[] = "ecom_payment_card_verification";
69const char kEcmlCardExpireDay[] = "ecom_payment_card_expdate_day";
70const char kEcmlCardExpireMonth[] = "ecom_payment_card_expdate_month";
71const char kEcmlCardExpireYear[] = "ecom_payment_card_expdate_year";
72
73namespace autofill {
74
75bool 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
90class EmailField : public FormField {
91 public:
92  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
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:
115  explicit EmailField(AutofillField *field) : field_(field) {}
116
117  AutofillField* field_;
118};
119
120FormFieldType FormField::GetFormFieldType() const {
121  return kOtherFieldType;
122}
123
124// static
125bool 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
147FormField* 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
171bool 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
178bool 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
185bool FormField::ParseEmptyText(
186    std::vector<AutofillField*>::const_iterator* iter,
187    AutofillField** dest) {
188  return ParseLabelText(iter, ASCIIToUTF16("^$"), dest);
189}
190
191// static
192bool 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
200bool 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
219bool 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
239bool FormField::ParseEmpty(std::vector<AutofillField*>::const_iterator* iter) {
240  // TODO(jhawkins): Handle select fields.
241  return ParseLabelAndName(iter, ASCIIToUTF16("^$"), NULL);
242}
243
244// static
245bool 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
254string16 FormField::GetEcmlPattern(const char* ecml_name) {
255  return ASCIIToUTF16(std::string("^") + ecml_name);
256}
257
258string16 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
265FormFieldSet::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
308bool 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