Chromium Code Reviews| 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 |