Changeset 224206 in webkit


Ignore:
Timestamp:
Oct 30, 2017 3:42:23 PM (6 years ago)
Author:
Michael Catanzaro
Message:

WKBundlePageWillSendSubmitEventCallback is called with incorrect frame parameter
https://bugs.webkit.org/show_bug.cgi?id=176719

Reviewed by Chris Dumez.

Source/WebCore:

WKBundlePageWillSendSubmitEventCallback is clearly intended to parallel
WKBundlePageWillSubmitFormCallback, since almost all the parameters are the same. Now, in
WKBundlePageWillSubmitFormCallback, the first WKBundleFrameRef, "frame", is the frame of the
form target, and the second WKBundleFrameRef, sourceFrame, is the frame containing the form.
That's correct. But in WKBundlePageWillSendSubmitEventCallback, both frame and sourceFrame
are always identical. The problem is that the FrameLoaderClient delegate is called on the
wrong FrameLoaderClient. It should be called on the FrameLoaderClient of the target frame,
but HTMLFormElement calls it on the FrameLoaderClient of the source frame instead.

Fix this by factoring the target frame computation out of FormSubmission into some helpers.

  • html/HTMLFormElement.cpp:

(WebCore::HTMLFormElement::prepareForSubmission):
(WebCore::HTMLFormElement::effectiveTarget const):
(WebCore::HTMLFormElement::findSubmitButton const):

  • html/HTMLFormElement.h:
  • loader/FormSubmission.cpp:

(WebCore::FormSubmission::create):

Tools:

Test that WKBundlePageWillSendSubmitEventCallback is called with separate frame and
sourceFrame parameters when the target frame of the form submission is not the source frame.

  • TestWebKitAPI/Tests/WebKit/WillSendSubmitEvent.cpp:

(TestWebKitAPI::didReceiveMessageFromInjectedBundle):

  • TestWebKitAPI/Tests/WebKit/WillSendSubmitEvent_Bundle.cpp:

(TestWebKitAPI::willSendSubmitEvent):

  • TestWebKitAPI/Tests/WebKit/auto-submitting-form.html:
