Title: [285214] trunk
Revision
285214
Author
cdu...@apple.com
Date
2021-11-03 10:28:39 -0700 (Wed, 03 Nov 2021)

Log Message

_javascript_ URLs do not run in the right context when using frame targeting
https://bugs.webkit.org/show_bug.cgi?id=232382

Reviewed by Alex Christensen.

LayoutTests/imported/w3c:

* web-platform-tests/html/browsers/browsing-the-web/navigating-across-documents/010-expected.txt:
The test is no longer timing out now that we run the _javascript_ URL contained in the <form>'s action in the context
of the "test" iframe instead of the top frame. However, the test is still failing, possibly because the _javascript_
URL is run synchronously.

Source/WebCore:

_javascript_ URLs did not run in the right context when using frame targeting
(e.g. `<a target="foo" src="" We would previously run the
_javascript_ URL in the context of the anchor instead of the target frame/window.

Also, we would fail to open a new popup when there is no existing frame with
the given target name.

This patch fixes the issue by doing the executeJavaScriptURL() call later,
inside of FrameLoader::loadWithNavigationAction(), once we've already resolved
the target frame and created a new window if necessary.

This aligns our behavior with both Chrome and Firefox.

Tests: fast/frames/_javascript_-url-anchor-target-new-window.html
       fast/frames/_javascript_-url-anchor-target.html
       fast/frames/_javascript_-url-form-target-new-window.html
       fast/frames/_javascript_-url-form-target.html

* bindings/js/ScriptController.cpp:
(WebCore::ScriptController::executeJavaScriptURL):
* html/HTMLAnchorElement.cpp:
(WebCore::HTMLAnchorElement::handleClick):
* html/HTMLFormElement.cpp:
(WebCore::HTMLFormElement::submit):
* loader/FormSubmission.cpp:
(WebCore::FormSubmission::requestURL const):
* loader/FrameLoader.cpp:
(WebCore::FrameLoader::changeLocation):
(WebCore::FrameLoader::submitForm):
(WebCore::FrameLoader::loadURL):
(WebCore::FrameLoader::loadWithNavigationAction):
(WebCore::FrameLoader::loadPostRequest):
(WebCore::FrameLoader::continueLoadAfterNewWindowPolicy):
* loader/NavigationAction.h:
(WebCore::NavigationAction::shouldReplaceDocumentIfJavaScriptURL const):
(WebCore::NavigationAction::setShouldReplaceDocumentIfJavaScriptURL):
* loader/NavigationScheduler.cpp:
(WebCore::NavigationScheduler::scheduleFormSubmission):

LayoutTests:

Add layout test coverage. I have verified that these tests are passing in both
Chrome 94 and Firefox 94.

* fast/frames/_javascript_-url-anchor-target-expected.txt: Added.
* fast/frames/_javascript_-url-anchor-target-new-window-expected.txt: Added.
* fast/frames/_javascript_-url-anchor-target-new-window.html: Added.
* fast/frames/_javascript_-url-anchor-target.html: Added.
* fast/frames/_javascript_-url-form-target-expected.txt: Added.
* fast/frames/_javascript_-url-form-target-new-window-expected.txt: Added.
* fast/frames/_javascript_-url-form-target-new-window.html: Added.
* fast/frames/_javascript_-url-form-target.html: Added.

Modified Paths

Added Paths

Diff

Modified: trunk/LayoutTests/ChangeLog (285213 => 285214)


--- trunk/LayoutTests/ChangeLog	2021-11-03 17:05:50 UTC (rev 285213)
+++ trunk/LayoutTests/ChangeLog	2021-11-03 17:28:39 UTC (rev 285214)
@@ -1,3 +1,22 @@
+2021-11-03  Chris Dumez  <cdu...@apple.com>
+
+        _javascript_ URLs do not run in the right context when using frame targeting
+        https://bugs.webkit.org/show_bug.cgi?id=232382
+
+        Reviewed by Alex Christensen.
+
+        Add layout test coverage. I have verified that these tests are passing in both
+        Chrome 94 and Firefox 94.
+
+        * fast/frames/_javascript_-url-anchor-target-expected.txt: Added.
+        * fast/frames/_javascript_-url-anchor-target-new-window-expected.txt: Added.
+        * fast/frames/_javascript_-url-anchor-target-new-window.html: Added.
+        * fast/frames/_javascript_-url-anchor-target.html: Added.
+        * fast/frames/_javascript_-url-form-target-expected.txt: Added.
+        * fast/frames/_javascript_-url-form-target-new-window-expected.txt: Added.
+        * fast/frames/_javascript_-url-form-target-new-window.html: Added.
+        * fast/frames/_javascript_-url-form-target.html: Added.
+
 2021-11-03  Simon Fraser  <simon.fra...@apple.com>
 
         Expose fuzzy match data in layout test results

Added: trunk/LayoutTests/fast/frames/_javascript_-url-anchor-target-expected.txt (0 => 285214)


--- trunk/LayoutTests/fast/frames/_javascript_-url-anchor-target-expected.txt	                        (rev 0)
+++ trunk/LayoutTests/fast/frames/_javascript_-url-anchor-target-expected.txt	2021-11-03 17:28:39 UTC (rev 285214)
@@ -0,0 +1,10 @@
+Tests that _javascript_ URL execute in the right context when set as href on an anchor with a target frame.
+
+On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
+
+
+PASS contextName is "testFrame"
+PASS successfullyParsed is true
+
+TEST COMPLETE
+

Added: trunk/LayoutTests/fast/frames/_javascript_-url-anchor-target-new-window-expected.txt (0 => 285214)


--- trunk/LayoutTests/fast/frames/_javascript_-url-anchor-target-new-window-expected.txt	                        (rev 0)
+++ trunk/LayoutTests/fast/frames/_javascript_-url-anchor-target-new-window-expected.txt	2021-11-03 17:28:39 UTC (rev 285214)
@@ -0,0 +1,10 @@
+Tests that _javascript_ URL execute in the right context when set as href on an anchor with a target popup.
+
+On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
+
+
+PASS contextName is "testPopup"
+PASS successfullyParsed is true
+
+TEST COMPLETE
+

Added: trunk/LayoutTests/fast/frames/_javascript_-url-anchor-target-new-window.html (0 => 285214)


--- trunk/LayoutTests/fast/frames/_javascript_-url-anchor-target-new-window.html	                        (rev 0)
+++ trunk/LayoutTests/fast/frames/_javascript_-url-anchor-target-new-window.html	2021-11-03 17:28:39 UTC (rev 285214)
@@ -0,0 +1,24 @@
+<!DOCTYPE html>
+<html>
+<body>
+<script src=""
+<script>
+description("Tests that _javascript_ URL execute in the right context when set as href on an anchor with a target popup.");
+jsTestIsAsync = true;
+
+function didRunJSURLInContext(_contextName)
+{
+    contextName = _contextName;
+    // Since the anchor has target="testPopup", the _javascript_ URL should execute in the context of the popup, not the top frame.
+    shouldBeEqualToString("contextName", "testPopup");
+    finishJSTest();
+}
+
+_onload_ = () => {
+    window.name = "topWindow";
+    document.getElementById("testAnchor").click();
+};
+</script>
+<a id="testAnchor" target="testPopup" href="" style="display:none">Click me</a>
+</body>
+</html>

Added: trunk/LayoutTests/fast/frames/_javascript_-url-anchor-target.html (0 => 285214)


--- trunk/LayoutTests/fast/frames/_javascript_-url-anchor-target.html	                        (rev 0)
+++ trunk/LayoutTests/fast/frames/_javascript_-url-anchor-target.html	2021-11-03 17:28:39 UTC (rev 285214)
@@ -0,0 +1,25 @@
+<!DOCTYPE html>
+<html>
+<body>
+<script src=""
+<script>
+description("Tests that _javascript_ URL execute in the right context when set as href on an anchor with a target frame.");
+jsTestIsAsync = true;
+
+function didRunJSURLInContext(_contextName)
+{
+    contextName = _contextName;
+    // Since the anchor has target="testFrame", the _javascript_ URL should execute in the context of the testFrame, not the top frame.
+    shouldBeEqualToString("contextName", "testFrame");
+    finishJSTest();
+}
+
+_onload_ = () => {
+    window.name = "topWindow";
+    document.getElementById("testAnchor").click();
+};
+</script>
+<iframe id="testFrame" name="testFrame"></iframe>
+<a id="testAnchor" target="testFrame" href="" style="display:none">Click me</a>
+</body>
+</html>

Added: trunk/LayoutTests/fast/frames/_javascript_-url-form-target-expected.txt (0 => 285214)


--- trunk/LayoutTests/fast/frames/_javascript_-url-form-target-expected.txt	                        (rev 0)
+++ trunk/LayoutTests/fast/frames/_javascript_-url-form-target-expected.txt	2021-11-03 17:28:39 UTC (rev 285214)
@@ -0,0 +1,11 @@
+Tests that _javascript_ URL execute in the right context when set as action on a form with a target frame.
+
+On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
+
+
+PASS contextName is "testFrame"
+PASS successfullyParsed is true
+
+TEST COMPLETE
+
+

Added: trunk/LayoutTests/fast/frames/_javascript_-url-form-target-new-window-expected.txt (0 => 285214)


--- trunk/LayoutTests/fast/frames/_javascript_-url-form-target-new-window-expected.txt	                        (rev 0)
+++ trunk/LayoutTests/fast/frames/_javascript_-url-form-target-new-window-expected.txt	2021-11-03 17:28:39 UTC (rev 285214)
@@ -0,0 +1,10 @@
+Tests that _javascript_ URL execute in the right context when set as action on a form with a target popup.
+
+On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
+
+
+PASS contextName is "testPopup"
+PASS successfullyParsed is true
+
+TEST COMPLETE
+

Added: trunk/LayoutTests/fast/frames/_javascript_-url-form-target-new-window.html (0 => 285214)


--- trunk/LayoutTests/fast/frames/_javascript_-url-form-target-new-window.html	                        (rev 0)
+++ trunk/LayoutTests/fast/frames/_javascript_-url-form-target-new-window.html	2021-11-03 17:28:39 UTC (rev 285214)
@@ -0,0 +1,26 @@
+<!DOCTYPE html>
+<html>
+<body>
+<script src=""
+<script>
+description("Tests that _javascript_ URL execute in the right context when set as action on a form with a target popup.");
+jsTestIsAsync = true;
+
+function didRunJSURLInContext(_contextName)
+{
+    contextName = _contextName;
+    // Since the form has target="testPopup", the _javascript_ URL should execute in the context of the popup, not the top frame.
+    shouldBeEqualToString("contextName", "testPopup");
+    finishJSTest();
+}
+
+_onload_ = () => {
+    window.name = "topWindow";
+    document.getElementById("submitButton").click();
+};
+</script>
+<form id="testAnchor" target="testPopup" action=""
+<input id="submitButton" type="submit" value="Click me"></input>
+</form>
+</body>
+</html>

Added: trunk/LayoutTests/fast/frames/_javascript_-url-form-target.html (0 => 285214)


--- trunk/LayoutTests/fast/frames/_javascript_-url-form-target.html	                        (rev 0)
+++ trunk/LayoutTests/fast/frames/_javascript_-url-form-target.html	2021-11-03 17:28:39 UTC (rev 285214)
@@ -0,0 +1,27 @@
+<!DOCTYPE html>
+<html>
+<body>
+<script src=""
+<script>
+description("Tests that _javascript_ URL execute in the right context when set as action on a form with a target frame.");
+jsTestIsAsync = true;
+
+function didRunJSURLInContext(_contextName)
+{
+    contextName = _contextName;
+    // Since the form has target="testFrame", the _javascript_ URL should execute in the context of the testFrame, not the top frame.
+    shouldBeEqualToString("contextName", "testFrame");
+    finishJSTest();
+}
+
+_onload_ = () => {
+    window.name = "topWindow";
+    document.getElementById("submitButton").click();
+};
+</script>
+<iframe id="testFrame" name="testFrame"></iframe>
+<form id="testAnchor" target="testFrame" action=""
+<input id="submitButton" type="submit" value="Click me"></input>
+</form>
+</body>
+</html>

Modified: trunk/LayoutTests/http/tests/security/contentSecurityPolicy/_javascript_-url-allowed-expected.txt (285213 => 285214)


--- trunk/LayoutTests/http/tests/security/contentSecurityPolicy/_javascript_-url-allowed-expected.txt	2021-11-03 17:05:50 UTC (rev 285213)
+++ trunk/LayoutTests/http/tests/security/contentSecurityPolicy/_javascript_-url-allowed-expected.txt	2021-11-03 17:28:39 UTC (rev 285214)
@@ -1,7 +1,5 @@
 CONSOLE MESSAGE: The 'allow' directive has been replaced with 'default-src'. Please use that directive instead, as 'allow' has no effect.
 CONSOLE MESSAGE: The 'allow' directive has been replaced with 'default-src'. Please use that directive instead, as 'allow' has no effect.
 CONSOLE MESSAGE: The 'allow' directive has been replaced with 'default-src'. Please use that directive instead, as 'allow' has no effect.
-CONSOLE MESSAGE: The 'allow' directive has been replaced with 'default-src'. Please use that directive instead, as 'allow' has no effect.
-CONSOLE MESSAGE: The 'allow' directive has been replaced with 'default-src'. Please use that directive instead, as 'allow' has no effect.
 ALERT: PASS
 

Modified: trunk/LayoutTests/http/tests/security/contentSecurityPolicy/_javascript_-url-blocked-expected.txt (285213 => 285214)


--- trunk/LayoutTests/http/tests/security/contentSecurityPolicy/_javascript_-url-blocked-expected.txt	2021-11-03 17:05:50 UTC (rev 285213)
+++ trunk/LayoutTests/http/tests/security/contentSecurityPolicy/_javascript_-url-blocked-expected.txt	2021-11-03 17:28:39 UTC (rev 285214)
@@ -1,7 +1,5 @@
 CONSOLE MESSAGE: The 'allow' directive has been replaced with 'default-src'. Please use that directive instead, as 'allow' has no effect.
 CONSOLE MESSAGE: The 'allow' directive has been replaced with 'default-src'. Please use that directive instead, as 'allow' has no effect.
 CONSOLE MESSAGE: The 'allow' directive has been replaced with 'default-src'. Please use that directive instead, as 'allow' has no effect.
-CONSOLE MESSAGE: The 'allow' directive has been replaced with 'default-src'. Please use that directive instead, as 'allow' has no effect.
-CONSOLE MESSAGE: The 'allow' directive has been replaced with 'default-src'. Please use that directive instead, as 'allow' has no effect.
 CONSOLE MESSAGE: Refused to execute a script because its hash, its nonce, or 'unsafe-inline' does not appear in the script-src directive of the Content Security Policy.
 

Modified: trunk/LayoutTests/imported/w3c/ChangeLog (285213 => 285214)


--- trunk/LayoutTests/imported/w3c/ChangeLog	2021-11-03 17:05:50 UTC (rev 285213)
+++ trunk/LayoutTests/imported/w3c/ChangeLog	2021-11-03 17:28:39 UTC (rev 285214)
@@ -1,3 +1,15 @@
+2021-11-03  Chris Dumez  <cdu...@apple.com>
+
+        _javascript_ URLs do not run in the right context when using frame targeting
+        https://bugs.webkit.org/show_bug.cgi?id=232382
+
+        Reviewed by Alex Christensen.
+
+        * web-platform-tests/html/browsers/browsing-the-web/navigating-across-documents/010-expected.txt:
+        The test is no longer timing out now that we run the _javascript_ URL contained in the <form>'s action in the context
+        of the "test" iframe instead of the top frame. However, the test is still failing, possibly because the _javascript_
+        URL is run synchronously.
+
 2021-11-03  Antti Koivisto  <an...@apple.com>
 
         ::slotted element style not invalidated correctly in nested case

Modified: trunk/LayoutTests/imported/w3c/web-platform-tests/html/browsers/browsing-the-web/navigating-across-documents/010-expected.txt (285213 => 285214)


--- trunk/LayoutTests/imported/w3c/web-platform-tests/html/browsers/browsing-the-web/navigating-across-documents/010-expected.txt	2021-11-03 17:05:50 UTC (rev 285213)
+++ trunk/LayoutTests/imported/w3c/web-platform-tests/html/browsers/browsing-the-web/navigating-across-documents/010-expected.txt	2021-11-03 17:28:39 UTC (rev 285214)
@@ -1,5 +1,4 @@
 
-Harness Error (TIMEOUT), message = null
+FAIL Link with onclick form submit to _javascript_ url with delayed document.write and href navigation  assert_equals: expected "href" but got "write"
 
-TIMEOUT Link with onclick form submit to _javascript_ url with delayed document.write and href navigation  Test timed out
-
+Test

Modified: trunk/Source/WebCore/ChangeLog (285213 => 285214)


--- trunk/Source/WebCore/ChangeLog	2021-11-03 17:05:50 UTC (rev 285213)
+++ trunk/Source/WebCore/ChangeLog	2021-11-03 17:28:39 UTC (rev 285214)
@@ -1,3 +1,49 @@
+2021-11-03  Chris Dumez  <cdu...@apple.com>
+
+        _javascript_ URLs do not run in the right context when using frame targeting
+        https://bugs.webkit.org/show_bug.cgi?id=232382
+
+        Reviewed by Alex Christensen.
+
+        _javascript_ URLs did not run in the right context when using frame targeting
+        (e.g. `<a target="foo" src="" We would previously run the
+        _javascript_ URL in the context of the anchor instead of the target frame/window.
+
+        Also, we would fail to open a new popup when there is no existing frame with
+        the given target name.
+
+        This patch fixes the issue by doing the executeJavaScriptURL() call later,
+        inside of FrameLoader::loadWithNavigationAction(), once we've already resolved
+        the target frame and created a new window if necessary.
+
+        This aligns our behavior with both Chrome and Firefox.
+
+        Tests: fast/frames/_javascript_-url-anchor-target-new-window.html
+               fast/frames/_javascript_-url-anchor-target.html
+               fast/frames/_javascript_-url-form-target-new-window.html
+               fast/frames/_javascript_-url-form-target.html
+
+        * bindings/js/ScriptController.cpp:
+        (WebCore::ScriptController::executeJavaScriptURL):
+        * html/HTMLAnchorElement.cpp:
+        (WebCore::HTMLAnchorElement::handleClick):
+        * html/HTMLFormElement.cpp:
+        (WebCore::HTMLFormElement::submit):
+        * loader/FormSubmission.cpp:
+        (WebCore::FormSubmission::requestURL const):
+        * loader/FrameLoader.cpp:
+        (WebCore::FrameLoader::changeLocation):
+        (WebCore::FrameLoader::submitForm):
+        (WebCore::FrameLoader::loadURL):
+        (WebCore::FrameLoader::loadWithNavigationAction):
+        (WebCore::FrameLoader::loadPostRequest):
+        (WebCore::FrameLoader::continueLoadAfterNewWindowPolicy):
+        * loader/NavigationAction.h:
+        (WebCore::NavigationAction::shouldReplaceDocumentIfJavaScriptURL const):
+        (WebCore::NavigationAction::setShouldReplaceDocumentIfJavaScriptURL):
+        * loader/NavigationScheduler.cpp:
+        (WebCore::NavigationScheduler::scheduleFormSubmission):
+
 2021-11-03  Antti Koivisto  <an...@apple.com>
 
         ::slotted element style not invalidated correctly in nested case

Modified: trunk/Source/WebCore/html/HTMLAnchorElement.cpp (285213 => 285214)


--- trunk/Source/WebCore/html/HTMLAnchorElement.cpp	2021-11-03 17:05:50 UTC (rev 285213)
+++ trunk/Source/WebCore/html/HTMLAnchorElement.cpp	2021-11-03 17:28:39 UTC (rev 285214)
@@ -528,7 +528,7 @@
 
     auto effectiveTarget = this->effectiveTarget();
     NewFrameOpenerPolicy newFrameOpenerPolicy = NewFrameOpenerPolicy::Allow;
-    if (hasRel(Relation::NoOpener) || hasRel(Relation::NoReferrer) || (!hasRel(Relation::Opener) && document().settings().blankAnchorTargetImpliesNoOpenerEnabled() && isBlankTargetFrameName(effectiveTarget)))
+    if (hasRel(Relation::NoOpener) || hasRel(Relation::NoReferrer) || (!hasRel(Relation::Opener) && document().settings().blankAnchorTargetImpliesNoOpenerEnabled() && isBlankTargetFrameName(effectiveTarget) && !completedURL.protocolIsJavaScript()))
         newFrameOpenerPolicy = NewFrameOpenerPolicy::Suppress;
 
     auto privateClickMeasurement = parsePrivateClickMeasurement();

Modified: trunk/Source/WebCore/html/HTMLFormElement.cpp (285213 => 285214)


--- trunk/Source/WebCore/html/HTMLFormElement.cpp	2021-11-03 17:05:50 UTC (rev 285213)
+++ trunk/Source/WebCore/html/HTMLFormElement.cpp	2021-11-03 17:28:39 UTC (rev 285214)
@@ -428,7 +428,7 @@
         return;
 
     auto relAttributes = parseFormRelAttributes(getAttribute(HTMLNames::relAttr));
-    if (relAttributes.noopener || relAttributes.noreferrer || (!relAttributes.opener && document().settings().blankAnchorTargetImpliesNoOpenerEnabled() && isBlankTargetFrameName(formSubmission->target())))
+    if (relAttributes.noopener || relAttributes.noreferrer || (!relAttributes.opener && document().settings().blankAnchorTargetImpliesNoOpenerEnabled() && isBlankTargetFrameName(formSubmission->target()) && !formSubmission->requestURL().protocolIsJavaScript()))
         formSubmission->setNewFrameOpenerPolicy(NewFrameOpenerPolicy::Suppress);
     if (relAttributes.noreferrer)
         formSubmission->setReferrerPolicy(ReferrerPolicy::NoReferrer);

Modified: trunk/Source/WebCore/loader/FormSubmission.cpp (285213 => 285214)


--- trunk/Source/WebCore/loader/FormSubmission.cpp	2021-11-03 17:05:50 UTC (rev 285213)
+++ trunk/Source/WebCore/loader/FormSubmission.cpp	2021-11-03 17:28:39 UTC (rev 285214)
@@ -246,7 +246,8 @@
         return m_action;
 
     URL requestURL(m_action);
-    requestURL.setQuery(m_formData->flattenToString());
+    if (!requestURL.protocolIsJavaScript())
+        requestURL.setQuery(m_formData->flattenToString());
     return requestURL;
 }
 

