Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(343)

Side by Side Diff: components/autofill/core/browser/credit_card.cc

Issue 381613005: [Autofill] Autofill fails to fill credit card number when split across fields. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 6 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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 8
9 #include <algorithm> 9 #include <algorithm>
10 #include <ostream> 10 #include <ostream>
(...skipping 292 matching lines...) Expand 10 before | Expand all | Expand 10 after
303 base::string16 year = Expiration4DigitYearAsString(); 303 base::string16 year = Expiration4DigitYearAsString();
304 if (!month.empty() && !year.empty()) 304 if (!month.empty() && !year.empty())
305 return month + base::ASCIIToUTF16("/") + year; 305 return month + base::ASCIIToUTF16("/") + year;
306 return base::string16(); 306 return base::string16();
307 } 307 }
308 308
309 case CREDIT_CARD_TYPE: 309 case CREDIT_CARD_TYPE:
310 return TypeForDisplay(); 310 return TypeForDisplay();
311 311
312 case CREDIT_CARD_NUMBER: 312 case CREDIT_CARD_NUMBER:
313 return number_; 313 return this->GetNumber();
314
315 case CREDIT_CARD_NUMBER_PART1:
316 return this->number_part1_;
317
318 case CREDIT_CARD_NUMBER_PART2:
319 return this->number_part2_;
320
321 case CREDIT_CARD_NUMBER_PART3:
322 return this->number_part3_;
323
324 case CREDIT_CARD_NUMBER_PART4:
325 return this->number_part4_;
314 326
315 case CREDIT_CARD_VERIFICATION_CODE: 327 case CREDIT_CARD_VERIFICATION_CODE:
316 // Chrome doesn't store credit card verification codes. 328 // Chrome doesn't store credit card verification codes.
317 return base::string16(); 329 return base::string16();
318 330
319 default: 331 default:
320 // ComputeDataPresentForArray will hit this repeatedly. 332 // ComputeDataPresentForArray will hit this repeatedly.
321 return base::string16(); 333 return base::string16();
322 } 334 }
323 } 335 }
(...skipping 30 matching lines...) Expand all
354 // This is a read-only attribute, determined by the credit card number. 366 // This is a read-only attribute, determined by the credit card number.
355 break; 367 break;
356 368
357 case CREDIT_CARD_NUMBER: { 369 case CREDIT_CARD_NUMBER: {
358 // Don't change the real value if the input is an obfuscated string. 370 // Don't change the real value if the input is an obfuscated string.
359 if (value.size() > 0 && value[0] != kCreditCardObfuscationSymbol) 371 if (value.size() > 0 && value[0] != kCreditCardObfuscationSymbol)
360 SetNumber(value); 372 SetNumber(value);
361 break; 373 break;
362 } 374 }
363 375
376 case CREDIT_CARD_NUMBER_PART1: {
377 // Don't change the real value if the input is an obfuscated string.
378 if (value.size() > 0 && value[0] != kCreditCardObfuscationSymbol)
379 SetNumber(value, autofill::CreditCard::first_part);
380 break;
381 }
382
383 case CREDIT_CARD_NUMBER_PART2: {
384 // Don't change the real value if the input is an obfuscated string.
385 if (value.size() > 0 && value[0] != kCreditCardObfuscationSymbol)
386 SetNumber(value, autofill::CreditCard::second_part);
387 break;
388 }
389
390 case CREDIT_CARD_NUMBER_PART3: {
391 // Don't change the real value if the input is an obfuscated string.
392 if (value.size() > 0 && value[0] != kCreditCardObfuscationSymbol)
393 SetNumber(value, autofill::CreditCard::third_part);
394 break;
395 }
396
397 case CREDIT_CARD_NUMBER_PART4: {
398 // Don't change the real value if the input is an obfuscated string.
399 if (value.size() > 0 && value[0] != kCreditCardObfuscationSymbol)
400 SetNumber(value, autofill::CreditCard::last_part);
401 break;
402 }
403
364 case CREDIT_CARD_VERIFICATION_CODE: 404 case CREDIT_CARD_VERIFICATION_CODE:
365 // Chrome doesn't store the credit card verification code. 405 // Chrome doesn't store the credit card verification code.
366 break; 406 break;
367 407
368 default: 408 default:
369 NOTREACHED() << "Attempting to set unknown info-type " << type; 409 NOTREACHED() << "Attempting to set unknown info-type " << type;
370 break; 410 break;
371 } 411 }
372 } 412 }
373 413
374 base::string16 CreditCard::GetInfo(const AutofillType& type, 414 base::string16 CreditCard::GetInfo(const AutofillType& type,
375 const std::string& app_locale) const { 415 const std::string& app_locale) const {
376 ServerFieldType storable_type = type.GetStorableType(); 416 ServerFieldType storable_type = type.GetStorableType();
377 if (storable_type == CREDIT_CARD_NUMBER) 417 if (storable_type == CREDIT_CARD_NUMBER)
378 return StripSeparators(number_); 418 return this->GetNumber();
379 419
380 return GetRawInfo(storable_type); 420 return GetRawInfo(storable_type);
381 } 421 }
382 422
383 bool CreditCard::SetInfo(const AutofillType& type, 423 bool CreditCard::SetInfo(const AutofillType& type,
384 const base::string16& value, 424 const base::string16& value,
385 const std::string& app_locale) { 425 const std::string& app_locale) {
386 ServerFieldType storable_type = type.GetStorableType(); 426 ServerFieldType storable_type = type.GetStorableType();
387 if (storable_type == CREDIT_CARD_NUMBER) 427 if (storable_type == CREDIT_CARD_NUMBER)
388 SetRawInfo(storable_type, StripSeparators(value)); 428 SetRawInfo(storable_type, StripSeparators(value));
(...skipping 17 matching lines...) Expand all
406 446
407 int month; 447 int month;
408 if (ConvertMonth(text, app_locale, &month) && month != 0 && 448 if (ConvertMonth(text, app_locale, &month) && month != 0 &&
409 month == expiration_month_) { 449 month == expiration_month_) {
410 matching_types->insert(CREDIT_CARD_EXP_MONTH); 450 matching_types->insert(CREDIT_CARD_EXP_MONTH);
411 } 451 }
412 } 452 }
413 453
414 const base::string16 CreditCard::Label() const { 454 const base::string16 CreditCard::Label() const {
415 base::string16 label; 455 base::string16 label;
416 if (number().empty()) 456 if (GetNumber().empty())
417 return name_on_card_; // No CC number, return name only. 457 return name_on_card_; // No CC number, return name only.
418 458
419 base::string16 obfuscated_cc_number = ObfuscatedNumber(); 459 base::string16 obfuscated_cc_number = ObfuscatedNumber();
420 if (!expiration_month_ || !expiration_year_) 460 if (!expiration_month_ || !expiration_year_)
421 return obfuscated_cc_number; // No expiration date set. 461 return obfuscated_cc_number; // No expiration date set.
422 462
423 // TODO(georgey): Internationalize date. 463 // TODO(georgey): Internationalize date.
424 base::string16 formatted_date(ExpirationMonthAsString()); 464 base::string16 formatted_date(ExpirationMonthAsString());
425 formatted_date.append(base::ASCIIToUTF16("/")); 465 formatted_date.append(base::ASCIIToUTF16("/"));
426 formatted_date.append(Expiration4DigitYearAsString()); 466 formatted_date.append(Expiration4DigitYearAsString());
(...skipping 19 matching lines...) Expand all
446 converted = base::StringToInt(year_month[0], &num); 486 converted = base::StringToInt(year_month[0], &num);
447 DCHECK(converted); 487 DCHECK(converted);
448 SetExpirationYear(num); 488 SetExpirationYear(num);
449 converted = base::StringToInt(year_month[1], &num); 489 converted = base::StringToInt(year_month[1], &num);
450 DCHECK(converted); 490 DCHECK(converted);
451 SetExpirationMonth(num); 491 SetExpirationMonth(num);
452 } 492 }
453 493
454 base::string16 CreditCard::ObfuscatedNumber() const { 494 base::string16 CreditCard::ObfuscatedNumber() const {
455 // If the number is shorter than four digits, there's no need to obfuscate it. 495 // If the number is shorter than four digits, there's no need to obfuscate it.
456 if (number_.size() < 4) 496 if (this->GetNumber().size() < 4)
457 return number_; 497 return this->GetNumber();
458 498
459 base::string16 number = StripSeparators(number_); 499 base::string16 number = this->GetNumber();
460 500
461 // Avoid making very long obfuscated numbers. 501 // Avoid making very long obfuscated numbers.
462 size_t obfuscated_digits = std::min(kMaxObfuscationSize, number.size() - 4); 502 size_t obfuscated_digits = std::min(kMaxObfuscationSize, number.size() - 4);
463 base::string16 result(obfuscated_digits, kCreditCardObfuscationSymbol); 503 base::string16 result(obfuscated_digits, kCreditCardObfuscationSymbol);
464 return result.append(LastFourDigits()); 504 return result.append(LastFourDigits());
465 } 505 }
466 506
467 base::string16 CreditCard::LastFourDigits() const { 507 base::string16 CreditCard::LastFourDigits() const {
468 static const size_t kNumLastDigits = 4; 508 static const size_t kNumLastDigits = 4;
469 509
470 base::string16 number = StripSeparators(number_); 510 base::string16 number = this->GetNumber();
471 if (number.size() < kNumLastDigits) 511 if (number.size() < kNumLastDigits)
472 return base::string16(); 512 return base::string16();
473 513
474 return number.substr(number.size() - kNumLastDigits, kNumLastDigits); 514 return number.substr(number.size() - kNumLastDigits, kNumLastDigits);
475 } 515 }
476 516
477 base::string16 CreditCard::TypeForDisplay() const { 517 base::string16 CreditCard::TypeForDisplay() const {
478 return CreditCard::TypeForDisplay(type_); 518 return CreditCard::TypeForDisplay(type_);
479 } 519 }
480 520
481 base::string16 CreditCard::TypeAndLastFourDigits() const { 521 base::string16 CreditCard::TypeAndLastFourDigits() const {
482 base::string16 type = TypeForDisplay(); 522 base::string16 type = TypeForDisplay();
483 // TODO(estade): type may be empty, we probably want to return 523 // TODO(estade): type may be empty, we probably want to return
484 // "Card - 1234" or something in that case. 524 // "Card - 1234" or something in that case.
485 525
486 base::string16 digits = LastFourDigits(); 526 base::string16 digits = LastFourDigits();
487 if (digits.empty()) 527 if (digits.empty())
488 return type; 528 return type;
489 529
490 // TODO(estade): i18n. 530 // TODO(estade): i18n.
491 return type + base::ASCIIToUTF16(" - ") + digits; 531 return type + base::ASCIIToUTF16(" - ") + digits;
492 } 532 }
493 533
494 void CreditCard::operator=(const CreditCard& credit_card) { 534 void CreditCard::operator=(const CreditCard& credit_card) {
495 if (this == &credit_card) 535 if (this == &credit_card)
496 return; 536 return;
497 537
498 number_ = credit_card.number_; 538 number_part1_ = credit_card.number_part1_;
539 number_part2_ = credit_card.number_part2_;
540 number_part3_ = credit_card.number_part3_;
541 number_part4_ = credit_card.number_part4_;
499 name_on_card_ = credit_card.name_on_card_; 542 name_on_card_ = credit_card.name_on_card_;
500 type_ = credit_card.type_; 543 type_ = credit_card.type_;
501 expiration_month_ = credit_card.expiration_month_; 544 expiration_month_ = credit_card.expiration_month_;
502 expiration_year_ = credit_card.expiration_year_; 545 expiration_year_ = credit_card.expiration_year_;
503 546
504 set_guid(credit_card.guid()); 547 set_guid(credit_card.guid());
505 set_origin(credit_card.origin()); 548 set_origin(credit_card.origin());
506 } 549 }
507 550
508 bool CreditCard::UpdateFromImportedCard(const CreditCard& imported_card, 551 bool CreditCard::UpdateFromImportedCard(const CreditCard& imported_card,
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after
563 return !operator==(credit_card); 606 return !operator==(credit_card);
564 } 607 }
565 608
566 bool CreditCard::IsEmpty(const std::string& app_locale) const { 609 bool CreditCard::IsEmpty(const std::string& app_locale) const {
567 ServerFieldTypeSet types; 610 ServerFieldTypeSet types;
568 GetNonEmptyTypes(app_locale, &types); 611 GetNonEmptyTypes(app_locale, &types);
569 return types.empty(); 612 return types.empty();
570 } 613 }
571 614
572 bool CreditCard::IsComplete() const { 615 bool CreditCard::IsComplete() const {
573 return 616 return autofill::IsValidCreditCardNumber(this->GetNumber()) &&
574 autofill::IsValidCreditCardNumber(number_) && 617 expiration_month_ != 0 && expiration_year_ != 0;
575 expiration_month_ != 0 &&
576 expiration_year_ != 0;
577 } 618 }
578 619
579 bool CreditCard::IsValid() const { 620 bool CreditCard::IsValid() const {
580 return autofill::IsValidCreditCardNumber(number_) && 621 return autofill::IsValidCreditCardNumber(this->GetNumber()) &&
581 autofill::IsValidCreditCardExpirationDate( 622 autofill::IsValidCreditCardExpirationDate(
582 expiration_year_, expiration_month_, base::Time::Now()); 623 expiration_year_, expiration_month_, base::Time::Now());
583 } 624 }
584 625
585 void CreditCard::GetSupportedTypes(ServerFieldTypeSet* supported_types) const { 626 void CreditCard::GetSupportedTypes(ServerFieldTypeSet* supported_types) const {
586 supported_types->insert(CREDIT_CARD_NAME); 627 supported_types->insert(CREDIT_CARD_NAME);
587 supported_types->insert(CREDIT_CARD_NUMBER); 628 supported_types->insert(CREDIT_CARD_NUMBER);
629 supported_types->insert(CREDIT_CARD_NUMBER_PART1);
630 supported_types->insert(CREDIT_CARD_NUMBER_PART2);
631 supported_types->insert(CREDIT_CARD_NUMBER_PART3);
632 supported_types->insert(CREDIT_CARD_NUMBER_PART4);
588 supported_types->insert(CREDIT_CARD_TYPE); 633 supported_types->insert(CREDIT_CARD_TYPE);
589 supported_types->insert(CREDIT_CARD_EXP_MONTH); 634 supported_types->insert(CREDIT_CARD_EXP_MONTH);
590 supported_types->insert(CREDIT_CARD_EXP_2_DIGIT_YEAR); 635 supported_types->insert(CREDIT_CARD_EXP_2_DIGIT_YEAR);
591 supported_types->insert(CREDIT_CARD_EXP_4_DIGIT_YEAR); 636 supported_types->insert(CREDIT_CARD_EXP_4_DIGIT_YEAR);
592 supported_types->insert(CREDIT_CARD_EXP_DATE_2_DIGIT_YEAR); 637 supported_types->insert(CREDIT_CARD_EXP_DATE_2_DIGIT_YEAR);
593 supported_types->insert(CREDIT_CARD_EXP_DATE_4_DIGIT_YEAR); 638 supported_types->insert(CREDIT_CARD_EXP_DATE_4_DIGIT_YEAR);
594 } 639 }
595 640
596 base::string16 CreditCard::ExpirationMonthAsString() const { 641 base::string16 CreditCard::ExpirationMonthAsString() const {
597 if (expiration_month_ == 0) 642 if (expiration_month_ == 0)
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
630 } 675 }
631 676
632 void CreditCard::SetExpirationYearFromString(const base::string16& text) { 677 void CreditCard::SetExpirationYearFromString(const base::string16& text) {
633 int year; 678 int year;
634 if (!ConvertYear(text, &year)) 679 if (!ConvertYear(text, &year))
635 return; 680 return;
636 681
637 SetExpirationYear(year); 682 SetExpirationYear(year);
638 } 683 }
639 684
640 void CreditCard::SetNumber(const base::string16& number) { 685 void CreditCard::SetNumber(const base::string16& number, const Part& part) {
641 number_ = number; 686 base::string16 card_number = StripSeparators(number);
642 type_ = GetCreditCardType(StripSeparators(number_)); 687 switch (part) {
688 case autofill::CreditCard::first_part:
689 number_part1_ = card_number;
690 type_ = GetCreditCardType(number_part1_);
691 break;
692
693 case autofill::CreditCard::second_part:
694 number_part2_ = card_number;
695 break;
696
697 case autofill::CreditCard::third_part:
698 number_part3_ = card_number;
699 break;
700
701 case autofill::CreditCard::last_part:
702 number_part4_ = card_number;
703 break;
704
705 default: {
706 static const size_t kNumDigits = 4;
707 size_t card_number_length = card_number.size();
708 number_part1_ = base::string16();
709 number_part2_ = base::string16();
710 number_part3_ = base::string16();
711 number_part4_ = base::string16();
712 type_ = "";
713
714 if (card_number_length)
715 number_part1_ =
716 card_number.substr(0, std::min(kNumDigits, card_number_length));
717
718 if (card_number_length > kNumDigits)
719 number_part2_ = card_number.substr(
720 kNumDigits, std::min(kNumDigits, card_number_length - kNumDigits));
721
722 if (card_number_length > 2 * kNumDigits)
723 number_part3_ = card_number.substr(
724 2 * kNumDigits,
725 std::min(kNumDigits, card_number_length - 2 * kNumDigits));
726
727 if (card_number_length > 3 * kNumDigits)
728 number_part4_ = card_number.substr(3 * kNumDigits,
729 card_number_length - 3 * kNumDigits);
730
731 type_ = GetCreditCardType(card_number);
732 }
733 }
643 } 734 }
644 735
645 void CreditCard::SetExpirationMonth(int expiration_month) { 736 void CreditCard::SetExpirationMonth(int expiration_month) {
646 if (expiration_month < 0 || expiration_month > 12) 737 if (expiration_month < 0 || expiration_month > 12)
647 return; 738 return;
648 739
649 expiration_month_ = expiration_month; 740 expiration_month_ = expiration_month;
650 } 741 }
651 742
652 void CreditCard::SetExpirationYear(int expiration_year) { 743 void CreditCard::SetExpirationYear(int expiration_year) {
653 if (expiration_year != 0 && 744 if (expiration_year != 0 &&
654 (expiration_year < 2006 || expiration_year > 10000)) { 745 (expiration_year < 2006 || expiration_year > 10000)) {
655 return; 746 return;
656 } 747 }
657 748
658 expiration_year_ = expiration_year; 749 expiration_year_ = expiration_year;
659 } 750 }
660 751
752 base::string16 CreditCard::GetNumber() const {
753 base::string16 number = number_part1_;
754 number += number_part2_;
755 number += number_part3_;
756 number += number_part4_;
757 return number;
758 }
759
661 // So we can compare CreditCards with EXPECT_EQ(). 760 // So we can compare CreditCards with EXPECT_EQ().
662 std::ostream& operator<<(std::ostream& os, const CreditCard& credit_card) { 761 std::ostream& operator<<(std::ostream& os, const CreditCard& credit_card) {
663 return os 762 return os
664 << base::UTF16ToUTF8(credit_card.Label()) 763 << base::UTF16ToUTF8(credit_card.Label()) << " " << credit_card.guid()
665 << " " 764 << " " << credit_card.origin() << " "
666 << credit_card.guid() 765 << base::UTF16ToUTF8(credit_card.GetRawInfo(CREDIT_CARD_NAME)) << " "
667 << " " 766 << base::UTF16ToUTF8(credit_card.GetRawInfo(CREDIT_CARD_TYPE)) << " "
668 << credit_card.origin() 767 << base::UTF16ToUTF8(credit_card.GetRawInfo(CREDIT_CARD_NUMBER)) << " "
669 << " " 768 << base::UTF16ToUTF8(credit_card.GetRawInfo(CREDIT_CARD_NUMBER_PART1))
670 << base::UTF16ToUTF8(credit_card.GetRawInfo(CREDIT_CARD_NAME)) 769 << " "
671 << " " 770 << base::UTF16ToUTF8(credit_card.GetRawInfo(CREDIT_CARD_NUMBER_PART2))
672 << base::UTF16ToUTF8(credit_card.GetRawInfo(CREDIT_CARD_TYPE)) 771 << " "
673 << " " 772 << base::UTF16ToUTF8(credit_card.GetRawInfo(CREDIT_CARD_NUMBER_PART3))
674 << base::UTF16ToUTF8(credit_card.GetRawInfo(CREDIT_CARD_NUMBER)) 773 << " "
675 << " " 774 << base::UTF16ToUTF8(credit_card.GetRawInfo(CREDIT_CARD_NUMBER_PART4))
676 << base::UTF16ToUTF8(credit_card.GetRawInfo(CREDIT_CARD_EXP_MONTH)) 775 << " "
677 << " " 776 << base::UTF16ToUTF8(credit_card.GetRawInfo(CREDIT_CARD_EXP_MONTH))
678 << base::UTF16ToUTF8( 777 << " " << base::UTF16ToUTF8(
679 credit_card.GetRawInfo(CREDIT_CARD_EXP_4_DIGIT_YEAR)); 778 credit_card.GetRawInfo(CREDIT_CARD_EXP_4_DIGIT_YEAR));
680 } 779 }
681 780
682 // These values must match the values in WebKitPlatformSupportImpl in 781 // These values must match the values in WebKitPlatformSupportImpl in
683 // webkit/glue. We send these strings to WebKit, which then asks 782 // webkit/glue. We send these strings to WebKit, which then asks
684 // WebKitPlatformSupportImpl to load the image data. 783 // WebKitPlatformSupportImpl to load the image data.
685 const char* const kAmericanExpressCard = "americanExpressCC"; 784 const char* const kAmericanExpressCard = "americanExpressCC";
686 const char* const kDinersCard = "dinersCC"; 785 const char* const kDinersCard = "dinersCC";
687 const char* const kDiscoverCard = "discoverCC"; 786 const char* const kDiscoverCard = "discoverCC";
688 const char* const kGenericCard = "genericCC"; 787 const char* const kGenericCard = "genericCC";
689 const char* const kJCBCard = "jcbCC"; 788 const char* const kJCBCard = "jcbCC";
690 const char* const kMasterCard = "masterCardCC"; 789 const char* const kMasterCard = "masterCardCC";
691 const char* const kUnionPay = "unionPayCC"; 790 const char* const kUnionPay = "unionPayCC";
692 const char* const kVisaCard = "visaCC"; 791 const char* const kVisaCard = "visaCC";
693 792
694 } // namespace autofill 793 } // namespace autofill
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698