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 "base/strings/string_util.h" | 7 #include "base/strings/string_util.h" |
8 #include "components/autofill/content/renderer/form_autofill_util.h" | 8 #include "components/autofill/content/renderer/form_autofill_util.h" |
9 #include "components/autofill/core/common/password_form.h" | 9 #include "components/autofill/core/common/password_form.h" |
10 #include "third_party/WebKit/public/platform/WebString.h" | 10 #include "third_party/WebKit/public/platform/WebString.h" |
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
53 } | 53 } |
54 | 54 |
55 // If we have seen an element with either of autocomplete attributes above, | 55 // If we have seen an element with either of autocomplete attributes above, |
56 // take that as a signal that the page author must have intentionally left the | 56 // take that as a signal that the page author must have intentionally left the |
57 // rest of the password fields unmarked. Perhaps they are used for other | 57 // rest of the password fields unmarked. Perhaps they are used for other |
58 // purposes, e.g., PINs, OTPs, and the like. So we skip all the heuristics we | 58 // purposes, e.g., PINs, OTPs, and the like. So we skip all the heuristics we |
59 // normally do, and ignore the rest of the password fields. | 59 // normally do, and ignore the rest of the password fields. |
60 if (!current_password->isNull() || !new_password->isNull()) | 60 if (!current_password->isNull() || !new_password->isNull()) |
61 return true; | 61 return true; |
62 | 62 |
| 63 if (passwords.empty()) |
| 64 return false; |
| 65 |
63 switch (passwords.size()) { | 66 switch (passwords.size()) { |
64 case 1: | 67 case 1: |
65 // Single password, easy. | 68 // Single password, easy. |
66 *current_password = passwords[0]; | 69 *current_password = passwords[0]; |
67 break; | 70 break; |
68 case 2: | 71 case 2: |
69 if (passwords[0].value() == passwords[1].value()) { | 72 if (passwords[0].value() == passwords[1].value()) { |
70 // Two identical passwords: assume we are seeing a new password with a | 73 // Two identical passwords: assume we are seeing a new password with a |
71 // confirmation. This can be either a sign-up form or a password change | 74 // confirmation. This can be either a sign-up form or a password change |
72 // form that does not ask for the old password. | 75 // form that does not ask for the old password. |
73 *new_password = passwords[0]; | 76 *new_password = passwords[0]; |
74 } else { | 77 } else { |
75 // Assume first is old password, second is new (no choice but to guess). | 78 // Assume first is old password, second is new (no choice but to guess). |
76 *current_password = passwords[0]; | 79 *current_password = passwords[0]; |
77 *new_password = passwords[1]; | 80 *new_password = passwords[1]; |
78 } | 81 } |
79 break; | 82 break; |
80 case 3: | 83 default: |
81 if (!passwords[0].value().isEmpty() && | 84 if (!passwords[0].value().isEmpty() && |
82 passwords[0].value() == passwords[1].value() && | 85 passwords[0].value() == passwords[1].value() && |
83 passwords[0].value() == passwords[2].value()) { | 86 passwords[0].value() == passwords[2].value()) { |
84 // All three passwords are the same and non-empty? This does not make | 87 // All three passwords are the same and non-empty? This does not make |
85 // any sense, give up. | 88 // any sense, give up. |
86 return false; | 89 return false; |
87 } else if (passwords[1].value() == passwords[2].value()) { | 90 } else if (passwords[1].value() == passwords[2].value()) { |
88 // New password is the duplicated one, and comes second; or empty form | 91 // New password is the duplicated one, and comes second; or empty form |
89 // with 3 password fields, in which case we will assume this layout. | 92 // with 3 password fields, in which case we will assume this layout. |
90 *current_password = passwords[0]; | 93 *current_password = passwords[0]; |
91 *new_password = passwords[1]; | 94 *new_password = passwords[1]; |
92 } else if (passwords[0].value() == passwords[1].value()) { | 95 } else if (passwords[0].value() == passwords[1].value()) { |
93 // It is strange that the new password comes first, but trust more which | 96 // It is strange that the new password comes first, but trust more which |
94 // fields are duplicated than the ordering of fields. | 97 // fields are duplicated than the ordering of fields. Assume that |
95 *current_password = passwords[2]; | 98 // any password fields after the new password contain sensitive |
| 99 // information that isn't actually a password (security hint, SSN, etc.) |
96 *new_password = passwords[0]; | 100 *new_password = passwords[0]; |
97 } else { | 101 } else { |
98 // Three different passwords, or first and last match with middle | 102 // Three different passwords, or first and last match with middle |
99 // different. No idea which is which, so no luck. | 103 // different. No idea which is which, so no luck. |
100 return false; | 104 return false; |
101 } | 105 } |
102 break; | |
103 default: | |
104 return false; | |
105 } | 106 } |
106 return true; | 107 return true; |
107 } | 108 } |
108 | 109 |
109 // Get information about a login form encapsulated in a PasswordForm struct. | 110 // Get information about a login form encapsulated in a PasswordForm struct. |
110 // If an element of |form| has an entry in |user_modified_elements|, the | 111 // If an element of |form| has an entry in |user_modified_elements|, the |
111 // associated string is used instead of the element's value to create | 112 // associated string is used instead of the element's value to create |
112 // the PasswordForm. | 113 // the PasswordForm. |
113 void GetPasswordForm(const WebFormElement& form, | 114 void GetPasswordForm(const WebFormElement& form, |
114 PasswordForm* password_form, | 115 PasswordForm* password_form, |
(...skipping 169 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
284 blink::WebFormControlElement(), | 285 blink::WebFormControlElement(), |
285 REQUIRE_NONE, | 286 REQUIRE_NONE, |
286 EXTRACT_NONE, | 287 EXTRACT_NONE, |
287 &password_form->form_data, | 288 &password_form->form_data, |
288 NULL /* FormFieldData */); | 289 NULL /* FormFieldData */); |
289 | 290 |
290 return password_form.Pass(); | 291 return password_form.Pass(); |
291 } | 292 } |
292 | 293 |
293 } // namespace autofill | 294 } // namespace autofill |
OLD | NEW |