diff options
8 files changed, 71 insertions, 62 deletions
diff --git a/chrome/renderer/autofill/password_autofill_agent_browsertest.cc b/chrome/renderer/autofill/password_autofill_agent_browsertest.cc index 70321c2..bec975b 100644 --- a/chrome/renderer/autofill/password_autofill_agent_browsertest.cc +++ b/chrome/renderer/autofill/password_autofill_agent_browsertest.cc @@ -202,13 +202,13 @@ class PasswordAutofillAgentTest : public ChromeRenderViewTest { FormFieldData username_field; username_field.name = ASCIIToUTF16(kUsernameName); username_field.value = username1_; - fill_data_.basic_data.fields.push_back(username_field); + fill_data_.username_field = username_field; FormFieldData password_field; password_field.name = ASCIIToUTF16(kPasswordName); password_field.value = password1_; password_field.form_control_type = "password"; - fill_data_.basic_data.fields.push_back(password_field); + fill_data_.password_field = password_field; PasswordAndRealm password2; password2.password = password2_; @@ -226,7 +226,7 @@ class PasswordAutofillAgentTest : public ChromeRenderViewTest { // We need to set the origin so it matches the frame URL and the action so // it matches the form action, otherwise we won't autocomplete. UpdateOriginForHTML(kFormHTML); - fill_data_.basic_data.action = GURL("http://www.bidule.com"); + fill_data_.action = GURL("http://www.bidule.com"); LoadHTML(kFormHTML); @@ -242,7 +242,7 @@ class PasswordAutofillAgentTest : public ChromeRenderViewTest { void UpdateOriginForHTML(const std::string& html) { std::string origin = "data:text/html;charset=utf-8," + html; - fill_data_.basic_data.origin = GURL(origin); + fill_data_.origin = GURL(origin); } void UpdateUsernameAndPasswordElements() { @@ -399,7 +399,6 @@ class PasswordAutofillAgentTest : public ChromeRenderViewTest { Tuple5<int, base::i18n::TextDirection, base::string16, bool, gfx::RectF> args; AutofillHostMsg_ShowPasswordSuggestions::Read(message, &args); - EXPECT_EQ(2u, fill_data_.basic_data.fields.size()); EXPECT_EQ(kPasswordFillFormDataId, args.a); EXPECT_EQ(ASCIIToUTF16(username), args.c); EXPECT_EQ(show_all, args.d); @@ -490,7 +489,7 @@ TEST_F(PasswordAutofillAgentTest, InitialAutocompleteForEmptyAction) { // Set the expected form origin and action URLs. UpdateOriginForHTML(kEmptyActionFormHTML); - fill_data_.basic_data.action = fill_data_.basic_data.origin; + fill_data_.action = fill_data_.origin; // Simulate the browser sending back the login info, it triggers the // autocomplete. @@ -850,8 +849,8 @@ TEST_F(PasswordAutofillAgentTest, IframeNoFillTest) { LoadHTML(page_html.c_str()); // Set the expected form origin and action URLs. - fill_data_.basic_data.origin = GURL(origin); - fill_data_.basic_data.action = GURL(origin); + fill_data_.origin = GURL(origin); + fill_data_.action = GURL(origin); SimulateOnFillPasswordForm(fill_data_); diff --git a/components/autofill/content/common/autofill_messages.h b/components/autofill/content/common/autofill_messages.h index 57b6a9a..cd5cd1e 100644 --- a/components/autofill/content/common/autofill_messages.h +++ b/components/autofill/content/common/autofill_messages.h @@ -77,7 +77,12 @@ IPC_STRUCT_TRAITS_BEGIN(autofill::UsernamesCollectionKey) IPC_STRUCT_TRAITS_END() IPC_STRUCT_TRAITS_BEGIN(autofill::PasswordFormFillData) - IPC_STRUCT_TRAITS_MEMBER(basic_data) + IPC_STRUCT_TRAITS_MEMBER(name) + IPC_STRUCT_TRAITS_MEMBER(origin) + IPC_STRUCT_TRAITS_MEMBER(action) + IPC_STRUCT_TRAITS_MEMBER(user_submitted) + IPC_STRUCT_TRAITS_MEMBER(username_field) + IPC_STRUCT_TRAITS_MEMBER(password_field) IPC_STRUCT_TRAITS_MEMBER(preferred_realm) IPC_STRUCT_TRAITS_MEMBER(additional_logins) IPC_STRUCT_TRAITS_MEMBER(other_possible_usernames) diff --git a/components/autofill/content/renderer/password_autofill_agent.cc b/components/autofill/content/renderer/password_autofill_agent.cc index 2dc195e..cc24a9d 100644 --- a/components/autofill/content/renderer/password_autofill_agent.cc +++ b/components/autofill/content/renderer/password_autofill_agent.cc @@ -61,6 +61,10 @@ struct FormElements { typedef std::vector<FormElements*> FormElementsList; +bool FillDataContainsUsername(const PasswordFormFillData& fill_data) { + return !fill_data.username_field.name.empty(); +} + // Utility function to find the unique entry of the |form_element| for the // specified input |field|. On successful find, adds it to |result| and returns // |true|. Otherwise clears the references from each |HTMLInputElement| from @@ -118,25 +122,16 @@ bool FindFormInputElement(blink::WebFormElement* form_element, // Helper to search the given form element for the specified input elements in // |data|, and add results to |result|. bool FindFormInputElements(blink::WebFormElement* form_element, - const FormData& data, + const PasswordFormFillData& data, FormElements* result) { - const bool username_is_present = !data.fields[0].name.empty(); - - // Loop through the list of elements we need to find on the form in order to - // autofill it. If we don't find any one of them, abort processing this - // form; it can't be the right one. - // First field is the username, skip it if not present. - for (size_t j = (username_is_present ? 0 : 1); j < data.fields.size(); ++j) { - if (!FindFormInputElement(form_element, data.fields[j], result)) - return false; - } - - return true; + return FindFormInputElement(form_element, data.password_field, result) && + (!FillDataContainsUsername(data) || + FindFormInputElement(form_element, data.username_field, result)); } // Helper to locate form elements identified by |data|. void FindFormElements(blink::WebView* view, - const FormData& data, + const PasswordFormFillData& data, FormElementsList* results) { DCHECK(view); DCHECK(results); @@ -244,10 +239,6 @@ void LogHTMLForm(SavePasswordProgressLogger* logger, GURL(form.action().utf8())); } -bool FillDataContainsUsername(const PasswordFormFillData& fill_data) { - return !fill_data.basic_data.fields[0].name.empty(); -} - // Sets |suggestions_present| to true if there are any suggestions to be derived // from |fill_data|. Unless |show_all| is true, only considers suggestions with // usernames having |current_username| as a prefix. Returns true if a username @@ -269,8 +260,8 @@ bool GetSuggestionsStats(const PasswordFormFillData& fill_data, } } - if (show_all || StartsWith(fill_data.basic_data.fields[0].value, - current_username, false)) { + if (show_all || + StartsWith(fill_data.username_field.value, current_username, false)) { *suggestions_present = true; return false; } @@ -312,11 +303,10 @@ bool FillUserNameAndPassword( base::string16 password; // Look for any suitable matches to current field text. - if (DoUsernamesMatch(fill_data.basic_data.fields[0].value, - current_username, + if (DoUsernamesMatch(fill_data.username_field.value, current_username, exact_username_match)) { - username = fill_data.basic_data.fields[0].value; - password = fill_data.basic_data.fields[1].value; + username = fill_data.username_field.value; + password = fill_data.password_field.value; } else { // Scan additional logins for a match. PasswordFormFillData::LoginCollection::const_iterator iter; @@ -412,7 +402,7 @@ bool FillFormOnPasswordRecieved( IsElementAutocompletable(username_element) && username_element.value().isEmpty()) { // TODO(tkent): Check maxlength and pattern. - username_element.setValue(fill_data.basic_data.fields[0].value, true); + username_element.setValue(fill_data.username_field.value, true); } // Fill if we have an exact match for the username. Note that this sets @@ -1027,7 +1017,7 @@ void PasswordAutofillAgent::OnFillPasswordForm( FormElementsList forms; // We own the FormElements* in forms. - FindFormElements(render_view()->GetWebView(), form_data.basic_data, &forms); + FindFormElements(render_view()->GetWebView(), form_data, &forms); FormElementsList::iterator iter; for (iter = forms.begin(); iter != forms.end(); ++iter) { scoped_ptr<FormElements> form_elements(*iter); @@ -1039,17 +1029,17 @@ void PasswordAutofillAgent::OnFillPasswordForm( bool form_contains_username_field = FillDataContainsUsername(form_data); if (form_contains_username_field) { username_element = - form_elements->input_elements[form_data.basic_data.fields[0].name]; + form_elements->input_elements[form_data.username_field.name]; } // No password field, bail out. - if (form_data.basic_data.fields[1].name.empty()) + if (form_data.password_field.name.empty()) break; // Get pointer to password element. (We currently only support single // password forms). password_element = - form_elements->input_elements[form_data.basic_data.fields[1].name]; + form_elements->input_elements[form_data.password_field.name]; // If wait_for_username is true, we don't want to initially fill the form // until the user types in a valid username. diff --git a/components/autofill/core/common/autofill_data_validation.cc b/components/autofill/core/common/autofill_data_validation.cc index c8f6584..578cc04 100644 --- a/components/autofill/core/common/autofill_data_validation.cc +++ b/components/autofill/core/common/autofill_data_validation.cc @@ -59,9 +59,12 @@ bool IsValidFormData(const FormData& form) { } bool IsValidPasswordFormFillData(const PasswordFormFillData& form) { - if (!IsValidFormData(form.basic_data) || - !IsValidString(form.preferred_realm)) + if (!IsValidString16(form.name) || !IsValidGURL(form.origin) || + !IsValidGURL(form.action) || !IsValidFormFieldData(form.username_field) || + !IsValidFormFieldData(form.password_field) || + !IsValidString(form.preferred_realm)) { return false; + } for (PasswordFormFillData::LoginCollection::const_iterator it = form.additional_logins.begin(); diff --git a/components/autofill/core/common/password_form_fill_data.cc b/components/autofill/core/common/password_form_fill_data.cc index ffc3db7..714e8f5 100644 --- a/components/autofill/core/common/password_form_fill_data.cc +++ b/components/autofill/core/common/password_form_fill_data.cc @@ -22,7 +22,8 @@ bool UsernamesCollectionKey::operator<( return realm < other.realm; } -PasswordFormFillData::PasswordFormFillData() : wait_for_username(false) { +PasswordFormFillData::PasswordFormFillData() + : user_submitted(false), wait_for_username(false) { } PasswordFormFillData::~PasswordFormFillData() { @@ -47,11 +48,12 @@ void InitPasswordFormFillData( password_field.form_control_type = "password"; // Fill basic form data. - result->basic_data.name = form_on_page.form_data.name; - result->basic_data.origin = form_on_page.origin; - result->basic_data.action = form_on_page.action; - result->basic_data.fields.push_back(username_field); - result->basic_data.fields.push_back(password_field); + result->name = form_on_page.form_data.name; + result->origin = form_on_page.origin; + result->action = form_on_page.action; + result->user_submitted = form_on_page.form_data.user_submitted; + result->username_field = username_field; + result->password_field = password_field; result->wait_for_username = wait_for_username_before_autofill; result->preferred_realm = preferred_match->original_signon_realm; diff --git a/components/autofill/core/common/password_form_fill_data.h b/components/autofill/core/common/password_form_fill_data.h index 14c4759..31333d2 100644 --- a/components/autofill/core/common/password_form_fill_data.h +++ b/components/autofill/core/common/password_form_fill_data.h @@ -39,9 +39,22 @@ struct PasswordFormFillData { typedef std::map<UsernamesCollectionKey, std::vector<base::string16> > UsernamesCollection; - // Identifies the HTML form on the page and preferred username/password for - // login. - FormData basic_data; + // The name of the form. + base::string16 name; + + // An origin is (scheme, host, port, path and fragment identifier) only; it is + // just exactly a URL with the query string removed. + GURL origin; + + // The action target of the form. + GURL action; + + // True if this form was submitted by a user gesture and not javascript. + bool user_submitted; + + // Username and password input fields in the form. + FormFieldData username_field; + FormFieldData password_field; // The signon realm of the preferred user/pass pair. std::string preferred_realm; diff --git a/components/password_manager/core/browser/password_autofill_manager.cc b/components/password_manager/core/browser/password_autofill_manager.cc index 1a45c18..810e09d 100644 --- a/components/password_manager/core/browser/password_autofill_manager.cc +++ b/components/password_manager/core/browser/password_autofill_manager.cc @@ -29,9 +29,8 @@ void GetSuggestions(const autofill::PasswordFormFillData& fill_data, std::vector<base::string16>* realms, bool show_all) { if (show_all || - StartsWith( - fill_data.basic_data.fields[0].value, current_username, false)) { - suggestions->push_back(fill_data.basic_data.fields[0].value); + StartsWith(fill_data.username_field.value, current_username, false)) { + suggestions->push_back(fill_data.username_field.value); realms->push_back(base::UTF8ToUTF16(fill_data.preferred_realm)); } @@ -201,8 +200,8 @@ bool PasswordAutofillManager::GetPasswordForUsername( // fetch the actual password. See crbug.com/178358 for more context. // Look for any suitable matches to current field text. - if (fill_data.basic_data.fields[0].value == current_username) { - *password = fill_data.basic_data.fields[1].value; + if (fill_data.username_field.value == current_username) { + *password = fill_data.password_field.value; return true; } diff --git a/components/password_manager/core/browser/password_autofill_manager_unittest.cc b/components/password_manager/core/browser/password_autofill_manager_unittest.cc index 1f46b40..e8b5bd2 100644 --- a/components/password_manager/core/browser/password_autofill_manager_unittest.cc +++ b/components/password_manager/core/browser/password_autofill_manager_unittest.cc @@ -81,12 +81,12 @@ class PasswordAutofillManagerTest : public testing::Test { autofill::FormFieldData username_field; username_field.name = base::ASCIIToUTF16(kUsernameName); username_field.value = test_username_; - fill_data_.basic_data.fields.push_back(username_field); + fill_data_.username_field = username_field; autofill::FormFieldData password_field; password_field.name = base::ASCIIToUTF16(kPasswordName); password_field.value = test_password_; - fill_data_.basic_data.fields.push_back(password_field); + fill_data_.password_field = password_field; } void InitializePasswordAutofillManager( @@ -173,9 +173,8 @@ TEST_F(PasswordAutofillManagerTest, ExternalDelegatePasswordSuggestions) { gfx::RectF element_bounds; autofill::PasswordFormFillData data; - data.basic_data.fields.resize(2); - data.basic_data.fields[0].value = test_username_; - data.basic_data.fields[1].value = test_password_; + data.username_field.value = test_username_; + data.password_field.value = test_password_; data.preferred_realm = "http://foo.com/"; int dummy_key = 0; password_autofill_manager_->OnAddPasswordFormMapping(dummy_key, data); @@ -212,9 +211,8 @@ TEST_F(PasswordAutofillManagerTest, ExtractSuggestions) { gfx::RectF element_bounds; autofill::PasswordFormFillData data; - data.basic_data.fields.resize(2); - data.basic_data.fields[0].value = test_username_; - data.basic_data.fields[1].value = test_password_; + data.username_field.value = test_username_; + data.password_field.value = test_password_; data.preferred_realm = "http://foo.com/"; autofill::PasswordAndRealm additional; |