Chromium Code Reviews| Index: components/autofill/content/renderer/password_form_conversion_utils.cc |
| diff --git a/components/autofill/content/renderer/password_form_conversion_utils.cc b/components/autofill/content/renderer/password_form_conversion_utils.cc |
| index 72efccca58d6d485cb91e1ca52ad14a172fa282f..00beba60f3c1e83537b662d39af07aa7e6a755c8 100644 |
| --- a/components/autofill/content/renderer/password_form_conversion_utils.cc |
| +++ b/components/autofill/content/renderer/password_form_conversion_utils.cc |
| @@ -28,21 +28,44 @@ static const size_t kMaxPasswords = 3; |
| // Checks in a case-insensitive way if the autocomplete attribute for the given |
| // |element| is present and has the specified |value_in_lowercase|. |
| -bool HasAutocompleteAttributeValue(const WebInputElement* element, |
| +bool HasAutocompleteAttributeValue(const WebInputElement& element, |
| const char* value_in_lowercase) { |
| - return LowerCaseEqualsASCII(element->getAttribute("autocomplete"), |
| + return LowerCaseEqualsASCII(element.getAttribute("autocomplete"), |
| value_in_lowercase); |
| } |
| // Helper to determine which password is the main (current) one, and which is |
| // the new password (e.g., on a sign-up or change password form), if any. |
| bool LocateSpecificPasswords(std::vector<WebInputElement> passwords, |
| - WebInputElement* password, |
| + WebInputElement* current_password, |
| WebInputElement* new_password) { |
| + // First, look for elements marked with either autocomplete='current-password' |
| + // and/or 'new-password', and treat the first of each kind as that element. |
| + for (std::vector<WebInputElement>::const_iterator it = passwords.begin(); |
| + it != passwords.end(); it++) { |
| + // If some password elements are marked with autocomplete='current-password' |
| + // or with 'new-password', take the hint, and treat the first of each kind |
| + // the element we are looking for. |
|
vabr (Chromium)
2014/07/05 09:21:39
typo: the element -> as the element
engedy
2014/07/07 08:00:39
Done. I have actually removed this block of commen
|
| + if (HasAutocompleteAttributeValue(*it, "current-password") && |
| + current_password->isNull()) { |
| + *current_password = *it; |
|
vabr (Chromium)
2014/07/05 09:21:39
optional nit: I wonder if we should document that
engedy
2014/07/07 08:00:39
Done.
|
| + } else if (HasAutocompleteAttributeValue(*it, "new-password") && |
| + new_password->isNull()) { |
| + *new_password = *it; |
| + } |
| + } |
| + |
| + // If we have found any marked-up elements, take the hint and skip all the |
| + // heuristics we normally do, i.e., ignore the rest of the password fields. |
| + // We do this under the assumption they are not intentionally not marked, |
|
vabr (Chromium)
2014/07/05 09:21:39
typo: remove the first "not"
engedy
2014/07/07 08:00:39
Done, also rephrased.
|
| + // because they are used for other purposes, e.g., PINs, OTPs, and the like. |
| + if (!current_password->isNull() || !new_password->isNull()) |
| + return true; |
| + |
| switch (passwords.size()) { |
| case 1: |
| // Single password, easy. |
| - *password = passwords[0]; |
| + *current_password = passwords[0]; |
| break; |
| case 2: |
| if (passwords[0].value() == passwords[1].value()) { |
| @@ -52,7 +75,7 @@ bool LocateSpecificPasswords(std::vector<WebInputElement> passwords, |
| *new_password = passwords[0]; |
| } else { |
| // Assume first is old password, second is new (no choice but to guess). |
| - *password = passwords[0]; |
| + *current_password = passwords[0]; |
| *new_password = passwords[1]; |
| } |
| break; |
| @@ -66,12 +89,12 @@ bool LocateSpecificPasswords(std::vector<WebInputElement> passwords, |
| } else if (passwords[1].value() == passwords[2].value()) { |
| // New password is the duplicated one, and comes second; or empty form |
| // with 3 password fields, in which case we will assume this layout. |
| - *password = passwords[0]; |
| + *current_password = passwords[0]; |
| *new_password = passwords[1]; |
| } else if (passwords[0].value() == passwords[1].value()) { |
| // It is strange that the new password comes first, but trust more which |
| // fields are duplicated than the ordering of fields. |
| - *password = passwords[2]; |
| + *current_password = passwords[2]; |
| *new_password = passwords[0]; |
| } else { |
| // Three different passwords, or first and last match with middle |
| @@ -128,7 +151,7 @@ void GetPasswordForm(const WebFormElement& form, PasswordForm* password_form) { |
| // Various input types such as text, url, email can be a username field. |
| if (input_element->isTextField() && !input_element->isPasswordField()) { |
| - if (HasAutocompleteAttributeValue(input_element, "username")) { |
| + if (HasAutocompleteAttributeValue(*input_element, "username")) { |
| if (has_seen_element_with_autocomplete_username_before) { |
| // A second or subsequent element marked with autocomplete='username'. |
| // This makes us less confident that we have understood the form. We |