Commit ec39cd13 authored by Maria Kazinova's avatar Maria Kazinova Committed by Chromium LUCI CQ

[iOS][Passwords] Fixing getPasswordFormDataAsString method for formless

forms.

__gCrWeb.passwords.getPasswordFormDataAsString method is not supporting
forms that are outside the <form> tag properly, this CL fixes it.

Change-Id: If8897e966a6d5b62661c8094bb01cb82fdbf9681
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2640115Reviewed-by: default avatarJan Wilken Dörrie <jdoerrie@chromium.org>
Commit-Queue: Maria Kazinova <kazinova@google.com>
Cr-Commit-Position: refs/heads/master@{#845191}
parent c259c84a
...@@ -102,7 +102,7 @@ std::unique_ptr<base::Value> SerializeFillData( ...@@ -102,7 +102,7 @@ std::unique_ptr<base::Value> SerializeFillData(
completionHandler:(void (^)(NSString*))completionHandler { completionHandler:(void (^)(NSString*))completionHandler {
DCHECK(completionHandler); DCHECK(completionHandler);
std::vector<base::Value> parameters; std::vector<base::Value> parameters;
parameters.emplace_back(static_cast<int>(formIdentifier.value())); parameters.emplace_back(FormRendererIdToJsParameter(formIdentifier));
autofill::ExecuteJavaScriptFunction("passwords.getPasswordFormDataAsString", autofill::ExecuteJavaScriptFunction("passwords.getPasswordFormDataAsString",
parameters, frame, parameters, frame,
CreateStringCallback(completionHandler)); CreateStringCallback(completionHandler));
......
...@@ -177,11 +177,15 @@ const getFormInputElements = function(form) { ...@@ -177,11 +177,15 @@ const getFormInputElements = function(form) {
* @return {string} The password form. * @return {string} The password form.
*/ */
__gCrWeb.passwords['getPasswordFormDataAsString'] = function(identifier) { __gCrWeb.passwords['getPasswordFormDataAsString'] = function(identifier) {
const el = getPasswordFormElement(window, identifier); const hasFormTag =
if (!el) { identifier.toString() !== __gCrWeb.fill.RENDERER_ID_NOT_SET;
const form = hasFormTag ? getPasswordFormElement(window, identifier) : null;
if (!form && hasFormTag) {
return '{}'; return '{}';
} }
const formData = __gCrWeb.passwords.getPasswordFormData(el, window); const formData = hasFormTag ?
__gCrWeb.passwords.getPasswordFormData(form, window) :
__gCrWeb.passwords.getPasswordFormDataFromUnownedElements(window);
if (!formData) { if (!formData) {
return '{}'; return '{}';
} }
...@@ -351,7 +355,11 @@ const getPasswordFormDataList = function(formDataList, win) { ...@@ -351,7 +355,11 @@ const getPasswordFormDataList = function(formDataList, win) {
addSubmitButtonTouchEndHandler(forms[i]); addSubmitButtonTouchEndHandler(forms[i]);
} }
} }
getPasswordFormDataFromUnownedElements_(formDataList, win); const unownedFormData =
__gCrWeb.passwords.getPasswordFormDataFromUnownedElements(win);
if (unownedFormData) {
formDataList.push(unownedFormData);
}
// Recursively invoke for all iframes. // Recursively invoke for all iframes.
const frames = getSameOriginFrames(win); const frames = getSameOriginFrames(win);
for (let i = 0; i < frames.length; i++) { for (let i = 0; i < frames.length; i++) {
...@@ -360,13 +368,12 @@ const getPasswordFormDataList = function(formDataList, win) { ...@@ -360,13 +368,12 @@ const getPasswordFormDataList = function(formDataList, win) {
}; };
/** /**
* Finds all forms with passwords that are not inside any <form> tag and appends * Finds all forms with passwords that are not inside any <form> tag and returns
* JS object containing the form data to |formDataList|. * JS object containing the form data.
* @param {!Array<Object>} formDataList A list that this function populates
* with descriptions of discovered forms.
* @param {Window} win A window or a frame containing formData. * @param {Window} win A window or a frame containing formData.
* @return {Object} Object of data from formElement.
*/ */
function getPasswordFormDataFromUnownedElements_(formDataList, window) { __gCrWeb.passwords.getPasswordFormDataFromUnownedElements = function(window) {
const doc = window.document; const doc = window.document;
const extractMask = __gCrWeb.fill.EXTRACT_MASK_VALUE; const extractMask = __gCrWeb.fill.EXTRACT_MASK_VALUE;
const fieldsets = []; const fieldsets = [];
...@@ -380,10 +387,9 @@ function getPasswordFormDataFromUnownedElements_(formDataList, window) { ...@@ -380,10 +387,9 @@ function getPasswordFormDataFromUnownedElements_(formDataList, window) {
__gCrWeb.fill.unownedFormElementsAndFieldSetsToFormData( __gCrWeb.fill.unownedFormElementsAndFieldSetsToFormData(
window, fieldsets, unownedControlElements, extractMask, false, window, fieldsets, unownedControlElements, extractMask, false,
unownedForm); unownedForm);
if (hasUnownedForm) { return hasUnownedForm ? unownedForm : null;
formDataList.push(unownedForm); };
}
}
/** /**
* Returns a JS object containing the data from |formElement|. * Returns a JS object containing the data from |formElement|.
......
...@@ -712,4 +712,39 @@ TEST_F(PasswordControllerJsTest, FillOnlyPasswordField) { ...@@ -712,4 +712,39 @@ TEST_F(PasswordControllerJsTest, FillOnlyPasswordField) {
@[ @"password" ], @[ password ]); @[ @"password" ], @[ password ]);
} }
// Check that password form outside the <form> tag is extracted correctly.
TEST_F(PasswordControllerJsTest, ExtractFormOutsideTheFormTag) {
LoadHtmlAndInject(@"<html><body>"
" Name: <input type='text' name='name'>"
" Password: <input type='password' name='password'>"
" <input type='submit' value='Submit'>"
"</body></html>");
ExecuteJavaScript(@"__gCrWeb.fill.setUpForUniqueIDs(0);");
const std::string base_url = BaseUrl();
NSString* result = [NSString
stringWithFormat:
@"{\"name\":\"\",\"origin\":\"%s\",\"action\":\"\","
@"\"is_form_tag\":false,\"fields\":[{"
@"\"identifier\":\"gChrome~field~~INPUT~0\","
@"\"name\":\"name\",\"name_attribute\":\"name\",\"id_attribute\":"
@"\"\",\"unique_renderer_id\":\"0\",\"form_control_type\":\"text\","
@"\"aria_label\":\"\","
@"\"aria_description\":\"\",\"should_autocomplete\":true,"
@"\"is_focusable\":true,\"max_length\":524288,\"is_checkable\":false,"
@"\"value\":\"\",\"label\":\"Name:\"},{\"identifier\":"
@"\"gChrome~field~~INPUT~1\",\"name\":\"password\",\"name_"
@"attribute\":\"password\","
@"\"id_attribute\":\"\",\"unique_renderer_id\":\"1\",\"form_control_"
@"type\":\"password\","
@"\"aria_label\":\"\",\"aria_description\":\"\","
@"\"should_autocomplete\":true,\"is_focusable\":true,"
@"\"max_length\":524288,\"is_checkable\":false,\"value\":\"\","
@"\"label\":\"Password:\"}]}",
base_url.c_str()];
EXPECT_NSEQ(result,
ExecuteJavaScriptWithFormat(
@"__gCrWeb.passwords.getPasswordFormDataAsString(-1)"));
}
} // namespace } // namespace
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment