URL set by document.open() is not communicated to the UIProcess
authorcdumez@apple.com <cdumez@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Tue, 16 Apr 2019 02:01:32 +0000 (02:01 +0000)
committercdumez@apple.com <cdumez@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Tue, 16 Apr 2019 02:01:32 +0000 (02:01 +0000)
https://bugs.webkit.org/show_bug.cgi?id=196941
<rdar://problem/49237544>

Reviewed by Geoffrey Garen.

Source/WebCore:

Notify the FrameLoaderClient whenever an explicit open was done and provide it with
the latest document URL.

* loader/FrameLoader.cpp:
(WebCore::FrameLoader::didExplicitOpen):
* loader/FrameLoaderClient.h:

Source/WebKit:

Whenever the UIProcess is notified of an explicit document.open() call, update the
PageLoadState to make sure the URL is up-to-date. Also make sure the page / process
knows it committed a load (i.e. It is no longer showing the initially empty document).

* UIProcess/PageLoadState.cpp:
(WebKit::PageLoadState::didExplicitOpen):
* UIProcess/PageLoadState.h:
* UIProcess/WebPageProxy.cpp:
(WebKit::WebPageProxy::didExplicitOpenForFrame):
* UIProcess/WebPageProxy.h:
* UIProcess/WebPageProxy.messages.in:
* WebProcess/WebCoreSupport/WebFrameLoaderClient.cpp:
(WebKit::WebFrameLoaderClient::dispatchDidExplicitOpen):
* WebProcess/WebCoreSupport/WebFrameLoaderClient.h:

Tools:

Add API test coverage.

* TestWebKitAPI/TestWebKitAPI.xcodeproj/project.pbxproj:
* TestWebKitAPI/Tests/WebKit/open-window-then-write-to-it.html: Added.
* TestWebKitAPI/Tests/WebKitCocoa/OpenAndCloseWindow.mm:
(-[OpenWindowThenDocumentOpenUIDelegate webView:createWebViewWithConfiguration:forNavigationAction:windowFeatures:]):
(TEST):

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

15 files changed:
Source/WebCore/ChangeLog
Source/WebCore/loader/FrameLoader.cpp
Source/WebCore/loader/FrameLoaderClient.h
Source/WebKit/ChangeLog
Source/WebKit/UIProcess/PageLoadState.cpp
Source/WebKit/UIProcess/PageLoadState.h
Source/WebKit/UIProcess/WebPageProxy.cpp
Source/WebKit/UIProcess/WebPageProxy.h
Source/WebKit/UIProcess/WebPageProxy.messages.in
Source/WebKit/WebProcess/WebCoreSupport/WebFrameLoaderClient.cpp
Source/WebKit/WebProcess/WebCoreSupport/WebFrameLoaderClient.h
Tools/ChangeLog
Tools/TestWebKitAPI/TestWebKitAPI.xcodeproj/project.pbxproj
Tools/TestWebKitAPI/Tests/WebKit/open-window-then-write-to-it.html [new file with mode: 0644]
Tools/TestWebKitAPI/Tests/WebKitCocoa/OpenAndCloseWindow.mm

index aab0913..e9c8591 100644 (file)
@@ -1,3 +1,18 @@
+2019-04-15  Chris Dumez  <cdumez@apple.com>
+
+        URL set by document.open() is not communicated to the UIProcess
+        https://bugs.webkit.org/show_bug.cgi?id=196941
+        <rdar://problem/49237544>
+
+        Reviewed by Geoffrey Garen.
+
+        Notify the FrameLoaderClient whenever an explicit open was done and provide it with
+        the latest document URL.
+
+        * loader/FrameLoader.cpp:
+        (WebCore::FrameLoader::didExplicitOpen):
+        * loader/FrameLoaderClient.h:
+
 2019-04-15  Eike Rathke  <erack@redhat.com>
 
         Fix logic flow for error log
