diff options
4 files changed, 123 insertions, 2 deletions
diff --git a/chrome/browser/renderer_host/safe_browsing_resource_handler.cc b/chrome/browser/renderer_host/safe_browsing_resource_handler.cc index c40d52f..b665ce0b 100644 --- a/chrome/browser/renderer_host/safe_browsing_resource_handler.cc +++ b/chrome/browser/renderer_host/safe_browsing_resource_handler.cc @@ -206,7 +206,13 @@ void SafeBrowsingResourceHandler::OnBlockingPageComplete(bool proceed) { if (proceed) { safe_browsing_result_ = SafeBrowsingService::SAFE; - ResumeRequest(); + net::URLRequest* request = rdh_->GetURLRequest( + GlobalRequestID(render_process_host_id_, deferred_request_id_)); + + // The request could be canceled by renderer at this stage. + // As a result, click proceed will do nothing (crbug.com/76460). + if (request) + ResumeRequest(); } else { rdh_->CancelRequest(render_process_host_id_, deferred_request_id_, false); } diff --git a/chrome/browser/safe_browsing/safe_browsing_blocking_page_test.cc b/chrome/browser/safe_browsing/safe_browsing_blocking_page_test.cc index f65236b..50c41bc 100644 --- a/chrome/browser/safe_browsing/safe_browsing_blocking_page_test.cc +++ b/chrome/browser/safe_browsing/safe_browsing_blocking_page_test.cc @@ -303,6 +303,21 @@ class SafeBrowsingBlockingPageTest : public InProcessBrowserTest, ASSERT_FALSE(contents->showing_interstitial_page()); } + bool YesInterstitial() { + TabContents* contents = browser()->GetSelectedTabContents(); + InterstitialPage* interstitial_page = InterstitialPage::GetInterstitialPage( + contents); + return interstitial_page != NULL; + } + + void WaitForInterstitial() { + TabContents* contents = browser()->GetSelectedTabContents(); + if (!InterstitialPage::GetInterstitialPage(contents)) + ui_test_utils::WaitForNotificationFrom( + NotificationType::INTERSTITIAL_ATTACHED, + Source<TabContents>(contents)); + } + void WaitForNavigation() { NavigationController* controller = &browser()->GetSelectedTabContents()->controller(); @@ -327,6 +342,8 @@ class SafeBrowsingBlockingPageTest : public InProcessBrowserTest, EXPECT_TRUE(report.complete()); } + void MalwareRedirectCancelAndProceed(const std::string open_function); + protected: TestMalwareDetailsFactory details_factory_; @@ -337,12 +354,57 @@ class SafeBrowsingBlockingPageTest : public InProcessBrowserTest, DISALLOW_COPY_AND_ASSIGN(SafeBrowsingBlockingPageTest); }; +void SafeBrowsingBlockingPageTest::MalwareRedirectCancelAndProceed( + const std::string open_function) { + GURL load_url = test_server()->GetURL( + "files/safe_browsing/interstitial_cancel.html"); + GURL malware_url("http://localhost/files/safe_browsing/malware.html"); + AddURLResult(malware_url, SafeBrowsingService::URL_MALWARE); + + // Load the test page. + ui_test_utils::NavigateToURL(browser(), load_url); + // Trigger the safe browsing interstitial page via a redirect in "openWin()". + ui_test_utils::NavigateToURLWithDisposition( + browser(), + GURL("javascript:" + open_function + "()"), + CURRENT_TAB, + ui_test_utils::BROWSER_TEST_WAIT_FOR_TAB); + WaitForInterstitial(); + // Cancel the redirect request while interstitial page is open. + browser()->ActivateTabAt(0, true); + ui_test_utils::NavigateToURLWithDisposition( + browser(), + GURL("javascript:stopWin()"), + CURRENT_TAB, + ui_test_utils::BROWSER_TEST_WAIT_FOR_NAVIGATION); + browser()->ActivateTabAt(1, true); + // Simulate the user clicking "proceed", there should be no crash. + SendCommand("\"proceed\""); +} + namespace { const char kEmptyPage[] = "files/empty.html"; const char kMalwarePage[] = "files/safe_browsing/malware.html"; const char kMalwareIframe[] = "files/safe_browsing/malware_iframe.html"; +IN_PROC_BROWSER_TEST_F(SafeBrowsingBlockingPageTest, + MalwareRedirectInIFrameCanceled) { + // 1. Test the case that redirect is a subresource. + MalwareRedirectCancelAndProceed("openWinIFrame"); + // If the redirect was from subresource but canceled, "proceed" will continue + // with the rest of resources. + AssertNoInterstitial(true); +} + +IN_PROC_BROWSER_TEST_F(SafeBrowsingBlockingPageTest, MalwareRedirectCanceled) { + // 2. Test the case that redirect is the only resource. + MalwareRedirectCancelAndProceed("openWin"); + // Clicking proceed won't do anything if the main request is cancelled + // already. See crbug.com/76460. + EXPECT_TRUE(YesInterstitial()); +} + IN_PROC_BROWSER_TEST_F(SafeBrowsingBlockingPageTest, MalwareDontProceed) { GURL url = test_server()->GetURL(kEmptyPage); AddURLResult(url, SafeBrowsingService::URL_MALWARE); @@ -360,7 +422,6 @@ IN_PROC_BROWSER_TEST_F(SafeBrowsingBlockingPageTest, MalwareProceed) { AddURLResult(url, SafeBrowsingService::URL_MALWARE); ui_test_utils::NavigateToURL(browser(), url); - SendCommand("\"proceed\""); // Simulate the user clicking "proceed" WaitForNavigation(); // Wait until we finish the navigation. AssertNoInterstitial(true); // Assert the interstitial is gone. diff --git a/chrome/test/data/safe_browsing/iframe_redirect_malware.html b/chrome/test/data/safe_browsing/iframe_redirect_malware.html new file mode 100644 index 0000000..b8b94bf --- /dev/null +++ b/chrome/test/data/safe_browsing/iframe_redirect_malware.html @@ -0,0 +1,10 @@ +<html> +<body> +<iframe src ="/server-redirect?http://localhost/files/safe_browsing/malware.html" width="100%" height="300"> + <p>Your browser does not support iframes.</p> +</iframe> +<iframe src ="/empty.hml" width="100%" height="300"> + <p>Your browser does not support iframes.</p> +</iframe> +</body> +</html> diff --git a/chrome/test/data/safe_browsing/interstitial_cancel.html b/chrome/test/data/safe_browsing/interstitial_cancel.html new file mode 100644 index 0000000..1432387 --- /dev/null +++ b/chrome/test/data/safe_browsing/interstitial_cancel.html @@ -0,0 +1,44 @@ +<html> +<head> +<script type="text/javascript"> +var tab; +function openWinIFrame() +{ + tab = window.open("iframe_redirect_malware.html"); +} + +function openMalware() +{ + window.open("http://localhost"); +} + +function openWin() +{ + tab = window.open("/server-redirect?http://localhost/files/safe_browsing/malware.html"); +} + +function stopWin() +{ + tab.stop(); + // This will trigger a navigation event. + window.location = "http://localhost"; +} + +</script> +</head> + +<body> +<form> +<input type=button value="Open Redirect Window" onclick="openWin()"> +</form> + +<form> +<input type=button value="Stop Window" onclick="stopWin()"> +</form> + +<form> +<input type=button value="Open malware in tab" onclick="openMalware()"> +</form> +</body> + +</html> |