Regression(PSON) "Reload without content extensions" does not work when the main...
authorcdumez@apple.com <cdumez@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Wed, 20 Feb 2019 23:30:03 +0000 (23:30 +0000)
committercdumez@apple.com <cdumez@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Wed, 20 Feb 2019 23:30:03 +0000 (23:30 +0000)
https://bugs.webkit.org/show_bug.cgi?id=194872
<rdar://problem/47924500>

Reviewed by Alex Christensen.

Source/WebKit:

[WKWebView _reloadWithoutContentBlockers] relies on a ReloadOption flag that is passed to WebCore
instead of using WebsitePolicies.contentBlockersEnabled flag. If the reload causes a process swap
due to PSON, then the new process does not know about this ReloadOption and fails to honor it.

Since the modern way to do this is WebsitePolicies, and since WebsitePolicies are properly
propagated cross-process in case of process swap, this patch updates _reloadWithoutContentBlockers
to set a flag on the Navigation which we use to later set the WebsitePolicies.contentBlockersEnabled
flag in WebPageProxy::receivedNavigationPolicyDecision().

* UIProcess/API/APINavigation.h:
(API::Navigation::setUserContentExtensionsEnabled):
(API::Navigation::userContentExtensionsEnabled const):
* UIProcess/WebPageProxy.cpp:
(WebKit::WebPageProxy::reload):
(WebKit::WebPageProxy::receivedNavigationPolicyDecision):

Tools:

Add API test coverage.

* TestWebKitAPI/Tests/WebKitCocoa/ProcessSwapOnNavigation.mm:

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

Source/WebKit/ChangeLog
Source/WebKit/UIProcess/API/APINavigation.h
Source/WebKit/UIProcess/WebPageProxy.cpp
Tools/ChangeLog
Tools/TestWebKitAPI/Tests/WebKitCocoa/ProcessSwapOnNavigation.mm

index 014882f..405e9ad 100644 (file)
@@ -1,3 +1,27 @@
+2019-02-20  Chris Dumez  <cdumez@apple.com>
+
+        Regression(PSON) "Reload without content extensions" does not work when the main resource is blocked
+        https://bugs.webkit.org/show_bug.cgi?id=194872
+        <rdar://problem/47924500>
+
+        Reviewed by Alex Christensen.
+
+        [WKWebView _reloadWithoutContentBlockers] relies on a ReloadOption flag that is passed to WebCore
+        instead of using WebsitePolicies.contentBlockersEnabled flag. If the reload causes a process swap
+        due to PSON, then the new process does not know about this ReloadOption and fails to honor it.
+
+        Since the modern way to do this is WebsitePolicies, and since WebsitePolicies are properly
+        propagated cross-process in case of process swap, this patch updates _reloadWithoutContentBlockers
+        to set a flag on the Navigation which we use to later set the WebsitePolicies.contentBlockersEnabled
+        flag in WebPageProxy::receivedNavigationPolicyDecision().
+
+        * UIProcess/API/APINavigation.h:
+        (API::Navigation::setUserContentExtensionsEnabled):
+        (API::Navigation::userContentExtensionsEnabled const):
+        * UIProcess/WebPageProxy.cpp:
+        (WebKit::WebPageProxy::reload):
+        (WebKit::WebPageProxy::receivedNavigationPolicyDecision):
+
 2019-02-20  Truitt Savell  <tsavell@apple.com>
 
         Unreviewed, rolling out r241817.
index c996c36..1ac3c43 100644 (file)
@@ -124,6 +124,9 @@ public:
     bool openedByDOMWithOpener() const { return m_lastNavigationAction.openedByDOMWithOpener; }
     const WebCore::SecurityOriginData& requesterOrigin() const { return m_lastNavigationAction.requesterOrigin; }
 
+    void setUserContentExtensionsEnabled(bool enabled) { m_userContentExtensionsEnabled = enabled; }
+    bool userContentExtensionsEnabled() const { return m_userContentExtensionsEnabled; }
+
     WebCore::LockHistory lockHistory() const { return m_lastNavigationAction.lockHistory; }
     WebCore::LockBackForwardList lockBackForwardList() const { return m_lastNavigationAction.lockBackForwardList; }
 
@@ -165,6 +168,7 @@ private:
     WebKit::NavigationActionData m_lastNavigationAction;
     WebKit::FrameInfoData m_originatingFrameInfo;
     WebCore::SecurityOriginData m_destinationFrameSecurityOrigin;
+    bool m_userContentExtensionsEnabled { true };
 };
 
 } // namespace API