Modified: trunk/Source/WebCore/loader/FrameLoader.cpp (285213 => 285214)


--- trunk/Source/WebCore/loader/FrameLoader.cpp	2021-11-03 17:05:50 UTC (rev 285213)
+++ trunk/Source/WebCore/loader/FrameLoader.cpp	2021-11-03 17:28:39 UTC (rev 285214)
@@ -446,12 +446,6 @@
 
     Ref<Frame> protect(m_frame);
 
-    if (frameRequest.resourceRequest().url().protocolIsJavaScript()) {
-        m_frame.script().executeJavaScriptURL(frameRequest.resourceRequest().url(), &frameRequest.requester().securityOrigin(), frameRequest.shouldReplaceDocumentIfJavaScriptURL());
-        m_quickRedirectComing = false;
-        return;
-    }
-
     if (frameRequest.frameName().isEmpty())
         frameRequest.setFrameName(m_frame.document()->baseTarget());
 
@@ -483,14 +477,6 @@
     if (!m_frame.document()->contentSecurityPolicy()->allowFormAction(formAction))
         return;
 
-    if (formAction.protocolIsJavaScript()) {
-        m_isExecutingJavaScriptFormAction = true;
-        Ref<Frame> protect(m_frame);
-        m_frame.script().executeJavaScriptURL(submission->action(), nullptr, DoNotReplaceDocumentIfJavaScriptURL);
-        m_isExecutingJavaScriptFormAction = false;
-        return;
-    }
-
     Frame* targetFrame = findFrameForNavigation(submission->target(), &submission->state().sourceDocument());
     if (!targetFrame) {
         if (!DOMWindow::allowPopUp(m_frame) && !UserGestureIndicator::processingUserGesture())
@@ -1366,6 +1352,7 @@
     NavigationAction action { frameLoadRequest.requester(), request, frameLoadRequest.initiatedByMainFrame(), newLoadType, isFormSubmission, event, frameLoadRequest.shouldOpenExternalURLsPolicy(), frameLoadRequest.downloadAttribute() };
     action.setLockHistory(frameLoadRequest.lockHistory());
     action.setLockBackForwardList(frameLoadRequest.lockBackForwardList());
+    action.setShouldReplaceDocumentIfJavaScriptURL(frameLoadRequest.shouldReplaceDocumentIfJavaScriptURL());
     if (privateClickMeasurement && m_frame.isMainFrame())
         action.setPrivateClickMeasurement(WTFMove(*privateClickMeasurement));
 
@@ -1496,6 +1483,12 @@
 {
     FRAMELOADER_RELEASE_LOG(ResourceLoading, "loadWithNavigationAction: frame load started");
 
+    if (request.url().protocolIsJavaScript()) {
+        m_frame.script().executeJavaScriptURL(request.url(), action.requester() ? action.requester()->securityOrigin.ptr() : nullptr, action.shouldReplaceDocumentIfJavaScriptURL());
+        m_quickRedirectComing = false;
+        return completionHandler();
+    }
+
     Ref<DocumentLoader> loader = m_client->createDocumentLoader(request, defaultSubstituteDataForURL(request.url()));
     applyShouldOpenExternalURLsPolicyToNewDocumentLoader(m_frame, loader, action.initiatedByMainFrame(), action.shouldOpenExternalURLsPolicy());
 
@@ -3072,6 +3065,7 @@
 
     NavigationAction action { request.requester(), workingResourceRequest, request.initiatedByMainFrame(), loadType, true, event, request.shouldOpenExternalURLsPolicy(), { } };
     action.setLockHistory(lockHistory);
+    action.setShouldReplaceDocumentIfJavaScriptURL(request.shouldReplaceDocumentIfJavaScriptURL());
 
     if (!frameName.isEmpty()) {
         // The search for a target frame is done earlier in the case of form submission.
@@ -3566,6 +3560,10 @@
         return;
 
     Ref<Frame> frame(m_frame);
+
+    if (request.url().protocolIsJavaScript() && !frame->document()->contentSecurityPolicy()->allowJavaScriptURLs(frame->document()->url().string(), { }, request.url().string()))
+        return;
+
     RefPtr<Frame> mainFrame = m_client->dispatchCreatePage(action, openerPolicy);
     if (!mainFrame)
         return;
@@ -3585,6 +3583,7 @@
     }
 
     NavigationAction newAction { *frame->document(), request, InitiatedByMainFrame::Unknown, NavigationType::Other, action.shouldOpenExternalURLsPolicy(), nullptr, action.downloadAttribute() };
+    newAction.setShouldReplaceDocumentIfJavaScriptURL(action.shouldReplaceDocumentIfJavaScriptURL());
     mainFrame->loader().loadWithNavigationAction(request, WTFMove(newAction), FrameLoadType::Standard, formState, allowNavigationToInvalidURL);
 }
 

Modified: trunk/Source/WebCore/loader/NavigationAction.h (285213 => 285214)


--- trunk/Source/WebCore/loader/NavigationAction.h	2021-11-03 17:05:50 UTC (rev 285213)
+++ trunk/Source/WebCore/loader/NavigationAction.h	2021-11-03 17:28:39 UTC (rev 285214)
@@ -129,6 +129,11 @@
     const std::optional<PrivateClickMeasurement>& privateClickMeasurement() const { return m_privateClickMeasurement; };
     void setPrivateClickMeasurement(PrivateClickMeasurement&& privateClickMeasurement) { m_privateClickMeasurement = privateClickMeasurement; };
 
+    // The shouldReplaceDocumentIfJavaScriptURL parameter will go away when the FIXME to eliminate the
+    // corresponding parameter from ScriptController::executeIfJavaScriptURL() is addressed.
+    ShouldReplaceDocumentIfJavaScriptURL shouldReplaceDocumentIfJavaScriptURL() const { return m_shouldReplaceDocumentIfJavaScriptURL; }
+    void setShouldReplaceDocumentIfJavaScriptURL(ShouldReplaceDocumentIfJavaScriptURL shouldReplaceDocumentIfJavaScriptURL) { m_shouldReplaceDocumentIfJavaScriptURL = shouldReplaceDocumentIfJavaScriptURL; }
+
 private:
     // Do not add a strong reference to the originating document or a subobject that holds the
     // originating document. See comment above the class for more details.
@@ -149,6 +154,7 @@
     LockHistory m_lockHistory { LockHistory::No };
     LockBackForwardList m_lockBackForwardList { LockBackForwardList::No };
     std::optional<PrivateClickMeasurement> m_privateClickMeasurement;
+    ShouldReplaceDocumentIfJavaScriptURL m_shouldReplaceDocumentIfJavaScriptURL { ReplaceDocumentIfJavaScriptURL };
 };
 
 } // namespace WebCore