index 7ae8df2..e01825e 100644 (file)
@@ -592,6 +592,8 @@ void FrameLoader::didExplicitOpen()
     // Calling document.open counts as committing the first real document load.
     if (!m_stateMachine.committedFirstRealDocumentLoad())
         m_stateMachine.advanceTo(FrameLoaderStateMachine::DisplayingInitialEmptyDocumentPostCommit);
+
+    m_client.dispatchDidExplicitOpen(m_frame.document() ? m_frame.document()->url() : URL());
     
     // Prevent window.open(url) -- eg window.open("about:blank") -- from blowing away results
     // from a subsequent window.document.open / window.document.write call. 
index d7798f0..fa1df60 100644 (file)
@@ -181,6 +181,7 @@ public:
     virtual void dispatchDidFailLoad(const ResourceError&) = 0;
     virtual void dispatchDidFinishDocumentLoad() = 0;
     virtual void dispatchDidFinishLoad() = 0;
+    virtual void dispatchDidExplicitOpen(const URL&) { }
 #if ENABLE(DATA_DETECTION)
     virtual void dispatchDidFinishDataDetection(NSArray *detectionResults) = 0;
 #endif
index c21de30..78bd79e 100644 (file)
@@ -1,3 +1,26 @@
+2019-04-15  Chris Dumez  <cdumez@apple.com>
+
+        URL set by document.open() is not communicated to the UIProcess
+        https://bugs.webkit.org/show_bug.cgi?id=196941
+        <rdar://problem/49237544>
+
+        Reviewed by Geoffrey Garen.
+
+        Whenever the UIProcess is notified of an explicit document.open() call, update the
+        PageLoadState to make sure the URL is up-to-date. Also make sure the page / process
+        knows it committed a load (i.e. It is no longer showing the initially empty document).
+
+        * UIProcess/PageLoadState.cpp:
+        (WebKit::PageLoadState::didExplicitOpen):
+        * UIProcess/PageLoadState.h:
+        * UIProcess/WebPageProxy.cpp:
+        (WebKit::WebPageProxy::didExplicitOpenForFrame):
+        * UIProcess/WebPageProxy.h:
+        * UIProcess/WebPageProxy.messages.in:
+        * WebProcess/WebCoreSupport/WebFrameLoaderClient.cpp:
+        (WebKit::WebFrameLoaderClient::dispatchDidExplicitOpen):
+        * WebProcess/WebCoreSupport/WebFrameLoaderClient.h:
+
 2019-04-15  Alex Christensen  <achristensen@webkit.org>
 
         Stop using hyphenationFactor
index c2ae6f0..9e943ab 100644 (file)
@@ -246,6 +246,15 @@ void PageLoadState::clearPendingAPIRequestURL(const Transaction::Token& token)
     m_uncommittedState.pendingAPIRequestURL = String();
 }
 
