Changeset 237446 in webkit


Ignore:
Timestamp:
Oct 25, 2018 10:06:24 PM (5 years ago)
Author:
Chris Dumez
Message:

[PSON] Navigating cross-site with locked history but unlocked back/forward list fails to create a new BackForwardListItem
https://bugs.webkit.org/show_bug.cgi?id=190915
<rdar://problem/45059069>

Reviewed by Geoffrey Garen.

Source/WebCore:

  • history/PageCache.cpp:

(WebCore::canCacheFrame):
Make sure we do not put into PageCache a page whose main frame is showing the initial empty document.
We usually do not try to put those into PageCache because we do not have a HistoryItem to save the
PageCache entry on. However, when we process-swap on a navigation with the history locked, the new
process has a HistoryItem and is initially showing the initial empty document before continuing
the load from the previous process. Note that saving the initial empty document in PageCache would
lead to crashes later on previous the initial empty document's Window is taken and reused for the
next load.

  • loader/FrameLoader.cpp:

(WebCore::FrameLoader::load):
Stop assuming that we're continuing a client-side redirect when lockHistory is Yes. It is
lockBackForwardList that is actually Yes when we're doing a client-side redirect.

  • loader/PolicyChecker.cpp:

(WebCore::PolicyChecker::checkNavigationPolicy):
Stop using calling the completion handler with an invalid URL when the policy decision is 'Suspend' and
use 'about:blank' instead. Without this change, FrameLoader::continueLoadAfterNavigationPolicy() would
not load 'about:blank' when its AllowNavigationToInvalidURL parameter is No.

Tools:

Add API test coverage.

  • TestWebKitAPI/Tests/WebKitCocoa/ProcessSwapOnNavigation.mm:
