| 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 |