WebKit Bugzilla
Attachment 368732 Details for
Bug 197466
: Setting a frame's src to a javascript URL should not run it synchronously
Home
|
New
|
Browse
|
Search
|
[?]
|
Reports
|
Requests
|
Help
|
New Account
|
Log In
Remember
[x]
|
Forgot Password
Login:
[x]
[patch]
WiP Patch
197466_javascript_url_async_wip.patch (text/plain), 25.65 KB, created by
Chris Dumez
on 2019-05-01 16:27:49 PDT
(
hide
)
Description:
WiP Patch
Filename:
MIME Type:
Creator:
Chris Dumez
Created:
2019-05-01 16:27:49 PDT
Size:
25.65 KB
patch
obsolete
>diff --git a/LayoutTests/editing/pasteboard/paste-noscript-xhtml.xhtml b/LayoutTests/editing/pasteboard/paste-noscript-xhtml.xhtml >index b896029c934..56ec71cbefb 100644 >--- a/LayoutTests/editing/pasteboard/paste-noscript-xhtml.xhtml >+++ b/LayoutTests/editing/pasteboard/paste-noscript-xhtml.xhtml >@@ -27,7 +27,9 @@ function runTest() { > document.execCommand("Paste"); > Markup.dump('pastehere', 'Pasted content'); > >- Markup.notifyDone(); >+ setTimeout(() => { >+ Markup.notifyDone(); >+ }, 0); > } > > </script> >diff --git a/LayoutTests/fast/dom/Attr/only-attach-attr-once.html b/LayoutTests/fast/dom/Attr/only-attach-attr-once.html >index 6ad40d1feac..f992f37d0e4 100644 >--- a/LayoutTests/fast/dom/Attr/only-attach-attr-once.html >+++ b/LayoutTests/fast/dom/Attr/only-attach-attr-once.html >@@ -6,12 +6,14 @@ > <body> > <script> > description("Test that we properly handle attempts to attach an Attribute to the same node multiple times. Test passes if there is no Debug ASSERT."); >+jsTestIsAsync = true; > > window.callback = () => { > window.callback = null; > > shouldThrowErrorName("div.setAttributeNodeNS(src)", "InUseAttributeError"); > frame.setAttributeNodeNS(document.createAttribute('src')); >+ finishJSTest(); > }; > > let src = document.createAttribute('src'); >diff --git a/LayoutTests/fast/dom/Element/id-in-frameset-expected.txt b/LayoutTests/fast/dom/Element/id-in-frameset-expected.txt >index b3db1a31442..a71080b1b06 100644 >--- a/LayoutTests/fast/dom/Element/id-in-frameset-expected.txt >+++ b/LayoutTests/fast/dom/Element/id-in-frameset-expected.txt >@@ -1,2 +1,2 @@ >-ALERT: 1 >+ALERT: 2 > >diff --git a/LayoutTests/fast/dom/Element/id-in-frameset.html b/LayoutTests/fast/dom/Element/id-in-frameset.html >index 79165352966..9b632037d99 100644 >--- a/LayoutTests/fast/dom/Element/id-in-frameset.html >+++ b/LayoutTests/fast/dom/Element/id-in-frameset.html >@@ -1,5 +1,10 @@ > <html> >- >+<script> >+if (window.testRunner) { >+ testRunner.dumpAsText(); >+ testRunner.waitUntilDone(); >+} >+</script> > <frameset id="frameset"> > <frame name="frame2" src="about:blank"> > <frame name="frame1" src="javascript: >@@ -16,6 +21,8 @@ > > top.frameset.removeChild(top.frame2.frameElement); > log(top.frameset.children.length); >+ if (window.testRunner) >+ testRunner.notifyDone(); > "> > > <frame name="frame3" src="about:blank"> >diff --git a/LayoutTests/fast/dom/frame-src-javascript-url-async-expected.txt b/LayoutTests/fast/dom/frame-src-javascript-url-async-expected.txt >new file mode 100644 >index 00000000000..0a63862923b >--- /dev/null >+++ b/LayoutTests/fast/dom/frame-src-javascript-url-async-expected.txt >@@ -0,0 +1,10 @@ >+Checks that setting an iframe's src attribute to a javascript URL runs the javascript asynchronously >+ >+On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE". >+ >+ >+PASS messages is "1234" >+PASS successfullyParsed is true >+ >+TEST COMPLETE >+ >diff --git a/LayoutTests/fast/dom/frame-src-javascript-url-async.html b/LayoutTests/fast/dom/frame-src-javascript-url-async.html >new file mode 100644 >index 00000000000..022ee9e90dc >--- /dev/null >+++ b/LayoutTests/fast/dom/frame-src-javascript-url-async.html >@@ -0,0 +1,28 @@ >+<!DOCTYPE html> >+<html> >+<body> >+<script src="../../resources/js-test.js"></script> >+<script> >+description("Checks that setting an iframe's src attribute to a javascript URL runs the javascript asynchronously"); >+jsTestIsAsync = true; >+ >+let messages = ""; >+const expectedMessageCount = 4; >+function log(msg) >+{ >+ messages += msg; >+ if (messages.length == expectedMessageCount) { >+ shouldBeEqualToString("messages", "1234"); >+ finishJSTest(); >+ } >+} >+</script> >+<iframe src="javascript:parent.log('3')"></iframe> >+<iframe id="testFrame"></iframe> >+<script> >+log('1'); >+testFrame.src = "javascript:parent.log('4')"; >+log('2'); >+</script> >+</body> >+</html> >diff --git a/LayoutTests/fast/dom/insertedIntoDocument-iframe-expected.txt b/LayoutTests/fast/dom/insertedIntoDocument-iframe-expected.txt >index 7ef22e9a431..6e1f6dfd9e6 100644 >--- a/LayoutTests/fast/dom/insertedIntoDocument-iframe-expected.txt >+++ b/LayoutTests/fast/dom/insertedIntoDocument-iframe-expected.txt >@@ -1 +1,3 @@ >+CONSOLE MESSAGE: line 1: TypeError: Argument 1 ('child') to Node.removeChild must be an instance of Node > PASS >+ >diff --git a/LayoutTests/fast/dom/javascript-url-exception-isolation-expected.txt b/LayoutTests/fast/dom/javascript-url-exception-isolation-expected.txt >index 51b343549ee..b7485a1ef6b 100644 >--- a/LayoutTests/fast/dom/javascript-url-exception-isolation-expected.txt >+++ b/LayoutTests/fast/dom/javascript-url-exception-isolation-expected.txt >@@ -1,5 +1,5 @@ > CONSOLE MESSAGE: line 1: 42 >-CONSOLE MESSAGE: line 25: SyntaxError: Unexpected token '<' >+CONSOLE MESSAGE: line 1: SyntaxError: Unexpected token '<' > Exceptions thrown in javascript URLs should not propagate to the main script. > > On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE". >diff --git a/LayoutTests/fast/dom/javascript-url-exception-isolation.html b/LayoutTests/fast/dom/javascript-url-exception-isolation.html >index 6f39b2cb9a6..858e590b3a5 100644 >--- a/LayoutTests/fast/dom/javascript-url-exception-isolation.html >+++ b/LayoutTests/fast/dom/javascript-url-exception-isolation.html >@@ -6,6 +6,7 @@ > <body> > <script> > description("Exceptions thrown in javascript URLs should not propagate to the main script.") >+jsTestIsAsync = true; > > var subframe = document.createElement("iframe"); > document.body.appendChild(subframe); >@@ -20,13 +21,16 @@ try { > } > shouldBeFalse('caughtException'); > >-// Compile-time exception. >-try { >- subframe.src = 'javascript:<html></html>'; >-} catch(e) { >- caughtException = true; >-} >-shouldBeFalse('caughtException'); >+setTimeout(() => { >+ // Compile-time exception. >+ try { >+ subframe.src = 'javascript:<html></html>'; >+ } catch(e) { >+ caughtException = true; >+ } >+ shouldBeFalse('caughtException'); >+ setTimeout(finishJSTest, 0); >+}, 0); > </script> > <script src="../../resources/js-test-post.js"></script> > </body> >diff --git a/LayoutTests/fast/dom/no-assert-for-malformed-js-url-attribute-expected.txt b/LayoutTests/fast/dom/no-assert-for-malformed-js-url-attribute-expected.txt >index e96375ae81d..2cb8efa3c99 100644 >--- a/LayoutTests/fast/dom/no-assert-for-malformed-js-url-attribute-expected.txt >+++ b/LayoutTests/fast/dom/no-assert-for-malformed-js-url-attribute-expected.txt >@@ -1,4 +1,4 @@ >-CONSOLE MESSAGE: line 14: SyntaxError: Unexpected identifier 'orem' >+CONSOLE MESSAGE: line 1: SyntaxError: Unexpected identifier 'orem' > This tests that we do not assert when a malformed JS URL is passed to the 'src' attribute of an iframe. The test passes if it does not ASSERT. > > On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE". >diff --git a/LayoutTests/fast/dom/no-assert-for-malformed-js-url-attribute.html b/LayoutTests/fast/dom/no-assert-for-malformed-js-url-attribute.html >index b6420405b41..3a48f738475 100644 >--- a/LayoutTests/fast/dom/no-assert-for-malformed-js-url-attribute.html >+++ b/LayoutTests/fast/dom/no-assert-for-malformed-js-url-attribute.html >@@ -5,8 +5,10 @@ > <script> > description("This tests that we do not assert when a malformed JS URL is passed to the 'src' attribute of an iframe. The test passes if it does not ASSERT."); > >-if (window.testRunner) >+if (window.testRunner) { > testRunner.dumpAsText(); >+ testRunner.waitUntilDone(); >+} > > function runTest() > { >@@ -15,6 +17,11 @@ function runTest() > > var testFrame2 = document.getElementById('testFrame2'); > testFrame2.getAttributeNode("src").value += "javascript:missingFunction(this) orem ipsum dosolorem"; >+ >+ setTimeout(() => { >+ if (window.testRunner) >+ testRunner.notifyDone(); >+ }, 0); > } > </script> > </head> >diff --git a/LayoutTests/fast/dom/resources/javascript-url-crash-function-iframe.html b/LayoutTests/fast/dom/resources/javascript-url-crash-function-iframe.html >index 1d6a49d827f..0a0154c4c25 100644 >--- a/LayoutTests/fast/dom/resources/javascript-url-crash-function-iframe.html >+++ b/LayoutTests/fast/dom/resources/javascript-url-crash-function-iframe.html >@@ -16,7 +16,9 @@ function test() > setTimeout(function () > { > test(); >- if (window.testRunner) >- testRunner.notifyDone(); >+ top.setTimeout(() => { >+ if (window.testRunner) >+ testRunner.notifyDone(); >+ }, 0); > }, 0); > </script> >diff --git a/LayoutTests/fast/frames/adopt-from-created-document.html b/LayoutTests/fast/frames/adopt-from-created-document.html >index 2a9829b0c0e..33855d562b3 100644 >--- a/LayoutTests/fast/frames/adopt-from-created-document.html >+++ b/LayoutTests/fast/frames/adopt-from-created-document.html >@@ -8,10 +8,10 @@ var doc = document.implementation.createDocument('http://www.w3.org/1999/xhtml', > alert(2); > var ifr = doc.createElement('iframe'); > alert(3); >-ifr.setAttribute('src', 'javascript:alert(6)'); >+ifr.setAttribute('src', 'javascript:alert(7)'); > alert(4); > var adopted = document.adoptNode(ifr) > alert(5); > document.body.appendChild(adopted); >-alert(7); >+alert(6); > </script> >diff --git a/LayoutTests/fast/frames/out-of-document-iframe-has-child-frame.html b/LayoutTests/fast/frames/out-of-document-iframe-has-child-frame.html >index e9e576beec0..8db38d75be7 100644 >--- a/LayoutTests/fast/frames/out-of-document-iframe-has-child-frame.html >+++ b/LayoutTests/fast/frames/out-of-document-iframe-has-child-frame.html >@@ -1,12 +1,13 @@ > <html> > <head> >-<script src="../../resources/js-test-pre.js"></script> >+<script src="../../resources/js-test.js"></script> > </head> > <body> > <div id="main"/> > <script> > description("This tests that several ways of making an iframe that isn't inserted into a document tree" > + " but has a child frame will fail."); >+jsTestIsAsync = true; > > main = document.getElementById("main"); > >@@ -44,9 +45,11 @@ try { > helperFrame.src = "javascript:top.container.removeChild(top.targetFrame3)"; > document.body.appendChild(container); > } catch (e) { } >-shouldBeTrue("targetFrame3.contentWindow == undefined"); > >-isSuccessfullyParsed(); >+setTimeout(() => { >+ shouldBeTrue("targetFrame3.contentWindow == undefined"); >+ finishJSTest(); >+}, 0); > </script> > </body> > </html> >diff --git a/LayoutTests/fast/loader/nested-document-handling.html b/LayoutTests/fast/loader/nested-document-handling.html >index 3e81697d537..ec9077708aa 100644 >--- a/LayoutTests/fast/loader/nested-document-handling.html >+++ b/LayoutTests/fast/loader/nested-document-handling.html >@@ -24,25 +24,27 @@ function runTest() { > aFrame.contentWindow.onunload = () => { > topFrame.src = "javascript:''"; > >- let bFrame = topFrame.contentDocument.appendChild(document.createElement("iframe")); >- bFrame.id = 'bFrame'; >+ topFrame.onload = () => { >+ let bFrame = topFrame.contentDocument.body.appendChild(document.createElement("iframe")); >+ bFrame.id = 'bFrame'; > >- bFrame.contentWindow.onunload = () => { >- topFrame.src = "javascript:''"; >+ bFrame.contentWindow.onunload = () => { >+ topFrame.src = "javascript:''"; > >- let doc = topFrame.contentDocument; >+ let doc = topFrame.contentDocument; > >- topFrame.onload = () => { > topFrame.onload = () => { >- topFrame.onload = null; >- let s = doc.createElement("form"); >- s.action = "javascript:alert(location)"; >- s.submit(); >+ topFrame.onload = () => { >+ topFrame.onload = null; >+ let s = doc.createElement("form"); >+ s.action = "javascript:alert(location)"; >+ s.submit(); >+ }; >+ >+ topFrame.src = "resources/subframe-success.html"; > }; >- >- topFrame.src = "resources/subframe-success.html"; > }; >- >+ topFrame.src = "javascript:''"; > }; > }; > >@@ -52,4 +54,4 @@ function runTest() { > </head> > <body onload="runTest()"> > </body> >-</html> >\ No newline at end of file >+</html> >diff --git a/LayoutTests/fast/loader/unload-mutation-crash.html b/LayoutTests/fast/loader/unload-mutation-crash.html >index 246fe169227..c78db43d468 100644 >--- a/LayoutTests/fast/loader/unload-mutation-crash.html >+++ b/LayoutTests/fast/loader/unload-mutation-crash.html >@@ -2,8 +2,10 @@ > <html> > <head> > <script> >-if (window.testRunner) >- window.testRunner.dumpAsText(); >+if (window.testRunner) { >+ testRunner.dumpAsText(); >+ testRunner.waitUntilDone(); >+} > > function start() { > window.firstFrame = document.createElement('iframe'); >@@ -20,6 +22,8 @@ function maybeStart() { > > window.firstFrame.src = 'javascript:"";'; > document.write("PASS. WebKit didn't crash."); >+ if (window.testRunner) >+ testRunner.notifyDone(); > } > </script> > </head> >diff --git a/LayoutTests/fast/parser/resources/set-parent-to-javascript-url.html b/LayoutTests/fast/parser/resources/set-parent-to-javascript-url.html >index 71d78bf68f3..4f1ebdd0301 100644 >--- a/LayoutTests/fast/parser/resources/set-parent-to-javascript-url.html >+++ b/LayoutTests/fast/parser/resources/set-parent-to-javascript-url.html >@@ -1,7 +1,7 @@ > <script> > const parent = window.parent; > alert(1); >-parent.document.getElementsByTagName('iframe')[0].src = "javascript:alert(2),'PASS<script>alert(3)<\/script>'"; >-alert(4); >+parent.document.getElementsByTagName('iframe')[0].src = "javascript:alert(3),'PASS<script>alert(4)<\/script>'"; >+alert(2); > parent.setTimeout("done()", 0); > </script> >diff --git a/LayoutTests/http/tests/security/contentSecurityPolicy/javascript-url-allowed-expected.txt b/LayoutTests/http/tests/security/contentSecurityPolicy/javascript-url-allowed-expected.txt >index ef6629340bb..3a1a9f47466 100644 >--- a/LayoutTests/http/tests/security/contentSecurityPolicy/javascript-url-allowed-expected.txt >+++ b/LayoutTests/http/tests/security/contentSecurityPolicy/javascript-url-allowed-expected.txt >@@ -1,7 +1,7 @@ > 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 > 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 > >diff --git a/LayoutTests/http/tests/security/contentSecurityPolicy/javascript-url-blocked-expected.txt b/LayoutTests/http/tests/security/contentSecurityPolicy/javascript-url-blocked-expected.txt >index 967bfa63956..7e1a9197a20 100644 >--- a/LayoutTests/http/tests/security/contentSecurityPolicy/javascript-url-blocked-expected.txt >+++ b/LayoutTests/http/tests/security/contentSecurityPolicy/javascript-url-blocked-expected.txt >@@ -1,7 +1,7 @@ > 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: line 1: 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. > 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: line 1: 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. > >diff --git a/LayoutTests/http/tests/security/javascriptURL/xss-ALLOWED-from-javascript-url-sub-frame-2-level.html b/LayoutTests/http/tests/security/javascriptURL/xss-ALLOWED-from-javascript-url-sub-frame-2-level.html >index 85ab9be7b72..236042a0f11 100644 >--- a/LayoutTests/http/tests/security/javascriptURL/xss-ALLOWED-from-javascript-url-sub-frame-2-level.html >+++ b/LayoutTests/http/tests/security/javascriptURL/xss-ALLOWED-from-javascript-url-sub-frame-2-level.html >@@ -7,11 +7,13 @@ > if (window.testRunner) { > testRunner.dumpAsText(); > testRunner.dumpChildFramesAsText(); >+ testRunner.waitUntilDone(); > } > > var innerURL = 'javascript:\\\"<html>' > + "<scr" + "ipt>" > + 'top.document.getElementById(\\\\\\\"accessMe\\\\\\\").innerHTML = \\\\\\\"PASS: Cross frame access from a javascript: URL inside another javascript: URL was allowed!\\\\\\\";' >+ + 'top.setTimeout(() => { testRunner.notifyDone(); }, 0);' > + "</scri" + "pt>" > + "<body>" > + "<p>Inner-inner iframe.</p>" >diff --git a/LayoutTests/http/tests/security/javascriptURL/xss-ALLOWED-from-javascript-url-sub-frame.html b/LayoutTests/http/tests/security/javascriptURL/xss-ALLOWED-from-javascript-url-sub-frame.html >index ce83c723a22..b94cd4e782c 100644 >--- a/LayoutTests/http/tests/security/javascriptURL/xss-ALLOWED-from-javascript-url-sub-frame.html >+++ b/LayoutTests/http/tests/security/javascriptURL/xss-ALLOWED-from-javascript-url-sub-frame.html >@@ -7,6 +7,7 @@ > if (window.testRunner) { > testRunner.dumpAsText(); > testRunner.dumpChildFramesAsText(); >+ testRunner.waitUntilDone(); > } > > var url = "javascript:\"<html>" >@@ -20,6 +21,12 @@ > > var iframe = document.getElementById("aFrame"); > iframe.src = url; >+ onload = () => { >+ setTimeout(() => { >+ if (window.testRunner) >+ testRunner.notifyDone(); >+ }); >+ } > </script> > </body> > </html> >diff --git a/LayoutTests/imported/blink/loader/iframe-sync-loads-expected.txt b/LayoutTests/imported/blink/loader/iframe-sync-loads-expected.txt >index 1159c11eb9e..686d3b3ecf2 100644 >--- a/LayoutTests/imported/blink/loader/iframe-sync-loads-expected.txt >+++ b/LayoutTests/imported/blink/loader/iframe-sync-loads-expected.txt >@@ -1,4 +1,4 @@ >- sync : src = javascript:"content" >+ASYNC : src = javascript:"content" > ASYNC : src = data:text/html,content > ASYNC : srcdoc = "content" > done >diff --git a/Source/WebCore/loader/NavigationScheduler.cpp b/Source/WebCore/loader/NavigationScheduler.cpp >index 617dedbfdfa..054a7c2528b 100644 >--- a/Source/WebCore/loader/NavigationScheduler.cpp >+++ b/Source/WebCore/loader/NavigationScheduler.cpp >@@ -193,8 +193,17 @@ public: > > class ScheduledLocationChange : public ScheduledURLNavigation { > public: >- ScheduledLocationChange(Document& initiatingDocument, SecurityOrigin* securityOrigin, const URL& url, const String& referrer, LockHistory lockHistory, LockBackForwardList lockBackForwardList, bool duringLoad) >- : ScheduledURLNavigation(initiatingDocument, 0.0, securityOrigin, url, referrer, lockHistory, lockBackForwardList, duringLoad, true) { } >+ ScheduledLocationChange(Document& initiatingDocument, SecurityOrigin* securityOrigin, const URL& url, const String& referrer, LockHistory lockHistory, LockBackForwardList lockBackForwardList, bool duringLoad, CompletionHandler<void()>&& whenDone) >+ : ScheduledURLNavigation(initiatingDocument, 0.0, securityOrigin, url, referrer, lockHistory, lockBackForwardList, duringLoad, true) >+ , m_whenDone(WTFMove(whenDone)) >+ { >+ } >+ >+ ~ScheduledLocationChange() >+ { >+ if (m_whenDone) >+ m_whenDone(); >+ } > > void fire(Frame& frame) override > { >@@ -203,8 +212,13 @@ public: > ResourceRequest resourceRequest { url(), referrer(), ResourceRequestCachePolicy::UseProtocolCachePolicy }; > FrameLoadRequest frameLoadRequest { initiatingDocument(), *securityOrigin(), resourceRequest, "_self", lockHistory(), lockBackForwardList(), MaybeSendReferrer, AllowNavigationToInvalidURL::No, NewFrameOpenerPolicy::Allow, shouldOpenExternalURLs(), initiatedByMainFrame() }; > >+ auto whenDone = WTFMove(m_whenDone); > frame.loader().changeLocation(WTFMove(frameLoadRequest)); >+ whenDone(); > } >+ >+private: >+ CompletionHandler<void()> m_whenDone; > }; > > class ScheduledRefresh : public ScheduledURLNavigation { >@@ -405,10 +419,10 @@ LockBackForwardList NavigationScheduler::mustLockBackForwardList(Frame& targetFr > return LockBackForwardList::No; > } > >-void NavigationScheduler::scheduleLocationChange(Document& initiatingDocument, SecurityOrigin& securityOrigin, const URL& url, const String& referrer, LockHistory lockHistory, LockBackForwardList lockBackForwardList) >+void NavigationScheduler::scheduleLocationChange(Document& initiatingDocument, SecurityOrigin& securityOrigin, const URL& url, const String& referrer, LockHistory lockHistory, LockBackForwardList lockBackForwardList, CompletionHandler<void()>&& whenDone) > { > if (!shouldScheduleNavigation(url)) >- return; >+ return whenDone(); > > if (lockBackForwardList == LockBackForwardList::No) > lockBackForwardList = mustLockBackForwardList(m_frame); >@@ -424,14 +438,14 @@ void NavigationScheduler::scheduleLocationChange(Document& initiatingDocument, S > > FrameLoadRequest frameLoadRequest { initiatingDocument, securityOrigin, resourceRequest, "_self"_s, lockHistory, lockBackForwardList, MaybeSendReferrer, AllowNavigationToInvalidURL::No, NewFrameOpenerPolicy::Allow, initiatingDocument.shouldOpenExternalURLsPolicyToPropagate(), initiatedByMainFrame }; > loader.changeLocation(WTFMove(frameLoadRequest)); >- return; >+ return whenDone(); > } > > // Handle a location change of a page with no document as a special case. > // This may happen when a frame changes the location of another frame. > bool duringLoad = !loader.stateMachine().committedFirstRealDocumentLoad(); > >- schedule(std::make_unique<ScheduledLocationChange>(initiatingDocument, &securityOrigin, url, referrer, lockHistory, lockBackForwardList, duringLoad)); >+ schedule(std::make_unique<ScheduledLocationChange>(initiatingDocument, &securityOrigin, url, referrer, lockHistory, lockBackForwardList, duringLoad, WTFMove(whenDone))); > } > > void NavigationScheduler::scheduleFormSubmission(Ref<FormSubmission>&& submission) >diff --git a/Source/WebCore/loader/NavigationScheduler.h b/Source/WebCore/loader/NavigationScheduler.h >index b97d9868161..7bb102605cf 100644 >--- a/Source/WebCore/loader/NavigationScheduler.h >+++ b/Source/WebCore/loader/NavigationScheduler.h >@@ -53,7 +53,7 @@ public: > bool locationChangePending(); > > void scheduleRedirect(Document& initiatingDocument, double delay, const URL&); >- void scheduleLocationChange(Document& initiatingDocument, SecurityOrigin&, const URL&, const String& referrer, LockHistory = LockHistory::Yes, LockBackForwardList = LockBackForwardList::Yes); >+ void scheduleLocationChange(Document& initiatingDocument, SecurityOrigin&, const URL&, const String& referrer, LockHistory = LockHistory::Yes, LockBackForwardList = LockBackForwardList::Yes, CompletionHandler<void()>&& whenDone = [] { }); > void scheduleFormSubmission(Ref<FormSubmission>&&); > void scheduleRefresh(Document& initiatingDocument); > void scheduleHistoryNavigation(int steps); >diff --git a/Source/WebCore/loader/SubframeLoader.cpp b/Source/WebCore/loader/SubframeLoader.cpp >index 1f90a83c779..18e8c27ec43 100644 >--- a/Source/WebCore/loader/SubframeLoader.cpp >+++ b/Source/WebCore/loader/SubframeLoader.cpp >@@ -56,6 +56,7 @@ > #include "SecurityOrigin.h" > #include "SecurityPolicy.h" > #include "Settings.h" >+#include <wtf/CompletionHandler.h> > > namespace WebCore { > >@@ -86,17 +87,23 @@ bool SubframeLoader::requestFrame(HTMLFrameOwnerElement& ownerElement, const Str > if (shouldConvertInvalidURLsToBlank() && !url.isValid()) > url = WTF::blankURL(); > >- bool hasExistingFrame = ownerElement.contentFrame(); >+ // If we will schedule a javascript URL load, we delay the firing of the load event at least until we've run the javascript URL. >+ bool shouldDelayLoadEvent = !scriptURL.isEmpty(); >+ CompletionHandlerCallingScope stopDelayingLoadEvent; >+ if (shouldDelayLoadEvent) { >+ ownerElement.document().incrementLoadEventDelayCount(); >+ stopDelayingLoadEvent = CompletionHandlerCallingScope([ownerElement = makeRef(ownerElement)] { >+ ownerElement->document().decrementLoadEventDelayCount(); >+ }); >+ } >+ > Frame* frame = loadOrRedirectSubframe(ownerElement, url, frameName, lockHistory, lockBackForwardList); > if (!frame) > return false; > >- // If we create a new subframe then an empty document is loaded into it synchronously and may >- // cause script execution (say, via a DOM load event handler) that can do anything, including >- // navigating the subframe. We only want to evaluate scriptURL if the frame has not been navigated. >- bool canExecuteScript = hasExistingFrame || (frame->loader().documentLoader() && frame->loader().documentLoader()->originalURL() == WTF::blankURL()); >- if (!scriptURL.isEmpty() && canExecuteScript && ownerElement.isURLAllowed(scriptURL)) >- frame->script().executeIfJavaScriptURL(scriptURL); >+ if (!scriptURL.isEmpty() && ownerElement.isURLAllowed(scriptURL)) { >+ frame->navigationScheduler().scheduleLocationChange(ownerElement.document(), ownerElement.document().securityOrigin(), scriptURL, m_frame.loader().outgoingReferrer(), lockHistory, lockBackForwardList, stopDelayingLoadEvent.release()); >+ } > > return true; > }
You cannot view the attachment while viewing its details because your browser does not support IFRAMEs.
View the attachment on a separate page
.
View Attachment As Diff
View Attachment As Raw
Actions:
View
|
Formatted Diff
|
Diff
Attachments on
bug 197466
:
368683
|
368689
|
368690
|
368691
|
368693
|
368699
|
368706
|
368709
|
368710
|
368719
|
368723
|
368725
|
368729
|
368732
|
368734
|
368736
|
368741
|
368742
|
368750
|
368751
|
368755
|
368756
|
368757
|
368758
|
368762
|
368763
|
368764
|
368765
|
368781
|
368786
|
368793
|
368796
|
368805
|
368807
|
368813
|
368821
|
368825