Commit 864df709 authored by tkent's avatar tkent Committed by Commit bot

submit() in submit event handler should not contains a value of a submit button.

The value of a submit button is appended to a FormData if its activatedSubmit flag
is set.
In a case of form.submit() is called in submit event handler, we did:

1. Set activatedSubmit flag of the submit button
2. Dispatch submit event
2.1. form.submit() builds FormData
3. Build FormData if the submit event was not prevented
4. Clear activatedSubmit flag of the submit button

In step 2.1, we should not include the submit button. So, this CL changes the
process as follows:

1. Dispatch submit event
1.1 form.submit() builds FormData
2. If the submit event was not prevented,
2.1. Set activatedSubmit flag of the submit button
2.2. Build FormData
2.3. Clear activatedSubmit flag of the submit button

Implementation:
We called setActivatedSubmit() before/after prepareForSubmission(). Instead, we
pass a submit button element to prepareForSubmission(), and call
setActivatedSubmit() just before/after building FormData.

BUG=646790

Review-Url: https://codereview.chromium.org/2340213002
Cr-Commit-Position: refs/heads/master@{#419073}
parent ecf51ddf
<!DOCTYPE html>
<body>
<script src="../../resources/testharness.js"></script>
<script src="../../resources/testharnessreport.js"></script>
<iframe name="target"></iframe>
<form action="about:blank" onsubmit="this.submit(); return false;" target="target">
<input name="t" value="text">
<input type="submit" name="b" value="Next">
</form>
<script>
var test = async_test('submit() in submit event handler should not contains a value of a submit button.');
test.step(() => {
var iframe = document.querySelector('iframe');
iframe.addEventListener('load', test.step_func(() => {
assert_true(iframe.contentWindow.location.href.endsWith('?t=text'));
test.done();
}), false);
document.querySelector('input[type=submit]').click();
});
</script>
...@@ -114,10 +114,8 @@ void HTMLButtonElement::defaultEventHandler(Event* event) ...@@ -114,10 +114,8 @@ void HTMLButtonElement::defaultEventHandler(Event* event)
{ {
if (event->type() == EventTypeNames::DOMActivate && !isDisabledFormControl()) { if (event->type() == EventTypeNames::DOMActivate && !isDisabledFormControl()) {
if (form() && m_type == SUBMIT) { if (form() && m_type == SUBMIT) {
m_isActivatedSubmit = true; form()->prepareForSubmission(event, this);
form()->prepareForSubmission(event);
event->setDefaultHandled(); event->setDefaultHandled();
m_isActivatedSubmit = false; // Do this in case submission was canceled.
} }
if (form() && m_type == RESET) { if (form() && m_type == RESET) {
form()->reset(); form()->reset();
......
...@@ -235,17 +235,7 @@ void HTMLFormElement::submitImplicitly(Event* event, bool fromImplicitSubmission ...@@ -235,17 +235,7 @@ void HTMLFormElement::submitImplicitly(Event* event, bool fromImplicitSubmission
} }
} }
if (fromImplicitSubmissionTrigger && submissionTriggerCount == 1) if (fromImplicitSubmissionTrigger && submissionTriggerCount == 1)
prepareForSubmission(event); prepareForSubmission(event, nullptr);
}
// FIXME: Consolidate this and similar code in FormSubmission.cpp.
static inline HTMLFormControlElement* submitElementFromEvent(const Event* event)
{
for (Node* node = event->target()->toNode(); node; node = node->parentOrShadowHostNode()) {
if (node->isElementNode() && toElement(node)->isFormControlElement())
return toHTMLFormControlElement(node);
}
return 0;
} }
bool HTMLFormElement::validateInteractively() bool HTMLFormElement::validateInteractively()
...@@ -291,7 +281,7 @@ bool HTMLFormElement::validateInteractively() ...@@ -291,7 +281,7 @@ bool HTMLFormElement::validateInteractively()
return false; return false;
} }
void HTMLFormElement::prepareForSubmission(Event* event) void HTMLFormElement::prepareForSubmission(Event* event, HTMLFormControlElement* submitButton)
{ {
LocalFrame* frame = document().frame(); LocalFrame* frame = document().frame();
if (!frame || m_isSubmitting || m_inUserJSSubmitEvent) if (!frame || m_isSubmitting || m_inUserJSSubmitEvent)
...@@ -304,8 +294,7 @@ void HTMLFormElement::prepareForSubmission(Event* event) ...@@ -304,8 +294,7 @@ void HTMLFormElement::prepareForSubmission(Event* event)
bool skipValidation = !document().page() || noValidate(); bool skipValidation = !document().page() || noValidate();
DCHECK(event); DCHECK(event);
HTMLFormControlElement* submitElement = submitElementFromEvent(event); if (submitButton && submitButton->formNoValidate())
if (submitElement && submitElement->formNoValidate())
skipValidation = true; skipValidation = true;
UseCounter::count(document(), UseCounter::FormSubmissionStarted); UseCounter::count(document(), UseCounter::FormSubmissionStarted);
...@@ -321,7 +310,7 @@ void HTMLFormElement::prepareForSubmission(Event* event) ...@@ -321,7 +310,7 @@ void HTMLFormElement::prepareForSubmission(Event* event)
} }
if (shouldSubmit) { if (shouldSubmit) {
m_plannedNavigation = nullptr; m_plannedNavigation = nullptr;
submit(event, true); submit(event, submitButton);
} }
if (!m_plannedNavigation) if (!m_plannedNavigation)
return; return;
...@@ -332,7 +321,7 @@ void HTMLFormElement::prepareForSubmission(Event* event) ...@@ -332,7 +321,7 @@ void HTMLFormElement::prepareForSubmission(Event* event)
void HTMLFormElement::submitFromJavaScript() void HTMLFormElement::submitFromJavaScript()
{ {
submit(0, false); submit(nullptr, nullptr);
} }
void HTMLFormElement::submitDialog(FormSubmission* formSubmission) void HTMLFormElement::submitDialog(FormSubmission* formSubmission)
...@@ -345,7 +334,7 @@ void HTMLFormElement::submitDialog(FormSubmission* formSubmission) ...@@ -345,7 +334,7 @@ void HTMLFormElement::submitDialog(FormSubmission* formSubmission)
} }
} }
void HTMLFormElement::submit(Event* event, bool activateSubmitButton) void HTMLFormElement::submit(Event* event, HTMLFormControlElement* submitButton)
{ {
FrameView* view = document().view(); FrameView* view = document().view();
LocalFrame* frame = document().frame(); LocalFrame* frame = document().frame();
...@@ -366,27 +355,24 @@ void HTMLFormElement::submit(Event* event, bool activateSubmitButton) ...@@ -366,27 +355,24 @@ void HTMLFormElement::submit(Event* event, bool activateSubmitButton)
EventQueueScope scopeForDialogClose; EventQueueScope scopeForDialogClose;
AutoReset<bool> submitScope(&m_isSubmitting, true); AutoReset<bool> submitScope(&m_isSubmitting, true);
HTMLFormControlElement* firstSuccessfulSubmitButton = nullptr; if (event && !submitButton) {
bool needButtonActivation = activateSubmitButton; // do we need to activate a submit button? // In a case of implicit submission without a submit button, 'submit'
// event handler might add a submit button. We search for a submit
const FormAssociatedElement::List& elements = associatedElements(); // button again.
for (unsigned i = 0; i < elements.size(); ++i) { // TODO(tkent): Do we really need to activate such submit button?
FormAssociatedElement* associatedElement = elements[i]; for (const auto& associatedElement : associatedElements()) {
if (!associatedElement->isFormControlElement()) if (!associatedElement->isFormControlElement())
continue; continue;
if (needButtonActivation) {
HTMLFormControlElement* control = toHTMLFormControlElement(associatedElement); HTMLFormControlElement* control = toHTMLFormControlElement(associatedElement);
if (control->isActivatedSubmit()) DCHECK(!control->isActivatedSubmit());
needButtonActivation = false; if (control->isSuccessfulSubmitButton()) {
else if (firstSuccessfulSubmitButton == 0 && control->isSuccessfulSubmitButton()) submitButton = control;
firstSuccessfulSubmitButton = control; break;
}
} }
} }
if (needButtonActivation && firstSuccessfulSubmitButton) FormSubmission* formSubmission = FormSubmission::create(this, m_attributes, event, submitButton);
firstSuccessfulSubmitButton->setActivatedSubmit(true);
FormSubmission* formSubmission = FormSubmission::create(this, m_attributes, event);
if (formSubmission->method() == FormSubmission::DialogMethod) { if (formSubmission->method() == FormSubmission::DialogMethod) {
submitDialog(formSubmission); submitDialog(formSubmission);
} else if (m_inUserJSSubmitEvent) { } else if (m_inUserJSSubmitEvent) {
...@@ -398,9 +384,6 @@ void HTMLFormElement::submit(Event* event, bool activateSubmitButton) ...@@ -398,9 +384,6 @@ void HTMLFormElement::submit(Event* event, bool activateSubmitButton)
// protocol. // protocol.
scheduleFormSubmission(formSubmission); scheduleFormSubmission(formSubmission);
} }
if (needButtonActivation && firstSuccessfulSubmitButton)
firstSuccessfulSubmitButton->setActivatedSubmit(false);
} }
void HTMLFormElement::scheduleFormSubmission(FormSubmission* submission) void HTMLFormElement::scheduleFormSubmission(FormSubmission* submission)
......
...@@ -66,7 +66,7 @@ public: ...@@ -66,7 +66,7 @@ public:
void disassociate(HTMLImageElement&); void disassociate(HTMLImageElement&);
void didAssociateByParser(); void didAssociateByParser();
void prepareForSubmission(Event*); void prepareForSubmission(Event*, HTMLFormControlElement* submitButton);
void submitFromJavaScript(); void submitFromJavaScript();
void reset(); void reset();
...@@ -119,7 +119,7 @@ private: ...@@ -119,7 +119,7 @@ private:
void copyNonAttributePropertiesFromElement(const Element&) override; void copyNonAttributePropertiesFromElement(const Element&) override;
void submitDialog(FormSubmission*); void submitDialog(FormSubmission*);
void submit(Event*, bool activateSubmitButton); void submit(Event*, HTMLFormControlElement* submitButton);
void scheduleFormSubmission(FormSubmission*); void scheduleFormSubmission(FormSubmission*);
......
...@@ -110,10 +110,8 @@ void ImageInputType::handleDOMActivateEvent(Event* event) ...@@ -110,10 +110,8 @@ void ImageInputType::handleDOMActivateEvent(Event* event)
{ {
if (element().isDisabledFormControl() || !element().form()) if (element().isDisabledFormControl() || !element().form())
return; return;
element().setActivatedSubmit(true);
m_clickLocation = extractClickLocation(event); m_clickLocation = extractClickLocation(event);
element().form()->prepareForSubmission(event); // Event handlers can run. element().form()->prepareForSubmission(event, &element()); // Event handlers can run.
element().setActivatedSubmit(false);
event->setDefaultHandled(); event->setDefaultHandled();
} }
......
...@@ -66,9 +66,7 @@ void SubmitInputType::handleDOMActivateEvent(Event* event) ...@@ -66,9 +66,7 @@ void SubmitInputType::handleDOMActivateEvent(Event* event)
{ {
if (element().isDisabledFormControl() || !element().form()) if (element().isDisabledFormControl() || !element().form())
return; return;
element().setActivatedSubmit(true); element().form()->prepareForSubmission(event, &element()); // Event handlers can run.
element().form()->prepareForSubmission(event); // Event handlers can run.
element().setActivatedSubmit(false);
event->setDefaultHandled(); event->setDefaultHandled();
} }
......
...@@ -162,20 +162,10 @@ inline FormSubmission::FormSubmission(const String& result) ...@@ -162,20 +162,10 @@ inline FormSubmission::FormSubmission(const String& result)
{ {
} }
FormSubmission* FormSubmission::create(HTMLFormElement* form, const Attributes& attributes, Event* event) FormSubmission* FormSubmission::create(HTMLFormElement* form, const Attributes& attributes, Event* event, HTMLFormControlElement* submitButton)
{ {
DCHECK(form); DCHECK(form);
HTMLFormControlElement* submitButton = 0;
if (event && event->target()) {
for (Node* node = event->target()->toNode(); node; node = node->parentOrShadowHostNode()) {
if (node->isElementNode() && toElement(node)->isFormControlElement()) {
submitButton = toHTMLFormControlElement(node);
break;
}
}
}
FormSubmission::Attributes copiedAttributes; FormSubmission::Attributes copiedAttributes;
copiedAttributes.copyFrom(attributes); copiedAttributes.copyFrom(attributes);
if (submitButton) { if (submitButton) {
...@@ -220,6 +210,8 @@ FormSubmission* FormSubmission::create(HTMLFormElement* form, const Attributes& ...@@ -220,6 +210,8 @@ FormSubmission* FormSubmission::create(HTMLFormElement* form, const Attributes&
WTF::TextEncoding dataEncoding = isMailtoForm ? UTF8Encoding() : FormDataEncoder::encodingFromAcceptCharset(copiedAttributes.acceptCharset(), document.encoding()); WTF::TextEncoding dataEncoding = isMailtoForm ? UTF8Encoding() : FormDataEncoder::encodingFromAcceptCharset(copiedAttributes.acceptCharset(), document.encoding());
FormData* domFormData = FormData::create(dataEncoding.encodingForFormSubmission()); FormData* domFormData = FormData::create(dataEncoding.encodingForFormSubmission());
if (submitButton)
submitButton->setActivatedSubmit(true);
bool containsPasswordData = false; bool containsPasswordData = false;
for (unsigned i = 0; i < form->associatedElements().size(); ++i) { for (unsigned i = 0; i < form->associatedElements().size(); ++i) {
FormAssociatedElement* control = form->associatedElements()[i]; FormAssociatedElement* control = form->associatedElements()[i];
...@@ -233,6 +225,8 @@ FormSubmission* FormSubmission::create(HTMLFormElement* form, const Attributes& ...@@ -233,6 +225,8 @@ FormSubmission* FormSubmission::create(HTMLFormElement* form, const Attributes&
containsPasswordData = true; containsPasswordData = true;
} }
} }
if (submitButton)
submitButton->setActivatedSubmit(false);
RefPtr<EncodedFormData> formData; RefPtr<EncodedFormData> formData;
String boundary; String boundary;
......
...@@ -42,6 +42,7 @@ namespace blink { ...@@ -42,6 +42,7 @@ namespace blink {
class Document; class Document;
class EncodedFormData; class EncodedFormData;
class Event; class Event;
class HTMLFormControlElement;
class HTMLFormElement; class HTMLFormElement;
class FormSubmission : public GarbageCollectedFinalized<FormSubmission> { class FormSubmission : public GarbageCollectedFinalized<FormSubmission> {
...@@ -90,7 +91,7 @@ public: ...@@ -90,7 +91,7 @@ public:
String m_acceptCharset; String m_acceptCharset;
}; };
static FormSubmission* create(HTMLFormElement*, const Attributes&, Event*); static FormSubmission* create(HTMLFormElement*, const Attributes&, Event*, HTMLFormControlElement* submitButton);
DECLARE_TRACE(); DECLARE_TRACE();
FrameLoadRequest createFrameLoadRequest(Document* originDocument); FrameLoadRequest createFrameLoadRequest(Document* originDocument);
......
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