| Index: components/autofill/content/renderer/password_generation_agent.cc
|
| diff --git a/components/autofill/content/renderer/password_generation_agent.cc b/components/autofill/content/renderer/password_generation_agent.cc
|
| index 0776b0ebf355bc83112ad59d2f78f5f804ab8522..ff16f8f4c400c2e00b745749591bb071a122f8c1 100644
|
| --- a/components/autofill/content/renderer/password_generation_agent.cc
|
| +++ b/components/autofill/content/renderer/password_generation_agent.cc
|
| @@ -18,6 +18,7 @@
|
| #include "components/autofill/core/common/password_form.h"
|
| #include "components/autofill/core/common/password_form_generation_data.h"
|
| #include "components/autofill/core/common/password_generation_util.h"
|
| +#include "components/autofill/core/common/signatures_util.h"
|
| #include "content/public/renderer/render_frame.h"
|
| #include "content/public/renderer/render_view.h"
|
| #include "google_apis/gaia/gaia_urls.h"
|
| @@ -57,46 +58,39 @@ bool ContainsURL(const std::vector<GURL>& urls, const GURL& url) {
|
| return std::find(urls.begin(), urls.end(), url) != urls.end();
|
| }
|
|
|
| -// Finds a form in |forms| that has the same action and name as |form|.
|
| -// If the action of a form in |forms| is empty, it uses |base_url| as action. It
|
| -// also strips parameters of the action.
|
| +// Calculates the signature of |form| and searches it in |forms|.
|
| const PasswordFormGenerationData* FindFormGenerationData(
|
| const std::vector<PasswordFormGenerationData>& forms,
|
| - const PasswordForm& form,
|
| - const GURL& base_url) {
|
| + const PasswordForm& form) {
|
| + FormSignature form_signature = CalculateFormSignature(form.form_data);
|
| for (const auto& form_it : forms) {
|
| - GURL action = form_it.action;
|
| - if (action.is_empty())
|
| - action = base_url;
|
| - action = form_util::StripAuthAndParams(action);
|
| - if (form_it.name == form.form_data.name && action == form.action)
|
| + if (form_it.form_signature == form_signature)
|
| return &form_it;
|
| }
|
| return nullptr;
|
| }
|
|
|
| // This function returns a vector of password fields into which Chrome should
|
| -// fill the generated password. It assumes that |field_data| describes the field
|
| -// where Chrome shows the password generation prompt. It returns no more
|
| +// fill the generated password. It assumes that |field_signature| describes the
|
| +// field where Chrome shows the password generation prompt. It returns no more
|
| // than 2 elements.
|
| std::vector<blink::WebInputElement> FindPasswordElementsForGeneration(
|
| const std::vector<blink::WebInputElement>& all_password_elements,
|
| - const base::string16& field_name) {
|
| - auto iter =
|
| - std::find_if(all_password_elements.begin(), all_password_elements.end(),
|
| - [&field_name](const blink::WebInputElement& input) {
|
| - // Make explicit conversion before comparing with string16.
|
| - base::string16 input_name = input.nameForAutofill();
|
| - return input_name == field_name;
|
| - });
|
| + const FieldSignature field_signature) {
|
| + auto iter = std::find_if(
|
| + all_password_elements.begin(), all_password_elements.end(),
|
| + [&field_signature](const blink::WebInputElement& input) {
|
| + FieldSignature signature = CalculateFieldSignatureByNameAndType(
|
| + input.nameForAutofill(), input.formControlType().utf8());
|
| + return signature == field_signature;
|
| + });
|
| std::vector<blink::WebInputElement> passwords;
|
|
|
| // We copy not more than 2 fields because occasionally there are forms where
|
| // the security question answers are put in password fields and we don't want
|
| // to fill those.
|
| - for (; iter != all_password_elements.end() && passwords.size() < 2; ++iter) {
|
| + for (; iter != all_password_elements.end() && passwords.size() < 2; ++iter)
|
| passwords.push_back(*iter);
|
| - }
|
| return passwords;
|
| }
|
|
|
| @@ -391,8 +385,7 @@ void PasswordGenerationAgent::DetermineGenerationElement() {
|
| continue;
|
| } else {
|
| generation_data = FindFormGenerationData(
|
| - generation_enabled_forms_, *possible_password_form,
|
| - render_frame()->GetWebFrame()->document().baseURL());
|
| + generation_enabled_forms_, *possible_password_form);
|
| if (!generation_data) {
|
| if (AutocompleteAttributesSetForGeneration(*possible_password_form)) {
|
| VLOG(2) << "Ignoring lack of Autofill signal due to Autocomplete "
|
| @@ -412,7 +405,7 @@ void PasswordGenerationAgent::DetermineGenerationElement() {
|
| std::vector<blink::WebInputElement> password_elements =
|
| generation_data ? FindPasswordElementsForGeneration(
|
| possible_form_data.password_elements,
|
| - generation_data->generation_field.name)
|
| + generation_data->field_signature)
|
| : possible_form_data.password_elements;
|
| if (password_elements.empty()) {
|
| // It might be if JavaScript changes field names.
|
| @@ -574,7 +567,10 @@ void PasswordGenerationAgent::UserTriggeredGeneratePassword() {
|
| std::vector<blink::WebInputElement> password_elements;
|
| GetAccountCreationPasswordFields(control_elements, &password_elements);
|
| password_elements = FindPasswordElementsForGeneration(
|
| - password_elements, last_focused_password_element_.nameForAutofill());
|
| + password_elements,
|
| + CalculateFieldSignatureByNameAndType(
|
| + last_focused_password_element_.nameForAutofill(),
|
| + last_focused_password_element_.formControlType().utf8()));
|
| generation_form_data_.reset(new AccountCreationFormData(
|
| make_linked_ptr(password_form.release()), password_elements));
|
| is_manually_triggered_ = true;
|
|
|