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

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

Issue 1753253003: [Autofill] Fix heuristics to detect consecutive CVCs. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Added scanner check Created 4 years, 9 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_field.h" 5 #include "components/autofill/core/browser/credit_card_field.h"
6 6
7 #include <stddef.h> 7 #include <stddef.h>
8 #include <utility> 8 #include <utility>
9 9
10 #include "base/memory/scoped_ptr.h" 10 #include "base/memory/scoped_ptr.h"
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after
65 case CREDIT_CARD_EXP_DATE_4_DIGIT_YEAR: { 65 case CREDIT_CARD_EXP_DATE_4_DIGIT_YEAR: {
66 static int kMinimum4YearCcExpLength = strlen("12/2014"); 66 static int kMinimum4YearCcExpLength = strlen("12/2014");
67 return max_length >= kMinimum4YearCcExpLength; 67 return max_length >= kMinimum4YearCcExpLength;
68 } 68 }
69 default: 69 default:
70 NOTREACHED(); 70 NOTREACHED();
71 return false; 71 return false;
72 } 72 }
73 } 73 }
74 74
75
76 } // namespace 75 } // namespace
77 76
78 // static 77 // static
79 scoped_ptr<FormField> CreditCardField::Parse(AutofillScanner* scanner) { 78 scoped_ptr<FormField> CreditCardField::Parse(AutofillScanner* scanner) {
80 if (scanner->IsEnd()) 79 if (scanner->IsEnd())
81 return nullptr; 80 return nullptr;
82 81
83 scoped_ptr<CreditCardField> credit_card_field(new CreditCardField); 82 scoped_ptr<CreditCardField> credit_card_field(new CreditCardField);
84 size_t saved_cursor = scanner->SaveCursor(); 83 size_t saved_cursor = scanner->SaveCursor();
85 84
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after
130 scanner->Advance(); 129 scanner->Advance();
131 continue; 130 continue;
132 } 131 }
133 132
134 // We look for a card security code before we look for a credit card number 133 // We look for a card security code before we look for a credit card number
135 // and match the general term "number". The security code has a plethora of 134 // and match the general term "number". The security code has a plethora of
136 // names; we've seen "verification #", "verification number", "card 135 // names; we've seen "verification #", "verification number", "card
137 // identification number", and others listed in the regex pattern used 136 // identification number", and others listed in the regex pattern used
138 // below. 137 // below.
139 // Note: Some sites use type="tel" or type="number" for numerical inputs. 138 // Note: Some sites use type="tel" or type="number" for numerical inputs.
140 const int kMatchNumAndTel = MATCH_DEFAULT | MATCH_NUMBER | MATCH_TELEPHONE; 139 // They also sometimes use type="password" for sensitive types.
140 const int kMatchNumTelAndPwd =
141 MATCH_DEFAULT | MATCH_NUMBER | MATCH_TELEPHONE | MATCH_PASSWORD;
141 if (!credit_card_field->verification_ && 142 if (!credit_card_field->verification_ &&
142 ParseFieldSpecifics(scanner, 143 ParseFieldSpecifics(scanner, base::UTF8ToUTF16(kCardCvcRe),
143 base::UTF8ToUTF16(kCardCvcRe), 144 kMatchNumTelAndPwd,
144 kMatchNumAndTel | MATCH_PASSWORD,
145 &credit_card_field->verification_)) { 145 &credit_card_field->verification_)) {
146 // A couple of sites have multiple verification codes right after another.
147 // Allow the classification of these codes one by one.
148 AutofillField* const saved_cvv = credit_card_field->verification_;
149
150 // Check if the verification code is the first detected field in the newly
151 // started card.
152 if (credit_card_field->numbers_.empty() &&
153 !credit_card_field->HasExpiration() &&
154 !credit_card_field->cardholder_ && scanner->SaveCursor() > 1) {
155 // Check if the previous field was a verification code.
156 scanner->RewindTo(scanner->SaveCursor() - 2);
157 if (ParseFieldSpecifics(scanner, base::UTF8ToUTF16(kCardCvcRe),
158 kMatchNumTelAndPwd,
159 &credit_card_field->verification_)) {
160 // Reset the current cvv (The verification parse overwrote it).
161 credit_card_field->verification_ = saved_cvv;
162 // Put the scanner back to the field right after the current cvv.
163 scanner->Advance();
164 return std::move(credit_card_field);
165 } else {
166 // Put the scanner back to the field right after the current cvv.
167 scanner->Advance();
168 scanner->Advance();
169 }
170 }
171
146 continue; 172 continue;
147 } 173 }
148 174
149 // TODO(crbug.com/591816): Make sure parsing cc-numbers of type password 175 // TODO(crbug.com/591816): Make sure parsing cc-numbers of type password
150 // doesn't have bad side effects. 176 // doesn't have bad side effects.
151 AutofillField* current_number_field; 177 AutofillField* current_number_field;
152 if (ParseFieldSpecifics(scanner, base::UTF8ToUTF16(kCardNumberRe), 178 if (ParseFieldSpecifics(scanner, base::UTF8ToUTF16(kCardNumberRe),
153 kMatchNumAndTel | MATCH_PASSWORD, 179 kMatchNumTelAndPwd, &current_number_field)) {
154 &current_number_field)) {
155 // Avoid autofilling any credit card number field having very low or high 180 // Avoid autofilling any credit card number field having very low or high
156 // |start_index| on the HTML form. 181 // |start_index| on the HTML form.
157 size_t start_index = 0; 182 size_t start_index = 0;
158 if (!credit_card_field->numbers_.empty()) { 183 if (!credit_card_field->numbers_.empty()) {
159 size_t last_number_field_size = 184 size_t last_number_field_size =
160 credit_card_field->numbers_.back()->credit_card_number_offset() + 185 credit_card_field->numbers_.back()->credit_card_number_offset() +
161 credit_card_field->numbers_.back()->max_length; 186 credit_card_field->numbers_.back()->max_length;
162 187
163 // Distinguish between 188 // Distinguish between
164 // (a) one card split across multiple fields 189 // (a) one card split across multiple fields
(...skipping 29 matching lines...) Expand all
194 if (credit_card_field->cardholder_) 219 if (credit_card_field->cardholder_)
195 return std::move(credit_card_field); 220 return std::move(credit_card_field);
196 221
197 // On some pages, the user selects a card type using radio buttons 222 // On some pages, the user selects a card type using radio buttons
198 // (e.g. test page Apple Store Billing.html). We can't handle that yet, 223 // (e.g. test page Apple Store Billing.html). We can't handle that yet,
199 // so we treat the card type as optional for now. 224 // so we treat the card type as optional for now.
200 // The existence of a number or cvc in combination with expiration date is 225 // The existence of a number or cvc in combination with expiration date is
201 // a strong enough signal that this is a credit card. It is possible that 226 // a strong enough signal that this is a credit card. It is possible that
202 // the number and name were parsed in a separate part of the form. So if 227 // the number and name were parsed in a separate part of the form. So if
203 // the cvc and date were found independently they are returned. 228 // the cvc and date were found independently they are returned.
204 bool has_cc_number_or_verification = (credit_card_field->verification_ || 229 const bool has_cc_number_or_verification =
205 !credit_card_field->numbers_.empty()); 230 (credit_card_field->verification_ ||
206 bool has_date_or_mm_yy = (credit_card_field->expiration_date_ || 231 !credit_card_field->numbers_.empty());
207 (credit_card_field->expiration_month_ && 232 if (has_cc_number_or_verification && credit_card_field->HasExpiration())
208 credit_card_field->expiration_year_));
209 if (has_cc_number_or_verification && has_date_or_mm_yy)
210 return std::move(credit_card_field); 233 return std::move(credit_card_field);
211 234
212 scanner->RewindTo(saved_cursor); 235 scanner->RewindTo(saved_cursor);
213 return nullptr; 236 return nullptr;
214 } 237 }
215 238
216 // static 239 // static
217 bool CreditCardField::LikelyCardMonthSelectField(AutofillScanner* scanner) { 240 bool CreditCardField::LikelyCardMonthSelectField(AutofillScanner* scanner) {
218 if (scanner->IsEnd()) 241 if (scanner->IsEnd())
219 return false; 242 return false;
(...skipping 255 matching lines...) Expand 10 before | Expand all | Expand 10 after
475 } 498 }
476 499
477 ServerFieldType CreditCardField::GetExpirationYearType() const { 500 ServerFieldType CreditCardField::GetExpirationYearType() const {
478 return (expiration_date_ 501 return (expiration_date_
479 ? exp_year_type_ 502 ? exp_year_type_
480 : ((expiration_year_ && expiration_year_->max_length == 2) 503 : ((expiration_year_ && expiration_year_->max_length == 2)
481 ? CREDIT_CARD_EXP_2_DIGIT_YEAR 504 ? CREDIT_CARD_EXP_2_DIGIT_YEAR
482 : CREDIT_CARD_EXP_4_DIGIT_YEAR)); 505 : CREDIT_CARD_EXP_4_DIGIT_YEAR));
483 } 506 }
484 507
508 bool CreditCardField::HasExpiration() const {
509 return expiration_date_ || (expiration_month_ && expiration_year_);
510 }
511
485 } // namespace autofill 512 } // namespace autofill
OLDNEW
« no previous file with comments | « components/autofill/core/browser/credit_card_field.h ('k') | components/autofill/core/browser/credit_card_field_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698