Title: [230919] trunk
Revision
230919
Author
[email protected]
Date
2018-04-23 13:49:57 -0700 (Mon, 23 Apr 2018)

Log Message

HTML String load cannot be prevented by responding 'Cancel' asynchronously in decidePolicyForNavigationAction
https://bugs.webkit.org/show_bug.cgi?id=184848
<rdar://problem/39145306>

Reviewed by Brady Eidson.

Source/WebCore:

When calling loadHTMLString on a WebView, we end up doing a load for 'about:blank'
with substitute data. In such case, we want to do a regular asynchronous policy
delegate check, there is no reason we need it to be synchronous. Update our check
to make sure we only do a synchronous policy check for initial 'about:blank' loads
that do not have substitute data.

* loader/PolicyChecker.cpp:
(WebCore::PolicyChecker::checkNavigationPolicy):

Tools:

Add API test coverage.

* TestWebKitAPI/Tests/WebKitCocoa/DecidePolicyForNavigationAction.mm:
(-[DecidePolicyForNavigationActionController webView:decidePolicyForNavigationAction:decisionHandler:]):
(TEST):

LayoutTests:

Update layout tests that wrongly expected 'about:blank' to load synchronously even
when it is not the initial empty document of an iframe. I have checked that our
behavior is now consistent with Chrome.

* fast/events/beforeunload-alert-user-interaction2.html:
* http/tests/security/cross-origin-reified-window-location-setting-expected.txt:
* http/tests/security/cross-origin-reified-window-location-setting.html:
* webarchive/loading/_javascript_-url-iframe-crash-expected.txt:

Modified Paths

Added Paths

Diff

Modified: trunk/LayoutTests/ChangeLog (230918 => 230919)


--- trunk/LayoutTests/ChangeLog	2018-04-23 20:29:36 UTC (rev 230918)
+++ trunk/LayoutTests/ChangeLog	2018-04-23 20:49:57 UTC (rev 230919)
@@ -1,3 +1,20 @@
+2018-04-23  Chris Dumez  <[email protected]>
+
+        HTML String load cannot be prevented by responding 'Cancel' asynchronously in decidePolicyForNavigationAction
+        https://bugs.webkit.org/show_bug.cgi?id=184848
+        <rdar://problem/39145306>
+
+        Reviewed by Brady Eidson.
+
+        Update layout tests that wrongly expected 'about:blank' to load synchronously even
+        when it is not the initial empty document of an iframe. I have checked that our
+        behavior is now consistent with Chrome.
+
+        * fast/events/beforeunload-alert-user-interaction2.html:
+        * http/tests/security/cross-origin-reified-window-location-setting-expected.txt:
+        * http/tests/security/cross-origin-reified-window-location-setting.html:
+        * webarchive/loading/_javascript_-url-iframe-crash-expected.txt:
+
 2018-04-23  Wenson Hsieh  <[email protected]>
 
         [Extra zoom mode] 100vw is roughly half of the viewport width in extra zoom mode

Modified: trunk/LayoutTests/fast/events/beforeunload-alert-user-interaction2.html (230918 => 230919)


--- trunk/LayoutTests/fast/events/beforeunload-alert-user-interaction2.html	2018-04-23 20:29:36 UTC (rev 230918)
+++ trunk/LayoutTests/fast/events/beforeunload-alert-user-interaction2.html	2018-04-23 20:49:57 UTC (rev 230919)
@@ -16,8 +16,8 @@
     const testInput = document.getElementById("testInput");
     UIHelper.activateAt(testInput.offsetLeft + 5, testInput.offsetTop + 5).then(function() {
         setTimeout(function() {
+            testFrame._onload_ = finishJSTest;
             testFrame.src = ""
-            setTimeout(finishJSTest, 0);
         }, 0);
     });
 };

Modified: trunk/LayoutTests/http/tests/security/cross-origin-reified-window-location-setting-expected.txt (230918 => 230919)


--- trunk/LayoutTests/http/tests/security/cross-origin-reified-window-location-setting-expected.txt	2018-04-23 20:29:36 UTC (rev 230918)
+++ trunk/LayoutTests/http/tests/security/cross-origin-reified-window-location-setting-expected.txt	2018-04-23 20:49:57 UTC (rev 230919)
@@ -3,7 +3,9 @@
 On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
 
 
+PASS crossOriginWindow.location.href threw exception SecurityError: Blocked a frame with origin "http://127.0.0.1:8000" from accessing a cross-origin frame. Protocols, domains, and ports must match..
 PASS crossOriginWindow.location = 'about:blank' did not throw exception.
+PASS crossOriginWindow.location.href threw exception SecurityError: Blocked a frame with origin "http://127.0.0.1:8000" from accessing a cross-origin frame. Protocols, domains, and ports must match..
 PASS crossOriginWindow.location.href is "about:blank"
 PASS successfullyParsed is true
 

Modified: trunk/LayoutTests/http/tests/security/cross-origin-reified-window-location-setting.html (230918 => 230919)