index fc19ce0..5a7a933 100644 (file)
@@ -1346,6 +1346,11 @@ RefPtr<API::Navigation> WebPageProxy::reload(OptionSet<WebCore::ReloadOption> op
     
     auto navigation = m_navigationState->createReloadNavigation();
 
+    // Store decision to reload without content blockers on the navigation so that we can later set the corresponding
+    // WebsitePolicies flag in WebPageProxy::receivedNavigationPolicyDecision().
+    if (options.contains(WebCore::ReloadOption::DisableContentBlockers))
+        navigation->setUserContentExtensionsEnabled(false);
+
     m_process->send(Messages::WebPage::Reload(navigation->navigationID(), options.toRaw(), sandboxExtensionHandle), m_pageID);
     m_process->responsivenessTimer().start();
 
@@ -2740,6 +2745,12 @@ void WebPageProxy::receivedNavigationPolicyDecision(PolicyAction policyAction, A
             changeWebsiteDataStore(policies->websiteDataStore()->websiteDataStore());
     }
 
+    if (navigation && !navigation->userContentExtensionsEnabled()) {
+        if (!data)
+            data = WebsitePoliciesData { };
+        data->contentBlockersEnabled = false;
+    }
+
     if (policyAction == PolicyAction::Use && navigation && (navigation->isSystemPreview() || navigation->shouldForceDownload()))
         policyAction = PolicyAction::Download;
 
index 0da744f..288beb0 100644 (file)
@@ -1,3 +1,15 @@
+2019-02-20  Chris Dumez  <cdumez@apple.com>
+
+        Regression(PSON) "Reload without content extensions" does not work when the main resource is blocked
+        https://bugs.webkit.org/show_bug.cgi?id=194872
+        <rdar://problem/47924500>
+
+        Reviewed by Alex Christensen.
+
+        Add API test coverage.
+
+        * TestWebKitAPI/Tests/WebKitCocoa/ProcessSwapOnNavigation.mm:
+
 2019-02-20  Jer Noble  <jer.noble@apple.com>
 
         Add a git utility method that allows the caller to determine if a specific commitish is within a specified range of commits.
index 1f210ac..ae764b5 100644 (file)
@@ -4913,6 +4913,81 @@ TEST(ProcessSwap, ContentBlockingAfterProcessSwap)
     done = false;
 }
 
+static const char* notifyLoadedBytes = R"PSONRESOURCE(
+<script>
+    window.webkit.messageHandlers.pson.postMessage("Loaded");
+</script>
+)PSONRESOURCE";
+
+TEST(ProcessSwap, ContentExtensionBlocksMainLoadThenReloadWithoutExtensions)
+{
+    [[WKContentRuleListStore defaultStore] removeContentRuleListForIdentifier:@"ContentBlockingAfterProcessSwapExtension" completionHandler:^(NSError *error) {
+        done = true;
+    }];
+    TestWebKitAPI::Util::run(&done);
+    done = false;
+
+    auto processPoolConfiguration = psonProcessPoolConfiguration();
+    auto processPool = adoptNS([[WKProcessPool alloc] _initWithConfiguration:processPoolConfiguration.get()]);
+
+    auto webViewConfiguration = adoptNS([[WKWebViewConfiguration alloc] init]);
+    [webViewConfiguration setProcessPool:processPool.get()];
+
+    RetainPtr<PSONMessageHandler> messageHandler = adoptNS([[PSONMessageHandler alloc] init]);
+    [[webViewConfiguration userContentController] addScriptMessageHandler:messageHandler.get() name:@"pson"];
+
+    __block bool doneCompiling = false;
+    [[WKContentRuleListStore defaultStore] compileContentRuleListForIdentifier:@"ContentBlockingAfterProcessSwapExtension" encodedContentRuleList:blockmeFilter completionHandler:^(WKContentRuleList *ruleList, NSError *error) {
+
+        EXPECT_NOT_NULL(ruleList);
+        EXPECT_NULL(error);
+
+        [webViewConfiguration.get().userContentController addContentRuleList:ruleList];
+
+        doneCompiling = true;
+    }];
+    TestWebKitAPI::Util::run(&doneCompiling);
+
+    auto handler = adoptNS([[PSONScheme alloc] init]);
+    [handler addMappingFromURLString:@"pson://www.apple.com/blockme.html" toData:notifyLoadedBytes];
+    [webViewConfiguration setURLSchemeHandler:handler.get() forURLScheme:@"PSON"];
+
+    auto webView = adoptNS([[WKWebView alloc] initWithFrame:NSMakeRect(0, 0, 800, 600) configuration:webViewConfiguration.get()]);
+    auto delegate = adoptNS([[PSONNavigationDelegate alloc] init]);
+    [webView setNavigationDelegate:delegate.get()];
+
+    NSURLRequest *request = [NSURLRequest requestWithURL:[NSURL URLWithString:@"pson://www.webkit.org/main.html"]];
+    [webView loadRequest:request];
+    TestWebKitAPI::Util::run(&done);
+    done = false;
+
+    receivedMessage = false;
+    failed = false;
+    request = [NSURLRequest requestWithURL:[NSURL URLWithString:@"pson://www.apple.com/blockme.html"]];
+    [webView loadRequest:request];
+    TestWebKitAPI::Util::run(&failed);
+    failed = false;
+    EXPECT_FALSE(receivedMessage);
+
+    [webView _loadAlternateHTMLString:@"Blocked" baseURL:[NSURL URLWithString:@"data:text/html,"] forUnreachableURL:[NSURL URLWithString:@"pson://www.apple.com/blockme.html"]];
+    TestWebKitAPI::Util::run(&done);
+    done = false;
+
+    [webView _reloadWithoutContentBlockers];
+    TestWebKitAPI::Util::run(&done);
+    done = false;
+
+    EXPECT_FALSE(failed);
+    EXPECT_TRUE(receivedMessage);
+    EXPECT_WK_STREQ(@"pson://www.apple.com/blockme.html", [[webView URL] absoluteString]);
+
+    [[WKContentRuleListStore defaultStore] removeContentRuleListForIdentifier:@"ContentBlockingAfterProcessSwapExtension" completionHandler:^(NSError *error) {
+        done = true;
+    }];
+    TestWebKitAPI::Util::run(&done);
+    done = false;
+}
+
 static bool isCapturing = false;
 @interface GetUserMediaUIDelegate : NSObject<WKUIDelegate>
 - (void)_webView:(WKWebView *)webView requestUserMediaAuthorizationForDevices:(_WKCaptureDevices)devices url:(NSURL *)url mainFrameURL:(NSURL *)mainFrameURL decisionHandler:(void (^)(BOOL authorized))decisionHandler;