Location:
trunk
Files:
8 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/WebCore/ChangeLog

    r224202 r224206  
     12017-10-30  Michael Catanzaro  <mcatanzaro@igalia.com>
     2
     3        WKBundlePageWillSendSubmitEventCallback is called with incorrect frame parameter
     4        https://bugs.webkit.org/show_bug.cgi?id=176719
     5
     6        Reviewed by Chris Dumez.
     7
     8        WKBundlePageWillSendSubmitEventCallback is clearly intended to parallel
     9        WKBundlePageWillSubmitFormCallback, since almost all the parameters are the same. Now, in
     10        WKBundlePageWillSubmitFormCallback, the first WKBundleFrameRef, "frame", is the frame of the
     11        form target, and the second WKBundleFrameRef, sourceFrame, is the frame containing the form.
     12        That's correct. But in WKBundlePageWillSendSubmitEventCallback, both frame and sourceFrame
     13        are always identical. The problem is that the FrameLoaderClient delegate is called on the
     14        wrong FrameLoaderClient. It should be called on the FrameLoaderClient of the target frame,
     15        but HTMLFormElement calls it on the FrameLoaderClient of the source frame instead.
     16
     17        Fix this by factoring the target frame computation out of FormSubmission into some helpers.
     18
     19        * html/HTMLFormElement.cpp:
     20        (WebCore::HTMLFormElement::prepareForSubmission):
     21        (WebCore::HTMLFormElement::effectiveTarget const):
     22        (WebCore::HTMLFormElement::findSubmitButton const):
     23        * html/HTMLFormElement.h:
     24        * loader/FormSubmission.cpp:
     25        (WebCore::FormSubmission::create):
     26
    1272017-10-30  Alex Christensen  <achristensen@webkit.org>
    228
  • trunk/Source/WebCore/html/HTMLFormElement.cpp

    r223802 r224206  
    280280    }
    281281
     282    auto targetFrame = frame->loader().findFrameForNavigation(effectiveTarget(&event), &document());
     283    if (!targetFrame)
     284        targetFrame = frame.get();
    282285    auto formState = FormState::create(*this, textFieldValues(), document(), NotSubmittedByJavaScript);
    283     frame->loader().client().dispatchWillSendSubmitEvent(WTFMove(formState));
     286    targetFrame->loader().client().dispatchWillSendSubmitEvent(WTFMove(formState));
    284287
    285288    Ref<HTMLFormElement> protectedThis(*this);
     
    643646}
    644647
     648String HTMLFormElement::effectiveTarget(const Event* event) const
     649{
     650    if (auto* submitButton = findSubmitButton(event)) {
     651        auto targetValue = submitButton->attributeWithoutSynchronization(formtargetAttr);
     652        if (!targetValue.isNull())
     653            return targetValue;
     654    }
     655
     656    auto targetValue = target();
     657    if (!targetValue.isNull())
     658        return targetValue;
     659
     660    return document().baseTarget();
     661}
     662
    645663bool HTMLFormElement::wasUserSubmitted() const
    646664{
    647665    return m_wasUserSubmitted;
     666}
     667
     668HTMLFormControlElement* HTMLFormElement::findSubmitButton(const Event* event) const
     669{
     670    if (event && event->target()) {
     671        for (auto node = event->target()->toNode(); node; node = node->parentNode()) {
     672            if (is<HTMLFormControlElement>(*node))
     673                return downcast<HTMLFormControlElement>(node.get());
     674        }
     675    }
     676    return nullptr;
    648677}
    649678
  • trunk/Source/WebCore/html/HTMLFormElement.h

    r223802 r224206  
    103103
    104104    String target() const final;
     105    String effectiveTarget(const Event*) const;
    105106
    106107    bool wasUserSubmitted() const;
     108
     109    HTMLFormControlElement* findSubmitButton(const Event*) const;
    107110
    108111    HTMLFormControlElement* defaultButton() const;
  • trunk/Source/WebCore/loader/FormSubmission.cpp

    r223644 r224206  
    148148Ref<FormSubmission> FormSubmission::create(HTMLFormElement& form, const Attributes& attributes, Event* event, LockHistory lockHistory, FormSubmissionTrigger trigger)
    149149{
    150     HTMLFormControlElement* submitButton = nullptr;
    151     if (event && event->target()) {
    152         for (auto node = event->target()->toNode(); node; node = node->parentNode()) {
    153             if (is<HTMLFormControlElement>(*node)) {
    154                 submitButton = downcast<HTMLFormControlElement>(node.get());
    155                 break;
    156             }
    157         }
    158     }
    159 
    160150    auto copiedAttributes = attributes;
    161     if (submitButton) {
     151
     152    if (auto* submitButton = form.findSubmitButton(event)) {
    162153        AtomicString attributeValue;
    163154        if (!(attributeValue = submitButton->attributeWithoutSynchronization(formactionAttr)).isNull())
     
    229220    formData->setContainsPasswordData(containsPasswordData);
    230221
    231     String targetOrBaseTarget = copiedAttributes.target().isEmpty() ? document.baseTarget() : copiedAttributes.target();
    232 
    233222    auto formState = FormState::create(form, WTFMove(formValues), document, trigger);
    234223
    235     return adoptRef(*new FormSubmission(copiedAttributes.method(), actionURL, targetOrBaseTarget, encodingType, WTFMove(formState), formData.releaseNonNull(), boundary, lockHistory, event));
     224    return adoptRef(*new FormSubmission(copiedAttributes.method(), actionURL, form.effectiveTarget(event), encodingType, WTFMove(formState), formData.releaseNonNull(), boundary, lockHistory, event));
    236225}
    237226
  • trunk/Tools/ChangeLog

    r224202 r224206  
     12017-10-30  Michael Catanzaro  <mcatanzaro@igalia.com>
     2
     3        WKBundlePageWillSendSubmitEventCallback is called with incorrect frame parameter
     4        https://bugs.webkit.org/show_bug.cgi?id=176719
     5
     6        Reviewed by Chris Dumez.
     7
     8        Test that WKBundlePageWillSendSubmitEventCallback is called with separate frame and
     9        sourceFrame parameters when the target frame of the form submission is not the source frame.
     10
     11        * TestWebKitAPI/Tests/WebKit/WillSendSubmitEvent.cpp:
     12        (TestWebKitAPI::didReceiveMessageFromInjectedBundle):
     13        * TestWebKitAPI/Tests/WebKit/WillSendSubmitEvent_Bundle.cpp:
     14        (TestWebKitAPI::willSendSubmitEvent):
     15        * TestWebKitAPI/Tests/WebKit/auto-submitting-form.html:
     16
    1172017-10-30  Alex Christensen  <achristensen@webkit.org>
    218
  • trunk/Tools/TestWebKitAPI/Tests/WebKit/WillSendSubmitEvent.cpp

    r221505 r224206  
    5757    WKStringRef hiddenFieldValueWK = static_cast<WKStringRef>(WKDictionaryGetItemForKey(values, hiddenFieldKey.get()));
    5858    EXPECT_NULL(hiddenFieldValueWK);
     59
     60    WKRetainPtr<WKStringRef> targetFrameKey(AdoptWK, WKStringCreateWithUTF8CString("targetFrameIsMainFrame"));
     61    WKBooleanRef targetFrameIsMainFrame = static_cast<WKBooleanRef>(WKDictionaryGetItemForKey(values, targetFrameKey.get()));
     62    EXPECT_FALSE(WKBooleanGetValue(targetFrameIsMainFrame));
     63
     64    WKRetainPtr<WKStringRef> sourceFrameKey(AdoptWK, WKStringCreateWithUTF8CString("sourceFrameIsMainFrame"));
     65    WKBooleanRef sourceFrameIsMainFrame = static_cast<WKBooleanRef>(WKDictionaryGetItemForKey(values, sourceFrameKey.get()));
     66    EXPECT_TRUE(WKBooleanGetValue(sourceFrameIsMainFrame));
    5967}
    6068
  • trunk/Tools/TestWebKitAPI/Tests/WebKit/WillSendSubmitEvent_Bundle.cpp

    r179409 r224206  
    3131
    3232#include "PlatformUtilities.h"
     33#include <WebKit/WKBundleFrame.h>
    3334#include <WebKit/WKBundlePage.h>
    3435
     
    4445static InjectedBundleTest::Register<WillSendSubmitEventTest> registrar("WillSendSubmitEventTest");
    4546
    46 static void willSendSubmitEvent(WKBundlePageRef, WKBundleNodeHandleRef, WKBundleFrameRef, WKBundleFrameRef, WKDictionaryRef values, const void*)
     47static void willSendSubmitEvent(WKBundlePageRef, WKBundleNodeHandleRef, WKBundleFrameRef targetFrame, WKBundleFrameRef sourceFrame, WKDictionaryRef values, const void*)
    4748{
     49    auto messageBody = const_cast<WKMutableDictionaryRef>(values);
     50
     51    auto targetFrameKey = Util::toWK("targetFrameIsMainFrame");
     52    auto targetFrameValue = adoptWK(WKBooleanCreate(WKBundleFrameIsMainFrame(targetFrame)));
     53    WKDictionarySetItem(messageBody, targetFrameKey.get(), targetFrameValue.get());
     54
     55    auto sourceFrameKey = Util::toWK("sourceFrameIsMainFrame");
     56    auto sourceFrameValue = adoptWK(WKBooleanCreate(WKBundleFrameIsMainFrame(sourceFrame)));
     57    WKDictionarySetItem(messageBody, sourceFrameKey.get(), sourceFrameValue.get());
     58
    4859    WKBundlePostMessage(InjectedBundleController::singleton().bundle(), Util::toWK("DidReceiveWillSendSubmitEvent").get(), values);
    4960}
  • trunk/Tools/TestWebKitAPI/Tests/WebKit/auto-submitting-form.html

    r116016 r224206  
    1111    </head>
    1212    <body onload="submitFormIfNecessary()">
    13         <form action="#" method="GET">
     13        <form action="#" method="GET" target="target_frame">
    1414            <input type="text" name="textField" value="text field">
    1515            <input type="password" name="passwordField" value="password field">
     
    1717            <input type="submit" name="submit">
    1818        </form>
     19        <iframe name="target_frame"></iframe>
    1920    </body>
    2021</html>
Note: See TracChangeset for help on using the changeset viewer.