--- trunk/LayoutTests/http/tests/security/cross-origin-reified-window-location-setting.html	2018-04-23 20:29:36 UTC (rev 230918)
+++ trunk/LayoutTests/http/tests/security/cross-origin-reified-window-location-setting.html	2018-04-23 20:49:57 UTC (rev 230919)
@@ -1,7 +1,7 @@
 <!DOCTYPE html>
 <html>
 <head>
-<script src=""
+<script src=""
 </head>
 <body _onload_="runTest()">
 <iframe id="crossOriginFrame" src=""
@@ -11,15 +11,19 @@
 
 function runTest()
 {
-    crossOriginWindow = crossOriginFrame.window;
+    crossOriginWindow = document.getElementById("crossOriginFrame").contentWindow;
+    shouldThrow("crossOriginWindow.location.href");
     shouldNotThrow("crossOriginWindow.location = 'about:blank'");
-
-    setTimeout(function() {
-        shouldBeEqualToString("crossOriginWindow.location.href", "about:blank");
-        finishJSTest();
-    }, 0);
+    shouldThrow("crossOriginWindow.location.href");
+    handle = setInterval(function() {
+        try {
+            crossOriginWindow.location.href;
+            shouldBeEqualToString("crossOriginWindow.location.href", "about:blank");
+            clearInterval(handle);
+            finishJSTest();
+        } catch(e) { }
+    }, 5);
 }
 </script>
 </body>
-<script src=""
 </html>

Added: trunk/LayoutTests/platform/wk2/webarchive/loading/_javascript_-url-iframe-crash-expected.txt (0 => 230919)


--- trunk/LayoutTests/platform/wk2/webarchive/loading/_javascript_-url-iframe-crash-expected.txt	                        (rev 0)
+++ trunk/LayoutTests/platform/wk2/webarchive/loading/_javascript_-url-iframe-crash-expected.txt	2018-04-23 20:49:57 UTC (rev 230919)
@@ -0,0 +1,15 @@
+main frame - didStartProvisionalLoadForFrame
+main frame - didCommitLoadForFrame
+main frame - willPerformClientRedirectToURL: resources/_javascript_-url-iframe-crash.webarchive 
+main frame - didFinishDocumentLoadForFrame
+main frame - didFinishLoadForFrame
+main frame - didStartProvisionalLoadForFrame
+main frame - didCancelClientRedirectForFrame
+main frame - didCommitLoadForFrame
+frame "<!--framePath //<!--frame0-->-->" - didFinishDocumentLoadForFrame
+frame "<!--framePath //<!--frame0-->-->" - didHandleOnloadEventsForFrame
+main frame - didFinishDocumentLoadForFrame
+main frame - didHandleOnloadEventsForFrame
+main frame - didFinishLoadForFrame
+Loading this webarchive with a "non-empty _javascript_ URL iframe" should not crash.
+

Modified: trunk/Source/WebCore/ChangeLog (230918 => 230919)


--- trunk/Source/WebCore/ChangeLog	2018-04-23 20:29:36 UTC (rev 230918)
+++ trunk/Source/WebCore/ChangeLog	2018-04-23 20:49:57 UTC (rev 230919)
@@ -1,3 +1,20 @@
+2018-04-23  Chris Dumez  <[email protected]>
+
+        HTML String load cannot be prevented by responding 'Cancel' asynchronously in decidePolicyForNavigationAction
+        https://bugs.webkit.org/show_bug.cgi?id=184848
+        <rdar://problem/39145306>
+
+        Reviewed by Brady Eidson.
+
+        When calling loadHTMLString on a WebView, we end up doing a load for 'about:blank'
+        with substitute data. In such case, we want to do a regular asynchronous policy
+        delegate check, there is no reason we need it to be synchronous. Update our check
+        to make sure we only do a synchronous policy check for initial 'about:blank' loads
+        that do not have substitute data.
+
+        * loader/PolicyChecker.cpp:
+        (WebCore::PolicyChecker::checkNavigationPolicy):
+
 2018-04-23  Wenson Hsieh  <[email protected]>
 
         [Extra zoom mode] 100vw is roughly half of the viewport width in extra zoom mode

Modified: trunk/Source/WebCore/loader/PolicyChecker.cpp (230918 => 230919)


--- trunk/Source/WebCore/loader/PolicyChecker.cpp	2018-04-23 20:29:36 UTC (rev 230918)
+++ trunk/Source/WebCore/loader/PolicyChecker.cpp	2018-04-23 20:49:57 UTC (rev 230919)
@@ -123,7 +123,8 @@
 
     loader->setLastCheckedRequest(ResourceRequest(request));
 
-    if (request.url().isBlankURL())
+    // Initial 'about:blank' load needs to happen synchronously so the policy check needs to be synchronous in this case.
+    if (!m_frame.loader().stateMachine().committedFirstRealDocumentLoad() && request.url().isBlankURL() && !substituteData.isValid())
         policyDecisionMode = PolicyDecisionMode::Synchronous;
 
 #if USE(QUICK_LOOK)

