Home | History | Annotate | Download | only in autofill
      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 
     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:
     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 
    120 FormFieldType FormField::GetFormFieldType() const {
    121   return kOtherFieldType;
    122 }
    123 
    124 // static
    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
    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
    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
    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
    185 bool FormField::ParseEmptyText(
    186     std::vector<AutofillField*>::const_iterator* iter,
    187     AutofillField** dest) {
    188   return ParseLabelText(iter, ASCIIToUTF16("^$"), dest);
    189 }
    190 
    191 // static
    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
    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
    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
    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
    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 
    254 string16 FormField::GetEcmlPattern(const char* ecml_name) {
    255   return ASCIIToUTF16(std::string("^") + ecml_name);
    256 }
    257 
    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 
    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 
    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