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 |