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