Modified: trunk/Tools/ChangeLog (230918 => 230919)


--- trunk/Tools/ChangeLog	2018-04-23 20:29:36 UTC (rev 230918)
+++ trunk/Tools/ChangeLog	2018-04-23 20:49:57 UTC (rev 230919)
@@ -1,3 +1,17 @@
+2018-04-23  Chris Dumez  <[email protected]>
+
+        HTML String load cannot be prevented by responding 'Cancel' asynchronously in decidePolicyForNavigationAction
+        https://bugs.webkit.org/show_bug.cgi?id=184848
+        <rdar://problem/39145306>
+
+        Reviewed by Brady Eidson.
+
+        Add API test coverage.
+
+        * TestWebKitAPI/Tests/WebKitCocoa/DecidePolicyForNavigationAction.mm:
+        (-[DecidePolicyForNavigationActionController webView:decidePolicyForNavigationAction:decisionHandler:]):
+        (TEST):
+
 2018-04-23  Michael Catanzaro  <[email protected]>
 
         [GTK][WPE] TestSSL fails due to additional TLS errors returned

Modified: trunk/Tools/TestWebKitAPI/Tests/WebKitCocoa/DecidePolicyForNavigationAction.mm (230918 => 230919)


--- trunk/Tools/TestWebKitAPI/Tests/WebKitCocoa/DecidePolicyForNavigationAction.mm	2018-04-23 20:29:36 UTC (rev 230918)
+++ trunk/Tools/TestWebKitAPI/Tests/WebKitCocoa/DecidePolicyForNavigationAction.mm	2018-04-23 20:49:57 UTC (rev 230919)
@@ -35,6 +35,7 @@
 
 #if WK_API_ENABLED
 
+static bool shouldCancelNavigation;
 static bool createdWebView;
 static bool decidedPolicy;
 static bool finishedNavigation;
@@ -51,6 +52,16 @@
 
 - (void)webView:(WKWebView *)webView decidePolicyForNavigationAction:(WKNavigationAction *)navigationAction decisionHandler:(void (^)(WKNavigationActionPolicy))decisionHandler
 {
+    if (shouldCancelNavigation) {
+        int64_t deferredWaitTime = 100 * NSEC_PER_MSEC;
+        dispatch_time_t when = dispatch_time(DISPATCH_TIME_NOW, deferredWaitTime);
+        dispatch_after(when, dispatch_get_main_queue(), ^{
+            decisionHandler(WKNavigationActionPolicyCancel);
+            decidedPolicy = true;
+        });
+        return;
+    }
+
     decisionHandler(webView == newWebView.get() ? WKNavigationActionPolicyCancel : WKNavigationActionPolicyAllow);
 
     action = ""
@@ -285,7 +296,7 @@
     action = ""
 }
 
-TEST(WebKit, DecidePolicyForNavigationActionForLoadHTMLString)
+TEST(WebKit, DecidePolicyForNavigationActionForLoadHTMLStringAllow)
 {
     auto webView = adoptNS([[WKWebView alloc] initWithFrame:NSMakeRect(0, 0, 800, 600)]);
 
@@ -296,11 +307,33 @@
     [webView setNavigationDelegate:controller.get()];
     [webView setUIDelegate:controller.get()];
 
+    finishedNavigation = false;
     decidedPolicy = false;
     [webView loadHTMLString:@"TEST" baseURL:[NSURL URLWithString:@"about:blank"]];
-    TestWebKitAPI::Util::run(&decidedPolicy);
+    TestWebKitAPI::Util::run(&finishedNavigation);
+    EXPECT_TRUE(decidedPolicy);
 }
 
+TEST(WebKit, DecidePolicyForNavigationActionForLoadHTMLStringDeny)
+{
+    auto webView = adoptNS([[WKWebView alloc] initWithFrame:NSMakeRect(0, 0, 800, 600)]);
+
+    auto window = adoptNS([[NSWindow alloc] initWithContentRect:[webView frame] styleMask:NSWindowStyleMaskBorderless backing:NSBackingStoreBuffered defer:YES]);
+    [[window contentView] addSubview:webView.get()];
+
+    auto controller = adoptNS([[DecidePolicyForNavigationActionController alloc] init]);
+    [webView setNavigationDelegate:controller.get()];
+    [webView setUIDelegate:controller.get()];
+
+    shouldCancelNavigation = true;
+    finishedNavigation = false;
+    decidedPolicy = false;
+    [webView loadHTMLString:@"TEST" baseURL:[NSURL URLWithString:@"about:blank"]];
+    TestWebKitAPI::Util::sleep(0.5);
+    EXPECT_FALSE(finishedNavigation);
+    shouldCancelNavigation = false;
+}
+
 TEST(WebKit, DecidePolicyForNavigationActionForTargetedWindowOpen)
 {
     auto webView = adoptNS([[WKWebView alloc] initWithFrame:NSMakeRect(0, 0, 800, 600)]);
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to