1eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch// Copyright 2013 The Chromium Authors. All rights reserved. 25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file. 45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#include "components/autofill/core/browser/credit_card_field.h" 65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <stddef.h> 85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/logging.h" 105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/memory/scoped_ptr.h" 11868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "base/strings/string16.h" 12868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "base/strings/string_util.h" 13868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "base/strings/utf_string_conversions.h" 14eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#include "components/autofill/core/browser/autofill_field.h" 15eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#include "components/autofill/core/browser/autofill_regex_constants.h" 16eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#include "components/autofill/core/browser/autofill_scanner.h" 17eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#include "components/autofill/core/browser/field_types.h" 185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/base/l10n/l10n_util.h" 195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 20c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)namespace autofill { 21c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 221320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci// Credit card numbers are at most 19 digits in length. 231320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci// [Ref: http://en.wikipedia.org/wiki/Bank_card_number] 241320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccistatic const size_t kMaxValidCardNumberSize = 19; 251320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// static 272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)FormField* CreditCardField::Parse(AutofillScanner* scanner) { 285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (scanner->IsEnd()) 295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return NULL; 305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_ptr<CreditCardField> credit_card_field(new CreditCardField); 325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) size_t saved_cursor = scanner->SaveCursor(); 331320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci bool form_has_valid_card_number_fields = true; 345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Credit card fields can appear in many different orders. 365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // We loop until no more credit card related fields are found, see |break| at 375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // bottom of the loop. 385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (int fields = 0; !scanner->IsEnd(); ++fields) { 395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Ignore gift card fields. 405d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (ParseField(scanner, base::UTF8ToUTF16(autofill::kGiftCardRe), NULL)) 415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Sometimes the cardholder field is just labeled "name". Unfortunately this 445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // is a dangerously generic word to search for, since it will often match a 455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // name (not cardholder name) field before or after credit card fields. So 465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // we search for "name" only when we've already parsed at least one other 475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // credit card field and haven't yet parsed the expiration date (which 485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // usually appears at the end). 495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (credit_card_field->cardholder_ == NULL) { 50c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) base::string16 name_pattern; 515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (fields == 0 || credit_card_field->expiration_month_) { 525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // at beginning or end 535d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) name_pattern = base::UTF8ToUTF16(autofill::kNameOnCardRe); 545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 555d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) name_pattern = base::UTF8ToUTF16(autofill::kNameOnCardContextualRe); 565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (ParseField(scanner, name_pattern, &credit_card_field->cardholder_)) 595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) continue; 605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // As a hard-coded hack for Expedia's billing pages (expedia_checkout.html 625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // and ExpediaBilling.html in our test suite), recognize separate fields 635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // for the cardholder's first and last name if they have the labels "cfnm" 645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // and "clnm". 655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scanner->SaveCursor(); 661320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci AutofillField* first; 675d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (ParseField(scanner, base::ASCIIToUTF16("^cfnm"), &first) && 681320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci ParseField(scanner, 691320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci base::ASCIIToUTF16("^clnm"), 705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) &credit_card_field->cardholder_last_)) { 715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) credit_card_field->cardholder_ = first; 725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) continue; 735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scanner->Rewind(); 755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Check for a credit card type (Visa, MasterCard, etc.) field. 785d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) base::string16 type_pattern = base::UTF8ToUTF16(autofill::kCardTypeRe); 792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (!credit_card_field->type_ && 801320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci ParseFieldSpecifics(scanner, 811320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci type_pattern, 822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) MATCH_DEFAULT | MATCH_SELECT, 832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) &credit_card_field->type_)) { 842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) continue; 855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // We look for a card security code before we look for a credit 885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // card number and match the general term "number". The security code 895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // has a plethora of names; we've seen "verification #", 905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // "verification number", "card identification number" and others listed 915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // in the |pattern| below. 925d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) base::string16 pattern = base::UTF8ToUTF16(autofill::kCardCvcRe); 935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!credit_card_field->verification_ && 945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ParseField(scanner, pattern, &credit_card_field->verification_)) { 955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) continue; 965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 985d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) pattern = base::UTF8ToUTF16(autofill::kCardNumberRe); 991320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci AutofillField* current_number_field; 1001320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci if (ParseField(scanner, pattern, ¤t_number_field)) { 1011320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci // Avoid autofilling any credit card number field having very low or high 1021320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci // |start_index| on the HTML form. 1031320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci size_t start_index = 0; 1041320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci if (!credit_card_field->numbers_.empty()) { 1051320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci size_t last_number_field_size = 1061320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci credit_card_field->numbers_.back()->credit_card_number_offset() + 1071320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci credit_card_field->numbers_.back()->max_length; 1081320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 1091320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci // In some cases, HTML form may have credit card number split across 1101320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci // multiple input fields and either one or cumulatively having 1111320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci // |max_length| more than |kMaxValidCardNumberSize|, mark these input 1121320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci // form fields as invalid and skip autofilling them. 1131320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci if (last_number_field_size == 0U || 1141320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci last_number_field_size >= kMaxValidCardNumberSize) { 1151320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci // Mark that the credit card number splits are invalid. But keep 1161320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci // scanning HTML form so that cursor moves beyond related fields. 1171320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci form_has_valid_card_number_fields = false; 1181320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci } 1191320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 1201320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci start_index = last_number_field_size; 1211320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci } 1221320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 1231320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci current_number_field->set_credit_card_number_offset(start_index); 1241320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci credit_card_field->numbers_.push_back(current_number_field); 1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) continue; 1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (LowerCaseEqualsASCII(scanner->Cursor()->form_control_type, "month")) { 1291e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) credit_card_field->expiration_date_ = scanner->Cursor(); 1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scanner->Advance(); 1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // First try to parse split month/year expiration fields. 1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scanner->SaveCursor(); 1345d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) pattern = base::UTF8ToUTF16(autofill::kExpirationMonthRe); 1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!credit_card_field->expiration_month_ && 1361320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci ParseFieldSpecifics(scanner, 1371320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci pattern, 1381320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci MATCH_DEFAULT | MATCH_SELECT, 1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) &credit_card_field->expiration_month_)) { 1405d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) pattern = base::UTF8ToUTF16(autofill::kExpirationYearRe); 1411320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci if (ParseFieldSpecifics(scanner, 1421320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci pattern, 1431320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci MATCH_DEFAULT | MATCH_SELECT, 1441320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci &credit_card_field->expiration_year_)) { 1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) continue; 1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // If that fails, try to parse a combined expiration field. 1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!credit_card_field->expiration_date_) { 1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Look for a 2-digit year first. 1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scanner->Rewind(); 1535d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) pattern = base::UTF8ToUTF16(autofill::kExpirationDate2DigitYearRe); 1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // We allow <select> fields, because they're used e.g. on qvc.com. 1551320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci if (ParseFieldSpecifics( 1561320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci scanner, 1571320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci pattern, 1581320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci MATCH_LABEL | MATCH_VALUE | MATCH_TEXT | MATCH_SELECT, 1591320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci &credit_card_field->expiration_date_)) { 1601320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci credit_card_field->exp_year_type_ = CREDIT_CARD_EXP_DATE_2_DIGIT_YEAR; 1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) continue; 1625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1645d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) pattern = base::UTF8ToUTF16(autofill::kExpirationDateRe); 1651320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci if (ParseFieldSpecifics( 1661320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci scanner, 1671320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci pattern, 1681320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci MATCH_LABEL | MATCH_VALUE | MATCH_TEXT | MATCH_SELECT, 1691320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci &credit_card_field->expiration_date_)) { 1705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) continue; 1715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (credit_card_field->expiration_month_ && 1755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) !credit_card_field->expiration_year_ && 1765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) !credit_card_field->expiration_date_) { 1775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Parsed a month but couldn't parse a year; give up. 1785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scanner->RewindTo(saved_cursor); 1795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return NULL; 1805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Some pages (e.g. ExpediaBilling.html) have a "card description" 1845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // field; we parse this field but ignore it. 1855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // We also ignore any other fields within a credit card block that 1865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // start with "card", under the assumption that they are related to 1875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // the credit card section being processed but are uninteresting to us. 1885d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (ParseField(scanner, base::UTF8ToUTF16(autofill::kCardIgnoredRe), NULL)) 1895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) continue; 1905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 1925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1941320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci // Cases where heuristic misinterprets input field as credit card number 1951320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci // field, refuse to autofill credit card number fields. 1961320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci if (!form_has_valid_card_number_fields) 1971320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci credit_card_field->numbers_.clear(); 1981320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 1995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Some pages have a billing address field after the cardholder name field. 2005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // For that case, allow only just the cardholder name field. The remaining 2015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // CC fields will be picked up in a following CreditCardField. 2025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (credit_card_field->cardholder_) 2035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return credit_card_field.release(); 2045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // On some pages, the user selects a card type using radio buttons 2065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // (e.g. test page Apple Store Billing.html). We can't handle that yet, 2075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // so we treat the card type as optional for now. 2085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // The existence of a number or cvc in combination with expiration date is 2095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // a strong enough signal that this is a credit card. It is possible that 2105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // the number and name were parsed in a separate part of the form. So if 2115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // the cvc and date were found independently they are returned. 2121320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci if ((!credit_card_field->numbers_.empty() || 2131320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci credit_card_field->verification_ || 2141320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci !form_has_valid_card_number_fields) && 2155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (credit_card_field->expiration_date_ || 2165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (credit_card_field->expiration_month_ && 2171e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) credit_card_field->expiration_year_))) { 2185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return credit_card_field.release(); 2195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scanner->RewindTo(saved_cursor); 2225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return NULL; 2235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)CreditCardField::CreditCardField() 2265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) : cardholder_(NULL), 2275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) cardholder_last_(NULL), 2285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) type_(NULL), 2295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) verification_(NULL), 2305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) expiration_month_(NULL), 2315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) expiration_year_(NULL), 2325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) expiration_date_(NULL), 2331320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci exp_year_type_(CREDIT_CARD_EXP_DATE_4_DIGIT_YEAR) { 2341320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci} 2351320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 2361320f92c476a1ad9d19dba2a48c72b75566198e9Primiano TucciCreditCardField::~CreditCardField() { 2375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2393240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdochbool CreditCardField::ClassifyField(ServerFieldTypeMap* map) const { 2401320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci bool ok = true; 2411320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci for (size_t index = 0; index < numbers_.size(); ++index) { 2421320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci ok = ok && AddClassification(numbers_[index], CREDIT_CARD_NUMBER, map); 2431320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci } 2441320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 2455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ok = ok && AddClassification(type_, CREDIT_CARD_TYPE, map); 2461320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci ok = ok && 2471320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci AddClassification(verification_, CREDIT_CARD_VERIFICATION_CODE, map); 2485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // If the heuristics detected first and last name in separate fields, 2505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // then ignore both fields. Putting them into separate fields is probably 2515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // wrong, because the credit card can also contain a middle name or middle 2525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // initial. 2535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (cardholder_last_ == NULL) 2545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ok = ok && AddClassification(cardholder_, CREDIT_CARD_NAME, map); 2555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (expiration_date_) { 2571320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci ok = 2581320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci ok && AddClassification(expiration_date_, GetExpirationYearType(), map); 2595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 2605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ok = ok && AddClassification(expiration_month_, CREDIT_CARD_EXP_MONTH, map); 2611320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci ok = 2621320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci ok && AddClassification(expiration_year_, GetExpirationYearType(), map); 2635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return ok; 2665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 267c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 2681320f92c476a1ad9d19dba2a48c72b75566198e9Primiano TucciServerFieldType CreditCardField::GetExpirationYearType() const { 2691320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci return (expiration_date_ 2701320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci ? exp_year_type_ 2711320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci : ((expiration_year_ && expiration_year_->max_length == 2) 2721320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci ? CREDIT_CARD_EXP_2_DIGIT_YEAR 2731320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci : CREDIT_CARD_EXP_4_DIGIT_YEAR)); 2741320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci} 2751320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 276c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} // namespace autofill 277