diff options
author | mattm@chromium.org <mattm@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2009-10-23 01:51:33 +0000 |
---|---|---|
committer | mattm@chromium.org <mattm@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2009-10-23 01:51:33 +0000 |
commit | 70853b00ae4f3a0b3c96978cfa4a5caeabacb60b (patch) | |
tree | 0963c7a0aeb351e66f7ece5f1ac52ec8be9f8667 /chrome/browser | |
parent | 7bf54f5ec74d9d3b3498c02b83da572a78fc1df6 (diff) | |
download | chromium_src-70853b00ae4f3a0b3c96978cfa4a5caeabacb60b.zip chromium_src-70853b00ae4f3a0b3c96978cfa4a5caeabacb60b.tar.gz chromium_src-70853b00ae4f3a0b3c96978cfa4a5caeabacb60b.tar.bz2 |
Linux: fix crash in PopulateCookieDetails called by OnSelectionChanged callback
which can be called while the view and model are in inconsistent states.
BUG=25535
TEST=open cookies manager, select all, remove all
Review URL: http://codereview.chromium.org/334001
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@29860 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'chrome/browser')
-rw-r--r-- | chrome/browser/gtk/options/cookies_view.cc | 9 | ||||
-rw-r--r-- | chrome/browser/gtk/options/cookies_view.h | 2 | ||||
-rw-r--r-- | chrome/browser/gtk/options/cookies_view_unittest.cc | 32 |
3 files changed, 43 insertions, 0 deletions
diff --git a/chrome/browser/gtk/options/cookies_view.cc b/chrome/browser/gtk/options/cookies_view.cc index b2b16e0..6e47043 100644 --- a/chrome/browser/gtk/options/cookies_view.cc +++ b/chrome/browser/gtk/options/cookies_view.cc @@ -366,7 +366,16 @@ void CookiesView::RemoveSelectedCookies() { } } +void CookiesView::OnAnyModelUpdateStart() { + g_signal_handlers_block_by_func( + G_OBJECT(selection_), reinterpret_cast<gpointer>(OnSelectionChanged), + this); +} + void CookiesView::OnAnyModelUpdate() { + g_signal_handlers_unblock_by_func( + G_OBJECT(selection_), reinterpret_cast<gpointer>(OnSelectionChanged), + this); EnableControls(); } diff --git a/chrome/browser/gtk/options/cookies_view.h b/chrome/browser/gtk/options/cookies_view.h index f47a95b..be9dbb8 100644 --- a/chrome/browser/gtk/options/cookies_view.h +++ b/chrome/browser/gtk/options/cookies_view.h @@ -33,6 +33,7 @@ class CookiesView : public gtk_tree::ModelAdapter::Delegate { static void Show(Profile* profile); // gtk_tree::ModelAdapter::Delegate implementation. + virtual void OnAnyModelUpdateStart(); virtual void OnAnyModelUpdate(); virtual void SetColumnValues(int row, GtkTreeIter* iter); @@ -140,6 +141,7 @@ class CookiesView : public gtk_tree::ModelAdapter::Delegate { friend class CookiesViewTest; FRIEND_TEST(CookiesViewTest, Empty); FRIEND_TEST(CookiesViewTest, RemoveAll); + FRIEND_TEST(CookiesViewTest, RemoveAllWithAllSelected); FRIEND_TEST(CookiesViewTest, Remove); FRIEND_TEST(CookiesViewTest, RemoveMultiple); FRIEND_TEST(CookiesViewTest, RemoveDefaultSelection); diff --git a/chrome/browser/gtk/options/cookies_view_unittest.cc b/chrome/browser/gtk/options/cookies_view_unittest.cc index 29337ff..ce0db2d 100644 --- a/chrome/browser/gtk/options/cookies_view_unittest.cc +++ b/chrome/browser/gtk/options/cookies_view_unittest.cc @@ -142,6 +142,38 @@ TEST_F(CookiesViewTest, RemoveAll) { } } +// When removing all items, if multiple items were selected the +// OnSelectionChanged callback could get called while the gtk list view and the +// CookiesTableModel were inconsistent. Test that it doesn't crash. +TEST_F(CookiesViewTest, RemoveAllWithAllSelected) { + net::CookieMonster* monster = + profile_->GetRequestContext()->cookie_store()->GetCookieMonster(); + monster->SetCookie(GURL("http://foo"), "A=1"); + monster->SetCookie(GURL("http://foo2"), "B=1"); + CookiesView cookies_view(profile_.get()); + + gtk_tree_selection_select_all(cookies_view.selection_); + { + SCOPED_TRACE("Before removing"); + EXPECT_EQ(TRUE, GTK_WIDGET_SENSITIVE(cookies_view.remove_all_button_)); + EXPECT_EQ(TRUE, GTK_WIDGET_SENSITIVE(cookies_view.remove_button_)); + CheckDetailsSensitivity(FALSE, cookies_view); + EXPECT_EQ(2, gtk_tree_model_iter_n_children( + GTK_TREE_MODEL(cookies_view.list_store_), NULL)); + } + + gtk_button_clicked(GTK_BUTTON(cookies_view.remove_all_button_)); + { + SCOPED_TRACE("After removing"); + EXPECT_EQ(0u, monster->GetAllCookies().size()); + EXPECT_EQ(FALSE, GTK_WIDGET_SENSITIVE(cookies_view.remove_all_button_)); + EXPECT_EQ(FALSE, GTK_WIDGET_SENSITIVE(cookies_view.remove_button_)); + CheckDetailsSensitivity(FALSE, cookies_view); + EXPECT_EQ(0, gtk_tree_model_iter_n_children( + GTK_TREE_MODEL(cookies_view.list_store_), NULL)); + } +} + TEST_F(CookiesViewTest, Remove) { net::CookieMonster* monster = profile_->GetRequestContext()->cookie_store()->GetCookieMonster(); |