| 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_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/logging.h" | 9 #include "base/logging.h" |
| 10 #include "base/memory/scoped_ptr.h" | 10 #include "base/memory/scoped_ptr.h" |
| (...skipping 12 matching lines...) Expand all Loading... |
| 23 // [Ref: http://en.wikipedia.org/wiki/Bank_card_number] | 23 // [Ref: http://en.wikipedia.org/wiki/Bank_card_number] |
| 24 static const size_t kMaxValidCardNumberSize = 19; | 24 static const size_t kMaxValidCardNumberSize = 19; |
| 25 | 25 |
| 26 // static | 26 // static |
| 27 FormField* CreditCardField::Parse(AutofillScanner* scanner) { | 27 FormField* CreditCardField::Parse(AutofillScanner* scanner) { |
| 28 if (scanner->IsEnd()) | 28 if (scanner->IsEnd()) |
| 29 return NULL; | 29 return NULL; |
| 30 | 30 |
| 31 scoped_ptr<CreditCardField> credit_card_field(new CreditCardField); | 31 scoped_ptr<CreditCardField> credit_card_field(new CreditCardField); |
| 32 size_t saved_cursor = scanner->SaveCursor(); | 32 size_t saved_cursor = scanner->SaveCursor(); |
| 33 bool form_has_valid_card_number_fields = true; | |
| 34 | 33 |
| 35 // Credit card fields can appear in many different orders. | 34 // Credit card fields can appear in many different orders. |
| 36 // We loop until no more credit card related fields are found, see |break| at | 35 // We loop until no more credit card related fields are found, see |break| at |
| 37 // bottom of the loop. | 36 // bottom of the loop. |
| 38 for (int fields = 0; !scanner->IsEnd(); ++fields) { | 37 for (int fields = 0; !scanner->IsEnd(); ++fields) { |
| 39 // Ignore gift card fields. | 38 // Ignore gift card fields. |
| 40 if (ParseField(scanner, base::UTF8ToUTF16(autofill::kGiftCardRe), NULL)) | 39 if (ParseField(scanner, base::UTF8ToUTF16(autofill::kGiftCardRe), NULL)) |
| 41 break; | 40 break; |
| 42 | 41 |
| 43 // Sometimes the cardholder field is just labeled "name". Unfortunately this | 42 // Sometimes the cardholder field is just labeled "name". Unfortunately this |
| (...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 99 AutofillField* current_number_field; | 98 AutofillField* current_number_field; |
| 100 if (ParseField(scanner, pattern, ¤t_number_field)) { | 99 if (ParseField(scanner, pattern, ¤t_number_field)) { |
| 101 // Avoid autofilling any credit card number field having very low or high | 100 // Avoid autofilling any credit card number field having very low or high |
| 102 // |start_index| on the HTML form. | 101 // |start_index| on the HTML form. |
| 103 size_t start_index = 0; | 102 size_t start_index = 0; |
| 104 if (!credit_card_field->numbers_.empty()) { | 103 if (!credit_card_field->numbers_.empty()) { |
| 105 size_t last_number_field_size = | 104 size_t last_number_field_size = |
| 106 credit_card_field->numbers_.back()->credit_card_number_offset() + | 105 credit_card_field->numbers_.back()->credit_card_number_offset() + |
| 107 credit_card_field->numbers_.back()->max_length; | 106 credit_card_field->numbers_.back()->max_length; |
| 108 | 107 |
| 109 // In some cases, HTML form may have credit card number split across | 108 // Distinguish between |
| 110 // multiple input fields and either one or cumulatively having | 109 // (a) one card split across multiple fields |
| 111 // |max_length| more than |kMaxValidCardNumberSize|, mark these input | 110 // (b) multiple fields for multiple cards |
| 112 // form fields as invalid and skip autofilling them. | 111 // Treat this field as a part of the same card as the last field, except |
| 113 if (last_number_field_size == 0U || | 112 // when doing so would cause overflow. |
| 114 last_number_field_size >= kMaxValidCardNumberSize) { | 113 if (last_number_field_size < kMaxValidCardNumberSize) |
| 115 // Mark that the credit card number splits are invalid. But keep | 114 start_index = last_number_field_size; |
| 116 // scanning HTML form so that cursor moves beyond related fields. | |
| 117 form_has_valid_card_number_fields = false; | |
| 118 } | |
| 119 | |
| 120 start_index = last_number_field_size; | |
| 121 } | 115 } |
| 122 | 116 |
| 123 current_number_field->set_credit_card_number_offset(start_index); | 117 current_number_field->set_credit_card_number_offset(start_index); |
| 124 credit_card_field->numbers_.push_back(current_number_field); | 118 credit_card_field->numbers_.push_back(current_number_field); |
| 125 continue; | 119 continue; |
| 126 } | 120 } |
| 127 | 121 |
| 128 if (LowerCaseEqualsASCII(scanner->Cursor()->form_control_type, "month")) { | 122 if (LowerCaseEqualsASCII(scanner->Cursor()->form_control_type, "month")) { |
| 129 credit_card_field->expiration_date_ = scanner->Cursor(); | 123 credit_card_field->expiration_date_ = scanner->Cursor(); |
| 130 scanner->Advance(); | 124 scanner->Advance(); |
| (...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 184 // field; we parse this field but ignore it. | 178 // field; we parse this field but ignore it. |
| 185 // We also ignore any other fields within a credit card block that | 179 // We also ignore any other fields within a credit card block that |
| 186 // start with "card", under the assumption that they are related to | 180 // start with "card", under the assumption that they are related to |
| 187 // the credit card section being processed but are uninteresting to us. | 181 // the credit card section being processed but are uninteresting to us. |
| 188 if (ParseField(scanner, base::UTF8ToUTF16(autofill::kCardIgnoredRe), NULL)) | 182 if (ParseField(scanner, base::UTF8ToUTF16(autofill::kCardIgnoredRe), NULL)) |
| 189 continue; | 183 continue; |
| 190 | 184 |
| 191 break; | 185 break; |
| 192 } | 186 } |
| 193 | 187 |
| 194 // Cases where heuristic misinterprets input field as credit card number | |
| 195 // field, refuse to autofill credit card number fields. | |
| 196 if (!form_has_valid_card_number_fields) | |
| 197 credit_card_field->numbers_.clear(); | |
| 198 | |
| 199 // Some pages have a billing address field after the cardholder name field. | 188 // Some pages have a billing address field after the cardholder name field. |
| 200 // For that case, allow only just the cardholder name field. The remaining | 189 // For that case, allow only just the cardholder name field. The remaining |
| 201 // CC fields will be picked up in a following CreditCardField. | 190 // CC fields will be picked up in a following CreditCardField. |
| 202 if (credit_card_field->cardholder_) | 191 if (credit_card_field->cardholder_) |
| 203 return credit_card_field.release(); | 192 return credit_card_field.release(); |
| 204 | 193 |
| 205 // On some pages, the user selects a card type using radio buttons | 194 // On some pages, the user selects a card type using radio buttons |
| 206 // (e.g. test page Apple Store Billing.html). We can't handle that yet, | 195 // (e.g. test page Apple Store Billing.html). We can't handle that yet, |
| 207 // so we treat the card type as optional for now. | 196 // so we treat the card type as optional for now. |
| 208 // The existence of a number or cvc in combination with expiration date is | 197 // The existence of a number or cvc in combination with expiration date is |
| 209 // a strong enough signal that this is a credit card. It is possible that | 198 // a strong enough signal that this is a credit card. It is possible that |
| 210 // the number and name were parsed in a separate part of the form. So if | 199 // the number and name were parsed in a separate part of the form. So if |
| 211 // the cvc and date were found independently they are returned. | 200 // the cvc and date were found independently they are returned. |
| 212 if ((!credit_card_field->numbers_.empty() || | 201 if ((!credit_card_field->numbers_.empty() || |
| 213 credit_card_field->verification_ || | 202 credit_card_field->verification_) && |
| 214 !form_has_valid_card_number_fields) && | |
| 215 (credit_card_field->expiration_date_ || | 203 (credit_card_field->expiration_date_ || |
| 216 (credit_card_field->expiration_month_ && | 204 (credit_card_field->expiration_month_ && |
| 217 credit_card_field->expiration_year_))) { | 205 credit_card_field->expiration_year_))) { |
| 218 return credit_card_field.release(); | 206 return credit_card_field.release(); |
| 219 } | 207 } |
| 220 | 208 |
| 221 scanner->RewindTo(saved_cursor); | 209 scanner->RewindTo(saved_cursor); |
| 222 return NULL; | 210 return NULL; |
| 223 } | 211 } |
| 224 | 212 |
| (...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 267 | 255 |
| 268 ServerFieldType CreditCardField::GetExpirationYearType() const { | 256 ServerFieldType CreditCardField::GetExpirationYearType() const { |
| 269 return (expiration_date_ | 257 return (expiration_date_ |
| 270 ? exp_year_type_ | 258 ? exp_year_type_ |
| 271 : ((expiration_year_ && expiration_year_->max_length == 2) | 259 : ((expiration_year_ && expiration_year_->max_length == 2) |
| 272 ? CREDIT_CARD_EXP_2_DIGIT_YEAR | 260 ? CREDIT_CARD_EXP_2_DIGIT_YEAR |
| 273 : CREDIT_CARD_EXP_4_DIGIT_YEAR)); | 261 : CREDIT_CARD_EXP_4_DIGIT_YEAR)); |
| 274 } | 262 } |
| 275 | 263 |
| 276 } // namespace autofill | 264 } // namespace autofill |
| OLD | NEW |