Modified: trunk/Source/WebCore/loader/NavigationScheduler.cpp (285213 => 285214)


--- trunk/Source/WebCore/loader/NavigationScheduler.cpp	2021-11-03 17:05:50 UTC (rev 285213)
+++ trunk/Source/WebCore/loader/NavigationScheduler.cpp	2021-11-03 17:28:39 UTC (rev 285214)
@@ -318,6 +318,7 @@
         frameLoadRequest.setReferrerPolicy(m_submission->referrerPolicy());
         frameLoadRequest.setNewFrameOpenerPolicy(m_submission->newFrameOpenerPolicy());
         frameLoadRequest.setShouldOpenExternalURLsPolicy(shouldOpenExternalURLs());
+        frameLoadRequest.disableShouldReplaceDocumentIfJavaScriptURL();
         m_submission->populateFrameLoadRequest(frameLoadRequest);
         frame.loader().loadFrameRequest(WTFMove(frameLoadRequest), m_submission->event(), m_submission->takeState());
     }
@@ -505,8 +506,18 @@
         && (submission->state().formSubmissionTrigger() == SubmittedByJavaScript && m_frame.tree().parent() && !UserGestureIndicator::processingUserGesture())) {
         lockBackForwardList = LockBackForwardList::Yes;
     }
+
+    bool isJavaScriptURL = submission->requestURL().protocolIsJavaScript();
+
+    auto scheduledFormSubmission = makeUnique<ScheduledFormSubmission>(WTFMove(submission), lockBackForwardList, duringLoad);
+
+    // FIXME: We currently run _javascript_ URLs synchronously even though this doesn't appear to match the specification.
+    if (isJavaScriptURL) {
+        scheduledFormSubmission->fire(m_frame);
+        return;
+    }
     
