summaryrefslogtreecommitdiffstats
path: root/chrome/renderer
diff options
context:
space:
mode:
authorjhawkins@chromium.org <jhawkins@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2010-05-06 19:17:25 +0000
committerjhawkins@chromium.org <jhawkins@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2010-05-06 19:17:25 +0000
commita263d56dd156e94f3453604d231e06a9bb1f537d (patch)
treeb1737da94bee012cd470bbb049d9ca9d9be3d966 /chrome/renderer
parent00e1756a97e0502fe0b1f6f726eb3e92888238bc (diff)
downloadchromium_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.cc13
-rw-r--r--chrome/renderer/form_manager_unittest.cc84
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\"/>"