diff options
author | jhawkins@chromium.org <jhawkins@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-05-06 19:17:25 +0000 |
---|---|---|
committer | jhawkins@chromium.org <jhawkins@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-05-06 19:17:25 +0000 |
commit | a263d56dd156e94f3453604d231e06a9bb1f537d (patch) | |
tree | b1737da94bee012cd470bbb049d9ca9d9be3d966 /chrome/renderer | |
parent | 00e1756a97e0502fe0b1f6f726eb3e92888238bc (diff) | |
download | chromium_src-a263d56dd156e94f3453604d231e06a9bb1f537d.zip chromium_src-a263d56dd156e94f3453604d231e06a9bb1f537d.tar.gz chromium_src-a263d56dd156e94f3453604d231e06a9bb1f537d.tar.bz2 |
AutoFill: Handle the case where the cached form has extra fields at the end of
the form compared to the FormData. Fixes a crash.
BUG=41573
TEST=FormManagerTest.FillFormExtraFieldInCache
Review URL: http://codereview.chromium.org/2003002
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@46600 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'chrome/renderer')
-rw-r--r-- | chrome/renderer/form_manager.cc | 13 | ||||
-rw-r--r-- | chrome/renderer/form_manager_unittest.cc | 84 |
2 files changed, 94 insertions, 3 deletions
diff --git a/chrome/renderer/form_manager.cc b/chrome/renderer/form_manager.cc index e39c3b1..f81d6df 100644 --- a/chrome/renderer/form_manager.cc +++ b/chrome/renderer/form_manager.cc @@ -414,12 +414,19 @@ bool FormManager::FillForm(const FormData& form) { // so loop past non-matching fields in the set with more elements. while (form_element->control_elements[i].nameForAutofill() != form.fields[j].name()) { - if (form_element->control_elements.size() > form.fields.size()) + if (form_element->control_elements.size() > form.fields.size()) { + // We're at the end of the elements already. + if (i + 1 == form_element->control_elements.size()) + break; ++i; - else if (form.fields.size() > form_element->control_elements.size()) + } else if (form.fields.size() > form_element->control_elements.size()) { + // We're at the end of the elements already. + if (j + 1 == form.fields.size()) + break; ++j; - else + } else { NOTREACHED(); + } continue; } diff --git a/chrome/renderer/form_manager_unittest.cc b/chrome/renderer/form_manager_unittest.cc index 2f37362..1f5e1b5 100644 --- a/chrome/renderer/form_manager_unittest.cc +++ b/chrome/renderer/form_manager_unittest.cc @@ -1175,6 +1175,90 @@ TEST_F(FormManagerTest, FillFormFewerFormDataFields) { fields[7]); } +// This test sends a FormData object to FillForm with fewer fields than are in +// the cached WebFormElement. In this case, we only fill out the fields that +// match between the FormData object and the WebFormElement. +TEST_F(FormManagerTest, FillFormExtraFieldInCache) { + LoadHTML("<FORM name=\"TestForm\" action=\"http://buh.com\" method=\"post\">" + " <INPUT type=\"text\" id=\"firstname\"/>" + " <INPUT type=\"text\" id=\"middlename\"/>" + " <INPUT type=\"text\" id=\"lastname\"/>" + " <INPUT type=\"text\" id=\"postfix\"/>" + " <INPUT type=\"submit\" name=\"reply-send\" value=\"Send\"/>" + "</FORM>"); + + WebFrame* web_frame = GetMainFrame(); + ASSERT_NE(static_cast<WebFrame*>(NULL), web_frame); + + FormManager form_manager; + form_manager.ExtractForms(web_frame); + + // Verify that we have the form. + std::vector<FormData> forms; + form_manager.GetForms(FormManager::REQUIRE_NONE, &forms); + ASSERT_EQ(1U, forms.size()); + + // After the field modification, the fields in |form| will look like: + // firstname + // middlename + // lastname + FormData* form = &forms[0]; + form->fields.erase(form->fields.end()); + + // Fill the form. + form->fields[0].set_value(ASCIIToUTF16("Brother")); + form->fields[1].set_value(ASCIIToUTF16("Joseph")); + form->fields[2].set_value(ASCIIToUTF16("Jonathan")); + EXPECT_TRUE(form_manager.FillForm(*form)); + + // Get the input element we want to find. + WebElement element = + web_frame->document().getElementById(WebString::fromUTF8("firstname")); + WebInputElement input_element = element.toElement<WebInputElement>(); + + // Find the newly-filled form that contains the input element. + FormData form2; + EXPECT_TRUE(form_manager.FindFormWithFormControlElement( + input_element, FormManager::REQUIRE_NONE, &form2)); + EXPECT_EQ(ASCIIToUTF16("TestForm"), form2.name); + EXPECT_EQ(GURL(web_frame->url()), form2.origin); + EXPECT_EQ(GURL("http://buh.com"), form2.action); + + // TODO(jhawkins): We don't actually compare the value of the field in + // FormField::operator==()! + const std::vector<FormField>& fields = form2.fields; + ASSERT_EQ(5U, fields.size()); + EXPECT_EQ(FormField(string16(), + ASCIIToUTF16("firstname"), + ASCIIToUTF16("Brother"), + ASCIIToUTF16("text")), + fields[0]); + EXPECT_EQ(ASCIIToUTF16("Brother"), fields[0].value()); + EXPECT_EQ(FormField(string16(), + ASCIIToUTF16("middlename"), + ASCIIToUTF16("Joseph"), + ASCIIToUTF16("text")), + fields[1]); + EXPECT_EQ(ASCIIToUTF16("Joseph"), fields[1].value()); + EXPECT_EQ(FormField(string16(), + ASCIIToUTF16("lastname"), + ASCIIToUTF16("Jonathan"), + ASCIIToUTF16("text")), + fields[2]); + EXPECT_EQ(ASCIIToUTF16("Jonathan"), fields[2].value()); + EXPECT_EQ(FormField(string16(), + ASCIIToUTF16("postfix"), + string16(), + ASCIIToUTF16("text")), + fields[3]); + EXPECT_EQ(string16(), fields[3].value()); + EXPECT_EQ(FormField(string16(), + ASCIIToUTF16("reply-send"), + ASCIIToUTF16("Send"), + ASCIIToUTF16("submit")), + fields[4]); +} + TEST_F(FormManagerTest, FillFormEmptyName) { LoadHTML("<FORM name=\"TestForm\" action=\"http://buh.com\" method=\"post\">" " <INPUT type=\"text\" id=\"firstname\"/>" |