Universal links from Google search results pages don't open the app.
authorbeidson@apple.com <beidson@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Thu, 28 Feb 2019 00:50:30 +0000 (00:50 +0000)
committerbeidson@apple.com <beidson@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Thu, 28 Feb 2019 00:50:30 +0000 (00:50 +0000)
<rdar://problem/46887179> and https://bugs.webkit.org/show_bug.cgi?id=195126

Reviewed by Geoffrey Garen.

Source/WebCore:

Covered by new API tests.

* loader/DocumentLoader.cpp:
(WebCore::DocumentLoader::shouldOpenExternalURLsPolicyToPropagate const): Propagate the external URL policy from
  an iframe if it is from the same security origin as the main frame.

Tools:

* TestWebKitAPI/Tests/WebKitCocoa/ShouldOpenExternalURLsInNewWindowActions.mm:
* TestWebKitAPI/cocoa/TestNavigationDelegate.h:
* TestWebKitAPI/cocoa/TestNavigationDelegate.mm:
(-[TestNavigationDelegate webView:decidePolicyForNavigationAction:decisionHandler:]):

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

Source/WebCore/ChangeLog
Source/WebCore/loader/DocumentLoader.cpp
Tools/ChangeLog
Tools/TestWebKitAPI/Tests/WebKitCocoa/ShouldOpenExternalURLsInNewWindowActions.mm
Tools/TestWebKitAPI/cocoa/TestNavigationDelegate.h
Tools/TestWebKitAPI/cocoa/TestNavigationDelegate.mm

index a717f9a..21536ae 100644 (file)
@@ -1,3 +1,16 @@
+2019-02-27  Brady Eidson  <beidson@apple.com>
+
+        Universal links from Google search results pages don't open the app.
+        <rdar://problem/46887179> and https://bugs.webkit.org/show_bug.cgi?id=195126
+
+        Reviewed by Geoffrey Garen.
+
+        Covered by new API tests.
+
+        * loader/DocumentLoader.cpp:
+        (WebCore::DocumentLoader::shouldOpenExternalURLsPolicyToPropagate const): Propagate the external URL policy from
+          an iframe if it is from the same security origin as the main frame.
+
 2019-02-27  Zalan Bujtas  <zalan@apple.com>
 
         [ContentChangeObserver] Move DOMTimer schedule handling from global to ContentChangeObserver class
index f963c5d..b0f94a5 100644 (file)
@@ -2076,10 +2076,18 @@ void DocumentLoader::setTriggeringAction(NavigationAction&& action)
 
 ShouldOpenExternalURLsPolicy DocumentLoader::shouldOpenExternalURLsPolicyToPropagate() const
 {
-    if (!m_frame || !m_frame->isMainFrame())
+    if (!m_frame)
         return ShouldOpenExternalURLsPolicy::ShouldNotAllow;
 
-    return m_shouldOpenExternalURLsPolicy;
+    if (m_frame->isMainFrame())
+        return m_shouldOpenExternalURLsPolicy;
+
+    if (auto* currentDocument = document()) {
+        if (originsMatch(currentDocument->securityOrigin(), currentDocument->topOrigin()))
+            return m_shouldOpenExternalURLsPolicy;
+    }
+
+    return ShouldOpenExternalURLsPolicy::ShouldNotAllow;
 }
 
 void DocumentLoader::becomeMainResourceClient()
index 4c28090..5a91204 100644 (file)
@@ -1,3 +1,15 @@
+2019-02-27  Brady Eidson  <beidson@apple.com>
+
+        Universal links from Google search results pages don't open the app.
+        <rdar://problem/46887179> and https://bugs.webkit.org/show_bug.cgi?id=195126
+
+        Reviewed by Geoffrey Garen.
+
+        * TestWebKitAPI/Tests/WebKitCocoa/ShouldOpenExternalURLsInNewWindowActions.mm:
+        * TestWebKitAPI/cocoa/TestNavigationDelegate.h:
+        * TestWebKitAPI/cocoa/TestNavigationDelegate.mm:
+        (-[TestNavigationDelegate webView:decidePolicyForNavigationAction:decisionHandler:]):
+
 2019-02-27  Chris Dumez  <cdumez@apple.com>
 
         Flaky API Test: TestWebKitAPI.ProcessSwap.NumberOfCachedProcesses
index a1263e7..aa0010e 100644 (file)
@@ -28,6 +28,8 @@
 #if PLATFORM(MAC)
 
 #import "PlatformUtilities.h"
+#import "TestNavigationDelegate.h"
+#import "TestURLSchemeHandler.h"
 #import <WebKit/WKNavigationActionPrivate.h>
 #import <WebKit/WKWebViewPrivate.h>
 #import <wtf/RetainPtr.h>
@@ -250,6 +252,82 @@ TEST(WebKit, RestoreShouldOpenExternalURLsPolicyAfterCrash)
     ASSERT_FALSE([action _shouldOpenAppLinks]);
 };
 