-    schedule(makeUnique<ScheduledFormSubmission>(WTFMove(submission), lockBackForwardList, duringLoad));
+    schedule(WTFMove(scheduledFormSubmission));
 }
 
 void NavigationScheduler::scheduleRefresh(Document& initiatingDocument)

Modified: trunk/Source/WebCore/loader/SubframeLoader.cpp (285213 => 285214)


--- trunk/Source/WebCore/loader/SubframeLoader.cpp	2021-11-03 17:05:50 UTC (rev 285213)
+++ trunk/Source/WebCore/loader/SubframeLoader.cpp	2021-11-03 17:28:39 UTC (rev 285214)
@@ -223,6 +223,10 @@
 
     document.contentSecurityPolicy()->upgradeInsecureRequestIfNeeded(completedURL, ContentSecurityPolicy::InsecureRequestType::Load);
 
+    // Historically, we haven't run _javascript_ URLs in <embed> / <object> elements.
+    if (completedURL.protocolIsJavaScript())
+        return false;
+
     bool hasFallbackContent = is<HTMLObjectElement>(ownerElement) && downcast<HTMLObjectElement>(ownerElement).hasFallbackContent();
 
     bool useFallback;
_______________________________________________
webkit-changes mailing list
webkit-changes@lists.webkit.org
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to