The page's focusedFrame / frameSetLargestFrame do not get cleared on process swap...
authorcdumez@apple.com <cdumez@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Thu, 4 Apr 2019 03:09:48 +0000 (03:09 +0000)
committercdumez@apple.com <cdumez@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Thu, 4 Apr 2019 03:09:48 +0000 (03:09 +0000)
https://bugs.webkit.org/show_bug.cgi?id=196588
<rdar://problem/49365787>

Reviewed by Ryosuke Niwa.

Source/WebKit:

The page's focusedFrame / frameSetLargestFrame do not get cleared on process swap or crash.
This can lead to returning stale frames to the client if it asks for those.

* UIProcess/WebPageProxy.cpp:
(WebKit::WebPageProxy::resetState):

Tools:

Add API test coverage.

* TestWebKitAPI/Tests/WebKit/ReloadPageAfterCrash.cpp:
(TestWebKitAPI::nullJavaScriptCallback):
(TestWebKitAPI::didCrashCheckFrames):
(TestWebKitAPI::TEST):

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

Source/WebKit/ChangeLog
Source/WebKit/UIProcess/WebPageProxy.cpp
Tools/ChangeLog
Tools/TestWebKitAPI/Tests/WebKit/ReloadPageAfterCrash.cpp

index 9026ac1..e5af263 100644 (file)
@@ -1,3 +1,17 @@
+2019-04-03  Chris Dumez  <cdumez@apple.com>
+
+        The page's focusedFrame / frameSetLargestFrame do not get cleared on process swap or crash
+        https://bugs.webkit.org/show_bug.cgi?id=196588
+        <rdar://problem/49365787>
+
+        Reviewed by Ryosuke Niwa.
+
+        The page's focusedFrame / frameSetLargestFrame do not get cleared on process swap or crash.
+        This can lead to returning stale frames to the client if it asks for those.
+
+        * UIProcess/WebPageProxy.cpp:
+        (WebKit::WebPageProxy::resetState):
+
 2019-04-03  Simon Fraser  <simon.fraser@apple.com>
 
         Remove the isProgrammaticScroll argument to requestScroll() because no-one uses it