+
+
+static const char* iframeBytes = R"schemeresource(
+<script>
+top.location.href = "externalScheme://someotherhost/foo";
+</script>
+)schemeresource";
+
+static const char* mainFrameBytes = R"schemeresource(
+<script>
+function clicked() {
+    var iframe = document.createElement('iframe');
+    iframe.src = "custom://firsthost/iframe.html";
+    document.body.appendChild(iframe);
+}
+</script>
+
+<a style="display: block; height: 100%" onclick="clicked();">Click to start iframe dance</a>
+)schemeresource";
+
+TEST(WebKit, IFrameWithSameOriginAsMainFramePropagates)
+{
+    auto schemeHandler = adoptNS([[TestURLSchemeHandler alloc] init]);
+    auto configuration = adoptNS([[WKWebViewConfiguration alloc] init]);
+    [configuration setURLSchemeHandler:schemeHandler.get() forURLScheme:@"custom"];
+
+    [schemeHandler setStartURLSchemeTaskHandler:^(WKWebView *, id<WKURLSchemeTask> task) {
+        NSURL *requestURL = [task request].URL;
+        
+        NSString *responseText = nil;
+        if ([[task request].URL.absoluteString containsString:@"iframe.html"])
+            responseText = [NSString stringWithUTF8String:iframeBytes];
+        else if ([[task request].URL.absoluteString containsString:@"mainframe.html"])
+            responseText = [NSString stringWithUTF8String:mainFrameBytes];
+
+        auto response = adoptNS([[NSURLResponse alloc] initWithURL:requestURL MIMEType:@"text/html" expectedContentLength:[responseText length] textEncodingName:nil]);
+        [task didReceiveResponse:response.get()];
+        [task didReceiveData:[responseText dataUsingEncoding:NSUTF8StringEncoding]];
+        [task didFinish];
+    }];
+
+    auto webView = adoptNS([[WKWebView alloc] initWithFrame:NSMakeRect(0, 0, 800, 600) configuration:configuration.get()]);
+    auto navigationDelegate = adoptNS([[TestNavigationDelegate alloc] init]);
+    [webView setNavigationDelegate:navigationDelegate.get()];
+
+    [webView loadRequest:[NSURLRequest requestWithURL:[NSURL URLWithString:@"custom://firsthost/mainframe.html"]]];
+    [navigationDelegate waitForDidFinishNavigation];
+    
+    // Install the decidePolicyListener
+    static bool openAppLinks;
+    static bool externalSchemes;
+    static bool finished = false;
+    navigationDelegate.get().decidePolicyForNavigationAction = ^(WKNavigationAction *action, void (^decisionHandler)(WKNavigationActionPolicy)) {
+        if (!action.targetFrame.mainFrame) {
+            decisionHandler(WKNavigationActionPolicyAllow);
+            return;
+        }
+
+        openAppLinks = [action _shouldOpenAppLinks];
+        externalSchemes = [action _shouldOpenExternalSchemes];
+        
+        decisionHandler(WKNavigationActionPolicyCancel);
+        finished = true;
+    };
+    
+    // Click the link
+    NSPoint clickPoint = NSMakePoint(100, 100);
+    [[webView hitTest:clickPoint] mouseDown:[NSEvent mouseEventWithType:NSEventTypeLeftMouseDown location:clickPoint modifierFlags:0 timestamp:0 windowNumber:[webView.get().window windowNumber] context:nil eventNumber:0 clickCount:1 pressure:1]];
+    [[webView hitTest:clickPoint] mouseUp:[NSEvent mouseEventWithType:NSEventTypeLeftMouseUp location:clickPoint modifierFlags:0 timestamp:0 windowNumber:[webView.get().window windowNumber] context:nil eventNumber:0 clickCount:1 pressure:1]];
+
+    TestWebKitAPI::Util::run(&finished);
+    
+    ASSERT_TRUE(openAppLinks);
+    ASSERT_TRUE(externalSchemes);
+};
+
 #endif
 
 #endif
index 16a0bce..ff785f6 100644 (file)
@@ -32,6 +32,7 @@
 
 @interface TestNavigationDelegate : NSObject <WKNavigationDelegate>
 
+@property (nonatomic, copy) void (^decidePolicyForNavigationAction)(WKNavigationAction *, void (^)(WKNavigationActionPolicy));
 @property (nonatomic, copy) void (^didFailProvisionalNavigation)(WKWebView *, WKNavigation *, NSError *);
 @property (nonatomic, copy) void (^didStartProvisionalNavigation)(WKWebView *, WKNavigation *);
 @property (nonatomic, copy) void (^didFinishNavigation)(WKWebView *, WKNavigation *);
index ecd3551..b49b73d 100644 (file)
 
 @implementation TestNavigationDelegate
 
+- (void)webView:(WKWebView *)webView decidePolicyForNavigationAction:(WKNavigationAction *)navigationAction decisionHandler:(void (^)(WKNavigationActionPolicy))decisionHandler
+{
+    if (_decidePolicyForNavigationAction)
+        _decidePolicyForNavigationAction(navigationAction, decisionHandler);
+    else
+        decisionHandler(WKNavigationActionPolicyAllow);
+}
+
 - (void)webView:(WKWebView *)webView didStartProvisionalNavigation:(WKNavigation *)navigation
 {
     if (_didStartProvisionalNavigation)