+void PageLoadState::didExplicitOpen(const Transaction::Token& token, const String& url)
+{
+    ASSERT_UNUSED(token, &token.m_pageLoadState == this);
+
+    m_uncommittedState.state = State::Finished;
+    m_uncommittedState.url = url;
+    m_uncommittedState.provisionalURL = String();
+}
+
 void PageLoadState::didStartProvisionalLoad(const Transaction::Token& token, const String& url, const String& unreachableURL)
 {
     ASSERT_UNUSED(token, &token.m_pageLoadState == this);
index 6f03f86..652d360 100644 (file)
@@ -143,6 +143,7 @@ public:
     void clearPendingAPIRequestURL(const Transaction::Token&);
 
     void didStartProvisionalLoad(const Transaction::Token&, const String& url, const String& unreachableURL);
+    void didExplicitOpen(const Transaction::Token&, const String& url);
     void didReceiveServerRedirectForProvisionalLoad(const Transaction::Token&, const String& url);
     void didFailProvisionalLoad(const Transaction::Token&);
 
index b352e2e..a9a6a28 100644 (file)
@@ -3922,6 +3922,23 @@ void WebPageProxy::didStartProvisionalLoadForFrameShared(Ref<WebProcessProxy>&&
         m_navigationClient->didStartProvisionalNavigation(*this, navigation.get(), process->transformHandlesToObjects(userData.object()).get());
 }
 
+void WebPageProxy::didExplicitOpenForFrame(uint64_t frameID, URL&& url)
+{
+    auto* frame = m_process->webFrame(frameID);
+    MESSAGE_CHECK(m_process, frame);
+    MESSAGE_CHECK_URL(m_process, url);
+
+    auto transaction = m_pageLoadState.transaction();
+
+    if (frame->isMainFrame())
+        m_pageLoadState.didExplicitOpen(transaction, url);
+
+    m_hasCommittedAnyProvisionalLoads = true;
+    m_process->didCommitProvisionalLoad();
+
+    m_pageLoadState.commitChanges();
+}
+
 void WebPageProxy::didReceiveServerRedirectForProvisionalLoadForFrame(uint64_t frameID, uint64_t navigationID, ResourceRequest&& request, const UserData& userData)
 {
     didReceiveServerRedirectForProvisionalLoadForFrameShared(m_process.copyRef(), frameID, navigationID, WTFMove(request), userData);
index 20bfeae..9a06de7 100644 (file)
@@ -1591,6 +1591,7 @@ private:
     void didFailLoadForFrame(uint64_t frameID, uint64_t navigationID, const WebCore::ResourceError&, const UserData&);
     void didSameDocumentNavigationForFrame(uint64_t frameID, uint64_t navigationID, uint32_t sameDocumentNavigationType, URL&&, const UserData&);
     void didChangeMainDocument(uint64_t frameID);
+    void didExplicitOpenForFrame(uint64_t frameID, URL&&);
 
     void didReceiveTitleForFrame(uint64_t frameID, const String&, const UserData&);
     void didFirstLayoutForFrame(uint64_t frameID, const UserData&);
index 2ac1021..a1a2fea 100644 (file)
@@ -140,7 +140,8 @@ messages -> WebPageProxy {
     DidRunInsecureContentForFrame(uint64_t frameID, WebKit::UserData userData)
     DidDetectXSSForFrame(uint64_t frameID, WebKit::UserData userData)
     DidSameDocumentNavigationForFrame(uint64_t frameID, uint64_t navigationID, uint32_t type, URL url, WebKit::UserData userData)
-    DidChangeMainDocument(uint64_t frameID);
+    DidChangeMainDocument(uint64_t frameID)
+    DidExplicitOpenForFrame(uint64_t frameID, URL url)
     DidDestroyNavigation(uint64_t navigationID)
 
     HasInsecureContent() -> (enum:bool WebCore::HasInsecureContent hasInsecureContent) Synchronous
index 592e0a7..4ac9db6 100644 (file)
@@ -458,6 +458,16 @@ void WebFrameLoaderClient::dispatchWillClose()
     notImplemented();
 }
 
+void WebFrameLoaderClient::dispatchDidExplicitOpen(const URL& url)
+{
+    auto* webPage = m_frame->page();
+    if (!webPage)
+        return;
+
+    // Notify the UIProcess.
+    webPage->send(Messages::WebPageProxy::DidExplicitOpenForFrame(m_frame->frameID(), url));
+}
+
 void WebFrameLoaderClient::dispatchDidStartProvisionalLoad()
 {
     WebPage* webPage = m_frame->page();
index a021c55..cb4ff5c 100644 (file)
@@ -116,6 +116,7 @@ private:
     void dispatchDidFailLoad(const WebCore::ResourceError&) final;
     void dispatchDidFinishDocumentLoad() final;
     void dispatchDidFinishLoad() final;
+    void dispatchDidExplicitOpen(const URL&) final;
 
     void dispatchDidReachLayoutMilestone(OptionSet<WebCore::LayoutMilestone>) final;
     void dispatchDidLayout() final;
index 8d046d8..51e5928 100644 (file)
@@ -1,3 +1,19 @@
+2019-04-15  Chris Dumez  <cdumez@apple.com>
+
+        URL set by document.open() is not communicated to the UIProcess
+        https://bugs.webkit.org/show_bug.cgi?id=196941
+        <rdar://problem/49237544>
+
+        Reviewed by Geoffrey Garen.
+
+        Add API test coverage.
+
+        * TestWebKitAPI/TestWebKitAPI.xcodeproj/project.pbxproj:
+        * TestWebKitAPI/Tests/WebKit/open-window-then-write-to-it.html: Added.
+        * TestWebKitAPI/Tests/WebKitCocoa/OpenAndCloseWindow.mm:
+        (-[OpenWindowThenDocumentOpenUIDelegate webView:createWebViewWithConfiguration:forNavigationAction:windowFeatures:]):
+        (TEST):
+
 2019-04-15  Dean Johnson  <dean_johnson@apple.com>
 
         Using Tools/Scripts/clean-webkit should not install requests
index 2ef36c4..8f90a22 100644 (file)
                466C3843210637DE006A88DE /* notify-resourceLoadObserver.html in Copy Resources */ = {isa = PBXBuildFile; fileRef = 466C3842210637CE006A88DE /* notify-resourceLoadObserver.html */; };
                467C565321B5ED130057516D /* GetSessionCookie.html in Copy Resources */ = {isa = PBXBuildFile; fileRef = 467C565121B5ECDF0057516D /* GetSessionCookie.html */; };
                467C565421B5ED130057516D /* SetSessionCookie.html in Copy Resources */ = {isa = PBXBuildFile; fileRef = 467C565221B5ECDF0057516D /* SetSessionCookie.html */; };
+               468BC45522653A1000A36C96 /* open-window-then-write-to-it.html in Copy Resources */ = {isa = PBXBuildFile; fileRef = 468BC454226539C800A36C96 /* open-window-then-write-to-it.html */; };
                46918EFC2237283C00468DFE /* DeviceOrientation.mm in Sources */ = {isa = PBXBuildFile; fileRef = 46918EFB2237283500468DFE /* DeviceOrientation.mm */; };
                46A911592108E6780078D40D /* CustomUserAgent.mm in Sources */ = {isa = PBXBuildFile; fileRef = 46A911582108E66B0078D40D /* CustomUserAgent.mm */; };
                46AE5A3720F9066D00E0873E /* SimpleServiceWorkerRegistrations-4.sqlite3 in Copy Resources */ = {isa = PBXBuildFile; fileRef = 4656A75720F9054F0002E21F /* SimpleServiceWorkerRegistrations-4.sqlite3 */; };
                                074994421EA5034B000DA44F /* ondevicechange.html in Copy Resources */,
                                CEA6CF2819CCF69D0064F5A7 /* open-and-close-window.html in Copy Resources */,
                                7CCB99231D3B4A46003922F6 /* open-multiple-external-url.html in Copy Resources */,
+                               468BC45522653A1000A36C96 /* open-window-then-write-to-it.html in Copy Resources */,
                                290A9BB91735F63800D71BBC /* OpenNewWindow.html in Copy Resources */,
                                83148B09202AC78D00BADE99 /* override-builtins-test.html in Copy Resources */,
                                CEBCA1391E3A807A00C73293 /* page-with-csp-iframe.html in Copy Resources */,
                466C3842210637CE006A88DE /* notify-resourceLoadObserver.html */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.html; path = "notify-resourceLoadObserver.html"; sourceTree = "<group>"; };
                467C565121B5ECDF0057516D /* GetSessionCookie.html */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.html; path = GetSessionCookie.html; sourceTree = "<group>"; };
                467C565221B5ECDF0057516D /* SetSessionCookie.html */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.html; path = SetSessionCookie.html; sourceTree = "<group>"; };
