summaryrefslogtreecommitdiffstats
path: root/chrome/browser/safe_browsing
diff options
context:
space:
mode:
authorjcampan@chromium.org <jcampan@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2010-03-09 23:56:31 +0000
committerjcampan@chromium.org <jcampan@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2010-03-09 23:56:31 +0000
commita1a482b78c02ea8da62485a7fde77ff1867865be (patch)
tree5854f16b1ceeda9fe1b8145933f77a8eab0e9463 /chrome/browser/safe_browsing
parent9eaf0bac5e352ef93d7722d02d13e684446b3ad1 (diff)
downloadchromium_src-a1a482b78c02ea8da62485a7fde77ff1867865be.zip
chromium_src-a1a482b78c02ea8da62485a7fde77ff1867865be.tar.gz
chromium_src-a1a482b78c02ea8da62485a7fde77ff1867865be.tar.bz2
This CL ensures the SafeBrowsingService is only notified once
by the SafeBrowsingInterstitialPage. The interstitial page logic makes sure its Proceed/DontProceed are called only once, but the DontProceed could also be called when navigating back. Since the SafeBrowsingService::Client is deleted when the SafeBrowsingService is notified, that would cause a crasher on the 2nd notification. BUG=http://crbug.com/30079 TEST=See bug. Review URL: http://codereview.chromium.org/697002 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@41092 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'chrome/browser/safe_browsing')
-rw-r--r--chrome/browser/safe_browsing/safe_browsing_blocking_page.cc10
-rw-r--r--chrome/browser/safe_browsing/safe_browsing_blocking_page_unittest.cc26
2 files changed, 36 insertions, 0 deletions
diff --git a/chrome/browser/safe_browsing/safe_browsing_blocking_page.cc b/chrome/browser/safe_browsing/safe_browsing_blocking_page.cc
index 6d62b5e..d37c6ce 100644
--- a/chrome/browser/safe_browsing/safe_browsing_blocking_page.cc
+++ b/chrome/browser/safe_browsing/safe_browsing_blocking_page.cc
@@ -417,6 +417,16 @@ void SafeBrowsingBlockingPage::Proceed() {
}
void SafeBrowsingBlockingPage::DontProceed() {
+ DCHECK(action_taken() != DONT_PROCEED_ACTION);
+ // We could have already called Proceed(), in which case we must not notify
+ // the SafeBrowsingService again, as the client has been deleted.
+ if (action_taken() == PROCEED_ACTION) {
+ // We still want to hide the interstitial page.
+ InterstitialPage::DontProceed();
+ // We are now deleted.
+ return;
+ }
+
RecordSafeBrowsingBlockingPageStats(DONT_PROCEED);
NotifySafeBrowsingService(sb_service_, unsafe_resources_, false);
diff --git a/chrome/browser/safe_browsing/safe_browsing_blocking_page_unittest.cc b/chrome/browser/safe_browsing/safe_browsing_blocking_page_unittest.cc
index cc55d3b..6fadf58 100644
--- a/chrome/browser/safe_browsing/safe_browsing_blocking_page_unittest.cc
+++ b/chrome/browser/safe_browsing/safe_browsing_blocking_page_unittest.cc
@@ -406,3 +406,29 @@ TEST_F(SafeBrowsingBlockingPageTest, NavigatingBackAndForth) {
ASSERT_EQ(2, controller().entry_count());
EXPECT_EQ(kBadURL, controller().GetActiveEntry()->url().spec());
}
+
+// Tests that calling "don't proceed" after "proceed" has been called doesn't
+// cause problems. http://crbug.com/30079
+TEST_F(SafeBrowsingBlockingPageTest, ProceedThenDontProceed) {
+ // Start a load.
+ controller().LoadURL(GURL(kBadURL), GURL(), PageTransition::TYPED);
+
+ // Simulate the load causing a safe browsing interstitial to be shown.
+ ShowInterstitial(ResourceType::MAIN_FRAME, kBadURL);
+ SafeBrowsingBlockingPage* sb_interstitial = GetSafeBrowsingBlockingPage();
+ ASSERT_TRUE(sb_interstitial);
+
+ MessageLoop::current()->RunAllPending();
+
+ // Simulate the user clicking "proceed" then "don't proceed" (before the
+ // interstitial is shown).
+ sb_interstitial->Proceed();
+ sb_interstitial->DontProceed();
+ // Proceed() and DontProceed() post a task to update the
+ // SafeBrowsingService::Client.
+ MessageLoop::current()->RunAllPending();
+
+ // The interstitial should be gone.
+ EXPECT_EQ(OK, user_response());
+ EXPECT_FALSE(GetSafeBrowsingBlockingPage());
+}