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

Unified Diff: components/autofill/core/browser/credit_card.cc

Issue 2136453003: [Autofill] Improve support for various credit card expiration dates. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: addressed comments Created 4 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 side-by-side diff with in-line comments
Download patch
Index: components/autofill/core/browser/credit_card.cc
diff --git a/components/autofill/core/browser/credit_card.cc b/components/autofill/core/browser/credit_card.cc
index 1503a437d38f38996a4dd88a084f9ee46c89851b..a5f25096880445f7c704533155f520cc421d07ea 100644
--- a/components/autofill/core/browser/credit_card.cc
+++ b/components/autofill/core/browser/credit_card.cc
@@ -35,6 +35,8 @@
#include "third_party/icu/source/i18n/unicode/dtfmtsym.h"
#include "ui/base/l10n/l10n_util.h"
+using base::ASCIIToUTF16;
+
namespace autofill {
const base::char16 kMidlineEllipsis[] = { 0x22ef, 0 };
@@ -118,7 +120,7 @@ CreditCard::~CreditCard() {}
// static
const base::string16 CreditCard::StripSeparators(const base::string16& number) {
base::string16 stripped;
- base::RemoveChars(number, base::ASCIIToUTF16("- "), &stripped);
+ base::RemoveChars(number, ASCIIToUTF16("- "), &stripped);
return stripped;
}
@@ -290,7 +292,7 @@ base::string16 CreditCard::GetRawInfo(ServerFieldType type) const {
base::string16 month = ExpirationMonthAsString();
base::string16 year = Expiration2DigitYearAsString();
if (!month.empty() && !year.empty())
- return month + base::ASCIIToUTF16("/") + year;
+ return month + ASCIIToUTF16("/") + year;
return base::string16();
}
@@ -298,7 +300,7 @@ base::string16 CreditCard::GetRawInfo(ServerFieldType type) const {
base::string16 month = ExpirationMonthAsString();
base::string16 year = Expiration4DigitYearAsString();
if (!month.empty() && !year.empty())
- return month + base::ASCIIToUTF16("/") + year;
+ return month + ASCIIToUTF16("/") + year;
return base::string16();
}
@@ -331,7 +333,7 @@ void CreditCard::SetRawInfo(ServerFieldType type,
break;
case CREDIT_CARD_EXP_2_DIGIT_YEAR:
- // This is a read-only attribute.
+ SetExpirationYearFromString(value);
break;
case CREDIT_CARD_EXP_4_DIGIT_YEAR:
@@ -339,11 +341,11 @@ void CreditCard::SetRawInfo(ServerFieldType type,
break;
case CREDIT_CARD_EXP_DATE_2_DIGIT_YEAR:
- // This is a read-only attribute.
+ SetExpirationDateFromString(value);
break;
case CREDIT_CARD_EXP_DATE_4_DIGIT_YEAR:
- // This is a read-only attribute.
+ SetExpirationDateFromString(value);
break;
case CREDIT_CARD_TYPE:
@@ -431,7 +433,7 @@ const std::pair<base::string16, base::string16> CreditCard::LabelPieces()
return std::make_pair(obfuscated_cc_number, base::string16());
base::string16 formatted_date(ExpirationMonthAsString());
- formatted_date.append(base::ASCIIToUTF16("/"));
+ formatted_date.append(ASCIIToUTF16("/"));
formatted_date.append(Expiration4DigitYearAsString());
base::string16 separator =
@@ -445,8 +447,7 @@ void CreditCard::SetInfoForMonthInputType(const base::string16& value) {
return;
std::vector<base::StringPiece16> year_month = base::SplitStringPiece(
- value, base::ASCIIToUTF16("-"),
- base::TRIM_WHITESPACE, base::SPLIT_WANT_ALL);
+ value, ASCIIToUTF16("-"), base::TRIM_WHITESPACE, base::SPLIT_WANT_ALL);
DCHECK_EQ(2u, year_month.size());
int num = 0;
bool converted = false;
@@ -465,9 +466,20 @@ void CreditCard::SetExpirationMonth(int expiration_month) {
}
void CreditCard::SetExpirationYear(int expiration_year) {
- if (expiration_year != 0 &&
- (expiration_year < 2006 || expiration_year > 10000))
+ // If |expiration_year| is beyond this millenium, or more than 2 digits but
+ // before the current millenium (e.g. "545", "1995"), return. What is left are
+ // values like "45" or "2018".
+ if (expiration_year > 2999 ||
+ (expiration_year > 99 && expiration_year < 2000))
return;
+
+ // Will normalize 2-digit years to the 4-digit version.
+ if (expiration_year > 0 && expiration_year < 100) {
+ base::Time::Exploded now_exploded;
+ base::Time::Now().LocalExplode(&now_exploded);
+ expiration_year += (now_exploded.year / 100) * 100;
+ }
+
expiration_year_ = expiration_year;
}
@@ -672,7 +684,7 @@ base::string16 CreditCard::ExpirationMonthAsString() const {
if (expiration_month_ >= 10)
return month;
- base::string16 zero = base::ASCIIToUTF16("0");
+ base::string16 zero = ASCIIToUTF16("0");
zero.append(month);
return zero;
}
@@ -716,6 +728,50 @@ void CreditCard::SetExpirationYearFromString(const base::string16& text) {
SetExpirationYear(year);
}
+void CreditCard::SetExpirationDateFromString(const base::string16& text) {
+ // Check that |text| fits the supported patterns: mmyy, mmyyyy, m-yy,
+ // mm-yy, m-yyyy and mm-yyyy. Note that myy and myyyy matched by this pattern
+ // but are not supported (ambiguous). Separators: -, / and |.
+ if (!MatchesPattern(text, base::UTF8ToUTF16("^[0-9]{1,2}[-/|]?[0-9]{2,4}$")))
+ return;
+
+ base::string16 month;
+ base::string16 year;
+
+ // Check for a separator.
+ base::string16 found_separator;
+ const std::vector<const base::string16> kSeparators{
+ ASCIIToUTF16("-"), ASCIIToUTF16("/"), ASCIIToUTF16("|")};
+ for (const base::string16& separator : kSeparators) {
+ if (text.find(separator) != base::string16::npos)
+ 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.
+ }
+
+ if (!found_separator.empty()) {
+ std::vector<base::string16> month_year = base::SplitString(
+ text, found_separator, base::TRIM_WHITESPACE, base::SPLIT_WANT_ALL);
+ DCHECK_EQ(2u, month_year.size());
+ month = month_year[0];
+ year = month_year[1];
+ } else if (text.size() % 2 == 0) {
+ // 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.
+ month = text.substr(0, 2);
+ year = text.substr(2);
+ } else {
+ // Odd number of digits with no separator is too ambiguous.
+ return;
+ }
+
+ int num = 0;
+ bool converted = false;
+ converted = base::StringToInt(month, &num);
+ DCHECK(converted);
+ SetExpirationMonth(num);
+ converted = base::StringToInt(year, &num);
+ DCHECK(converted);
+ SetExpirationYear(num);
+}
+
void CreditCard::SetNumber(const base::string16& number) {
number_ = number;
@@ -768,10 +824,10 @@ bool CreditCard::ConvertMonth(const base::string16& month,
// Some abbreviations have . at the end (e.g., "janv." in French). We don't
// care about matching that.
base::string16 trimmed_month;
- base::TrimString(month, base::ASCIIToUTF16("."), &trimmed_month);
+ base::TrimString(month, ASCIIToUTF16("."), &trimmed_month);
for (int32_t i = 0; i < num_months; ++i) {
base::string16 icu_month(months[i].getBuffer(), months[i].length());
- base::TrimString(icu_month, base::ASCIIToUTF16("."), &icu_month);
+ base::TrimString(icu_month, ASCIIToUTF16("."), &icu_month);
if (compare.StringsEqual(icu_month, trimmed_month)) {
*num = i + 1; // Adjust from 0-indexed to 1-indexed.
return true;
« no previous file with comments | « components/autofill/core/browser/credit_card.h ('k') | components/autofill/core/browser/credit_card_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698