+               468BC454226539C800A36C96 /* open-window-then-write-to-it.html */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.html; path = "open-window-then-write-to-it.html"; sourceTree = "<group>"; };
                46918EFB2237283500468DFE /* DeviceOrientation.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = DeviceOrientation.mm; sourceTree = "<group>"; };
                46A911582108E66B0078D40D /* CustomUserAgent.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = CustomUserAgent.mm; sourceTree = "<group>"; };
                46C519D81D355A7300DAA51A /* LocalStorageNullEntries.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = LocalStorageNullEntries.mm; sourceTree = "<group>"; };
                                C99B675E1E39735C00FC6C80 /* no-autoplay-with-controls.html */,
                                4A410F4D19AF7BEF002EBAB6 /* ondevicechange.html */,
                                CEA6CF2719CCF69D0064F5A7 /* open-and-close-window.html */,
+                               468BC454226539C800A36C96 /* open-window-then-write-to-it.html */,
                                83148B08202AC76800BADE99 /* override-builtins-test.html */,
                                0EBBCC651FFF9DCE00FA42AB /* pop-up-check.html */,
                                F6FDDDD514241C48004F1729 /* push-state.html */,
diff --git a/Tools/TestWebKitAPI/Tests/WebKit/open-window-then-write-to-it.html b/Tools/TestWebKitAPI/Tests/WebKit/open-window-then-write-to-it.html
new file mode 100644 (file)
index 0000000..2dd01fa
--- /dev/null
@@ -0,0 +1,13 @@
+<!DOCTYPE html>
+<html>
+<body>
+<script>
+onload = () => {
+    w = window.open("#", "name", "width=400,height=400")
+    w.document.open();
+    w.document.write("TEST");
+    w.document.close();
+};
+</script>
+</body>
+</html>
index d788407..9cc92bc 100644 (file)
@@ -282,3 +282,38 @@ TEST(WebKit, OpenWindowFeatures)
     EXPECT_FALSE([openWindowFeatures _fullscreenDisplay].boolValue);
     openWindowFeatures = nullptr;
 }
