| 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/autofill_field.h" | 5 #include "components/autofill/core/browser/autofill_field.h" |
| 6 | 6 |
| 7 #include <stdint.h> | 7 #include <stdint.h> |
| 8 | 8 |
| 9 #include "base/command_line.h" | 9 #include "base/command_line.h" |
| 10 #include "base/i18n/string_search.h" | 10 #include "base/i18n/string_search.h" |
| (...skipping 178 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 189 if (country_code == CountryNames::GetInstance()->GetCountryCode(value) || | 189 if (country_code == CountryNames::GetInstance()->GetCountryCode(value) || |
| 190 country_code == CountryNames::GetInstance()->GetCountryCode(contents)) { | 190 country_code == CountryNames::GetInstance()->GetCountryCode(contents)) { |
| 191 field_data->value = value; | 191 field_data->value = value; |
| 192 return true; | 192 return true; |
| 193 } | 193 } |
| 194 } | 194 } |
| 195 | 195 |
| 196 return false; | 196 return false; |
| 197 } | 197 } |
| 198 | 198 |
| 199 // Attempt to fill the user's expiration month |value| inside the <select> |
| 200 // |field|. Since |value| is well defined but the website's |field| option |
| 201 // values may not be, some heuristics are run to cover all observed cases. |
| 199 bool FillExpirationMonthSelectControl(const base::string16& value, | 202 bool FillExpirationMonthSelectControl(const base::string16& value, |
| 200 const std::string& app_locale, | 203 const std::string& app_locale, |
| 201 FormFieldData* field) { | 204 FormFieldData* field) { |
| 202 int index = 0; | 205 // |value| is defined to be between 1 and 12, inclusively. |
| 203 if (!StringToInt(value, &index) || index <= 0 || index > 12) | 206 int month = 0; |
| 207 if (!StringToInt(value, &month) || month <= 0 || month > 12) |
| 204 return false; | 208 return false; |
| 205 | 209 |
| 206 if (field->option_values.size() == 12) { | 210 // We trim the whitespace from the select values before attempting to convert |
| 207 // The select only contains the months. | 211 // them to months. |
| 208 // If the first value of the select is 0, decrement the value of the index | 212 std::vector<base::string16> trimmed_values(field->option_values.size()); |
| 209 // so January is associated with 0 instead of 1. | 213 for (size_t i = 0; i < field->option_values.size(); ++i) |
| 214 base::TrimWhitespace(field->option_values[i], base::TRIM_ALL, |
| 215 &trimmed_values[i]); |
| 216 |
| 217 if (trimmed_values.size() == 12) { |
| 218 // The select presumable only contains the year's months. |
| 219 // If the first value of the select is 0, decrement the value of |month| so |
| 220 // January is associated with 0 instead of 1. |
| 210 int first_value; | 221 int first_value; |
| 211 if (StringToInt(field->option_values[0], &first_value) && first_value == 0) | 222 if (StringToInt(trimmed_values[0], &first_value) && first_value == 0) |
| 212 --index; | 223 --month; |
| 213 } else if (field->option_values.size() == 13) { | 224 } else if (trimmed_values.size() == 13) { |
| 214 // The select uses the first value as a placeholder. | 225 // The select presumably uses the first value as a placeholder. |
| 215 // If the first value of the select is 1, increment the value of the index | 226 // If the first value of the select is 1, increment the value of |month| to |
| 216 // to skip the placeholder value (January = 2). | 227 // skip the placeholder value (January = 2). |
| 217 int first_value; | 228 int first_value; |
| 218 if (StringToInt(field->option_values[0], &first_value) && first_value == 1) | 229 if (StringToInt(trimmed_values[0], &first_value) && first_value == 1) |
| 219 ++index; | 230 ++month; |
| 220 } | 231 } |
| 221 | 232 |
| 222 for (const base::string16& option_value : field->option_values) { | 233 // Attempt to match the user's |month| with the field's value attributes. |
| 234 for (size_t i = 0; i < trimmed_values.size(); ++i) { |
| 223 int converted_value = 0; | 235 int converted_value = 0; |
| 224 if (CreditCard::ConvertMonth(option_value, app_locale, &converted_value) && | 236 // We use the trimmed value to match with |month|, but the original select |
| 225 index == converted_value) { | 237 // value to fill the field (otherwise filling wouldn't work). |
| 226 field->value = option_value; | 238 if (CreditCard::ConvertMonth(trimmed_values[i], app_locale, |
| 239 &converted_value) && |
| 240 month == converted_value) { |
| 241 field->value = field->option_values[i]; |
| 227 return true; | 242 return true; |
| 228 } | 243 } |
| 229 } | 244 } |
| 230 | 245 |
| 246 // Attempt to match with each of the options' content. |
| 231 for (const base::string16& option_contents : field->option_contents) { | 247 for (const base::string16& option_contents : field->option_contents) { |
| 232 int converted_contents = 0; | 248 int converted_contents = 0; |
| 233 if (CreditCard::ConvertMonth(option_contents, app_locale, | 249 if (CreditCard::ConvertMonth(option_contents, app_locale, |
| 234 &converted_contents) && | 250 &converted_contents) && |
| 235 index == converted_contents) { | 251 month == converted_contents) { |
| 236 field->value = option_contents; | 252 field->value = option_contents; |
| 237 return true; | 253 return true; |
| 238 } | 254 } |
| 239 } | 255 } |
| 240 | 256 |
| 241 return FillNumericSelectControl(index, field); | 257 return FillNumericSelectControl(month, field); |
| 242 } | 258 } |
| 243 | 259 |
| 244 // Returns true if the last two digits in |year| match those in |str|. | 260 // Returns true if the last two digits in |year| match those in |str|. |
| 245 bool LastTwoDigitsMatch(const base::string16& year, | 261 bool LastTwoDigitsMatch(const base::string16& year, |
| 246 const base::string16& str) { | 262 const base::string16& str) { |
| 247 int year_int; | 263 int year_int; |
| 248 int str_int; | 264 int str_int; |
| 249 if (!StringToInt(year, &year_int) || !StringToInt(str, &str_int)) | 265 if (!StringToInt(year, &year_int) || !StringToInt(str, &str_int)) |
| 250 return false; | 266 return false; |
| 251 | 267 |
| (...skipping 340 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 592 if (compare.StringsEqual(value_stripped, option_contents)) { | 608 if (compare.StringsEqual(value_stripped, option_contents)) { |
| 593 if (index) | 609 if (index) |
| 594 *index = i; | 610 *index = i; |
| 595 return true; | 611 return true; |
| 596 } | 612 } |
| 597 } | 613 } |
| 598 return false; | 614 return false; |
| 599 } | 615 } |
| 600 | 616 |
| 601 } // namespace autofill | 617 } // namespace autofill |
| OLD | NEW |