| OLD | NEW |
| 1 // Copyright 2013 The Chromium Authors. All rights reserved. | 1 // Copyright 2013 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "components/autofill/core/browser/credit_card.h" | 5 #include "components/autofill/core/browser/credit_card.h" |
| 6 | 6 |
| 7 #include <stddef.h> | 7 #include <stddef.h> |
| 8 #include <stdint.h> | 8 #include <stdint.h> |
| 9 | 9 |
| 10 #include <algorithm> | 10 #include <algorithm> |
| (...skipping 17 matching lines...) Expand all Loading... |
| 28 #include "components/autofill/core/browser/validation.h" | 28 #include "components/autofill/core/browser/validation.h" |
| 29 #include "components/autofill/core/common/autofill_l10n_util.h" | 29 #include "components/autofill/core/common/autofill_l10n_util.h" |
| 30 #include "components/autofill/core/common/autofill_regexes.h" | 30 #include "components/autofill/core/common/autofill_regexes.h" |
| 31 #include "components/autofill/core/common/form_field_data.h" | 31 #include "components/autofill/core/common/form_field_data.h" |
| 32 #include "grit/components_scaled_resources.h" | 32 #include "grit/components_scaled_resources.h" |
| 33 #include "grit/components_strings.h" | 33 #include "grit/components_strings.h" |
| 34 #include "third_party/icu/source/common/unicode/uloc.h" | 34 #include "third_party/icu/source/common/unicode/uloc.h" |
| 35 #include "third_party/icu/source/i18n/unicode/dtfmtsym.h" | 35 #include "third_party/icu/source/i18n/unicode/dtfmtsym.h" |
| 36 #include "ui/base/l10n/l10n_util.h" | 36 #include "ui/base/l10n/l10n_util.h" |
| 37 | 37 |
| 38 using base::ASCIIToUTF16; |
| 39 |
| 38 namespace autofill { | 40 namespace autofill { |
| 39 | 41 |
| 40 const base::char16 kMidlineEllipsis[] = { 0x22ef, 0 }; | 42 const base::char16 kMidlineEllipsis[] = { 0x22ef, 0 }; |
| 41 | 43 |
| 42 namespace { | 44 namespace { |
| 43 | 45 |
| 44 const base::char16 kCreditCardObfuscationSymbol = '*'; | 46 const base::char16 kCreditCardObfuscationSymbol = '*'; |
| 45 const base::char16 kNonBreakingSpace[] = { 0x00a0, 0 }; | 47 const base::char16 kNonBreakingSpace[] = { 0x00a0, 0 }; |
| 46 | 48 |
| 47 bool ConvertYear(const base::string16& year, int* num) { | 49 bool ConvertYear(const base::string16& year, int* num) { |
| (...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 111 | 113 |
| 112 CreditCard::CreditCard(const CreditCard& credit_card) : CreditCard() { | 114 CreditCard::CreditCard(const CreditCard& credit_card) : CreditCard() { |
| 113 operator=(credit_card); | 115 operator=(credit_card); |
| 114 } | 116 } |
| 115 | 117 |
| 116 CreditCard::~CreditCard() {} | 118 CreditCard::~CreditCard() {} |
| 117 | 119 |
| 118 // static | 120 // static |
| 119 const base::string16 CreditCard::StripSeparators(const base::string16& number) { | 121 const base::string16 CreditCard::StripSeparators(const base::string16& number) { |
| 120 base::string16 stripped; | 122 base::string16 stripped; |
| 121 base::RemoveChars(number, base::ASCIIToUTF16("- "), &stripped); | 123 base::RemoveChars(number, ASCIIToUTF16("- "), &stripped); |
| 122 return stripped; | 124 return stripped; |
| 123 } | 125 } |
| 124 | 126 |
| 125 // static | 127 // static |
| 126 base::string16 CreditCard::TypeForDisplay(const std::string& type) { | 128 base::string16 CreditCard::TypeForDisplay(const std::string& type) { |
| 127 if (kGenericCard == type) | 129 if (kGenericCard == type) |
| 128 return l10n_util::GetStringUTF16(IDS_AUTOFILL_CC_GENERIC); | 130 return l10n_util::GetStringUTF16(IDS_AUTOFILL_CC_GENERIC); |
| 129 if (kAmericanExpressCard == type) | 131 if (kAmericanExpressCard == type) |
| 130 return l10n_util::GetStringUTF16(IDS_AUTOFILL_CC_AMEX_SHORT); | 132 return l10n_util::GetStringUTF16(IDS_AUTOFILL_CC_AMEX_SHORT); |
| 131 | 133 |
| (...skipping 151 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 283 case CREDIT_CARD_EXP_2_DIGIT_YEAR: | 285 case CREDIT_CARD_EXP_2_DIGIT_YEAR: |
| 284 return Expiration2DigitYearAsString(); | 286 return Expiration2DigitYearAsString(); |
| 285 | 287 |
| 286 case CREDIT_CARD_EXP_4_DIGIT_YEAR: | 288 case CREDIT_CARD_EXP_4_DIGIT_YEAR: |
| 287 return Expiration4DigitYearAsString(); | 289 return Expiration4DigitYearAsString(); |
| 288 | 290 |
| 289 case CREDIT_CARD_EXP_DATE_2_DIGIT_YEAR: { | 291 case CREDIT_CARD_EXP_DATE_2_DIGIT_YEAR: { |
| 290 base::string16 month = ExpirationMonthAsString(); | 292 base::string16 month = ExpirationMonthAsString(); |
| 291 base::string16 year = Expiration2DigitYearAsString(); | 293 base::string16 year = Expiration2DigitYearAsString(); |
| 292 if (!month.empty() && !year.empty()) | 294 if (!month.empty() && !year.empty()) |
| 293 return month + base::ASCIIToUTF16("/") + year; | 295 return month + ASCIIToUTF16("/") + year; |
| 294 return base::string16(); | 296 return base::string16(); |
| 295 } | 297 } |
| 296 | 298 |
| 297 case CREDIT_CARD_EXP_DATE_4_DIGIT_YEAR: { | 299 case CREDIT_CARD_EXP_DATE_4_DIGIT_YEAR: { |
| 298 base::string16 month = ExpirationMonthAsString(); | 300 base::string16 month = ExpirationMonthAsString(); |
| 299 base::string16 year = Expiration4DigitYearAsString(); | 301 base::string16 year = Expiration4DigitYearAsString(); |
| 300 if (!month.empty() && !year.empty()) | 302 if (!month.empty() && !year.empty()) |
| 301 return month + base::ASCIIToUTF16("/") + year; | 303 return month + ASCIIToUTF16("/") + year; |
| 302 return base::string16(); | 304 return base::string16(); |
| 303 } | 305 } |
| 304 | 306 |
| 305 case CREDIT_CARD_TYPE: | 307 case CREDIT_CARD_TYPE: |
| 306 return TypeForFill(); | 308 return TypeForFill(); |
| 307 | 309 |
| 308 case CREDIT_CARD_NUMBER: | 310 case CREDIT_CARD_NUMBER: |
| 309 return number_; | 311 return number_; |
| 310 | 312 |
| 311 case CREDIT_CARD_VERIFICATION_CODE: | 313 case CREDIT_CARD_VERIFICATION_CODE: |
| (...skipping 12 matching lines...) Expand all Loading... |
| 324 switch (type) { | 326 switch (type) { |
| 325 case CREDIT_CARD_NAME_FULL: | 327 case CREDIT_CARD_NAME_FULL: |
| 326 name_on_card_ = value; | 328 name_on_card_ = value; |
| 327 break; | 329 break; |
| 328 | 330 |
| 329 case CREDIT_CARD_EXP_MONTH: | 331 case CREDIT_CARD_EXP_MONTH: |
| 330 SetExpirationMonthFromString(value, std::string()); | 332 SetExpirationMonthFromString(value, std::string()); |
| 331 break; | 333 break; |
| 332 | 334 |
| 333 case CREDIT_CARD_EXP_2_DIGIT_YEAR: | 335 case CREDIT_CARD_EXP_2_DIGIT_YEAR: |
| 334 // This is a read-only attribute. | 336 SetExpirationYearFromString(value); |
| 335 break; | 337 break; |
| 336 | 338 |
| 337 case CREDIT_CARD_EXP_4_DIGIT_YEAR: | 339 case CREDIT_CARD_EXP_4_DIGIT_YEAR: |
| 338 SetExpirationYearFromString(value); | 340 SetExpirationYearFromString(value); |
| 339 break; | 341 break; |
| 340 | 342 |
| 341 case CREDIT_CARD_EXP_DATE_2_DIGIT_YEAR: | 343 case CREDIT_CARD_EXP_DATE_2_DIGIT_YEAR: |
| 342 // This is a read-only attribute. | 344 SetExpirationDateFromString(value); |
| 343 break; | 345 break; |
| 344 | 346 |
| 345 case CREDIT_CARD_EXP_DATE_4_DIGIT_YEAR: | 347 case CREDIT_CARD_EXP_DATE_4_DIGIT_YEAR: |
| 346 // This is a read-only attribute. | 348 SetExpirationDateFromString(value); |
| 347 break; | 349 break; |
| 348 | 350 |
| 349 case CREDIT_CARD_TYPE: | 351 case CREDIT_CARD_TYPE: |
| 350 // This is a read-only attribute, determined by the credit card number. | 352 // This is a read-only attribute, determined by the credit card number. |
| 351 break; | 353 break; |
| 352 | 354 |
| 353 case CREDIT_CARD_NUMBER: { | 355 case CREDIT_CARD_NUMBER: { |
| 354 // Don't change the real value if the input is an obfuscated string. | 356 // Don't change the real value if the input is an obfuscated string. |
| 355 if (value.size() > 0 && value[0] != kCreditCardObfuscationSymbol) | 357 if (value.size() > 0 && value[0] != kCreditCardObfuscationSymbol) |
| 356 SetNumber(value); | 358 SetNumber(value); |
| (...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 424 // No CC number, return name only. | 426 // No CC number, return name only. |
| 425 if (number().empty()) | 427 if (number().empty()) |
| 426 return std::make_pair(name_on_card_, base::string16()); | 428 return std::make_pair(name_on_card_, base::string16()); |
| 427 | 429 |
| 428 base::string16 obfuscated_cc_number = TypeAndLastFourDigits(); | 430 base::string16 obfuscated_cc_number = TypeAndLastFourDigits(); |
| 429 // No expiration date set. | 431 // No expiration date set. |
| 430 if (!expiration_month_ || !expiration_year_) | 432 if (!expiration_month_ || !expiration_year_) |
| 431 return std::make_pair(obfuscated_cc_number, base::string16()); | 433 return std::make_pair(obfuscated_cc_number, base::string16()); |
| 432 | 434 |
| 433 base::string16 formatted_date(ExpirationMonthAsString()); | 435 base::string16 formatted_date(ExpirationMonthAsString()); |
| 434 formatted_date.append(base::ASCIIToUTF16("/")); | 436 formatted_date.append(ASCIIToUTF16("/")); |
| 435 formatted_date.append(Expiration4DigitYearAsString()); | 437 formatted_date.append(Expiration4DigitYearAsString()); |
| 436 | 438 |
| 437 base::string16 separator = | 439 base::string16 separator = |
| 438 l10n_util::GetStringUTF16(IDS_AUTOFILL_ADDRESS_SUMMARY_SEPARATOR); | 440 l10n_util::GetStringUTF16(IDS_AUTOFILL_ADDRESS_SUMMARY_SEPARATOR); |
| 439 return std::make_pair(obfuscated_cc_number, separator + formatted_date); | 441 return std::make_pair(obfuscated_cc_number, separator + formatted_date); |
| 440 } | 442 } |
| 441 | 443 |
| 442 void CreditCard::SetInfoForMonthInputType(const base::string16& value) { | 444 void CreditCard::SetInfoForMonthInputType(const base::string16& value) { |
| 443 // Check if |text| is "yyyy-mm" format first, and check normal month format. | 445 // Check if |text| is "yyyy-mm" format first, and check normal month format. |
| 444 if (!MatchesPattern(value, base::UTF8ToUTF16("^[0-9]{4}-[0-9]{1,2}$"))) | 446 if (!MatchesPattern(value, base::UTF8ToUTF16("^[0-9]{4}-[0-9]{1,2}$"))) |
| 445 return; | 447 return; |
| 446 | 448 |
| 447 std::vector<base::StringPiece16> year_month = base::SplitStringPiece( | 449 std::vector<base::StringPiece16> year_month = base::SplitStringPiece( |
| 448 value, base::ASCIIToUTF16("-"), | 450 value, ASCIIToUTF16("-"), base::TRIM_WHITESPACE, base::SPLIT_WANT_ALL); |
| 449 base::TRIM_WHITESPACE, base::SPLIT_WANT_ALL); | |
| 450 DCHECK_EQ(2u, year_month.size()); | 451 DCHECK_EQ(2u, year_month.size()); |
| 451 int num = 0; | 452 int num = 0; |
| 452 bool converted = false; | 453 bool converted = false; |
| 453 converted = base::StringToInt(year_month[0], &num); | 454 converted = base::StringToInt(year_month[0], &num); |
| 454 DCHECK(converted); | 455 DCHECK(converted); |
| 455 SetExpirationYear(num); | 456 SetExpirationYear(num); |
| 456 converted = base::StringToInt(year_month[1], &num); | 457 converted = base::StringToInt(year_month[1], &num); |
| 457 DCHECK(converted); | 458 DCHECK(converted); |
| 458 SetExpirationMonth(num); | 459 SetExpirationMonth(num); |
| 459 } | 460 } |
| 460 | 461 |
| 461 void CreditCard::SetExpirationMonth(int expiration_month) { | 462 void CreditCard::SetExpirationMonth(int expiration_month) { |
| 462 if (expiration_month < 0 || expiration_month > 12) | 463 if (expiration_month < 0 || expiration_month > 12) |
| 463 return; | 464 return; |
| 464 expiration_month_ = expiration_month; | 465 expiration_month_ = expiration_month; |
| 465 } | 466 } |
| 466 | 467 |
| 467 void CreditCard::SetExpirationYear(int expiration_year) { | 468 void CreditCard::SetExpirationYear(int expiration_year) { |
| 468 if (expiration_year != 0 && | 469 // If |expiration_year| is beyond this millenium, or more than 2 digits but |
| 469 (expiration_year < 2006 || expiration_year > 10000)) | 470 // before the current millenium (e.g. "545", "1995"), return. What is left are |
| 471 // values like "45" or "2018". |
| 472 if (expiration_year > 2999 || |
| 473 (expiration_year > 99 && expiration_year < 2000)) |
| 470 return; | 474 return; |
| 475 |
| 476 // Will normalize 2-digit years to the 4-digit version. |
| 477 if (expiration_year > 0 && expiration_year < 100) { |
| 478 base::Time::Exploded now_exploded; |
| 479 base::Time::Now().LocalExplode(&now_exploded); |
| 480 expiration_year += (now_exploded.year / 100) * 100; |
| 481 } |
| 482 |
| 471 expiration_year_ = expiration_year; | 483 expiration_year_ = expiration_year; |
| 472 } | 484 } |
| 473 | 485 |
| 474 base::string16 CreditCard::LastFourDigits() const { | 486 base::string16 CreditCard::LastFourDigits() const { |
| 475 static const size_t kNumLastDigits = 4; | 487 static const size_t kNumLastDigits = 4; |
| 476 | 488 |
| 477 base::string16 number = StripSeparators(number_); | 489 base::string16 number = StripSeparators(number_); |
| 478 if (number.size() <= kNumLastDigits) | 490 if (number.size() <= kNumLastDigits) |
| 479 return number; | 491 return number; |
| 480 | 492 |
| (...skipping 189 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 670 } | 682 } |
| 671 | 683 |
| 672 base::string16 CreditCard::ExpirationMonthAsString() const { | 684 base::string16 CreditCard::ExpirationMonthAsString() const { |
| 673 if (expiration_month_ == 0) | 685 if (expiration_month_ == 0) |
| 674 return base::string16(); | 686 return base::string16(); |
| 675 | 687 |
| 676 base::string16 month = base::IntToString16(expiration_month_); | 688 base::string16 month = base::IntToString16(expiration_month_); |
| 677 if (expiration_month_ >= 10) | 689 if (expiration_month_ >= 10) |
| 678 return month; | 690 return month; |
| 679 | 691 |
| 680 base::string16 zero = base::ASCIIToUTF16("0"); | 692 base::string16 zero = ASCIIToUTF16("0"); |
| 681 zero.append(month); | 693 zero.append(month); |
| 682 return zero; | 694 return zero; |
| 683 } | 695 } |
| 684 | 696 |
| 685 base::string16 CreditCard::TypeForFill() const { | 697 base::string16 CreditCard::TypeForFill() const { |
| 686 return ::autofill::TypeForFill(type_); | 698 return ::autofill::TypeForFill(type_); |
| 687 } | 699 } |
| 688 | 700 |
| 689 base::string16 CreditCard::Expiration4DigitYearAsString() const { | 701 base::string16 CreditCard::Expiration4DigitYearAsString() const { |
| 690 if (expiration_year_ == 0) | 702 if (expiration_year_ == 0) |
| (...skipping 23 matching lines...) Expand all Loading... |
| 714 } | 726 } |
| 715 | 727 |
| 716 void CreditCard::SetExpirationYearFromString(const base::string16& text) { | 728 void CreditCard::SetExpirationYearFromString(const base::string16& text) { |
| 717 int year; | 729 int year; |
| 718 if (!ConvertYear(text, &year)) | 730 if (!ConvertYear(text, &year)) |
| 719 return; | 731 return; |
| 720 | 732 |
| 721 SetExpirationYear(year); | 733 SetExpirationYear(year); |
| 722 } | 734 } |
| 723 | 735 |
| 736 void CreditCard::SetExpirationDateFromString(const base::string16& text) { |
| 737 // Check that |text| fits the supported patterns: mmyy, mmyyyy, m-yy, |
| 738 // mm-yy, m-yyyy and mm-yyyy. Note that myy and myyyy matched by this pattern |
| 739 // but are not supported (ambiguous). Separators: -, / and |. |
| 740 if (!MatchesPattern(text, base::UTF8ToUTF16("^[0-9]{1,2}[-/|]?[0-9]{2,4}$"))) |
| 741 return; |
| 742 |
| 743 base::string16 month; |
| 744 base::string16 year; |
| 745 |
| 746 // Check for a separator. |
| 747 base::string16 found_separator; |
| 748 const std::vector<base::string16> kSeparators{ |
| 749 ASCIIToUTF16("-"), ASCIIToUTF16("/"), ASCIIToUTF16("|")}; |
| 750 for (const base::string16& separator : kSeparators) { |
| 751 if (text.find(separator) != base::string16::npos) { |
| 752 found_separator = separator; |
| 753 break; |
| 754 } |
| 755 } |
| 756 |
| 757 if (!found_separator.empty()) { |
| 758 std::vector<base::string16> month_year = base::SplitString( |
| 759 text, found_separator, base::TRIM_WHITESPACE, base::SPLIT_WANT_ALL); |
| 760 DCHECK_EQ(2u, month_year.size()); |
| 761 month = month_year[0]; |
| 762 year = month_year[1]; |
| 763 } else if (text.size() % 2 == 0) { |
| 764 // If there are no separators, the supported formats are mmyy and mmyyyy. |
| 765 month = text.substr(0, 2); |
| 766 year = text.substr(2); |
| 767 } else { |
| 768 // Odd number of digits with no separator is too ambiguous. |
| 769 return; |
| 770 } |
| 771 |
| 772 int num = 0; |
| 773 bool converted = false; |
| 774 converted = base::StringToInt(month, &num); |
| 775 DCHECK(converted); |
| 776 SetExpirationMonth(num); |
| 777 converted = base::StringToInt(year, &num); |
| 778 DCHECK(converted); |
| 779 SetExpirationYear(num); |
| 780 } |
| 781 |
| 724 void CreditCard::SetNumber(const base::string16& number) { | 782 void CreditCard::SetNumber(const base::string16& number) { |
| 725 number_ = number; | 783 number_ = number; |
| 726 | 784 |
| 727 // Set the type based on the card number, but only for full numbers, not | 785 // Set the type based on the card number, but only for full numbers, not |
| 728 // when we have masked cards from the server (last 4 digits). | 786 // when we have masked cards from the server (last 4 digits). |
| 729 if (record_type_ != MASKED_SERVER_CARD) | 787 if (record_type_ != MASKED_SERVER_CARD) |
| 730 type_ = GetCreditCardType(StripSeparators(number_)); | 788 type_ = GetCreditCardType(StripSeparators(number_)); |
| 731 } | 789 } |
| 732 | 790 |
| 733 void CreditCard::RecordAndLogUse() { | 791 void CreditCard::RecordAndLogUse() { |
| (...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 766 if (compare.StringsEqual(icu_month, month)) { | 824 if (compare.StringsEqual(icu_month, month)) { |
| 767 *num = i + 1; // Adjust from 0-indexed to 1-indexed. | 825 *num = i + 1; // Adjust from 0-indexed to 1-indexed. |
| 768 return true; | 826 return true; |
| 769 } | 827 } |
| 770 } | 828 } |
| 771 | 829 |
| 772 months = date_format_symbols.getShortMonths(num_months); | 830 months = date_format_symbols.getShortMonths(num_months); |
| 773 // Some abbreviations have . at the end (e.g., "janv." in French). We don't | 831 // Some abbreviations have . at the end (e.g., "janv." in French). We don't |
| 774 // care about matching that. | 832 // care about matching that. |
| 775 base::string16 trimmed_month; | 833 base::string16 trimmed_month; |
| 776 base::TrimString(month, base::ASCIIToUTF16("."), &trimmed_month); | 834 base::TrimString(month, ASCIIToUTF16("."), &trimmed_month); |
| 777 for (int32_t i = 0; i < num_months; ++i) { | 835 for (int32_t i = 0; i < num_months; ++i) { |
| 778 base::string16 icu_month(months[i].getBuffer(), months[i].length()); | 836 base::string16 icu_month(months[i].getBuffer(), months[i].length()); |
| 779 base::TrimString(icu_month, base::ASCIIToUTF16("."), &icu_month); | 837 base::TrimString(icu_month, ASCIIToUTF16("."), &icu_month); |
| 780 if (compare.StringsEqual(icu_month, trimmed_month)) { | 838 if (compare.StringsEqual(icu_month, trimmed_month)) { |
| 781 *num = i + 1; // Adjust from 0-indexed to 1-indexed. | 839 *num = i + 1; // Adjust from 0-indexed to 1-indexed. |
| 782 return true; | 840 return true; |
| 783 } | 841 } |
| 784 } | 842 } |
| 785 | 843 |
| 786 return false; | 844 return false; |
| 787 } | 845 } |
| 788 | 846 |
| 789 bool CreditCard::IsExpired(const base::Time& current_time) const { | 847 bool CreditCard::IsExpired(const base::Time& current_time) const { |
| (...skipping 28 matching lines...) Expand all Loading... |
| 818 const char kAmericanExpressCard[] = "americanExpressCC"; | 876 const char kAmericanExpressCard[] = "americanExpressCC"; |
| 819 const char kDinersCard[] = "dinersCC"; | 877 const char kDinersCard[] = "dinersCC"; |
| 820 const char kDiscoverCard[] = "discoverCC"; | 878 const char kDiscoverCard[] = "discoverCC"; |
| 821 const char kGenericCard[] = "genericCC"; | 879 const char kGenericCard[] = "genericCC"; |
| 822 const char kJCBCard[] = "jcbCC"; | 880 const char kJCBCard[] = "jcbCC"; |
| 823 const char kMasterCard[] = "masterCardCC"; | 881 const char kMasterCard[] = "masterCardCC"; |
| 824 const char kUnionPay[] = "unionPayCC"; | 882 const char kUnionPay[] = "unionPayCC"; |
| 825 const char kVisaCard[] = "visaCC"; | 883 const char kVisaCard[] = "visaCC"; |
| 826 | 884 |
| 827 } // namespace autofill | 885 } // namespace autofill |
| OLD | NEW |