+
+@interface OpenWindowThenDocumentOpenUIDelegate : NSObject <WKUIDelegate>
+@end
+
+@implementation OpenWindowThenDocumentOpenUIDelegate
+
+- (WKWebView *)webView:(WKWebView *)webView createWebViewWithConfiguration:(WKWebViewConfiguration *)configuration forNavigationAction:(WKNavigationAction *)navigationAction windowFeatures:(WKWindowFeatures *)windowFeatures
+{
+    openedWebView = adoptNS([[WKWebView alloc] initWithFrame:NSMakeRect(0, 0, 800, 600) configuration:configuration]);
+    [openedWebView setUIDelegate:sharedUIDelegate.get()];
+    return openedWebView.get();
+}
+
+@end
+
+TEST(WebKit, OpenWindowThenDocumentOpen)
+{
+    resetToConsistentState();
+
+    auto webView = adoptNS([[WKWebView alloc] initWithFrame:NSMakeRect(0, 0, 800, 600)]);
+
+    auto uiDelegate = adoptNS([[OpenWindowThenDocumentOpenUIDelegate alloc] init]);
+    [webView setUIDelegate:uiDelegate.get()];
+    [webView configuration].preferences.javaScriptCanOpenWindowsAutomatically = YES;
+
+    NSURLRequest *request = [NSURLRequest requestWithURL:[[NSBundle mainBundle] URLForResource:@"open-window-then-write-to-it" withExtension:@"html" subdirectory:@"TestWebKitAPI.resources"]];
+    [webView loadRequest:request];
+
+    while (!openedWebView)
+        TestWebKitAPI::Util::sleep(0.1);
+
+    // Both WebViews should have the same URL because of document.open().
+    while (![[[openedWebView URL] absoluteString] isEqualToString:[[webView URL] absoluteString]])
+        TestWebKitAPI::Util::sleep(0.1);
+}