OLD | NEW |
---|---|
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "content/browser/site_per_process_browsertest.h" | 5 #include "content/browser/site_per_process_browsertest.h" |
6 | 6 |
7 #include <stddef.h> | 7 #include <stddef.h> |
8 #include <stdint.h> | 8 #include <stdint.h> |
9 | 9 |
10 #include <algorithm> | 10 #include <algorithm> |
(...skipping 8321 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
8332 | 8332 |
8333 // Now have the cross-process navigation commit and mark the current RFH as | 8333 // Now have the cross-process navigation commit and mark the current RFH as |
8334 // pending deletion. | 8334 // pending deletion. |
8335 cross_site_manager.WaitForNavigationFinished(); | 8335 cross_site_manager.WaitForNavigationFinished(); |
8336 | 8336 |
8337 // Resume the navigation in the previous RFH that has just been marked as | 8337 // Resume the navigation in the previous RFH that has just been marked as |
8338 // pending deletion. We should not crash. | 8338 // pending deletion. We should not crash. |
8339 transfer_manager.WaitForNavigationFinished(); | 8339 transfer_manager.WaitForNavigationFinished(); |
8340 } | 8340 } |
8341 | 8341 |
8342 // Test that when canceling a pending RenderFrameHost in the middle of a | |
8343 // redirect, and then killing the corresponding RenderView's renderer process, | |
8344 // the RenderViewHost isn't reused in an improper state later. Previously this | |
8345 // led to a crash in CreateRenderView when recreating the RenderView due to a | |
8346 // stale main frame routing ID. See https://crbug.com/627400. | |
8347 IN_PROC_BROWSER_TEST_F(SitePerProcessBrowserTest, | |
8348 ReuseNonLiveRenderViewAfterCancelPending) { | |
8349 GURL a_url(embedded_test_server()->GetURL("a.com", "/title1.html")); | |
8350 GURL b_url(embedded_test_server()->GetURL("b.com", "/title2.html")); | |
8351 GURL c_url(embedded_test_server()->GetURL("c.com", "/title3.html")); | |
8352 | |
8353 EXPECT_TRUE(NavigateToURL(shell(), a_url)); | |
8354 | |
8355 // Open a popup and navigate it to b.com. | |
8356 Shell* popup = OpenPopup(shell(), a_url, "popup"); | |
8357 EXPECT_TRUE(NavigateToURL(popup, b_url)); | |
8358 | |
8359 // Open a second popup and navigate it to b.com, which redirects to c.com. | |
8360 // The navigation to b.com will create a pending RenderFrameHost, which will | |
8361 // be canceled during the redirect to c.com. Note that NavigateToURL will | |
8362 // return false because the committed URL won't match the requested URL due | |
8363 // to the redirect. | |
8364 Shell* popup2 = OpenPopup(shell(), a_url, "popup2"); | |
8365 TestNavigationObserver observer(popup2->web_contents()); | |
8366 GURL redirect_url(embedded_test_server()->GetURL( | |
8367 "b.com", "/server-redirect?" + c_url.spec())); | |
8368 EXPECT_FALSE(NavigateToURL(popup2, redirect_url)); | |
8369 EXPECT_EQ(c_url, observer.last_navigation_url()); | |
8370 EXPECT_TRUE(observer.last_navigation_succeeded()); | |
8371 | |
8372 // Kill the b.com process (which currently hosts a RenderFrameProxy that | |
8373 // replaced the pending RenderFrame in |popup2|, as well as the RenderFrame | |
8374 // for |popup|). | |
8375 RenderProcessHost* b_process = | |
8376 popup->web_contents()->GetMainFrame()->GetProcess(); | |
8377 RenderProcessHostWatcher crash_observer( | |
8378 b_process, RenderProcessHostWatcher::WATCH_FOR_PROCESS_EXIT); | |
8379 b_process->Shutdown(0, false); | |
8380 crash_observer.Wait(); | |
8381 | |
8382 // Navigate the second popup to b.com. This used to crash when creating the | |
8383 // RenderView, because it reused the RenderViewHost created by the canceled | |
8384 // navigation to b.com, and that RenderViewHost had a stale main frame | |
8385 // routing ID and active state. | |
8386 EXPECT_TRUE(NavigateToURL(popup2, b_url)); | |
8387 } | |
8388 | |
8389 // Check that after a pending RFH is canceled and replaced with a proxy (which | |
8390 // reuses the canceled RFH's RenderView), navigating to a main frame in the | |
nasko
2016/10/13 21:26:28
nit: RenderViewHost, since you mention RFH's.
alexmos
2016/10/14 17:07:38
Done.
| |
8391 // same site as the canceled RFH doesn't lead to a renderer crash. The steps | |
8392 // here are similar to the test above, but don't involve crashing the renderer. | |
nasko
2016/10/13 21:26:28
nit: replace "test above" with the explicit name o
alexmos
2016/10/14 17:07:38
Done.
| |
8393 // See https://crbug.com/651980. | |
8394 IN_PROC_BROWSER_TEST_F(SitePerProcessBrowserTest, | |
8395 RecreateMainFrameAfterCancelPending) { | |
8396 GURL a_url(embedded_test_server()->GetURL("a.com", "/title1.html")); | |
8397 GURL b_url(embedded_test_server()->GetURL("b.com", "/title2.html")); | |
8398 GURL c_url(embedded_test_server()->GetURL("c.com", "/title3.html")); | |
8399 | |
8400 EXPECT_TRUE(NavigateToURL(shell(), a_url)); | |
8401 | |
8402 // Open a popup and navigate it to b.com. | |
8403 Shell* popup = OpenPopup(shell(), a_url, "popup"); | |
8404 EXPECT_TRUE(NavigateToURL(popup, b_url)); | |
8405 | |
8406 // Open a second popup and navigate it to b.com, which redirects to c.com. | |
8407 // The navigation to b.com will create a pending RenderFrameHost, which will | |
8408 // be canceled during the redirect to c.com. Note that NavigateToURL will | |
8409 // return false because the committed URL won't match the requested URL due | |
8410 // to the redirect. | |
8411 Shell* popup2 = OpenPopup(shell(), a_url, "popup2"); | |
8412 TestNavigationObserver observer(popup2->web_contents()); | |
8413 GURL redirect_url(embedded_test_server()->GetURL( | |
8414 "b.com", "/server-redirect?" + c_url.spec())); | |
8415 EXPECT_FALSE(NavigateToURL(popup2, redirect_url)); | |
8416 EXPECT_EQ(c_url, observer.last_navigation_url()); | |
8417 EXPECT_TRUE(observer.last_navigation_succeeded()); | |
8418 | |
8419 // Navigate the second popup to b.com. This used to crash the b.com renderer | |
8420 // because it failed to delete the canceled RFH's RenderFrame, so this caused | |
8421 // it to try to create a frame widget which already existed. | |
8422 EXPECT_TRUE(NavigateToURL(popup2, b_url)); | |
8423 } | |
8424 | |
8425 // Check that when a pending RFH is canceled and a proxy needs to be created in | |
8426 // its place, the proxy is properly initialized on the renderer side. See | |
8427 // https://crbug.com/653746. | |
8428 IN_PROC_BROWSER_TEST_F(SitePerProcessBrowserTest, | |
8429 CommunicateWithProxyAfterCancelPending) { | |
8430 GURL a_url(embedded_test_server()->GetURL("a.com", "/title1.html")); | |
8431 GURL b_url(embedded_test_server()->GetURL("b.com", "/title2.html")); | |
8432 GURL c_url(embedded_test_server()->GetURL("c.com", "/title3.html")); | |
8433 | |
8434 EXPECT_TRUE(NavigateToURL(shell(), a_url)); | |
8435 | |
8436 // Open a popup and navigate it to b.com. | |
8437 Shell* popup = OpenPopup(shell(), a_url, "popup"); | |
8438 EXPECT_TRUE(NavigateToURL(popup, b_url)); | |
8439 | |
8440 // Open a second popup and navigate it to b.com, which redirects to c.com. | |
8441 // The navigation to b.com will create a pending RenderFrameHost, which will | |
8442 // be canceled during the redirect to c.com. Note that NavigateToURL will | |
8443 // return false because the committed URL won't match the requested URL due | |
8444 // to the redirect. | |
8445 Shell* popup2 = OpenPopup(shell(), a_url, "popup2"); | |
8446 TestNavigationObserver observer(popup2->web_contents()); | |
8447 GURL redirect_url(embedded_test_server()->GetURL( | |
8448 "b.com", "/server-redirect?" + c_url.spec())); | |
8449 EXPECT_FALSE(NavigateToURL(popup2, redirect_url)); | |
8450 EXPECT_EQ(c_url, observer.last_navigation_url()); | |
8451 EXPECT_TRUE(observer.last_navigation_succeeded()); | |
8452 | |
8453 // Because b.com has other active frames (namely, the frame in |popup|), | |
8454 // there should be a proxy created for the canceled RFH, and it should be | |
8455 // live. | |
8456 SiteInstance* b_instance = popup->web_contents()->GetSiteInstance(); | |
8457 FrameTreeNode* popup2_root = | |
8458 static_cast<WebContentsImpl*>(popup2->web_contents()) | |
8459 ->GetFrameTree() | |
8460 ->root(); | |
8461 RenderFrameProxyHost* proxy = | |
8462 popup2_root->render_manager()->GetRenderFrameProxyHost(b_instance); | |
8463 EXPECT_TRUE(proxy); | |
8464 EXPECT_TRUE(proxy->is_render_frame_proxy_live()); | |
8465 | |
8466 // Add a postMessage listener in |popup2| (currently at a c.com URL). | |
8467 EXPECT_TRUE( | |
8468 ExecuteScript(popup2, | |
8469 "window.addEventListener('message', function(event) {\n" | |
8470 " document.title=event.data;\n" | |
8471 "});")); | |
8472 | |
8473 // Check that a postMessage can be sent via |proxy| above. This needs to be | |
8474 // done from the b.com process. |popup| is currently in b.com, but it can't | |
8475 // reach the window reference for |popup2| due to a security restriction in | |
8476 // Blink. So, navigate the main tab to b.com and then send a postMessage to | |
8477 // |popup2|. This is allowed since the main tab is |popup2|'s opener. | |
8478 EXPECT_TRUE(NavigateToURL(shell(), b_url)); | |
8479 | |
8480 base::string16 expected_title(base::UTF8ToUTF16("foo")); | |
8481 TitleWatcher title_watcher(popup2->web_contents(), expected_title); | |
8482 EXPECT_TRUE(ExecuteScript( | |
8483 shell(), "window.open('','popup2').postMessage('foo', '*');")); | |
8484 EXPECT_EQ(expected_title, title_watcher.WaitAndGetTitle()); | |
8485 } | |
8486 | |
8342 } // namespace content | 8487 } // namespace content |
OLD | NEW |