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 |