credit_card.cc revision a1401311d1ab56c4ed0a474bd38c108f75cb0cd9
15c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)// Copyright 2013 The Chromium Authors. All rights reserved. 25c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 35c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)// found in the LICENSE file. 45c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 55c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)#include "components/autofill/core/browser/credit_card.h" 65c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 75c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)#include <stddef.h> 85c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 95c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)#include <algorithm> 105c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)#include <ostream> 115c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)#include <string> 125c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 135c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)#include "base/basictypes.h" 145c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)#include "base/guid.h" 155c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)#include "base/logging.h" 165c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)#include "base/strings/string16.h" 175c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)#include "base/strings/string_number_conversions.h" 185c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)#include "base/strings/string_split.h" 195c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)#include "base/strings/string_util.h" 205c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)#include "base/strings/utf_string_conversions.h" 215c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)#include "base/time/time.h" 225c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)#include "components/autofill/core/browser/autofill_field.h" 235c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)#include "components/autofill/core/browser/autofill_regexes.h" 245c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)#include "components/autofill/core/browser/autofill_type.h" 255c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)#include "components/autofill/core/browser/validation.h" 265c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)#include "components/autofill/core/common/form_field_data.h" 275c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)#include "grit/component_scaled_resources.h" 285c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)#include "grit/component_strings.h" 295c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)#include "third_party/icu/source/common/unicode/uloc.h" 305c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)#include "third_party/icu/source/i18n/unicode/dtfmtsym.h" 315c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)#include "ui/base/l10n/l10n_util.h" 3253e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles) 335c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)namespace autofill { 345c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 355c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)namespace { 365c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 375c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)const base::char16 kCreditCardObfuscationSymbol = '*'; 385c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 395c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)// This is the maximum obfuscated symbols displayed. 405c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)// It is introduced to avoid rare cases where the credit card number is 415c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)// too large and fills the screen. 425c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)const size_t kMaxObfuscationSize = 20; 435c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 445c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)bool ConvertYear(const base::string16& year, int* num) { 455c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // If the |year| is empty, clear the stored value. 465c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (year.empty()) { 475c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) *num = 0; 485c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return true; 4953e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles) } 5053e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles) 517242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci // Try parsing the |year| as a number. 5253e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles) if (base::StringToInt(year, num)) 53f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles) return true; 54f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles) 55f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles) *num = 0; 5653e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles) return false; 577242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci} 587242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci 597242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tuccibool ConvertMonth(const base::string16& month, 607242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci const std::string& app_locale, 617242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci int* num) { 627242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci // If the |month| is empty, clear the stored value. 637242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci if (month.empty()) { 647242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci *num = 0; 65e69819bd8e388ea4ad1636a19aa6b2eed4952191Ben Murdoch return true; 66e69819bd8e388ea4ad1636a19aa6b2eed4952191Ben Murdoch } 67e69819bd8e388ea4ad1636a19aa6b2eed4952191Ben Murdoch 687242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci // Try parsing the |month| as a number. 697242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci if (base::StringToInt(month, num)) 70e69819bd8e388ea4ad1636a19aa6b2eed4952191Ben Murdoch return true; 71e69819bd8e388ea4ad1636a19aa6b2eed4952191Ben Murdoch 72e69819bd8e388ea4ad1636a19aa6b2eed4952191Ben Murdoch // If the locale is unknown, give up. 73e69819bd8e388ea4ad1636a19aa6b2eed4952191Ben Murdoch if (app_locale.empty()) 74e69819bd8e388ea4ad1636a19aa6b2eed4952191Ben Murdoch return false; 757242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci 76e69819bd8e388ea4ad1636a19aa6b2eed4952191Ben Murdoch // Otherwise, try parsing the |month| as a named month, e.g. "January" or 77e69819bd8e388ea4ad1636a19aa6b2eed4952191Ben Murdoch // "Jan". 78e69819bd8e388ea4ad1636a19aa6b2eed4952191Ben Murdoch base::string16 lowercased_month = StringToLowerASCII(month); 7953e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles) 807242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci UErrorCode status = U_ZERO_ERROR; 817242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci icu::Locale locale(app_locale.c_str()); 827242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci icu::DateFormatSymbols date_format_symbols(locale, status); 837242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci DCHECK(status == U_ZERO_ERROR || status == U_USING_FALLBACK_WARNING || 847242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci status == U_USING_DEFAULT_WARNING); 857242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci 867242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci int32_t num_months; 877242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci const icu::UnicodeString* months = date_format_symbols.getMonths(num_months); 887242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci for (int32_t i = 0; i < num_months; ++i) { 897242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci const base::string16 icu_month = base::string16(months[i].getBuffer(), 907242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci months[i].length()); 915c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (lowercased_month == StringToLowerASCII(icu_month)) { 92f5e4ad553afbc08dd2e729bb77e937a9a94d5827Torne (Richard Coles) *num = i + 1; // Adjust from 0-indexed to 1-indexed. 93e69819bd8e388ea4ad1636a19aa6b2eed4952191Ben Murdoch return true; 94e69819bd8e388ea4ad1636a19aa6b2eed4952191Ben Murdoch } 959e12abdf8c3a23d52091ea54ebb6a04d327f9300Torne (Richard Coles) } 969e12abdf8c3a23d52091ea54ebb6a04d327f9300Torne (Richard Coles) 97e69819bd8e388ea4ad1636a19aa6b2eed4952191Ben Murdoch months = date_format_symbols.getShortMonths(num_months); 987242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci for (int32_t i = 0; i < num_months; ++i) { 99e69819bd8e388ea4ad1636a19aa6b2eed4952191Ben Murdoch const base::string16 icu_month = base::string16(months[i].getBuffer(), 100e69819bd8e388ea4ad1636a19aa6b2eed4952191Ben Murdoch months[i].length()); 101e69819bd8e388ea4ad1636a19aa6b2eed4952191Ben Murdoch if (lowercased_month == StringToLowerASCII(icu_month)) { 102e69819bd8e388ea4ad1636a19aa6b2eed4952191Ben Murdoch *num = i + 1; // Adjust from 0-indexed to 1-indexed. 103f5e4ad553afbc08dd2e729bb77e937a9a94d5827Torne (Richard Coles) return true; 104f5e4ad553afbc08dd2e729bb77e937a9a94d5827Torne (Richard Coles) } 105f5e4ad553afbc08dd2e729bb77e937a9a94d5827Torne (Richard Coles) } 106f5e4ad553afbc08dd2e729bb77e937a9a94d5827Torne (Richard Coles) 1077242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci *num = 0; 108e69819bd8e388ea4ad1636a19aa6b2eed4952191Ben Murdoch return false; 10953e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)} 110f5e4ad553afbc08dd2e729bb77e937a9a94d5827Torne (Richard Coles) 1115c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} // namespace 1125c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 1135c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)CreditCard::CreditCard(const std::string& guid, const std::string& origin) 1145c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) : AutofillDataModel(guid, origin), 115e69819bd8e388ea4ad1636a19aa6b2eed4952191Ben Murdoch type_(kGenericCard), 1165c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) expiration_month_(0), 1177242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci expiration_year_(0) { 1187242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci} 1195c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 1205c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)CreditCard::CreditCard() 1215c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) : AutofillDataModel(base::GenerateGUID(), std::string()), 1225c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) type_(kGenericCard), 1235c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) expiration_month_(0), 12453e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles) expiration_year_(0) { 125e69819bd8e388ea4ad1636a19aa6b2eed4952191Ben Murdoch} 12653e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles) 1277242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano TucciCreditCard::CreditCard(const CreditCard& credit_card) 1287242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci : AutofillDataModel(std::string(), std::string()) { 12953e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles) operator=(credit_card); 13053e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)} 13153e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles) 132e69819bd8e388ea4ad1636a19aa6b2eed4952191Ben MurdochCreditCard::~CreditCard() {} 13353e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles) 13453e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)// static 135e69819bd8e388ea4ad1636a19aa6b2eed4952191Ben Murdochconst base::string16 CreditCard::StripSeparators(const base::string16& number) { 13653e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles) const base::char16 kSeparators[] = {'-', ' ', '\0'}; 13753e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles) base::string16 stripped; 13853e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles) base::RemoveChars(number, kSeparators, &stripped); 139e69819bd8e388ea4ad1636a19aa6b2eed4952191Ben Murdoch return stripped; 14053e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)} 14153e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles) 14253e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)// static 14353e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)base::string16 CreditCard::TypeForDisplay(const std::string& type) { 14453e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles) if (type == kAmericanExpressCard) 14553e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles) return l10n_util::GetStringUTF16(IDS_AUTOFILL_CC_AMEX); 14653e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles) if (type == kDinersCard) 14753e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles) return l10n_util::GetStringUTF16(IDS_AUTOFILL_CC_DINERS); 14853e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles) if (type == kDiscoverCard) 14953e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles) return l10n_util::GetStringUTF16(IDS_AUTOFILL_CC_DISCOVER); 15053e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles) if (type == kJCBCard) 15153e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles) return l10n_util::GetStringUTF16(IDS_AUTOFILL_CC_JCB); 15253e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles) if (type == kMasterCard) 15353e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles) return l10n_util::GetStringUTF16(IDS_AUTOFILL_CC_MASTERCARD); 15453e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles) if (type == kUnionPay) 1557242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci return l10n_util::GetStringUTF16(IDS_AUTOFILL_CC_UNION_PAY); 156e69819bd8e388ea4ad1636a19aa6b2eed4952191Ben Murdoch if (type == kVisaCard) 15753e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles) return l10n_util::GetStringUTF16(IDS_AUTOFILL_CC_VISA); 15853e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles) 15953e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles) // If you hit this DCHECK, the above list of cases needs to be updated to 160e69819bd8e388ea4ad1636a19aa6b2eed4952191Ben Murdoch // include a new card. 161e69819bd8e388ea4ad1636a19aa6b2eed4952191Ben Murdoch DCHECK_EQ(kGenericCard, type); 16253e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles) return base::string16(); 16353e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)} 164e69819bd8e388ea4ad1636a19aa6b2eed4952191Ben Murdoch 16553e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)// static 16653e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)int CreditCard::IconResourceId(const std::string& type) { 1675c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (type == kAmericanExpressCard) 1685c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return IDR_AUTOFILL_CC_AMEX; 1695c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (type == kDinersCard) 170e69819bd8e388ea4ad1636a19aa6b2eed4952191Ben Murdoch return IDR_AUTOFILL_CC_DINERS; 1715c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (type == kDiscoverCard) 1725c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return IDR_AUTOFILL_CC_DISCOVER; 173e69819bd8e388ea4ad1636a19aa6b2eed4952191Ben Murdoch if (type == kJCBCard) 174e69819bd8e388ea4ad1636a19aa6b2eed4952191Ben Murdoch return IDR_AUTOFILL_CC_JCB; 1755c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (type == kMasterCard) 1765c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return IDR_AUTOFILL_CC_MASTERCARD; 1775c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (type == kUnionPay) 178e69819bd8e388ea4ad1636a19aa6b2eed4952191Ben Murdoch return IDR_AUTOFILL_CC_GENERIC; // Needs resource: http://crbug.com/259211 17953e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles) if (type == kVisaCard) 1807242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci return IDR_AUTOFILL_CC_VISA; 18153e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles) 18253e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles) // If you hit this DCHECK, the above list of cases needs to be updated to 18353e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles) // include a new card. 18453e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles) DCHECK_EQ(kGenericCard, type); 18553e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles) return IDR_AUTOFILL_CC_GENERIC; 18653e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)} 1877242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci 18853e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)// static 18953e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)std::string CreditCard::GetCreditCardType(const base::string16& number) { 19053e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles) // Credit card number specifications taken from: 19153e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles) // http://en.wikipedia.org/wiki/Credit_card_numbers, 19253e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles) // http://en.wikipedia.org/wiki/List_of_Issuer_Identification_Numbers, 19353e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles) // http://www.discovernetwork.com/merchants/images/Merchant_Marketing_PDF.pdf, 19453e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles) // http://www.regular-expressions.info/creditcard.html, 19553e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles) // http://developer.ean.com/general_info/Valid_Credit_Card_Types, 19653e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles) // http://www.bincodes.com/, 19753e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles) // http://www.fraudpractice.com/FL-binCC.html, and 19853e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles) // http://www.beachnet.com/~hstiles/cardtype.html 19953e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles) // 2005c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // The last site is currently unavailable, but a cached version remains at 2015c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // http://web.archive.org/web/20120923111349/http://www.beachnet.com/~hstiles/cardtype.html 20253e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles) // 2035c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // Card Type Prefix(es) Length 2045c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // --------------------------------------------------------------- 2055c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // Visa 4 13,16 2065c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // American Express 34,37 15 2075c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // Diners Club 300-305,3095,36,38-39 14 2085c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // Discover Card 6011,644-649,65 16 2095c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // JCB 3528-3589 16 2105c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // MasterCard 51-55 16 21153e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles) // UnionPay 62 16-19 2125c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 2135c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // Check for prefixes of length 1. 2145c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (number.empty()) 2155c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return kGenericCard; 2165c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 2175c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (number[0] == '4') 2185c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return kVisaCard; 2195c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 2205c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // Check for prefixes of length 2. 2215c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (number.size() < 2) 2225c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return kGenericCard; 223f5e4ad553afbc08dd2e729bb77e937a9a94d5827Torne (Richard Coles) 2245c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) int first_two_digits = 0; 2255c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (!base::StringToInt(number.substr(0, 2), &first_two_digits)) 22609380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) return kGenericCard; 22709380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) 2285c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (first_two_digits == 34 || first_two_digits == 37) 2295c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return kAmericanExpressCard; 23009380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) 23109380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) if (first_two_digits == 36 || 23209380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) first_two_digits == 38 || 23309380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) first_two_digits == 39) 23409380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) return kDinersCard; 23509380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) 23609380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) if (first_two_digits >= 51 && first_two_digits <= 55) 23709380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) return kMasterCard; 23809380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) 23909380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) if (first_two_digits == 62) 24009380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) return kUnionPay; 241f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles) 242f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles) if (first_two_digits == 65) 243f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles) return kDiscoverCard; 244f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles) 24509380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) // Check for prefixes of length 3. 24609380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) if (number.size() < 3) 24709380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) return kGenericCard; 24809380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) 24909380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) int first_three_digits = 0; 25009380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) if (!base::StringToInt(number.substr(0, 3), &first_three_digits)) 2515c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return kGenericCard; 2525c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 2535c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (first_three_digits >= 300 && first_three_digits <= 305) 2545c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return kDinersCard; 2555c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 2565c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (first_three_digits >= 644 && first_three_digits <= 649) 257f5e4ad553afbc08dd2e729bb77e937a9a94d5827Torne (Richard Coles) return kDiscoverCard; 2585c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 2595c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // Check for prefixes of length 4. 2605c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (number.size() < 4) 261f5e4ad553afbc08dd2e729bb77e937a9a94d5827Torne (Richard Coles) return kGenericCard; 2625c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 2635c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) int first_four_digits = 0; 2645c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (!base::StringToInt(number.substr(0, 4), &first_four_digits)) 2655c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return kGenericCard; 266f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles) 267f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles) if (first_four_digits == 3095) 268f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles) return kDinersCard; 269f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles) 270f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles) if (first_four_digits >= 3528 && first_four_digits <= 3589) 271f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles) return kJCBCard; 2725c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 2735c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (first_four_digits == 6011) 2745c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return kDiscoverCard; 2755c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 2765c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return kGenericCard; 2775c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 2785c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 279e69819bd8e388ea4ad1636a19aa6b2eed4952191Ben Murdochbase::string16 CreditCard::GetRawInfo(ServerFieldType type) const { 2805c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) DCHECK_EQ(CREDIT_CARD, AutofillType(type).group()); 2815c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) switch (type) { 28253e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles) case CREDIT_CARD_NAME: 2835c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return name_on_card_; 2845c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 2855c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) case CREDIT_CARD_EXP_MONTH: 2865c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return ExpirationMonthAsString(); 2875c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 2885c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) case CREDIT_CARD_EXP_2_DIGIT_YEAR: 28953e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles) return Expiration2DigitYearAsString(); 290e69819bd8e388ea4ad1636a19aa6b2eed4952191Ben Murdoch 2915c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) case CREDIT_CARD_EXP_4_DIGIT_YEAR: 29253e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles) return Expiration4DigitYearAsString(); 293e69819bd8e388ea4ad1636a19aa6b2eed4952191Ben Murdoch 29453e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles) case CREDIT_CARD_EXP_DATE_2_DIGIT_YEAR: { 29553e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles) base::string16 month = ExpirationMonthAsString(); 29653e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles) base::string16 year = Expiration2DigitYearAsString(); 2975c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (!month.empty() && !year.empty()) 2985c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return month + base::ASCIIToUTF16("/") + year; 2995c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return base::string16(); 3005c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 3015c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 3025c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) case CREDIT_CARD_EXP_DATE_4_DIGIT_YEAR: { 3035c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) base::string16 month = ExpirationMonthAsString(); 3045c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) base::string16 year = Expiration4DigitYearAsString(); 3055c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (!month.empty() && !year.empty()) 3065c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return month + base::ASCIIToUTF16("/") + year; 3075c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return base::string16(); 308e69819bd8e388ea4ad1636a19aa6b2eed4952191Ben Murdoch } 309e69819bd8e388ea4ad1636a19aa6b2eed4952191Ben Murdoch 3107242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci case CREDIT_CARD_TYPE: 311e69819bd8e388ea4ad1636a19aa6b2eed4952191Ben Murdoch return TypeForDisplay(); 312e69819bd8e388ea4ad1636a19aa6b2eed4952191Ben Murdoch 313e69819bd8e388ea4ad1636a19aa6b2eed4952191Ben Murdoch case CREDIT_CARD_NUMBER: 314e69819bd8e388ea4ad1636a19aa6b2eed4952191Ben Murdoch return number_; 315e69819bd8e388ea4ad1636a19aa6b2eed4952191Ben Murdoch 316e69819bd8e388ea4ad1636a19aa6b2eed4952191Ben Murdoch case CREDIT_CARD_VERIFICATION_CODE: 3177242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci // Chrome doesn't store credit card verification codes. 3187242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci return base::string16(); 319e69819bd8e388ea4ad1636a19aa6b2eed4952191Ben Murdoch 320e69819bd8e388ea4ad1636a19aa6b2eed4952191Ben Murdoch default: 321e69819bd8e388ea4ad1636a19aa6b2eed4952191Ben Murdoch // ComputeDataPresentForArray will hit this repeatedly. 322e69819bd8e388ea4ad1636a19aa6b2eed4952191Ben Murdoch return base::string16(); 323e69819bd8e388ea4ad1636a19aa6b2eed4952191Ben Murdoch } 324e69819bd8e388ea4ad1636a19aa6b2eed4952191Ben Murdoch} 325e69819bd8e388ea4ad1636a19aa6b2eed4952191Ben Murdoch 326f5e4ad553afbc08dd2e729bb77e937a9a94d5827Torne (Richard Coles)void CreditCard::SetRawInfo(ServerFieldType type, 327c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles) const base::string16& value) { 328c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles) DCHECK_EQ(CREDIT_CARD, AutofillType(type).group()); 329c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles) switch (type) { 330c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles) case CREDIT_CARD_NAME: 331c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles) name_on_card_ = value; 332c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles) break; 333c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles) 334c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles) case CREDIT_CARD_EXP_MONTH: 335f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles) SetExpirationMonthFromString(value, std::string()); 336c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles) break; 337c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles) 338e69819bd8e388ea4ad1636a19aa6b2eed4952191Ben Murdoch case CREDIT_CARD_EXP_2_DIGIT_YEAR: 339e69819bd8e388ea4ad1636a19aa6b2eed4952191Ben Murdoch // This is a read-only attribute. 340e69819bd8e388ea4ad1636a19aa6b2eed4952191Ben Murdoch break; 341e69819bd8e388ea4ad1636a19aa6b2eed4952191Ben Murdoch 342e69819bd8e388ea4ad1636a19aa6b2eed4952191Ben Murdoch case CREDIT_CARD_EXP_4_DIGIT_YEAR: 343e69819bd8e388ea4ad1636a19aa6b2eed4952191Ben Murdoch SetExpirationYearFromString(value); 344e69819bd8e388ea4ad1636a19aa6b2eed4952191Ben Murdoch break; 345e69819bd8e388ea4ad1636a19aa6b2eed4952191Ben Murdoch 3467242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci case CREDIT_CARD_EXP_DATE_2_DIGIT_YEAR: 3477242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci // This is a read-only attribute. 348e69819bd8e388ea4ad1636a19aa6b2eed4952191Ben Murdoch break; 349e69819bd8e388ea4ad1636a19aa6b2eed4952191Ben Murdoch 3507242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci case CREDIT_CARD_EXP_DATE_4_DIGIT_YEAR: 351e69819bd8e388ea4ad1636a19aa6b2eed4952191Ben Murdoch // This is a read-only attribute. 352f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles) break; 353e69819bd8e388ea4ad1636a19aa6b2eed4952191Ben Murdoch 354e69819bd8e388ea4ad1636a19aa6b2eed4952191Ben Murdoch case CREDIT_CARD_TYPE: 355e69819bd8e388ea4ad1636a19aa6b2eed4952191Ben Murdoch // This is a read-only attribute, determined by the credit card number. 356e69819bd8e388ea4ad1636a19aa6b2eed4952191Ben Murdoch break; 357e69819bd8e388ea4ad1636a19aa6b2eed4952191Ben Murdoch 358f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles) case CREDIT_CARD_NUMBER: { 359 // Don't change the real value if the input is an obfuscated string. 360 if (value.size() > 0 && value[0] != kCreditCardObfuscationSymbol) 361 SetNumber(value); 362 break; 363 } 364 365 case CREDIT_CARD_VERIFICATION_CODE: 366 // Chrome doesn't store the credit card verification code. 367 break; 368 369 default: 370 NOTREACHED() << "Attempting to set unknown info-type " << type; 371 break; 372 } 373} 374 375base::string16 CreditCard::GetInfo(const AutofillType& type, 376 const std::string& app_locale) const { 377 ServerFieldType storable_type = type.GetStorableType(); 378 if (storable_type == CREDIT_CARD_NUMBER) 379 return StripSeparators(number_); 380 381 return GetRawInfo(storable_type); 382} 383 384bool CreditCard::SetInfo(const AutofillType& type, 385 const base::string16& value, 386 const std::string& app_locale) { 387 ServerFieldType storable_type = type.GetStorableType(); 388 if (storable_type == CREDIT_CARD_NUMBER) 389 SetRawInfo(storable_type, StripSeparators(value)); 390 else if (storable_type == CREDIT_CARD_EXP_MONTH) 391 SetExpirationMonthFromString(value, app_locale); 392 else 393 SetRawInfo(storable_type, value); 394 395 return true; 396} 397 398void CreditCard::GetMatchingTypes(const base::string16& text, 399 const std::string& app_locale, 400 ServerFieldTypeSet* matching_types) const { 401 FormGroup::GetMatchingTypes(text, app_locale, matching_types); 402 403 base::string16 card_number = 404 GetInfo(AutofillType(CREDIT_CARD_NUMBER), app_locale); 405 if (!card_number.empty() && StripSeparators(text) == card_number) 406 matching_types->insert(CREDIT_CARD_NUMBER); 407 408 int month; 409 if (ConvertMonth(text, app_locale, &month) && month != 0 && 410 month == expiration_month_) { 411 matching_types->insert(CREDIT_CARD_EXP_MONTH); 412 } 413} 414 415const base::string16 CreditCard::Label() const { 416 base::string16 label; 417 if (number().empty()) 418 return name_on_card_; // No CC number, return name only. 419 420 base::string16 obfuscated_cc_number = ObfuscatedNumber(); 421 if (!expiration_month_ || !expiration_year_) 422 return obfuscated_cc_number; // No expiration date set. 423 424 // TODO(georgey): Internationalize date. 425 base::string16 formatted_date(ExpirationMonthAsString()); 426 formatted_date.append(base::ASCIIToUTF16("/")); 427 formatted_date.append(Expiration4DigitYearAsString()); 428 429 label = l10n_util::GetStringFUTF16(IDS_CREDIT_CARD_NUMBER_PREVIEW_FORMAT, 430 obfuscated_cc_number, 431 formatted_date); 432 return label; 433} 434 435void CreditCard::SetInfoForMonthInputType(const base::string16& value) { 436 // Check if |text| is "yyyy-mm" format first, and check normal month format. 437 if (!autofill::MatchesPattern(value, 438 base::UTF8ToUTF16("^[0-9]{4}-[0-9]{1,2}$"))) { 439 return; 440 } 441 442 std::vector<base::string16> year_month; 443 base::SplitString(value, L'-', &year_month); 444 DCHECK_EQ((int)year_month.size(), 2); 445 int num = 0; 446 bool converted = false; 447 converted = base::StringToInt(year_month[0], &num); 448 DCHECK(converted); 449 SetExpirationYear(num); 450 converted = base::StringToInt(year_month[1], &num); 451 DCHECK(converted); 452 SetExpirationMonth(num); 453} 454 455base::string16 CreditCard::ObfuscatedNumber() const { 456 // If the number is shorter than four digits, there's no need to obfuscate it. 457 if (number_.size() < 4) 458 return number_; 459 460 base::string16 number = StripSeparators(number_); 461 462 // Avoid making very long obfuscated numbers. 463 size_t obfuscated_digits = std::min(kMaxObfuscationSize, number.size() - 4); 464 base::string16 result(obfuscated_digits, kCreditCardObfuscationSymbol); 465 return result.append(LastFourDigits()); 466} 467 468base::string16 CreditCard::LastFourDigits() const { 469 static const size_t kNumLastDigits = 4; 470 471 base::string16 number = StripSeparators(number_); 472 if (number.size() < kNumLastDigits) 473 return base::string16(); 474 475 return number.substr(number.size() - kNumLastDigits, kNumLastDigits); 476} 477 478base::string16 CreditCard::TypeForDisplay() const { 479 return CreditCard::TypeForDisplay(type_); 480} 481 482base::string16 CreditCard::TypeAndLastFourDigits() const { 483 base::string16 type = TypeForDisplay(); 484 // TODO(estade): type may be empty, we probably want to return 485 // "Card - 1234" or something in that case. 486 487 base::string16 digits = LastFourDigits(); 488 if (digits.empty()) 489 return type; 490 491 // TODO(estade): i18n. 492 return type + base::ASCIIToUTF16(" - ") + digits; 493} 494 495void CreditCard::operator=(const CreditCard& credit_card) { 496 if (this == &credit_card) 497 return; 498 499 number_ = credit_card.number_; 500 name_on_card_ = credit_card.name_on_card_; 501 type_ = credit_card.type_; 502 expiration_month_ = credit_card.expiration_month_; 503 expiration_year_ = credit_card.expiration_year_; 504 505 set_guid(credit_card.guid()); 506 set_origin(credit_card.origin()); 507} 508 509bool CreditCard::UpdateFromImportedCard(const CreditCard& imported_card, 510 const std::string& app_locale) { 511 if (this->GetInfo(AutofillType(CREDIT_CARD_NUMBER), app_locale) != 512 imported_card.GetInfo(AutofillType(CREDIT_CARD_NUMBER), app_locale)) { 513 return false; 514 } 515 516 // Heuristically aggregated data should never overwrite verified data. 517 // Instead, discard any heuristically aggregated credit cards that disagree 518 // with explicitly entered data, so that the UI is not cluttered with 519 // duplicate cards. 520 if (this->IsVerified() && !imported_card.IsVerified()) 521 return true; 522 523 set_origin(imported_card.origin()); 524 525 // Note that the card number is intentionally not updated, so as to preserve 526 // any formatting (i.e. separator characters). Since the card number is not 527 // updated, there is no reason to update the card type, either. 528 if (!imported_card.name_on_card_.empty()) 529 name_on_card_ = imported_card.name_on_card_; 530 531 // The expiration date for |imported_card| should always be set. 532 DCHECK(imported_card.expiration_month_ && imported_card.expiration_year_); 533 expiration_month_ = imported_card.expiration_month_; 534 expiration_year_ = imported_card.expiration_year_; 535 536 return true; 537} 538 539int CreditCard::Compare(const CreditCard& credit_card) const { 540 // The following CreditCard field types are the only types we store in the 541 // WebDB so far, so we're only concerned with matching these types in the 542 // credit card. 543 const ServerFieldType types[] = { CREDIT_CARD_NAME, 544 CREDIT_CARD_NUMBER, 545 CREDIT_CARD_EXP_MONTH, 546 CREDIT_CARD_EXP_4_DIGIT_YEAR }; 547 for (size_t i = 0; i < arraysize(types); ++i) { 548 int comparison = 549 GetRawInfo(types[i]).compare(credit_card.GetRawInfo(types[i])); 550 if (comparison != 0) 551 return comparison; 552 } 553 554 return 0; 555} 556 557bool CreditCard::operator==(const CreditCard& credit_card) const { 558 return guid() == credit_card.guid() && 559 origin() == credit_card.origin() && 560 Compare(credit_card) == 0; 561} 562 563bool CreditCard::operator!=(const CreditCard& credit_card) const { 564 return !operator==(credit_card); 565} 566 567bool CreditCard::IsEmpty(const std::string& app_locale) const { 568 ServerFieldTypeSet types; 569 GetNonEmptyTypes(app_locale, &types); 570 return types.empty(); 571} 572 573bool CreditCard::IsComplete() const { 574 return 575 autofill::IsValidCreditCardNumber(number_) && 576 expiration_month_ != 0 && 577 expiration_year_ != 0; 578} 579 580bool CreditCard::IsValid() const { 581 return autofill::IsValidCreditCardNumber(number_) && 582 autofill::IsValidCreditCardExpirationDate( 583 expiration_year_, expiration_month_, base::Time::Now()); 584} 585 586void CreditCard::GetSupportedTypes(ServerFieldTypeSet* supported_types) const { 587 supported_types->insert(CREDIT_CARD_NAME); 588 supported_types->insert(CREDIT_CARD_NUMBER); 589 supported_types->insert(CREDIT_CARD_TYPE); 590 supported_types->insert(CREDIT_CARD_EXP_MONTH); 591 supported_types->insert(CREDIT_CARD_EXP_2_DIGIT_YEAR); 592 supported_types->insert(CREDIT_CARD_EXP_4_DIGIT_YEAR); 593 supported_types->insert(CREDIT_CARD_EXP_DATE_2_DIGIT_YEAR); 594 supported_types->insert(CREDIT_CARD_EXP_DATE_4_DIGIT_YEAR); 595} 596 597base::string16 CreditCard::ExpirationMonthAsString() const { 598 if (expiration_month_ == 0) 599 return base::string16(); 600 601 base::string16 month = base::IntToString16(expiration_month_); 602 if (expiration_month_ >= 10) 603 return month; 604 605 base::string16 zero = base::ASCIIToUTF16("0"); 606 zero.append(month); 607 return zero; 608} 609 610base::string16 CreditCard::Expiration4DigitYearAsString() const { 611 if (expiration_year_ == 0) 612 return base::string16(); 613 614 return base::IntToString16(Expiration4DigitYear()); 615} 616 617base::string16 CreditCard::Expiration2DigitYearAsString() const { 618 if (expiration_year_ == 0) 619 return base::string16(); 620 621 return base::IntToString16(Expiration2DigitYear()); 622} 623 624void CreditCard::SetExpirationMonthFromString(const base::string16& text, 625 const std::string& app_locale) { 626 int month; 627 if (!ConvertMonth(text, app_locale, &month)) 628 return; 629 630 SetExpirationMonth(month); 631} 632 633void CreditCard::SetExpirationYearFromString(const base::string16& text) { 634 int year; 635 if (!ConvertYear(text, &year)) 636 return; 637 638 SetExpirationYear(year); 639} 640 641void CreditCard::SetNumber(const base::string16& number) { 642 number_ = number; 643 type_ = GetCreditCardType(StripSeparators(number_)); 644} 645 646void CreditCard::SetExpirationMonth(int expiration_month) { 647 if (expiration_month < 0 || expiration_month > 12) 648 return; 649 650 expiration_month_ = expiration_month; 651} 652 653void CreditCard::SetExpirationYear(int expiration_year) { 654 if (expiration_year != 0 && 655 (expiration_year < 2006 || expiration_year > 10000)) { 656 return; 657 } 658 659 expiration_year_ = expiration_year; 660} 661 662// So we can compare CreditCards with EXPECT_EQ(). 663std::ostream& operator<<(std::ostream& os, const CreditCard& credit_card) { 664 return os 665 << base::UTF16ToUTF8(credit_card.Label()) 666 << " " 667 << credit_card.guid() 668 << " " 669 << credit_card.origin() 670 << " " 671 << base::UTF16ToUTF8(credit_card.GetRawInfo(CREDIT_CARD_NAME)) 672 << " " 673 << base::UTF16ToUTF8(credit_card.GetRawInfo(CREDIT_CARD_TYPE)) 674 << " " 675 << base::UTF16ToUTF8(credit_card.GetRawInfo(CREDIT_CARD_NUMBER)) 676 << " " 677 << base::UTF16ToUTF8(credit_card.GetRawInfo(CREDIT_CARD_EXP_MONTH)) 678 << " " 679 << base::UTF16ToUTF8( 680 credit_card.GetRawInfo(CREDIT_CARD_EXP_4_DIGIT_YEAR)); 681} 682 683// These values must match the values in WebKitPlatformSupportImpl in 684// webkit/glue. We send these strings to WebKit, which then asks 685// WebKitPlatformSupportImpl to load the image data. 686const char* const kAmericanExpressCard = "americanExpressCC"; 687const char* const kDinersCard = "dinersCC"; 688const char* const kDiscoverCard = "discoverCC"; 689const char* const kGenericCard = "genericCC"; 690const char* const kJCBCard = "jcbCC"; 691const char* const kMasterCard = "masterCardCC"; 692const char* const kUnionPay = "unionPayCC"; 693const char* const kVisaCard = "visaCC"; 694 695} // namespace autofill 696