Location:
trunk
Files:
6 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/WebCore/ChangeLog

    r237441 r237446  
     12018-10-25  Chris Dumez  <cdumez@apple.com>
     2
     3        [PSON] Navigating cross-site with locked history but unlocked back/forward list fails to create a new BackForwardListItem
     4        https://bugs.webkit.org/show_bug.cgi?id=190915
     5        <rdar://problem/45059069>
     6
     7        Reviewed by Geoffrey Garen.
     8
     9        * history/PageCache.cpp:
     10        (WebCore::canCacheFrame):
     11        Make sure we do not put into PageCache a page whose main frame is showing the initial empty document.
     12        We usually do not try to put those into PageCache because we do not have a HistoryItem to save the
     13        PageCache entry on. However, when we process-swap on a navigation with the history locked, the new
     14        process has a HistoryItem and is initially showing the initial empty document before continuing
     15        the load from the previous process. Note that saving the initial empty document in PageCache would
     16        lead to crashes later on previous the initial empty document's Window is taken and reused for the
     17        next load.
     18
     19        * loader/FrameLoader.cpp:
     20        (WebCore::FrameLoader::load):
     21        Stop assuming that we're continuing a client-side redirect when lockHistory is Yes. It is
     22        lockBackForwardList that is actually Yes when we're doing a client-side redirect.
     23
     24        * loader/PolicyChecker.cpp:
     25        (WebCore::PolicyChecker::checkNavigationPolicy):
     26        Stop using calling the completion handler with an invalid URL when the policy decision is 'Suspend' and
     27        use 'about:blank' instead. Without this change, FrameLoader::continueLoadAfterNavigationPolicy() would
     28        not load 'about:blank' when its AllowNavigationToInvalidURL parameter is No.
     29
    1302018-10-25  Devin Rousso  <drousso@apple.com>
    231
  • trunk/Source/WebCore/history/PageCache.cpp

    r237266 r237446  
    8686    }
    8787
     88    if (frame.isMainFrame() && frameLoader.stateMachine().isDisplayingInitialEmptyDocument()) {
     89        PCLOG("   -MainFrame is displaying initial empty document");
     90        return false;
     91    }
     92
    8893    DocumentLoader* documentLoader = frameLoader.documentLoader();
    8994    if (!documentLoader) {
  • trunk/Source/WebCore/loader/FrameLoader.cpp

    r237395 r237446  
    14621462    applyShouldOpenExternalURLsPolicyToNewDocumentLoader(m_frame, loader, request);
    14631463
    1464     if (request.shouldTreatAsContinuingLoad() && request.lockHistory() == LockHistory::Yes) {
    1465         // The load we're continuing is a client-side redirect so set things up accordingly.
     1464    if (request.shouldTreatAsContinuingLoad()) {
    14661465        loader->setClientRedirectSourceForHistory(request.clientRedirectSourceForHistory());
    1467         loader->setIsClientRedirect(true);
    1468         m_loadType = FrameLoadType::RedirectWithLockedBackForwardList;
     1466        if (request.lockBackForwardList() == LockBackForwardList::Yes) {
     1467            loader->setIsClientRedirect(true);
     1468            m_loadType = FrameLoadType::RedirectWithLockedBackForwardList;
     1469        }
    14691470    }
    14701471
  • trunk/Source/WebCore/loader/PolicyChecker.cpp

    r237073 r237446  
    180180            return function({ }, nullptr, ShouldContinue::No);
    181181        case PolicyAction::Suspend:
    182             return function({ }, nullptr, ShouldContinue::ForSuspension);
     182            return function({ blankURL() }, nullptr, ShouldContinue::ForSuspension);
    183183        case PolicyAction::Use:
    184184            if (!m_frame.loader().client().canHandleRequest(request)) {
  • trunk/Tools/ChangeLog

    r237422 r237446  
     12018-10-25  Chris Dumez  <cdumez@apple.com>
     2
     3        [PSON] Navigating cross-site with locked history but unlocked back/forward list fails to create a new BackForwardListItem
     4        https://bugs.webkit.org/show_bug.cgi?id=190915
     5        <rdar://problem/45059069>
     6
     7        Reviewed by Geoffrey Garen.
     8
     9        Add API test coverage.
     10
     11        * TestWebKitAPI/Tests/WebKitCocoa/ProcessSwapOnNavigation.mm:
     12
    1132018-10-25  Joseph Pecoraro  <pecoraro@apple.com>
    214
  • trunk/Tools/TestWebKitAPI/Tests/WebKitCocoa/ProcessSwapOnNavigation.mm

    r237386 r237446  
    281281)PSONRESOURCE";
    282282
     283static const char* navigationWithLockedHistoryBytes = R"PSONRESOURCE(
     284<script>
     285let shouldNavigate = true;
     286window.addEventListener('pageshow', function(event) {
     287    if (event.persisted) {
     288        window.webkit.messageHandlers.pson.postMessage("Was persisted");
     289        shouldNavigate = false;
     290    }
     291});
     292
     293onload = function()
     294{
     295    if (!shouldNavigate)
     296        return;
     297
     298    // JS navigation via window.location
     299    setTimeout(() => {
     300        location = "pson://www.apple.com/main.html";
     301    }, 10);
     302}
     303</script>
     304)PSONRESOURCE";
     305
     306static const char* pageCache1Bytes = R"PSONRESOURCE(
     307<script>
     308window.addEventListener('pageshow', function(event) {
     309    if (event.persisted)
     310        window.webkit.messageHandlers.pson.postMessage("Was persisted");
     311});
     312</script>
     313)PSONRESOURCE";
     314
    283315#if PLATFORM(MAC)
    284316
     
    12681300}
    12691301
     1302static void runNavigationWithLockedHistoryTest(ShouldEnablePSON shouldEnablePSON)
     1303{
     1304    auto processPoolConfiguration = adoptNS([[_WKProcessPoolConfiguration alloc] init]);
     1305    processPoolConfiguration.get().processSwapsOnNavigation = shouldEnablePSON == ShouldEnablePSON::Yes ? YES : NO;
     1306    auto processPool = adoptNS([[WKProcessPool alloc] _initWithConfiguration:processPoolConfiguration.get()]);
     1307
     1308    auto webViewConfiguration = adoptNS([[WKWebViewConfiguration alloc] init]);
     1309    [webViewConfiguration setProcessPool:processPool.get()];
     1310    auto handler = adoptNS([[PSONScheme alloc] init]);
     1311    [handler addMappingFromURLString:@"pson://www.webkit.org/main.html" toData:navigationWithLockedHistoryBytes];
     1312    [handler addMappingFromURLString:@"pson://www.apple.com/main.html" toData:pageCache1Bytes];
     1313    [webViewConfiguration setURLSchemeHandler:handler.get() forURLScheme:@"pson"];
     1314
     1315    auto messageHandler = adoptNS([[PSONMessageHandler alloc] init]);
     1316    [[webViewConfiguration userContentController] addScriptMessageHandler:messageHandler.get() name:@"pson"];
     1317
     1318    auto webView = adoptNS([[WKWebView alloc] initWithFrame:NSMakeRect(0, 0, 800, 600) configuration:webViewConfiguration.get()]);
     1319    auto delegate = adoptNS([[PSONNavigationDelegate alloc] init]);
     1320    [webView setNavigationDelegate:delegate.get()];
     1321
     1322    NSURLRequest *request = [NSURLRequest requestWithURL:[NSURL URLWithString:@"pson://www.webkit.org/main.html"]];
     1323    [webView loadRequest:request];
     1324
     1325    TestWebKitAPI::Util::run(&done);
     1326    done = false;
     1327
     1328    auto webkitPID = [webView _webProcessIdentifier];
     1329
     1330    // Page redirects to apple.com.
     1331    TestWebKitAPI::Util::run(&done);
     1332    done = false;
     1333
     1334    auto applePID = [webView _webProcessIdentifier];
     1335    if (shouldEnablePSON == ShouldEnablePSON::Yes)
     1336        EXPECT_NE(webkitPID, applePID);
     1337    else
     1338        EXPECT_EQ(webkitPID, applePID);
     1339
     1340    auto* backForwardList = [webView backForwardList];
     1341    EXPECT_WK_STREQ(@"pson://www.apple.com/main.html", [backForwardList.currentItem.URL absoluteString]);
     1342    EXPECT_TRUE(!backForwardList.forwardItem);
     1343    EXPECT_EQ(1U, backForwardList.backList.count);
     1344    EXPECT_WK_STREQ(@"pson://www.webkit.org/main.html", [backForwardList.backItem.URL absoluteString]);
     1345
     1346    receivedMessage = false;
     1347    [webView goBack];
     1348    TestWebKitAPI::Util::run(&receivedMessage); // Should be restored from PageCache.
     1349    receivedMessage = false;
     1350    TestWebKitAPI::Util::run(&done);
     1351    done = false;
     1352
     1353    EXPECT_EQ(webkitPID, [webView _webProcessIdentifier]);
     1354    EXPECT_WK_STREQ(@"pson://www.webkit.org/main.html", [backForwardList.currentItem.URL absoluteString]);
     1355    EXPECT_TRUE(!backForwardList.backItem);
     1356    EXPECT_EQ(1U, backForwardList.forwardList.count);
     1357    EXPECT_WK_STREQ(@"pson://www.apple.com/main.html", [backForwardList.forwardItem.URL absoluteString]);
     1358
     1359    [webView goForward];
     1360    TestWebKitAPI::Util::run(&done);
     1361    TestWebKitAPI::Util::run(&receivedMessage); // Should be restored from PageCache.
     1362    receivedMessage = false;
     1363    done = false;
     1364
     1365    EXPECT_EQ(applePID, [webView _webProcessIdentifier]);
     1366
     1367    EXPECT_WK_STREQ(@"pson://www.apple.com/main.html", [backForwardList.currentItem.URL absoluteString]);
     1368    EXPECT_TRUE(!backForwardList.forwardItem);
     1369    EXPECT_EQ(1U, backForwardList.backList.count);
     1370    EXPECT_WK_STREQ(@"pson://www.webkit.org/main.html", [backForwardList.backItem.URL absoluteString]);
     1371}
     1372
     1373TEST(ProcessSwap, NavigationWithLockedHistoryWithPSON)
     1374{
     1375    runNavigationWithLockedHistoryTest(ShouldEnablePSON::Yes);
     1376}
     1377
     1378TEST(ProcessSwap, NavigationWithLockedHistoryWithoutPSON)
     1379{
     1380    runNavigationWithLockedHistoryTest(ShouldEnablePSON::No);
     1381}
     1382
    12701383static const char* sessionStorageTestBytes = R"PSONRESOURCE(
    12711384<head>
     
    14481561    EXPECT_EQ(4u, [processPool _webProcessCountIgnoringPrewarmed]);
    14491562}
    1450 
    1451 static const char* pageCache1Bytes = R"PSONRESOURCE(
    1452 <script>
    1453 window.addEventListener('pageshow', function(event) {
    1454     if (event.persisted)
    1455         window.webkit.messageHandlers.pson.postMessage("Was persisted");
    1456 });
    1457 </script>
    1458 )PSONRESOURCE";
    14591563
    14601564TEST(ProcessSwap, PageCache1)
Note: See TracChangeset for help on using the changeset viewer.