Chromium Code Reviews| 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/content/renderer/password_form_conversion_utils.h" | 5 #include "components/autofill/content/renderer/password_form_conversion_utils.h" |
| 6 | 6 |
| 7 #include <vector> | 7 #include <vector> |
| 8 | 8 |
| 9 #include "base/i18n/case_conversion.h" | 9 #include "base/i18n/case_conversion.h" |
| 10 #include "base/lazy_instance.h" | 10 #include "base/lazy_instance.h" |
| 11 #include "base/memory/scoped_ptr.h" | 11 #include "base/memory/scoped_ptr.h" |
| 12 #include "base/metrics/histogram_macros.h" | 12 #include "base/metrics/histogram_macros.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 "components/autofill/content/renderer/form_autofill_util.h" | 15 #include "components/autofill/content/renderer/form_autofill_util.h" |
| 15 #include "components/autofill/core/common/password_form.h" | 16 #include "components/autofill/core/common/password_form.h" |
| 16 #include "components/autofill/core/common/password_form_field_prediction_map.h" | 17 #include "components/autofill/core/common/password_form_field_prediction_map.h" |
| 17 #include "third_party/WebKit/public/platform/WebString.h" | 18 #include "third_party/WebKit/public/platform/WebString.h" |
| 18 #include "third_party/WebKit/public/web/WebDocument.h" | 19 #include "third_party/WebKit/public/web/WebDocument.h" |
| 19 #include "third_party/WebKit/public/web/WebFormControlElement.h" | 20 #include "third_party/WebKit/public/web/WebFormControlElement.h" |
| 20 #include "third_party/WebKit/public/web/WebInputElement.h" | 21 #include "third_party/WebKit/public/web/WebInputElement.h" |
| 21 #include "third_party/icu/source/i18n/unicode/regex.h" | 22 #include "third_party/icu/source/i18n/unicode/regex.h" |
| 22 | 23 |
| 23 using blink::WebDocument; | 24 using blink::WebDocument; |
| (...skipping 30 matching lines...) Expand all Loading... | |
| 54 // (N*PPP?.*) and forms which use password fields to store private but | 55 // (N*PPP?.*) and forms which use password fields to store private but |
| 55 // non-password data (could look like, e.g., PN+P.*). | 56 // non-password data (could look like, e.g., PN+P.*). |
| 56 const char kLoginAndSignupRegex[] = | 57 const char kLoginAndSignupRegex[] = |
| 57 "NP" // Login section. | 58 "NP" // Login section. |
| 58 "N+P" // Sign-up section. | 59 "N+P" // Sign-up section. |
| 59 ".*"; // Anything beyond that. | 60 ".*"; // Anything beyond that. |
| 60 | 61 |
| 61 const char kAutocompleteUsername[] = "username"; | 62 const char kAutocompleteUsername[] = "username"; |
| 62 const char kAutocompleteCurrentPassword[] = "current-password"; | 63 const char kAutocompleteCurrentPassword[] = "current-password"; |
| 63 const char kAutocompleteNewPassword[] = "new-password"; | 64 const char kAutocompleteNewPassword[] = "new-password"; |
| 65 const char kDummyUsernameField[] = "anonymous_username"; | |
|
dvadym
2015/08/24 13:32:08
Probably it's better to make fake names that are n
Pritam Nikam
2015/08/25 09:01:10
Acknowledged.
According to W3C spec, <input name>
dvadym
2015/09/07 15:19:58
Ok, I agree, that we hardly can do something with
Pritam Nikam
2015/09/08 15:09:36
Acknowledged.
| |
| 66 const char kDummyPasswordField[] = "anonymous_password"; | |
| 67 const char kDummyNewPasswordField[] = "anonymous_new_password"; | |
| 64 | 68 |
| 65 struct LoginAndSignupLazyInstanceTraits | 69 struct LoginAndSignupLazyInstanceTraits |
| 66 : public base::DefaultLazyInstanceTraits<icu::RegexMatcher> { | 70 : public base::DefaultLazyInstanceTraits<icu::RegexMatcher> { |
| 67 static icu::RegexMatcher* New(void* instance) { | 71 static icu::RegexMatcher* New(void* instance) { |
| 68 const icu::UnicodeString icu_pattern(kLoginAndSignupRegex); | 72 const icu::UnicodeString icu_pattern(kLoginAndSignupRegex); |
| 69 | 73 |
| 70 UErrorCode status = U_ZERO_ERROR; | 74 UErrorCode status = U_ZERO_ERROR; |
| 71 // Use placement new to initialize the instance in the preallocated space. | 75 // Use placement new to initialize the instance in the preallocated space. |
| 72 // The "(instance)" is very important to force POD type initialization. | 76 // The "(instance)" is very important to force POD type initialization. |
| 73 scoped_ptr<icu::RegexMatcher> matcher(new (instance) icu::RegexMatcher( | 77 scoped_ptr<icu::RegexMatcher> matcher(new (instance) icu::RegexMatcher( |
| (...skipping 180 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 254 // https://crbug.com/517490 for more details. | 258 // https://crbug.com/517490 for more details. |
| 255 if (input_element) { | 259 if (input_element) { |
| 256 (*predicted_elements)[*input_element] = type; | 260 (*predicted_elements)[*input_element] = type; |
| 257 } | 261 } |
| 258 break; | 262 break; |
| 259 } | 263 } |
| 260 } | 264 } |
| 261 } | 265 } |
| 262 } | 266 } |
| 263 | 267 |
| 268 // Returns the |input_field| name if its non-empty; otherwise a |dummy_name|. | |
| 269 base::string16 FieldName(const WebInputElement& input_field, | |
| 270 const char dummy_name[]) { | |
| 271 base::string16 field_name = input_field.nameForAutofill(); | |
| 272 return field_name.empty() ? base::ASCIIToUTF16(dummy_name) : field_name; | |
| 273 } | |
| 274 | |
| 264 // Get information about a login form encapsulated in a PasswordForm struct. | 275 // Get information about a login form encapsulated in a PasswordForm struct. |
| 265 // If an element of |form| has an entry in |nonscript_modified_values|, the | 276 // If an element of |form| has an entry in |nonscript_modified_values|, the |
| 266 // associated string is used instead of the element's value to create | 277 // associated string is used instead of the element's value to create |
| 267 // the PasswordForm. | 278 // the PasswordForm. |
| 268 void GetPasswordForm( | 279 void GetPasswordForm( |
| 269 const WebFormElement& form, | 280 const WebFormElement& form, |
| 270 PasswordForm* password_form, | 281 PasswordForm* password_form, |
| 271 const std::map<const blink::WebInputElement, blink::WebString>* | 282 const std::map<const blink::WebInputElement, blink::WebString>* |
| 272 nonscript_modified_values, | 283 nonscript_modified_values, |
| 273 const std::map<FormData, PasswordFormFieldPredictionMap>* | 284 const std::map<FormData, PasswordFormFieldPredictionMap>* |
| (...skipping 139 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 413 if (it != other_possible_usernames.end()) | 424 if (it != other_possible_usernames.end()) |
| 414 other_possible_usernames.erase(it); | 425 other_possible_usernames.erase(it); |
| 415 if (!username_element.isNull()) { | 426 if (!username_element.isNull()) { |
| 416 other_possible_usernames.push_back(username_element.value()); | 427 other_possible_usernames.push_back(username_element.value()); |
| 417 } | 428 } |
| 418 username_element = predicted_username_element; | 429 username_element = predicted_username_element; |
| 419 password_form->was_parsed_using_autofill_predictions = true; | 430 password_form->was_parsed_using_autofill_predictions = true; |
| 420 } | 431 } |
| 421 | 432 |
| 422 if (!username_element.isNull()) { | 433 if (!username_element.isNull()) { |
| 423 password_form->username_element = username_element.nameForAutofill(); | 434 password_form->username_element = |
| 435 FieldName(username_element, kDummyUsernameField); | |
| 424 base::string16 username_value = username_element.value(); | 436 base::string16 username_value = username_element.value(); |
| 425 if (nonscript_modified_values != nullptr) { | 437 if (nonscript_modified_values != nullptr) { |
| 426 auto username_iterator = | 438 auto username_iterator = |
| 427 nonscript_modified_values->find(username_element); | 439 nonscript_modified_values->find(username_element); |
| 428 if (username_iterator != nonscript_modified_values->end()) { | 440 if (username_iterator != nonscript_modified_values->end()) { |
| 429 base::string16 typed_username_value = username_iterator->second; | 441 base::string16 typed_username_value = username_iterator->second; |
| 430 if (!base::StartsWith( | 442 if (!base::StartsWith( |
| 431 base::i18n::ToLower(username_value), | 443 base::i18n::ToLower(username_value), |
| 432 base::i18n::ToLower(typed_username_value), | 444 base::i18n::ToLower(typed_username_value), |
| 433 base::CompareCase::SENSITIVE)) { | 445 base::CompareCase::SENSITIVE)) { |
| (...skipping 17 matching lines...) Expand all Loading... | |
| 451 return; | 463 return; |
| 452 | 464 |
| 453 password_form->origin = GetCanonicalOriginForDocument(form.document()); | 465 password_form->origin = GetCanonicalOriginForDocument(form.document()); |
| 454 GURL::Replacements rep; | 466 GURL::Replacements rep; |
| 455 rep.SetPathStr(""); | 467 rep.SetPathStr(""); |
| 456 password_form->signon_realm = | 468 password_form->signon_realm = |
| 457 password_form->origin.ReplaceComponents(rep).spec(); | 469 password_form->origin.ReplaceComponents(rep).spec(); |
| 458 password_form->other_possible_usernames.swap(other_possible_usernames); | 470 password_form->other_possible_usernames.swap(other_possible_usernames); |
| 459 | 471 |
| 460 if (!password.isNull()) { | 472 if (!password.isNull()) { |
| 461 password_form->password_element = password.nameForAutofill(); | 473 password_form->password_element = FieldName(password, kDummyPasswordField); |
| 462 blink::WebString password_value = password.value(); | 474 blink::WebString password_value = password.value(); |
| 463 if (nonscript_modified_values != nullptr) { | 475 if (nonscript_modified_values != nullptr) { |
| 464 auto password_iterator = nonscript_modified_values->find(password); | 476 auto password_iterator = nonscript_modified_values->find(password); |
| 465 if (password_iterator != nonscript_modified_values->end()) | 477 if (password_iterator != nonscript_modified_values->end()) |
| 466 password_value = password_iterator->second; | 478 password_value = password_iterator->second; |
| 467 } | 479 } |
| 468 password_form->password_value = password_value; | 480 password_form->password_value = password_value; |
| 469 } | 481 } |
| 470 if (!new_password.isNull()) { | 482 if (!new_password.isNull()) { |
| 471 password_form->new_password_element = new_password.nameForAutofill(); | 483 password_form->new_password_element = |
| 484 FieldName(new_password, kDummyNewPasswordField); | |
| 472 password_form->new_password_value = new_password.value(); | 485 password_form->new_password_value = new_password.value(); |
| 473 if (HasAutocompleteAttributeValue(new_password, kAutocompleteNewPassword)) | 486 if (HasAutocompleteAttributeValue(new_password, kAutocompleteNewPassword)) |
| 474 password_form->new_password_marked_by_site = true; | 487 password_form->new_password_marked_by_site = true; |
| 475 } | 488 } |
| 476 | 489 |
| 477 if (username_element.isNull()) { | 490 if (username_element.isNull()) { |
| 478 // To get a better idea on how password forms without a username field | 491 // To get a better idea on how password forms without a username field |
| 479 // look like, report the total number of text and password fields. | 492 // look like, report the total number of text and password fields. |
| 480 UMA_HISTOGRAM_COUNTS_100( | 493 UMA_HISTOGRAM_COUNTS_100( |
| 481 "PasswordManager.EmptyUsernames.TextAndPasswordFieldCount", | 494 "PasswordManager.EmptyUsernames.TextAndPasswordFieldCount", |
| (...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 538 WebFormElementToFormData(web_form, | 551 WebFormElementToFormData(web_form, |
| 539 blink::WebFormControlElement(), | 552 blink::WebFormControlElement(), |
| 540 EXTRACT_NONE, | 553 EXTRACT_NONE, |
| 541 &password_form->form_data, | 554 &password_form->form_data, |
| 542 NULL /* FormFieldData */); | 555 NULL /* FormFieldData */); |
| 543 | 556 |
| 544 return password_form.Pass(); | 557 return password_form.Pass(); |
| 545 } | 558 } |
| 546 | 559 |
| 547 } // namespace autofill | 560 } // namespace autofill |
| OLD | NEW |