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

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

Issue 1518783002: Revert of autofill: switch autofill_regexes to RE2 library (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 5 years 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_field.h" 5 #include "components/autofill/core/browser/credit_card_field.h"
6 6
7 #include <stddef.h> 7 #include <stddef.h>
8 8
9 #include "base/memory/scoped_ptr.h" 9 #include "base/memory/scoped_ptr.h"
10 #include "base/stl_util.h" 10 #include "base/stl_util.h"
11 #include "base/strings/string16.h" 11 #include "base/strings/string16.h"
12 #include "base/strings/string_number_conversions.h" 12 #include "base/strings/string_number_conversions.h"
13 #include "base/strings/string_util.h" 13 #include "base/strings/string_util.h"
14 #include "base/strings/utf_string_conversions.h"
14 #include "base/time/time.h" 15 #include "base/time/time.h"
15 #include "components/autofill/core/browser/autofill_field.h" 16 #include "components/autofill/core/browser/autofill_field.h"
16 #include "components/autofill/core/browser/autofill_regex_constants.h" 17 #include "components/autofill/core/browser/autofill_regex_constants.h"
17 #include "components/autofill/core/browser/autofill_scanner.h" 18 #include "components/autofill/core/browser/autofill_scanner.h"
18 #include "components/autofill/core/browser/field_types.h" 19 #include "components/autofill/core/browser/field_types.h"
19 #include "components/autofill/core/common/autofill_regexes.h" 20 #include "components/autofill/core/common/autofill_regexes.h"
20 #include "grit/components_strings.h" 21 #include "grit/components_strings.h"
21 #include "ui/base/l10n/l10n_util.h" 22 #include "ui/base/l10n/l10n_util.h"
22 23
23 namespace autofill { 24 namespace autofill {
24 25
25 namespace { 26 namespace {
26 27
27 // Credit card numbers are at most 19 digits in length. 28 // Credit card numbers are at most 19 digits in length.
28 // [Ref: http://en.wikipedia.org/wiki/Bank_card_number] 29 // [Ref: http://en.wikipedia.org/wiki/Bank_card_number]
29 const size_t kMaxValidCardNumberSize = 19; 30 const size_t kMaxValidCardNumberSize = 19;
30 31
31 // Look for the vector |regex_needles| in |haystack|. Returns true if a 32 // Look for the vector |regex_needles| in |haystack|. Returns true if a
32 // consecutive section of |haystack| matches |regex_needles|. 33 // consecutive section of |haystack| matches |regex_needles|.
33 bool FindConsecutiveStrings(const std::vector<std::string>& regex_needles, 34 bool FindConsecutiveStrings(const std::vector<base::string16>& regex_needles,
34 const std::vector<base::string16>& haystack) { 35 const std::vector<base::string16>& haystack) {
35 if (regex_needles.empty() || 36 if (regex_needles.empty() ||
36 haystack.empty() || 37 haystack.empty() ||
37 (haystack.size() < regex_needles.size())) 38 (haystack.size() < regex_needles.size()))
38 return false; 39 return false;
39 40
40 for (size_t i = 0; i < haystack.size() - regex_needles.size() + 1; ++i) { 41 for (size_t i = 0; i < haystack.size() - regex_needles.size() + 1; ++i) {
41 for (size_t j = 0; j < regex_needles.size(); ++j) { 42 for (size_t j = 0; j < regex_needles.size(); ++j) {
42 if (!MatchesPattern(haystack[i + j], regex_needles[j])) 43 if (!MatchesPattern(haystack[i + j], regex_needles[j]))
43 break; 44 break;
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after
83 84
84 // Credit card fields can appear in many different orders. 85 // Credit card fields can appear in many different orders.
85 // We loop until no more credit card related fields are found, see |break| at 86 // We loop until no more credit card related fields are found, see |break| at
86 // the bottom of the loop. 87 // the bottom of the loop.
87 for (int fields = 0; !scanner->IsEnd(); ++fields) { 88 for (int fields = 0; !scanner->IsEnd(); ++fields) {
88 // Ignore gift card fields. 89 // Ignore gift card fields.
89 if (IsGiftCardField(scanner)) 90 if (IsGiftCardField(scanner))
90 break; 91 break;
91 92
92 if (!credit_card_field->cardholder_) { 93 if (!credit_card_field->cardholder_) {
93 if (ParseField(scanner, kNameOnCardRe, &credit_card_field->cardholder_)) { 94 if (ParseField(scanner,
95 base::UTF8ToUTF16(kNameOnCardRe),
96 &credit_card_field->cardholder_)) {
94 continue; 97 continue;
95 } 98 }
96 99
97 // Sometimes the cardholder field is just labeled "name". Unfortunately 100 // Sometimes the cardholder field is just labeled "name". Unfortunately
98 // this is a dangerously generic word to search for, since it will often 101 // this is a dangerously generic word to search for, since it will often
99 // match a name (not cardholder name) field before or after credit card 102 // match a name (not cardholder name) field before or after credit card
100 // fields. So we search for "name" only when we've already parsed at 103 // fields. So we search for "name" only when we've already parsed at
101 // least one other credit card field and haven't yet parsed the 104 // least one other credit card field and haven't yet parsed the
102 // expiration date (which usually appears at the end). 105 // expiration date (which usually appears at the end).
103 if (fields > 0 && !credit_card_field->expiration_month_ && 106 if (fields > 0 &&
104 ParseField(scanner, kNameOnCardContextualRe, 107 !credit_card_field->expiration_month_ &&
108 ParseField(scanner,
109 base::UTF8ToUTF16(kNameOnCardContextualRe),
105 &credit_card_field->cardholder_)) { 110 &credit_card_field->cardholder_)) {
106 continue; 111 continue;
107 } 112 }
108 } 113 }
109 114
110 // Check for a credit card type (Visa, MasterCard, etc.) field. 115 // Check for a credit card type (Visa, MasterCard, etc.) field.
111 // All CC type fields encountered so far have been of type select. 116 // All CC type fields encountered so far have been of type select.
112 if (!credit_card_field->type_ && LikelyCardTypeSelectField(scanner)) { 117 if (!credit_card_field->type_ && LikelyCardTypeSelectField(scanner)) {
113 credit_card_field->type_ = scanner->Cursor(); 118 credit_card_field->type_ = scanner->Cursor();
114 scanner->Advance(); 119 scanner->Advance();
115 continue; 120 continue;
116 } 121 }
117 122
118 // We look for a card security code before we look for a credit card number 123 // We look for a card security code before we look for a credit card number
119 // and match the general term "number". The security code has a plethora of 124 // and match the general term "number". The security code has a plethora of
120 // names; we've seen "verification #", "verification number", "card 125 // names; we've seen "verification #", "verification number", "card
121 // identification number", and others listed in the regex pattern used 126 // identification number", and others listed in the regex pattern used
122 // below. 127 // below.
123 // Note: Some sites use type="tel" or type="number" for numerical inputs. 128 // Note: Some sites use type="tel" or type="number" for numerical inputs.
124 const int kMatchNumAndTel = MATCH_DEFAULT | MATCH_NUMBER | MATCH_TELEPHONE; 129 const int kMatchNumAndTel = MATCH_DEFAULT | MATCH_NUMBER | MATCH_TELEPHONE;
125 if (!credit_card_field->verification_ && 130 if (!credit_card_field->verification_ &&
126 ParseFieldSpecifics(scanner, 131 ParseFieldSpecifics(scanner,
127 kCardCvcRe, 132 base::UTF8ToUTF16(kCardCvcRe),
128 kMatchNumAndTel | MATCH_PASSWORD, 133 kMatchNumAndTel | MATCH_PASSWORD,
129 &credit_card_field->verification_)) { 134 &credit_card_field->verification_)) {
130 continue; 135 continue;
131 } 136 }
132 137
133 AutofillField* current_number_field; 138 AutofillField* current_number_field;
134 if (ParseFieldSpecifics(scanner, 139 if (ParseFieldSpecifics(scanner,
135 kCardNumberRe, 140 base::UTF8ToUTF16(kCardNumberRe),
136 kMatchNumAndTel, 141 kMatchNumAndTel,
137 &current_number_field)) { 142 &current_number_field)) {
138 // Avoid autofilling any credit card number field having very low or high 143 // Avoid autofilling any credit card number field having very low or high
139 // |start_index| on the HTML form. 144 // |start_index| on the HTML form.
140 size_t start_index = 0; 145 size_t start_index = 0;
141 if (!credit_card_field->numbers_.empty()) { 146 if (!credit_card_field->numbers_.empty()) {
142 size_t last_number_field_size = 147 size_t last_number_field_size =
143 credit_card_field->numbers_.back()->credit_card_number_offset() + 148 credit_card_field->numbers_.back()->credit_card_number_offset() +
144 credit_card_field->numbers_.back()->max_length; 149 credit_card_field->numbers_.back()->max_length;
145 150
(...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after
202 return false; 207 return false;
203 208
204 AutofillField* field = scanner->Cursor(); 209 AutofillField* field = scanner->Cursor();
205 if (!MatchesFormControlType(field->form_control_type, MATCH_SELECT)) 210 if (!MatchesFormControlType(field->form_control_type, MATCH_SELECT))
206 return false; 211 return false;
207 212
208 if (field->option_values.size() < 12 || field->option_values.size() > 13) 213 if (field->option_values.size() < 12 || field->option_values.size() > 13)
209 return false; 214 return false;
210 215
211 // Filter out years. 216 // Filter out years.
212 const char kNumericalYearRe[] = "[1-9][0-9][0-9][0-9]"; 217 const base::string16 kNumericalYearRe =
218 base::ASCIIToUTF16("[1-9][0-9][0-9][0-9]");
213 for (const auto& value : field->option_values) { 219 for (const auto& value : field->option_values) {
214 if (MatchesPattern(value, kNumericalYearRe)) 220 if (MatchesPattern(value, kNumericalYearRe))
215 return false; 221 return false;
216 } 222 }
217 for (const auto& value : field->option_contents) { 223 for (const auto& value : field->option_contents) {
218 if (MatchesPattern(value, kNumericalYearRe)) 224 if (MatchesPattern(value, kNumericalYearRe))
219 return false; 225 return false;
220 } 226 }
221 227
222 // Look for numerical months. 228 // Look for numerical months.
223 const char kNumericalMonthRe[] = "12"; 229 const base::string16 kNumericalMonthRe = base::ASCIIToUTF16("12");
224 if (MatchesPattern(field->option_values.back(), kNumericalMonthRe) || 230 if (MatchesPattern(field->option_values.back(), kNumericalMonthRe) ||
225 MatchesPattern(field->option_contents.back(), kNumericalMonthRe)) { 231 MatchesPattern(field->option_contents.back(), kNumericalMonthRe)) {
226 return true; 232 return true;
227 } 233 }
228 234
229 // Maybe do more matches here. e.g. look for (translated) December. 235 // Maybe do more matches here. e.g. look for (translated) December.
230 236
231 // Unsure? Return false. 237 // Unsure? Return false.
232 return false; 238 return false;
233 } 239 }
234 240
235 // static 241 // static
236 bool CreditCardField::LikelyCardYearSelectField(AutofillScanner* scanner) { 242 bool CreditCardField::LikelyCardYearSelectField(AutofillScanner* scanner) {
237 if (scanner->IsEnd()) 243 if (scanner->IsEnd())
238 return false; 244 return false;
239 245
240 AutofillField* field = scanner->Cursor(); 246 AutofillField* field = scanner->Cursor();
241 if (!MatchesFormControlType(field->form_control_type, MATCH_SELECT)) 247 if (!MatchesFormControlType(field->form_control_type, MATCH_SELECT))
242 return false; 248 return false;
243 249
244 const base::Time time_now = base::Time::Now(); 250 const base::Time time_now = base::Time::Now();
245 base::Time::Exploded time_exploded; 251 base::Time::Exploded time_exploded;
246 time_now.UTCExplode(&time_exploded); 252 time_now.UTCExplode(&time_exploded);
247 253
248 const int kYearsToMatch = 3; 254 const int kYearsToMatch = 3;
249 std::vector<std::string> years_to_check; 255 std::vector<base::string16> years_to_check;
250 for (int year = time_exploded.year; 256 for (int year = time_exploded.year;
251 year < time_exploded.year + kYearsToMatch; 257 year < time_exploded.year + kYearsToMatch;
252 ++year) { 258 ++year) {
253 years_to_check.push_back(base::IntToString(year)); 259 years_to_check.push_back(base::IntToString16(year));
254 } 260 }
255 return (FindConsecutiveStrings(years_to_check, field->option_values) || 261 return (FindConsecutiveStrings(years_to_check, field->option_values) ||
256 FindConsecutiveStrings(years_to_check, field->option_contents)); 262 FindConsecutiveStrings(years_to_check, field->option_contents));
257 } 263 }
258 264
259 // static 265 // static
260 bool CreditCardField::LikelyCardTypeSelectField(AutofillScanner* scanner) { 266 bool CreditCardField::LikelyCardTypeSelectField(AutofillScanner* scanner) {
261 if (scanner->IsEnd()) 267 if (scanner->IsEnd())
262 return false; 268 return false;
263 269
264 AutofillField* field = scanner->Cursor(); 270 AutofillField* field = scanner->Cursor();
265 if (!MatchesFormControlType(field->form_control_type, MATCH_SELECT)) 271 if (!MatchesFormControlType(field->form_control_type, MATCH_SELECT))
266 return false; 272 return false;
267 273
268 return AutofillField::FindValueInSelectControl( 274 return AutofillField::FindValueInSelectControl(
269 *field, l10n_util::GetStringUTF16(IDS_AUTOFILL_CC_VISA), 275 *field, l10n_util::GetStringUTF16(IDS_AUTOFILL_CC_VISA),
270 nullptr) || 276 nullptr) ||
271 AutofillField::FindValueInSelectControl( 277 AutofillField::FindValueInSelectControl(
272 *field, l10n_util::GetStringUTF16(IDS_AUTOFILL_CC_MASTERCARD), 278 *field, l10n_util::GetStringUTF16(IDS_AUTOFILL_CC_MASTERCARD),
273 nullptr); 279 nullptr);
274 } 280 }
275 281
276 // static 282 // static
277 bool CreditCardField::IsGiftCardField(AutofillScanner* scanner) { 283 bool CreditCardField::IsGiftCardField(AutofillScanner* scanner) {
278 if (scanner->IsEnd()) 284 if (scanner->IsEnd())
279 return false; 285 return false;
280 286
281 size_t saved_cursor = scanner->SaveCursor(); 287 size_t saved_cursor = scanner->SaveCursor();
282 if (ParseField(scanner, kDebitCardRe, nullptr)) { 288 if (ParseField(scanner, base::UTF8ToUTF16(kDebitCardRe), nullptr)) {
283 scanner->RewindTo(saved_cursor); 289 scanner->RewindTo(saved_cursor);
284 return false; 290 return false;
285 } 291 }
286 if (ParseField(scanner, kDebitGiftCardRe, nullptr)) { 292 if (ParseField(scanner, base::UTF8ToUTF16(kDebitGiftCardRe), nullptr)) {
287 scanner->RewindTo(saved_cursor); 293 scanner->RewindTo(saved_cursor);
288 return false; 294 return false;
289 } 295 }
290 296
291 return ParseField(scanner, kGiftCardRe, nullptr); 297 return ParseField(scanner, base::UTF8ToUTF16(kGiftCardRe), nullptr);
292 } 298 }
293 299
294 CreditCardField::CreditCardField() 300 CreditCardField::CreditCardField()
295 : cardholder_(nullptr), 301 : cardholder_(nullptr),
296 cardholder_last_(nullptr), 302 cardholder_last_(nullptr),
297 type_(nullptr), 303 type_(nullptr),
298 verification_(nullptr), 304 verification_(nullptr),
299 expiration_month_(nullptr), 305 expiration_month_(nullptr),
300 expiration_year_(nullptr), 306 expiration_year_(nullptr),
301 expiration_date_(nullptr), 307 expiration_date_(nullptr),
(...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after
363 return true; 369 return true;
364 } 370 }
365 expiration_month_ = nullptr; 371 expiration_month_ = nullptr;
366 expiration_year_ = nullptr; 372 expiration_year_ = nullptr;
367 } 373 }
368 374
369 // If that fails, do a general regex search. 375 // If that fails, do a general regex search.
370 scanner->RewindTo(month_year_saved_cursor); 376 scanner->RewindTo(month_year_saved_cursor);
371 const int kMatchTelAndSelect = MATCH_DEFAULT | MATCH_TELEPHONE | MATCH_SELECT; 377 const int kMatchTelAndSelect = MATCH_DEFAULT | MATCH_TELEPHONE | MATCH_SELECT;
372 if (ParseFieldSpecifics(scanner, 378 if (ParseFieldSpecifics(scanner,
373 kExpirationMonthRe, 379 base::UTF8ToUTF16(kExpirationMonthRe),
374 kMatchTelAndSelect, 380 kMatchTelAndSelect,
375 &expiration_month_) && 381 &expiration_month_) &&
376 ParseFieldSpecifics(scanner, 382 ParseFieldSpecifics(scanner,
377 kExpirationYearRe, 383 base::UTF8ToUTF16(kExpirationYearRe),
378 kMatchTelAndSelect, 384 kMatchTelAndSelect,
379 &expiration_year_)) { 385 &expiration_year_)) {
380 return true; 386 return true;
381 } 387 }
382 388
383 // If that fails, look for just MM/YY(YY). 389 // If that fails, look for just MM/YY(YY).
384 scanner->RewindTo(month_year_saved_cursor); 390 scanner->RewindTo(month_year_saved_cursor);
385 if (ParseFieldSpecifics(scanner, 391 if (ParseFieldSpecifics(scanner,
386 "^mm$", 392 base::ASCIIToUTF16("^mm$"),
387 kMatchTelAndSelect, 393 kMatchTelAndSelect,
388 &expiration_month_) && 394 &expiration_month_) &&
389 ParseFieldSpecifics(scanner, 395 ParseFieldSpecifics(scanner,
390 "^(yy|yyyy)$", 396 base::ASCIIToUTF16("^(yy|yyyy)$"),
391 kMatchTelAndSelect, 397 kMatchTelAndSelect,
392 &expiration_year_)) { 398 &expiration_year_)) {
393 return true; 399 return true;
394 } 400 }
395 401
396 // If that fails, try to parse a combined expiration field. 402 // If that fails, try to parse a combined expiration field.
397 // We allow <select> fields, because they're used e.g. on qvc.com. 403 // We allow <select> fields, because they're used e.g. on qvc.com.
398 scanner->RewindTo(month_year_saved_cursor); 404 scanner->RewindTo(month_year_saved_cursor);
399 405
400 // Bail out if the field cannot fit a 2-digit year expiration date. 406 // Bail out if the field cannot fit a 2-digit year expiration date.
401 const int current_field_max_length = scanner->Cursor()->max_length; 407 const int current_field_max_length = scanner->Cursor()->max_length;
402 if (!FieldCanFitDataForFieldType(current_field_max_length, 408 if (!FieldCanFitDataForFieldType(current_field_max_length,
403 CREDIT_CARD_EXP_DATE_2_DIGIT_YEAR)) { 409 CREDIT_CARD_EXP_DATE_2_DIGIT_YEAR)) {
404 return false; 410 return false;
405 } 411 }
406 412
407 // Try to look for a 2-digit year expiration date. 413 // Try to look for a 2-digit year expiration date.
408 if (ParseFieldSpecifics(scanner, 414 if (ParseFieldSpecifics(scanner,
409 kExpirationDate2DigitYearRe, 415 base::UTF8ToUTF16(kExpirationDate2DigitYearRe),
410 kMatchTelAndSelect, 416 kMatchTelAndSelect,
411 &expiration_date_)) { 417 &expiration_date_)) {
412 exp_year_type_ = CREDIT_CARD_EXP_DATE_2_DIGIT_YEAR; 418 exp_year_type_ = CREDIT_CARD_EXP_DATE_2_DIGIT_YEAR;
413 expiration_month_ = nullptr; 419 expiration_month_ = nullptr;
414 return true; 420 return true;
415 } 421 }
416 422
417 // Try to look for a generic expiration date field. (2 or 4 digit year) 423 // Try to look for a generic expiration date field. (2 or 4 digit year)
418 if (ParseFieldSpecifics(scanner, 424 if (ParseFieldSpecifics(scanner,
419 kExpirationDateRe, 425 base::UTF8ToUTF16(kExpirationDateRe),
420 kMatchTelAndSelect, 426 kMatchTelAndSelect,
421 &expiration_date_)) { 427 &expiration_date_)) {
422 // If such a field exists, but it cannot fit a 4-digit year expiration 428 // If such a field exists, but it cannot fit a 4-digit year expiration
423 // date, then the likely possibility is that it is a 2-digit year expiration 429 // date, then the likely possibility is that it is a 2-digit year expiration
424 // date. 430 // date.
425 if (!FieldCanFitDataForFieldType(current_field_max_length, 431 if (!FieldCanFitDataForFieldType(current_field_max_length,
426 CREDIT_CARD_EXP_DATE_4_DIGIT_YEAR)) { 432 CREDIT_CARD_EXP_DATE_4_DIGIT_YEAR)) {
427 exp_year_type_ = CREDIT_CARD_EXP_DATE_2_DIGIT_YEAR; 433 exp_year_type_ = CREDIT_CARD_EXP_DATE_2_DIGIT_YEAR;
428 } 434 }
429 expiration_month_ = nullptr; 435 expiration_month_ = nullptr;
430 return true; 436 return true;
431 } 437 }
432 438
433 // Try to look for a 4-digit year expiration date. 439 // Try to look for a 4-digit year expiration date.
434 if (FieldCanFitDataForFieldType(current_field_max_length, 440 if (FieldCanFitDataForFieldType(current_field_max_length,
435 CREDIT_CARD_EXP_DATE_4_DIGIT_YEAR) && 441 CREDIT_CARD_EXP_DATE_4_DIGIT_YEAR) &&
436 ParseFieldSpecifics(scanner, 442 ParseFieldSpecifics(scanner,
437 kExpirationDate4DigitYearRe, 443 base::UTF8ToUTF16(kExpirationDate4DigitYearRe),
438 kMatchTelAndSelect, 444 kMatchTelAndSelect,
439 &expiration_date_)) { 445 &expiration_date_)) {
440 expiration_month_ = nullptr; 446 expiration_month_ = nullptr;
441 return true; 447 return true;
442 } 448 }
443 449
444 return false; 450 return false;
445 } 451 }
446 452
447 ServerFieldType CreditCardField::GetExpirationYearType() const { 453 ServerFieldType CreditCardField::GetExpirationYearType() const {
448 return (expiration_date_ 454 return (expiration_date_
449 ? exp_year_type_ 455 ? exp_year_type_
450 : ((expiration_year_ && expiration_year_->max_length == 2) 456 : ((expiration_year_ && expiration_year_->max_length == 2)
451 ? CREDIT_CARD_EXP_2_DIGIT_YEAR 457 ? CREDIT_CARD_EXP_2_DIGIT_YEAR
452 : CREDIT_CARD_EXP_4_DIGIT_YEAR)); 458 : CREDIT_CARD_EXP_4_DIGIT_YEAR));
453 } 459 }
454 460
455 } // namespace autofill 461 } // namespace autofill
OLDNEW
« no previous file with comments | « components/autofill/core/browser/credit_card.cc ('k') | components/autofill/core/browser/email_field.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698