index f4c7f31..67c76fc 100644 (file)
@@ -6775,6 +6775,8 @@ void WebPageProxy::processWillBecomeForeground()
 void WebPageProxy::resetState(ResetStateReason resetStateReason)
 {
     m_mainFrame = nullptr;
+    m_focusedFrame = nullptr;
+    m_frameSetLargestFrame = nullptr;
 
 #if PLATFORM(COCOA)
     m_scrollingPerformanceData = nullptr;
index 411a97a..59f9428 100644 (file)
@@ -1,3 +1,18 @@
+2019-04-03  Chris Dumez  <cdumez@apple.com>
+
+        The page's focusedFrame / frameSetLargestFrame do not get cleared on process swap or crash
+        https://bugs.webkit.org/show_bug.cgi?id=196588
+        <rdar://problem/49365787>
+
+        Reviewed by Ryosuke Niwa.
+
+        Add API test coverage.
+
+        * TestWebKitAPI/Tests/WebKit/ReloadPageAfterCrash.cpp:
+        (TestWebKitAPI::nullJavaScriptCallback):
+        (TestWebKitAPI::didCrashCheckFrames):
+        (TestWebKitAPI::TEST):
+
 2019-04-03  Jonathan Bedard  <jbedard@apple.com>
 
         run-webkit-tests: Upload test results (new results database)
index 4710527..1e7b373 100644 (file)
 #include "PlatformUtilities.h"
 #include "PlatformWebView.h"
 #include "Test.h"
+#include <WebKit/WKPagePrivate.h>
 #include <WebKit/WKRetainPtr.h>
+#include <signal.h>
 
 namespace TestWebKitAPI {
 
 static bool loadBeforeCrash = false;
 static bool loadAfterCrash = false;
+static bool calledCrashHandler = false;
 
 static void didFinishLoad(WKPageRef page, WKNavigationRef, WKTypeRef userData, const void* clientInfo)
 {
@@ -88,6 +91,83 @@ TEST(WebKit, ReloadPageAfterCrash)
     Util::run(&loadAfterCrash);
 }
 
+static void nullJavaScriptCallback(WKSerializedScriptValueRef, WKErrorRef, void*)
+{
+}
+
+static void didCrashCheckFrames(WKPageRef page, const void*)
+{
+    // Test if first load actually worked.
+    EXPECT_TRUE(loadBeforeCrash);
+
+    EXPECT_TRUE(!WKPageGetMainFrame(page));
+    EXPECT_TRUE(!WKPageGetFocusedFrame(page));
+    EXPECT_TRUE(!WKPageGetFrameSetLargestFrame(page));
+
+    calledCrashHandler = true;
+}
+
+TEST(WebKit, FocusedFrameAfterCrash)
+{
+    WKRetainPtr<WKContextRef> context(AdoptWK, WKContextCreateWithConfiguration(nullptr));
+    PlatformWebView webView(context.get());
+
+    WKPageNavigationClientV0 loaderClient;
+    memset(&loaderClient, 0, sizeof(loaderClient));
+
+    loaderClient.base.version = 0;
+    loaderClient.didFinishNavigation = didFinishLoad;
+    loaderClient.webProcessDidCrash = didCrashCheckFrames;
+
+    WKPageSetPageNavigationClient(webView.page(), &loaderClient.base);
+
+    WKRetainPtr<WKURLRef> url = adoptWK(Util::createURLForResource("many-iframes", "html"));
+    WKPageLoadURL(webView.page(), url.get());
+    Util::run(&loadBeforeCrash);
+
+    EXPECT_FALSE(!WKPageGetMainFrame(webView.page()));
+
+    WKRetainPtr<WKStringRef> javaScriptString(AdoptWK, WKStringCreateWithUTF8CString("frames[2].focus()"));
+    WKPageRunJavaScriptInMainFrame(webView.page(), javaScriptString.get(), 0, nullJavaScriptCallback);
+
+    while (!WKPageGetFocusedFrame(webView.page()))
+        Util::spinRunLoop(10);
+
+    kill(WKPageGetProcessIdentifier(webView.page()), 9);
+
+    Util::run(&calledCrashHandler);
+}
+
+TEST(WebKit, FrameSetLargestFramAfterCrash)
+{
+    WKRetainPtr<WKContextRef> context(AdoptWK, WKContextCreateWithConfiguration(nullptr));
+    PlatformWebView webView(context.get());
+
+    WKPageNavigationClientV0 loaderClient;
+    memset(&loaderClient, 0, sizeof(loaderClient));
+
+    loaderClient.base.version = 0;
+    loaderClient.didFinishNavigation = didFinishLoad;
+    loaderClient.webProcessDidCrash = didCrashCheckFrames;
+
+    WKPageSetPageNavigationClient(webView.page(), &loaderClient.base);
+
+    WKRetainPtr<WKURLRef> baseURL = adoptWK(WKURLCreateWithUTF8CString("about:blank"));
+    WKRetainPtr<WKStringRef> htmlString = Util::toWK("<frameset cols='25%,*,25%'><frame src='about:blank'><frame src='about:blank'><frame src='about:blank'></frameset>");
+
+    WKPageLoadHTMLString(webView.page(), htmlString.get(), baseURL.get());
+    Util::run(&loadBeforeCrash);
+
+    EXPECT_FALSE(!WKPageGetMainFrame(webView.page()));
+
+    while (!WKPageGetFrameSetLargestFrame(webView.page()))
+        Util::spinRunLoop(10);
+
+    kill(WKPageGetProcessIdentifier(webView.page()), 9);
+
+    Util::run(&calledCrashHandler);
+}
+
 } // namespace TestWebKitAPI
 
 #endif