⚠ Archived content — this site is no longer maintained.   Current WebKit documentation is at docs.webkit.org.

Changeset 245916 in webkit


Ignore:
Timestamp:
May 30, 2019, 5:29:43 PM (7 years ago)
Author:
Alan Coon
Message:

Cherry-pick r244892. rdar://problem/50753927

Setting a frame's src to a javascript URL should not run it synchronously
https://bugs.webkit.org/show_bug.cgi?id=197466

Reviewed by Darin Adler.

Source/WebCore:

When an iframe's src attribute is set to a javascript URL, whether when parsing
or later on via JS, we now execute the URL's JavaScript asynchronously. We used
to execute it synchronously, which was a source of bugs and also did not match
other browsers.

I have verified that our new behavior is aligned with both Firefox and Chrome.

Note that for backward-compatibility and interoperability with Blink
(https://bugs.chromium.org/p/chromium/issues/detail?id=923585), the
"javascript:" URL will still run synchronously. We should consider dropping
this quirk at some point.

Test: fast/dom/frame-src-javascript-url-async.html

  • loader/NavigationScheduler.cpp: (WebCore::ScheduledLocationChange::ScheduledLocationChange): (WebCore::ScheduledLocationChange::~ScheduledLocationChange): (WebCore::NavigationScheduler::scheduleLocationChange):
  • loader/NavigationScheduler.h: (WebCore::NavigationScheduler::scheduleLocationChange):
  • loader/SubframeLoader.cpp: (WebCore::SubframeLoader::requestFrame):

LayoutTests:

  • fast/dom/frame-src-javascript-url-async-expected.txt: Added.
  • fast/dom/frame-src-javascript-url-async.html: Added. Add layout test coverage for the fact that the javascript URL is executed asynchronously whether set during parsing or later via JS. Also makes sure that executing the javascript URL asynchronously does not replace the frame's window. This test passes in both Chrome and Firefox.
  • imported/blink/fast/frames/navigation-in-pagehide.html: Re-sync this test from the Blink repository.
  • fast/dom/Element/id-in-frameset-expected.txt:
  • fast/dom/Element/id-in-frameset.html:
  • fast/dom/insertedIntoDocument-iframe-expected.txt:
  • fast/dom/javascript-url-exception-isolation-expected.txt:
  • fast/dom/javascript-url-exception-isolation.html:
  • fast/dom/no-assert-for-malformed-js-url-attribute-expected.txt:
  • fast/dom/resources/javascript-url-crash-function-iframe.html:
  • fast/frames/adopt-from-created-document.html:
  • fast/frames/out-of-document-iframe-has-child-frame.html:
  • fast/loader/javascript-url-iframe-remove-on-navigate-async-delegate.html:
  • fast/loader/javascript-url-iframe-remove-on-navigate.html:
  • fast/loader/unload-mutation-crash.html:
  • fast/parser/resources/set-parent-to-javascript-url.html:
  • fast/parser/xml-error-adopted.xml:
  • http/tests/navigation/lockedhistory-iframe-expected.txt:
  • http/tests/security/contentSecurityPolicy/block-all-mixed-content/insecure-image-in-javascript-url-iframe-in-iframe-expected.txt:
  • http/tests/security/contentSecurityPolicy/javascript-url-allowed-expected.txt:
  • http/tests/security/contentSecurityPolicy/javascript-url-blocked-by-default-src-star-expected.txt:
  • http/tests/security/contentSecurityPolicy/javascript-url-blocked-expected.txt:
  • http/tests/security/javascriptURL/xss-ALLOWED-from-javascript-url-sub-frame-2-level.html:
  • http/tests/security/javascriptURL/xss-ALLOWED-from-javascript-url-sub-frame.html:
  • http/tests/security/javascriptURL/xss-ALLOWED-to-javascript-url-from-javscript-url.html:
  • imported/blink/loader/iframe-sync-loads-expected.txt:
  • js/dom/call-base-resolution.html:
  • platform/wk2/http/tests/security/contentSecurityPolicy/block-all-mixed-content/insecure-image-in-javascript-url-iframe-in-iframe-expected.txt: Update / Rebaseline existing tests to reflect behavior change. I ran those tests in Firefox and Chrome to confirm that our behavior is indeed aligned.

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@244892 268f45cc-cd09-0410-ab3c-d52691b4dbfc

Location:
branches/safari-607-branch
Files:
2 added
31 edited

Legend:

Unmodified
Added
Removed
  • branches/safari-607-branch/LayoutTests/ChangeLog

    r245725 r245916  
     12019-05-30  Kocsen Chung  <kocsen_chung@apple.com>
     2
     3        Cherry-pick r244892. rdar://problem/50753927
     4
     5    Setting a frame's src to a javascript URL should not run it synchronously
     6    https://bugs.webkit.org/show_bug.cgi?id=197466
     7   
     8    Reviewed by Darin Adler.
     9   
     10    Source/WebCore:
     11   
     12    When an iframe's src attribute is set to a javascript URL, whether when parsing
     13    or later on via JS, we now execute the URL's JavaScript asynchronously. We used
     14    to execute it synchronously, which was a source of bugs and also did not match
     15    other browsers.
     16   
     17    I have verified that our new behavior is aligned with both Firefox and Chrome.
     18   
     19    Note that for backward-compatibility and interoperability with Blink
     20    (https://bugs.chromium.org/p/chromium/issues/detail?id=923585), the
     21    "javascript:''" URL will still run synchronously. We should consider dropping
     22    this quirk at some point.
     23   
     24    Test: fast/dom/frame-src-javascript-url-async.html
     25   
     26    * loader/NavigationScheduler.cpp:
     27    (WebCore::ScheduledLocationChange::ScheduledLocationChange):
     28    (WebCore::ScheduledLocationChange::~ScheduledLocationChange):
     29    (WebCore::NavigationScheduler::scheduleLocationChange):
     30    * loader/NavigationScheduler.h:
     31    (WebCore::NavigationScheduler::scheduleLocationChange):
     32    * loader/SubframeLoader.cpp:
     33    (WebCore::SubframeLoader::requestFrame):
     34   
     35    LayoutTests:
     36   
     37    * fast/dom/frame-src-javascript-url-async-expected.txt: Added.
     38    * fast/dom/frame-src-javascript-url-async.html: Added.
     39    Add layout test coverage for the fact that the javascript URL is executed asynchronously
     40    whether set during parsing or later via JS. Also makes sure that executing the javascript
     41    URL asynchronously does not replace the frame's window. This test passes in both Chrome
     42    and Firefox.
     43   
     44    * imported/blink/fast/frames/navigation-in-pagehide.html:
     45    Re-sync this test from the Blink repository.
     46   
     47    * fast/dom/Element/id-in-frameset-expected.txt:
     48    * fast/dom/Element/id-in-frameset.html:
     49    * fast/dom/insertedIntoDocument-iframe-expected.txt:
     50    * fast/dom/javascript-url-exception-isolation-expected.txt:
     51    * fast/dom/javascript-url-exception-isolation.html:
     52    * fast/dom/no-assert-for-malformed-js-url-attribute-expected.txt:
     53    * fast/dom/resources/javascript-url-crash-function-iframe.html:
     54    * fast/frames/adopt-from-created-document.html:
     55    * fast/frames/out-of-document-iframe-has-child-frame.html:
     56    * fast/loader/javascript-url-iframe-remove-on-navigate-async-delegate.html:
     57    * fast/loader/javascript-url-iframe-remove-on-navigate.html:
     58    * fast/loader/unload-mutation-crash.html:
     59    * fast/parser/resources/set-parent-to-javascript-url.html:
     60    * fast/parser/xml-error-adopted.xml:
     61    * http/tests/navigation/lockedhistory-iframe-expected.txt:
     62    * http/tests/security/contentSecurityPolicy/block-all-mixed-content/insecure-image-in-javascript-url-iframe-in-iframe-expected.txt:
     63    * http/tests/security/contentSecurityPolicy/javascript-url-allowed-expected.txt:
     64    * http/tests/security/contentSecurityPolicy/javascript-url-blocked-by-default-src-star-expected.txt:
     65    * http/tests/security/contentSecurityPolicy/javascript-url-blocked-expected.txt:
     66    * http/tests/security/javascriptURL/xss-ALLOWED-from-javascript-url-sub-frame-2-level.html:
     67    * http/tests/security/javascriptURL/xss-ALLOWED-from-javascript-url-sub-frame.html:
     68    * http/tests/security/javascriptURL/xss-ALLOWED-to-javascript-url-from-javscript-url.html:
     69    * imported/blink/loader/iframe-sync-loads-expected.txt:
     70    * js/dom/call-base-resolution.html:
     71    * platform/wk2/http/tests/security/contentSecurityPolicy/block-all-mixed-content/insecure-image-in-javascript-url-iframe-in-iframe-expected.txt:
     72    Update / Rebaseline existing tests to reflect behavior change. I ran those tests in Firefox and Chrome to confirm that our behavior
     73    is indeed aligned.
     74   
     75   
     76    git-svn-id: https://svn.webkit.org/repository/webkit/trunk@244892 268f45cc-cd09-0410-ab3c-d52691b4dbfc
     77
     78    2019-05-02  Chris Dumez  <cdumez@apple.com>
     79
     80            Setting a frame's src to a javascript URL should not run it synchronously
     81            https://bugs.webkit.org/show_bug.cgi?id=197466
     82
     83            Reviewed by Darin Adler.
     84
     85            * fast/dom/frame-src-javascript-url-async-expected.txt: Added.
     86            * fast/dom/frame-src-javascript-url-async.html: Added.
     87            Add layout test coverage for the fact that the javascript URL is executed asynchronously
     88            whether set during parsing or later via JS. Also makes sure that executing the javascript
     89            URL asynchronously does not replace the frame's window. This test passes in both Chrome
     90            and Firefox.
     91
     92            * imported/blink/fast/frames/navigation-in-pagehide.html:
     93            Re-sync this test from the Blink repository.
     94
     95            * fast/dom/Element/id-in-frameset-expected.txt:
     96            * fast/dom/Element/id-in-frameset.html:
     97            * fast/dom/insertedIntoDocument-iframe-expected.txt:
     98            * fast/dom/javascript-url-exception-isolation-expected.txt:
     99            * fast/dom/javascript-url-exception-isolation.html:
     100            * fast/dom/no-assert-for-malformed-js-url-attribute-expected.txt:
     101            * fast/dom/resources/javascript-url-crash-function-iframe.html:
     102            * fast/frames/adopt-from-created-document.html:
     103            * fast/frames/out-of-document-iframe-has-child-frame.html:
     104            * fast/loader/javascript-url-iframe-remove-on-navigate-async-delegate.html:
     105            * fast/loader/javascript-url-iframe-remove-on-navigate.html:
     106            * fast/loader/unload-mutation-crash.html:
     107            * fast/parser/resources/set-parent-to-javascript-url.html:
     108            * fast/parser/xml-error-adopted.xml:
     109            * http/tests/navigation/lockedhistory-iframe-expected.txt:
     110            * http/tests/security/contentSecurityPolicy/block-all-mixed-content/insecure-image-in-javascript-url-iframe-in-iframe-expected.txt:
     111            * http/tests/security/contentSecurityPolicy/javascript-url-allowed-expected.txt:
     112            * http/tests/security/contentSecurityPolicy/javascript-url-blocked-by-default-src-star-expected.txt:
     113            * http/tests/security/contentSecurityPolicy/javascript-url-blocked-expected.txt:
     114            * http/tests/security/javascriptURL/xss-ALLOWED-from-javascript-url-sub-frame-2-level.html:
     115            * http/tests/security/javascriptURL/xss-ALLOWED-from-javascript-url-sub-frame.html:
     116            * http/tests/security/javascriptURL/xss-ALLOWED-to-javascript-url-from-javscript-url.html:
     117            * imported/blink/loader/iframe-sync-loads-expected.txt:
     118            * js/dom/call-base-resolution.html:
     119            * platform/wk2/http/tests/security/contentSecurityPolicy/block-all-mixed-content/insecure-image-in-javascript-url-iframe-in-iframe-expected.txt:
     120            Update / Rebaseline existing tests to reflect behavior change. I ran those tests in Firefox and Chrome to confirm that our behavior
     121            is indeed aligned.
     122
    11232019-05-23  Ryan Haddad  <ryanhaddad@apple.com>
    2124
  • branches/safari-607-branch/LayoutTests/fast/dom/Element/id-in-frameset-expected.txt

    r52312 r245916  
    1 ALERT: 1
     1ALERT: 2
    22
  • branches/safari-607-branch/LayoutTests/fast/dom/Element/id-in-frameset.html

    r120792 r245916  
    11<html>
    2 
     2<script>
     3if (window.testRunner) {
     4    testRunner.dumpAsText();
     5    testRunner.waitUntilDone();
     6}
     7</script>
    38<frameset id="frameset">
    49  <frame name="frame2" src="about:blank">
     
    1722    top.frameset.removeChild(top.frame2.frameElement);
    1823    log(top.frameset.children.length);
     24    if (window.testRunner)
     25        testRunner.notifyDone();
    1926  ">
    2027
  • branches/safari-607-branch/LayoutTests/fast/dom/insertedIntoDocument-iframe-expected.txt

    r81611 r245916  
     1CONSOLE MESSAGE: line 1: TypeError: Argument 1 ('child') to Node.removeChild must be an instance of Node
    12PASS
     3
  • branches/safari-607-branch/LayoutTests/fast/dom/javascript-url-exception-isolation-expected.txt

    r217390 r245916  
    11CONSOLE MESSAGE: line 1: 42
    2 CONSOLE MESSAGE: line 25: SyntaxError: Unexpected token '<'
     2CONSOLE MESSAGE: line 1: SyntaxError: Unexpected token '<'
    33Exceptions thrown in javascript URLs should not propagate to the main script.
    44
  • branches/safari-607-branch/LayoutTests/fast/dom/javascript-url-exception-isolation.html

    r217390 r245916  
    2121shouldBeFalse('caughtException');
    2222
     23var subframe2 = document.createElement("iframe");
     24document.body.appendChild(subframe2);
     25
    2326// Compile-time exception.
    2427try {
    25     subframe.src = 'javascript:<html></html>';
     28    subframe2.src = 'javascript:<html></html>';
    2629} catch(e) {
    2730    caughtException = true;
  • branches/safari-607-branch/LayoutTests/fast/dom/no-assert-for-malformed-js-url-attribute-expected.txt

    r216259 r245916  
    1 CONSOLE MESSAGE: line 14: SyntaxError: Unexpected identifier 'orem'
     1CONSOLE MESSAGE: line 1: SyntaxError: Unexpected identifier 'orem'
    22This 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.
    33
  • branches/safari-607-branch/LayoutTests/fast/dom/resources/javascript-url-crash-function-iframe.html

    r120792 r245916  
    1717{
    1818    test();
    19     if (window.testRunner)
    20         testRunner.notifyDone();
     19    top.setTimeout(() => {
     20        if (window.testRunner)
     21            testRunner.notifyDone();
     22    }, 0);
    2123}, 0);
    2224</script>
  • branches/safari-607-branch/LayoutTests/fast/frames/adopt-from-created-document.html

    r121008 r245916  
    99var ifr = doc.createElement('iframe');
    1010alert(3);
    11 ifr.setAttribute('src', 'javascript:alert(6)');
     11ifr.setAttribute('src', 'javascript:alert(7)');
    1212alert(4);
    1313var adopted = document.adoptNode(ifr)
    1414alert(5);
    1515document.body.appendChild(adopted);
    16 alert(7);
     16alert(6);
    1717</script>
  • branches/safari-607-branch/LayoutTests/fast/frames/out-of-document-iframe-has-child-frame.html

    r155268 r245916  
    11<html>
    22<head>
    3 <script src="../../resources/js-test-pre.js"></script>
     3<script src="../../resources/js-test.js"></script>
    44</head>
    55<body>
     
    88description("This tests that several ways of making an iframe that isn't inserted into a document tree"
    99    + " but has a child frame will fail.");
     10jsTestIsAsync = true;
    1011
    1112main = document.getElementById("main");
     
    4546    document.body.appendChild(container);
    4647} catch (e) { }
    47 shouldBeTrue("targetFrame3.contentWindow == undefined");
    4848
    49 isSuccessfullyParsed();
     49setTimeout(() => {
     50    shouldBeTrue("targetFrame3.contentWindow == undefined");
     51    finishJSTest();
     52}, 0);
    5053</script>
    5154</body>
  • branches/safari-607-branch/LayoutTests/fast/loader/javascript-url-iframe-remove-on-navigate-async-delegate.html

    r232144 r245916  
    99
    1010let frame = document.getElementById("target");
    11 frame.contentWindow.onbeforeunload = function() {
    12     setTimeout(function() {
    13         frame.src = "javascript:alert('FAIL')";
    14     }, 0);
    15 };
    1611
    1712window.addEventListener("load", function() {
     13    frame.contentWindow.onbeforeunload = function() {
     14        setTimeout(function() {
     15            frame.src = "javascript:alert('FAIL')";
     16        }, 0);
     17    };
     18
    1819    document.write("PASS - Javascript URL blocked without crashing.");
    1920    if (window.testRunner)
  • branches/safari-607-branch/LayoutTests/fast/loader/javascript-url-iframe-remove-on-navigate.html

    r232144 r245916  
    77
    88let frame = document.getElementById("target");
    9 frame.contentWindow.onbeforeunload = function() {
    10     setTimeout(function() {
    11         frame.src = "javascript:alert('FAIL')";
    12     }, 0);
    13 };
    149
    1510window.addEventListener("load", function() {
     11    frame.contentWindow.onbeforeunload = function() {
     12        setTimeout(function() {
     13            frame.src = "javascript:alert('FAIL')";
     14        }, 0);
     15    };
    1616    document.write("PASS - Javascript URL blocked without crashing.");
    1717    if (window.testRunner)
  • branches/safari-607-branch/LayoutTests/fast/loader/unload-mutation-crash.html

    r192947 r245916  
    33<head>
    44<script>
    5 if (window.testRunner)
    6     window.testRunner.dumpAsText();
     5if (window.testRunner) {
     6    testRunner.dumpAsText();
     7    testRunner.waitUntilDone();
     8}
    79
    810function start() {
     
    2123    window.firstFrame.src = 'javascript:"";';
    2224    document.write("PASS. WebKit didn't crash.");
     25    if (window.testRunner)
     26       testRunner.notifyDone();
    2327}
    2428</script>
  • branches/safari-607-branch/LayoutTests/fast/parser/resources/set-parent-to-javascript-url.html

    r236862 r245916  
    22const parent = window.parent;
    33alert(1);
    4 parent.document.getElementsByTagName('iframe')[0].src = "javascript:alert(2),'PASS<script>alert(3)<\/script>'";
    5 alert(4);
     4parent.document.getElementsByTagName('iframe')[0].src = "javascript:alert(3),'PASS<script>alert(4)<\/script>'";
     5alert(2);
    66parent.setTimeout("done()", 0);
    77</script>
  • branches/safari-607-branch/LayoutTests/fast/parser/xml-error-adopted.xml

    r141198 r245916  
    1616}
    1717
    18 setTimeout(test, 0);
     18onload = () => {
     19    setTimeout(test, 0);
     20};
    1921</script>
    2022<elt attr="1" attr="2"/>
  • branches/safari-607-branch/LayoutTests/http/tests/navigation/lockedhistory-iframe-expected.txt

    r231450 r245916  
    55============== Back Forward List ==============
    66curr->  http://127.0.0.1:8000/navigation/lockedhistory-iframe.html  **nav target**
    7             about:blank (in frame "<!--frame1-->")
     7            http://127.0.0.1:8000/navigation/lockedhistory-iframe.html# (in frame "<!--frame1-->")
     8                about:blank (in frame "<!--frame2-->")
    89===============================================
  • branches/safari-607-branch/LayoutTests/http/tests/security/contentSecurityPolicy/block-all-mixed-content/insecure-image-in-javascript-url-iframe-in-iframe-expected.txt

    r231450 r245916  
    77frame "<!--frame2-->" - didHandleOnloadEventsForFrame
    88frame "<!--frame2-->" - didFinishLoadForFrame
     9frame "<!--frame2-->" - willPerformClientRedirectToURL: javascript:document.write('%3Cimg%20src=%22http://127.0.0.1:8000/security/resources/compass.jpg%22%3E');
     10frame "<!--frame1-->" - didFinishDocumentLoadForFrame
    911CONSOLE MESSAGE: Blocked mixed content http://127.0.0.1:8000/security/resources/compass.jpg because 'block-all-mixed-content' appears in the Content Security Policy.
    10 frame "<!--frame1-->" - didFinishDocumentLoadForFrame
    1112frame "<!--frame1-->" - didFinishLoadForFrame
    1213main frame - didFinishLoadForFrame
  • branches/safari-607-branch/LayoutTests/http/tests/security/contentSecurityPolicy/javascript-url-allowed-expected.txt

    r133193 r245916  
     1CONSOLE MESSAGE: The 'allow' directive has been replaced with 'default-src'. Please use that directive instead, as 'allow' has no effect.
     2CONSOLE MESSAGE: The 'allow' directive has been replaced with 'default-src'. Please use that directive instead, as 'allow' has no effect.
    13CONSOLE MESSAGE: The 'allow' directive has been replaced with 'default-src'. Please use that directive instead, as 'allow' has no effect.
    24CONSOLE MESSAGE: The 'allow' directive has been replaced with 'default-src'. Please use that directive instead, as 'allow' has no effect.
    35CONSOLE MESSAGE: The 'allow' directive has been replaced with 'default-src'. Please use that directive instead, as 'allow' has no effect.
    46ALERT: PASS
    5 CONSOLE MESSAGE: The 'allow' directive has been replaced with 'default-src'. Please use that directive instead, as 'allow' has no effect.
    6 CONSOLE MESSAGE: The 'allow' directive has been replaced with 'default-src'. Please use that directive instead, as 'allow' has no effect.
    77
  • branches/safari-607-branch/LayoutTests/http/tests/security/contentSecurityPolicy/javascript-url-blocked-by-default-src-star-expected.txt

    r198591 r245916  
    1 CONSOLE MESSAGE: line 1: Refused to execute a script because its hash, its nonce, or 'unsafe-inline' appears in neither the script-src directive nor the default-src directive of the Content Security Policy.
    21CONSOLE MESSAGE: Refused to load javascript:alert('FAIL'); because it appears in neither the object-src directive nor the default-src directive of the Content Security Policy.
    32CONSOLE MESSAGE: Refused to load javascript:alert('FAIL'); because it appears in neither the object-src directive nor the default-src directive of the Content Security Policy.
     3CONSOLE MESSAGE: line 1: Refused to execute a script because its hash, its nonce, or 'unsafe-inline' appears in neither the script-src directive nor the default-src directive of the Content Security Policy.
    44
  • branches/safari-607-branch/LayoutTests/http/tests/security/contentSecurityPolicy/javascript-url-blocked-expected.txt

    r198591 r245916  
     1CONSOLE MESSAGE: The 'allow' directive has been replaced with 'default-src'. Please use that directive instead, as 'allow' has no effect.
     2CONSOLE MESSAGE: The 'allow' directive has been replaced with 'default-src'. Please use that directive instead, as 'allow' has no effect.
    13CONSOLE MESSAGE: The 'allow' directive has been replaced with 'default-src'. Please use that directive instead, as 'allow' has no effect.
    24CONSOLE MESSAGE: The 'allow' directive has been replaced with 'default-src'. Please use that directive instead, as 'allow' has no effect.
    35CONSOLE MESSAGE: The 'allow' directive has been replaced with 'default-src'. Please use that directive instead, as 'allow' has no effect.
    46CONSOLE 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.
    5 CONSOLE MESSAGE: The 'allow' directive has been replaced with 'default-src'. Please use that directive instead, as 'allow' has no effect.
    6 CONSOLE MESSAGE: The 'allow' directive has been replaced with 'default-src'. Please use that directive instead, as 'allow' has no effect.
    77
  • branches/safari-607-branch/LayoutTests/http/tests/security/javascriptURL/xss-ALLOWED-from-javascript-url-sub-frame-2-level.html

    r191652 r245916  
    88            testRunner.dumpAsText();
    99            testRunner.dumpChildFramesAsText();
     10            testRunner.waitUntilDone();
    1011        }
    1112
     
    1314            + "<scr" + "ipt>"
    1415            +     'top.document.getElementById(\\\\\\\"accessMe\\\\\\\").innerHTML = \\\\\\\"PASS: Cross frame access from a javascript: URL inside another javascript: URL was allowed!\\\\\\\";'
     16            +     'top.setTimeout(() => { testRunner.notifyDone(); }, 0);'
    1517            + "</scri" + "pt>"
    1618            + "<body>"
  • branches/safari-607-branch/LayoutTests/http/tests/security/javascriptURL/xss-ALLOWED-from-javascript-url-sub-frame.html

    r191652 r245916  
    88            testRunner.dumpAsText();
    99            testRunner.dumpChildFramesAsText();
     10            testRunner.waitUntilDone();
    1011        }
    1112
     
    2122        var iframe = document.getElementById("aFrame");
    2223        iframe.src = url;
     24        onload = () => {
     25            setTimeout(() => {
     26                if (window.testRunner)
     27                    testRunner.notifyDone();
     28            }, 0);
     29        }
    2330    </script>
    2431</body>
  • branches/safari-607-branch/LayoutTests/http/tests/security/javascriptURL/xss-ALLOWED-to-javascript-url-from-javscript-url.html

    r191652 r245916  
    88            testRunner.dumpAsText();
    99            testRunner.dumpChildFramesAsText();
     10            testRunner.waitUntilDone();
    1011        }
    1112
     
    3132        var iframe = document.getElementById("aFrame");
    3233        iframe.src = url;
     34
     35        onload = () => {
     36            setTimeout(() => {
     37                if (window.testRunner)
     38                    testRunner.notifyDone();
     39            }, 0);
     40        };
    3341    </script>
    3442</body>
  • branches/safari-607-branch/LayoutTests/imported/blink/fast/frames/navigation-in-pagehide.html

    r194919 r245916  
    1818  firstFrame.appendChild(div);
    1919  secondFrame = document.createElement('iframe');
    20   secondFrame.src = 'javascript:window.top.maybeStart();';
     20  secondFrame.src = 'javascript:window.top.reallyStart();';
    2121  div.appendChild(secondFrame);
    2222  var firstFrameRoot = firstFrame.contentDocument.documentElement;
    2323  document.documentElement.appendChild(div);
    2424  firstFrameRoot.appendChild(secondFrame);
    25 }
    26 
    27 function maybeStart() {
    28   if (callbackCount++ > 1) {
    29     reallyStart();
    30     return;
    31   }
    3225}
    3326
     
    4033  if (window.location.hash == '#done') {
    4134    if (window.testRunner)
    42       window.testRunner.notifyDone();
     35      testRunner.notifyDone();
    4336    return;
    4437  }
  • branches/safari-607-branch/LayoutTests/imported/blink/loader/iframe-sync-loads-expected.txt

    r190629 r245916  
    1  sync : src = javascript:"content"
     1ASYNC : src = javascript:"content"
    22ASYNC : src = data:text/html,content
    33ASYNC : srcdoc = "content"
  • branches/safari-607-branch/LayoutTests/js/dom/call-base-resolution.html

    r156066 r245916  
    55<body>
    66
    7 <script src="../../resources/js-test-pre.js"></script>
     7<script src="../../resources/js-test.js"></script>
    88  <script>
    99    window.name = "o";
     
    7878    ">
    7979  </iframe>
    80 <script src="../../resources/js-test-post.js"></script>
    81 
    8280</body>
    8381</html>
  • branches/safari-607-branch/LayoutTests/platform/wk2/http/tests/security/contentSecurityPolicy/block-all-mixed-content/insecure-image-in-javascript-url-iframe-in-iframe-expected.txt

    r231450 r245916  
    77frame "<!--frame2-->" - didHandleOnloadEventsForFrame
    88frame "<!--frame2-->" - didFinishLoadForFrame
     9frame "<!--frame2-->" - willPerformClientRedirectToURL: javascript:document.write('<img src=%22http://127.0.0.1:8000/security/resources/compass.jpg%22>');
     10frame "<!--frame1-->" - didFinishDocumentLoadForFrame
    911CONSOLE MESSAGE: Blocked mixed content http://127.0.0.1:8000/security/resources/compass.jpg because 'block-all-mixed-content' appears in the Content Security Policy.
    10 frame "<!--frame1-->" - didFinishDocumentLoadForFrame
    1112frame "<!--frame1-->" - didFinishLoadForFrame
    1213main frame - didFinishLoadForFrame
  • branches/safari-607-branch/Source/WebCore/ChangeLog

    r245463 r245916  
     12019-05-30  Kocsen Chung  <kocsen_chung@apple.com>
     2
     3        Cherry-pick r244892. rdar://problem/50753927
     4
     5    Setting a frame's src to a javascript URL should not run it synchronously
     6    https://bugs.webkit.org/show_bug.cgi?id=197466
     7   
     8    Reviewed by Darin Adler.
     9   
     10    Source/WebCore:
     11   
     12    When an iframe's src attribute is set to a javascript URL, whether when parsing
     13    or later on via JS, we now execute the URL's JavaScript asynchronously. We used
     14    to execute it synchronously, which was a source of bugs and also did not match
     15    other browsers.
     16   
     17    I have verified that our new behavior is aligned with both Firefox and Chrome.
     18   
     19    Note that for backward-compatibility and interoperability with Blink
     20    (https://bugs.chromium.org/p/chromium/issues/detail?id=923585), the
     21    "javascript:''" URL will still run synchronously. We should consider dropping
     22    this quirk at some point.
     23   
     24    Test: fast/dom/frame-src-javascript-url-async.html
     25   
     26    * loader/NavigationScheduler.cpp:
     27    (WebCore::ScheduledLocationChange::ScheduledLocationChange):
     28    (WebCore::ScheduledLocationChange::~ScheduledLocationChange):
     29    (WebCore::NavigationScheduler::scheduleLocationChange):
     30    * loader/NavigationScheduler.h:
     31    (WebCore::NavigationScheduler::scheduleLocationChange):
     32    * loader/SubframeLoader.cpp:
     33    (WebCore::SubframeLoader::requestFrame):
     34   
     35    LayoutTests:
     36   
     37    * fast/dom/frame-src-javascript-url-async-expected.txt: Added.
     38    * fast/dom/frame-src-javascript-url-async.html: Added.
     39    Add layout test coverage for the fact that the javascript URL is executed asynchronously
     40    whether set during parsing or later via JS. Also makes sure that executing the javascript
     41    URL asynchronously does not replace the frame's window. This test passes in both Chrome
     42    and Firefox.
     43   
     44    * imported/blink/fast/frames/navigation-in-pagehide.html:
     45    Re-sync this test from the Blink repository.
     46   
     47    * fast/dom/Element/id-in-frameset-expected.txt:
     48    * fast/dom/Element/id-in-frameset.html:
     49    * fast/dom/insertedIntoDocument-iframe-expected.txt:
     50    * fast/dom/javascript-url-exception-isolation-expected.txt:
     51    * fast/dom/javascript-url-exception-isolation.html:
     52    * fast/dom/no-assert-for-malformed-js-url-attribute-expected.txt:
     53    * fast/dom/resources/javascript-url-crash-function-iframe.html:
     54    * fast/frames/adopt-from-created-document.html:
     55    * fast/frames/out-of-document-iframe-has-child-frame.html:
     56    * fast/loader/javascript-url-iframe-remove-on-navigate-async-delegate.html:
     57    * fast/loader/javascript-url-iframe-remove-on-navigate.html:
     58    * fast/loader/unload-mutation-crash.html:
     59    * fast/parser/resources/set-parent-to-javascript-url.html:
     60    * fast/parser/xml-error-adopted.xml:
     61    * http/tests/navigation/lockedhistory-iframe-expected.txt:
     62    * http/tests/security/contentSecurityPolicy/block-all-mixed-content/insecure-image-in-javascript-url-iframe-in-iframe-expected.txt:
     63    * http/tests/security/contentSecurityPolicy/javascript-url-allowed-expected.txt:
     64    * http/tests/security/contentSecurityPolicy/javascript-url-blocked-by-default-src-star-expected.txt:
     65    * http/tests/security/contentSecurityPolicy/javascript-url-blocked-expected.txt:
     66    * http/tests/security/javascriptURL/xss-ALLOWED-from-javascript-url-sub-frame-2-level.html:
     67    * http/tests/security/javascriptURL/xss-ALLOWED-from-javascript-url-sub-frame.html:
     68    * http/tests/security/javascriptURL/xss-ALLOWED-to-javascript-url-from-javscript-url.html:
     69    * imported/blink/loader/iframe-sync-loads-expected.txt:
     70    * js/dom/call-base-resolution.html:
     71    * platform/wk2/http/tests/security/contentSecurityPolicy/block-all-mixed-content/insecure-image-in-javascript-url-iframe-in-iframe-expected.txt:
     72    Update / Rebaseline existing tests to reflect behavior change. I ran those tests in Firefox and Chrome to confirm that our behavior
     73    is indeed aligned.
     74   
     75   
     76    git-svn-id: https://svn.webkit.org/repository/webkit/trunk@244892 268f45cc-cd09-0410-ab3c-d52691b4dbfc
     77
     78    2019-05-02  Chris Dumez  <cdumez@apple.com>
     79
     80            Setting a frame's src to a javascript URL should not run it synchronously
     81            https://bugs.webkit.org/show_bug.cgi?id=197466
     82
     83            Reviewed by Darin Adler.
     84
     85            When an iframe's src attribute is set to a javascript URL, whether when parsing
     86            or later on via JS, we now execute the URL's JavaScript asynchronously. We used
     87            to execute it synchronously, which was a source of bugs and also did not match
     88            other browsers.
     89
     90            I have verified that our new behavior is aligned with both Firefox and Chrome.
     91
     92            Note that for backward-compatibility and interoperability with Blink
     93            (https://bugs.chromium.org/p/chromium/issues/detail?id=923585), the
     94            "javascript:''" URL will still run synchronously. We should consider dropping
     95            this quirk at some point.
     96
     97            Test: fast/dom/frame-src-javascript-url-async.html
     98
     99            * loader/NavigationScheduler.cpp:
     100            (WebCore::ScheduledLocationChange::ScheduledLocationChange):
     101            (WebCore::ScheduledLocationChange::~ScheduledLocationChange):
     102            (WebCore::NavigationScheduler::scheduleLocationChange):
     103            * loader/NavigationScheduler.h:
     104            (WebCore::NavigationScheduler::scheduleLocationChange):
     105            * loader/SubframeLoader.cpp:
     106            (WebCore::SubframeLoader::requestFrame):
     107
    11082019-05-17  Alan Coon  <alancoon@apple.com>
    2109
  • branches/safari-607-branch/Source/WebCore/loader/NavigationScheduler.cpp

    r238771 r245916  
    194194class ScheduledLocationChange : public ScheduledURLNavigation {
    195195public:
    196     ScheduledLocationChange(Document& initiatingDocument, SecurityOrigin* securityOrigin, const URL& url, const String& referrer, LockHistory lockHistory, LockBackForwardList lockBackForwardList, bool duringLoad)
    197         : ScheduledURLNavigation(initiatingDocument, 0.0, securityOrigin, url, referrer, lockHistory, lockBackForwardList, duringLoad, true) { }
     196    ScheduledLocationChange(Document& initiatingDocument, SecurityOrigin* securityOrigin, const URL& url, const String& referrer, LockHistory lockHistory, LockBackForwardList lockBackForwardList, bool duringLoad, CompletionHandler<void()>&& completionHandler)
     197        : ScheduledURLNavigation(initiatingDocument, 0.0, securityOrigin, url, referrer, lockHistory, lockBackForwardList, duringLoad, true)
     198        , m_completionHandler(WTFMove(completionHandler))
     199    {
     200    }
     201
     202    ~ScheduledLocationChange()
     203    {
     204        if (m_completionHandler)
     205            m_completionHandler();
     206    }
    198207
    199208    void fire(Frame& frame) override
     
    204213        FrameLoadRequest frameLoadRequest { initiatingDocument(), *securityOrigin(), resourceRequest, "_self", lockHistory(), lockBackForwardList(), MaybeSendReferrer, AllowNavigationToInvalidURL::No, NewFrameOpenerPolicy::Allow, shouldOpenExternalURLs(), initiatedByMainFrame() };
    205214
     215        auto completionHandler = WTFMove(m_completionHandler);
    206216        frame.loader().changeLocation(WTFMove(frameLoadRequest));
    207     }
     217        completionHandler();
     218    }
     219
     220private:
     221    CompletionHandler<void()> m_completionHandler;
    208222};
    209223
     
    406420}
    407421
    408 void NavigationScheduler::scheduleLocationChange(Document& initiatingDocument, SecurityOrigin& securityOrigin, const URL& url, const String& referrer, LockHistory lockHistory, LockBackForwardList lockBackForwardList)
     422void NavigationScheduler::scheduleLocationChange(Document& initiatingDocument, SecurityOrigin& securityOrigin, const URL& url, const String& referrer, LockHistory lockHistory, LockBackForwardList lockBackForwardList, CompletionHandler<void()>&& completionHandler)
    409423{
    410424    if (!shouldScheduleNavigation(url))
    411         return;
     425        return completionHandler();
    412426
    413427    if (lockBackForwardList == LockBackForwardList::No)
     
    425439        FrameLoadRequest frameLoadRequest { initiatingDocument, securityOrigin, resourceRequest, "_self"_s, lockHistory, lockBackForwardList, MaybeSendReferrer, AllowNavigationToInvalidURL::No, NewFrameOpenerPolicy::Allow, initiatingDocument.shouldOpenExternalURLsPolicyToPropagate(), initiatedByMainFrame };
    426440        loader.changeLocation(WTFMove(frameLoadRequest));
    427         return;
     441        return completionHandler();
    428442    }
    429443
     
    432446    bool duringLoad = !loader.stateMachine().committedFirstRealDocumentLoad();
    433447
    434     schedule(std::make_unique<ScheduledLocationChange>(initiatingDocument, &securityOrigin, url, referrer, lockHistory, lockBackForwardList, duringLoad));
     448    schedule(std::make_unique<ScheduledLocationChange>(initiatingDocument, &securityOrigin, url, referrer, lockHistory, lockBackForwardList, duringLoad, WTFMove(completionHandler)));
    435449}
    436450
  • branches/safari-607-branch/Source/WebCore/loader/NavigationScheduler.h

    r238771 r245916  
    5454
    5555    void scheduleRedirect(Document& initiatingDocument, double delay, const URL&);
    56     void scheduleLocationChange(Document& initiatingDocument, SecurityOrigin&, const URL&, const String& referrer, LockHistory = LockHistory::Yes, LockBackForwardList = LockBackForwardList::Yes);
     56    void scheduleLocationChange(Document& initiatingDocument, SecurityOrigin&, const URL&, const String& referrer, LockHistory = LockHistory::Yes, LockBackForwardList = LockBackForwardList::Yes, CompletionHandler<void()>&& = [] { });
    5757    void scheduleFormSubmission(Ref<FormSubmission>&&);
    5858    void scheduleRefresh(Document& initiatingDocument);
  • branches/safari-607-branch/Source/WebCore/loader/SubframeLoader.cpp

    r238771 r245916  
    5757#include "SecurityPolicy.h"
    5858#include "Settings.h"
     59#include <wtf/CompletionHandler.h>
    5960
    6061namespace WebCore {
     
    8788        url = WTF::blankURL();
    8889
    89     bool hasExistingFrame = ownerElement.contentFrame();
     90    // If we will schedule a JavaScript URL load, we need to delay the firing of the load event at least until we've run the JavaScript in the URL.
     91    CompletionHandlerCallingScope stopDelayingLoadEvent;
     92    if (!scriptURL.isEmpty()) {
     93        ownerElement.document().incrementLoadEventDelayCount();
     94        stopDelayingLoadEvent = CompletionHandlerCallingScope([ownerDocument = makeRef(ownerElement.document())] {
     95            ownerDocument->decrementLoadEventDelayCount();
     96        });
     97    }
     98
    9099    Frame* frame = loadOrRedirectSubframe(ownerElement, url, frameName, lockHistory, lockBackForwardList);
    91100    if (!frame)
    92101        return false;
    93102
    94     // If we create a new subframe then an empty document is loaded into it synchronously and may
    95     // cause script execution (say, via a DOM load event handler) that can do anything, including
    96     // navigating the subframe. We only want to evaluate scriptURL if the frame has not been navigated.
    97     bool canExecuteScript = hasExistingFrame || (frame->loader().documentLoader() && frame->loader().documentLoader()->originalURL() == WTF::blankURL());
    98     if (!scriptURL.isEmpty() && canExecuteScript && ownerElement.isURLAllowed(scriptURL))
    99         frame->script().executeIfJavaScriptURL(scriptURL);
     103    if (!scriptURL.isEmpty() && ownerElement.isURLAllowed(scriptURL)) {
     104        // FIXME: Some sites rely on the javascript:'' loading synchronously, which is why we have this special case.
     105        // Blink has the same workaround (https://bugs.chromium.org/p/chromium/issues/detail?id=923585).
     106        if (urlString == "javascript:''" || urlString == "javascript:\"\"")
     107            frame->script().executeIfJavaScriptURL(scriptURL);
     108        else
     109            frame->navigationScheduler().scheduleLocationChange(ownerElement.document(), ownerElement.document().securityOrigin(), scriptURL, m_frame.loader().outgoingReferrer(), lockHistory, lockBackForwardList, stopDelayingLoadEvent.release());
     110    }
    100111
    101112    return true;
Note: See TracChangeset for help on using the changeset viewer.