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 184 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
665 } | 677 } |
666 | 678 |
667 base::string16 CreditCard::ExpirationMonthAsString() const { | 679 base::string16 CreditCard::ExpirationMonthAsString() const { |
668 if (expiration_month_ == 0) | 680 if (expiration_month_ == 0) |
669 return base::string16(); | 681 return base::string16(); |
670 | 682 |
671 base::string16 month = base::IntToString16(expiration_month_); | 683 base::string16 month = base::IntToString16(expiration_month_); |
672 if (expiration_month_ >= 10) | 684 if (expiration_month_ >= 10) |
673 return month; | 685 return month; |
674 | 686 |
675 base::string16 zero = base::ASCIIToUTF16("0"); | 687 base::string16 zero = ASCIIToUTF16("0"); |
676 zero.append(month); | 688 zero.append(month); |
677 return zero; | 689 return zero; |
678 } | 690 } |
679 | 691 |
680 base::string16 CreditCard::TypeForFill() const { | 692 base::string16 CreditCard::TypeForFill() const { |
681 return ::autofill::TypeForFill(type_); | 693 return ::autofill::TypeForFill(type_); |
682 } | 694 } |
683 | 695 |
684 base::string16 CreditCard::Expiration4DigitYearAsString() const { | 696 base::string16 CreditCard::Expiration4DigitYearAsString() const { |
685 if (expiration_year_ == 0) | 697 if (expiration_year_ == 0) |
(...skipping 23 matching lines...) Expand all Loading... | |
709 } | 721 } |
710 | 722 |
711 void CreditCard::SetExpirationYearFromString(const base::string16& text) { | 723 void CreditCard::SetExpirationYearFromString(const base::string16& text) { |
712 int year; | 724 int year; |
713 if (!ConvertYear(text, &year)) | 725 if (!ConvertYear(text, &year)) |
714 return; | 726 return; |
715 | 727 |
716 SetExpirationYear(year); | 728 SetExpirationYear(year); |
717 } | 729 } |
718 | 730 |
731 void CreditCard::SetExpirationDateFromString(const base::string16& text) { | |
732 // Check that |text| fits the supported patterns: mmyy, mmyyyy, m-yy, | |
733 // mm-yy, m-yyyy and mm-yyyy. Note that myy and myyyy matched by this pattern | |
734 // but are not supported (ambiguous). Separators: -, / and |. | |
735 if (!MatchesPattern(text, base::UTF8ToUTF16("^[0-9]{1,2}[-/|]?[0-9]{2,4}$"))) | |
736 return; | |
737 | |
738 base::string16 month; | |
739 base::string16 year; | |
740 | |
741 // Check for a separator. | |
742 base::string16 found_separator; | |
743 const std::vector<const base::string16> kSeparators{ | |
744 ASCIIToUTF16("-"), ASCIIToUTF16("/"), ASCIIToUTF16("|")}; | |
745 for (const base::string16& separator : kSeparators) { | |
746 if (text.find(separator) != base::string16::npos) | |
747 found_separator = separator; | |
Justin Donnelly
2016/07/08 17:45:22
break? Obviously not a performance issue but as I
sebsg
2016/07/08 17:48:31
I noticed it too, took me a while to parse the loo
Mathieu
2016/07/08 18:32:57
Done.
Mathieu
2016/07/08 18:32:57
Done.
| |
748 } | |
749 | |
750 if (!found_separator.empty()) { | |
751 std::vector<base::string16> month_year = base::SplitString( | |
752 text, found_separator, base::TRIM_WHITESPACE, base::SPLIT_WANT_ALL); | |
753 DCHECK_EQ(2u, month_year.size()); | |
754 month = month_year[0]; | |
755 year = month_year[1]; | |
756 } else if (text.size() % 2 == 0) { | |
757 // There is no separator, the format is either mmyy or mmyyyy. | |
sebsg
2016/07/08 17:23:15
optional nit: If there is no separator, the suppor
Mathieu
2016/07/08 18:32:57
Done.
| |
758 month = text.substr(0, 2); | |
759 year = text.substr(2); | |
760 } else { | |
761 // Odd number of digits with no separator is too ambiguous. | |
762 return; | |
763 } | |
764 | |
765 int num = 0; | |
766 bool converted = false; | |
767 converted = base::StringToInt(month, &num); | |
768 DCHECK(converted); | |
769 SetExpirationMonth(num); | |
770 converted = base::StringToInt(year, &num); | |
771 DCHECK(converted); | |
772 SetExpirationYear(num); | |
773 } | |
774 | |
719 void CreditCard::SetNumber(const base::string16& number) { | 775 void CreditCard::SetNumber(const base::string16& number) { |
720 number_ = number; | 776 number_ = number; |
721 | 777 |
722 // Set the type based on the card number, but only for full numbers, not | 778 // Set the type based on the card number, but only for full numbers, not |
723 // when we have masked cards from the server (last 4 digits). | 779 // when we have masked cards from the server (last 4 digits). |
724 if (record_type_ != MASKED_SERVER_CARD) | 780 if (record_type_ != MASKED_SERVER_CARD) |
725 type_ = GetCreditCardType(StripSeparators(number_)); | 781 type_ = GetCreditCardType(StripSeparators(number_)); |
726 } | 782 } |
727 | 783 |
728 void CreditCard::RecordAndLogUse() { | 784 void CreditCard::RecordAndLogUse() { |
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
761 if (compare.StringsEqual(icu_month, month)) { | 817 if (compare.StringsEqual(icu_month, month)) { |
762 *num = i + 1; // Adjust from 0-indexed to 1-indexed. | 818 *num = i + 1; // Adjust from 0-indexed to 1-indexed. |
763 return true; | 819 return true; |
764 } | 820 } |
765 } | 821 } |
766 | 822 |
767 months = date_format_symbols.getShortMonths(num_months); | 823 months = date_format_symbols.getShortMonths(num_months); |
768 // Some abbreviations have . at the end (e.g., "janv." in French). We don't | 824 // Some abbreviations have . at the end (e.g., "janv." in French). We don't |
769 // care about matching that. | 825 // care about matching that. |
770 base::string16 trimmed_month; | 826 base::string16 trimmed_month; |
771 base::TrimString(month, base::ASCIIToUTF16("."), &trimmed_month); | 827 base::TrimString(month, ASCIIToUTF16("."), &trimmed_month); |
772 for (int32_t i = 0; i < num_months; ++i) { | 828 for (int32_t i = 0; i < num_months; ++i) { |
773 base::string16 icu_month(months[i].getBuffer(), months[i].length()); | 829 base::string16 icu_month(months[i].getBuffer(), months[i].length()); |
774 base::TrimString(icu_month, base::ASCIIToUTF16("."), &icu_month); | 830 base::TrimString(icu_month, ASCIIToUTF16("."), &icu_month); |
775 if (compare.StringsEqual(icu_month, trimmed_month)) { | 831 if (compare.StringsEqual(icu_month, trimmed_month)) { |
776 *num = i + 1; // Adjust from 0-indexed to 1-indexed. | 832 *num = i + 1; // Adjust from 0-indexed to 1-indexed. |
777 return true; | 833 return true; |
778 } | 834 } |
779 } | 835 } |
780 | 836 |
781 return false; | 837 return false; |
782 } | 838 } |
783 | 839 |
784 bool CreditCard::IsExpired(const base::Time& current_time) const { | 840 bool CreditCard::IsExpired(const base::Time& current_time) const { |
(...skipping 28 matching lines...) Expand all Loading... | |
813 const char kAmericanExpressCard[] = "americanExpressCC"; | 869 const char kAmericanExpressCard[] = "americanExpressCC"; |
814 const char kDinersCard[] = "dinersCC"; | 870 const char kDinersCard[] = "dinersCC"; |
815 const char kDiscoverCard[] = "discoverCC"; | 871 const char kDiscoverCard[] = "discoverCC"; |
816 const char kGenericCard[] = "genericCC"; | 872 const char kGenericCard[] = "genericCC"; |
817 const char kJCBCard[] = "jcbCC"; | 873 const char kJCBCard[] = "jcbCC"; |
818 const char kMasterCard[] = "masterCardCC"; | 874 const char kMasterCard[] = "masterCardCC"; |
819 const char kUnionPay[] = "unionPayCC"; | 875 const char kUnionPay[] = "unionPayCC"; |
820 const char kVisaCard[] = "visaCC"; | 876 const char kVisaCard[] = "visaCC"; |
821 | 877 |
822 } // namespace autofill | 878 } // namespace autofill |
OLD | NEW |