diff options
author | davemoore@chromium.org <davemoore@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2012-05-25 21:20:30 +0000 |
---|---|---|
committer | davemoore@chromium.org <davemoore@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2012-05-25 21:20:30 +0000 |
commit | 95ab07f5047797ede40a093fa4e0123a35342c0c (patch) | |
tree | 684e671667168167c4f7f415a25137920abc1552 /ui | |
parent | 24c7c9ef2410dddfbb28a34b54ecb1256bd42575 (diff) | |
download | chromium_src-95ab07f5047797ede40a093fa4e0123a35342c0c.zip chromium_src-95ab07f5047797ede40a093fa4e0123a35342c0c.tar.gz chromium_src-95ab07f5047797ede40a093fa4e0123a35342c0c.tar.bz2 |
Remove post delete access
BUG=129745
TEST=Run new ViewTest.DeleteOnPressed test with ASAN enabled.
Review URL: https://chromiumcodereview.appspot.com/10445041
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@139120 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'ui')
-rw-r--r-- | ui/views/view.cc | 3 | ||||
-rw-r--r-- | ui/views/view_unittest.cc | 37 |
2 files changed, 38 insertions, 2 deletions
diff --git a/ui/views/view.cc b/ui/views/view.cc index 1d47f06..45fbf7c 100644 --- a/ui/views/view.cc +++ b/ui/views/view.cc @@ -1885,10 +1885,11 @@ bool View::ProcessMousePressed(const MouseEvent& event, DragInfo* drag_info) { ContextMenuController* context_menu_controller = event.IsRightMouseButton() ? context_menu_controller_ : 0; + const bool enabled = enabled_; const bool result = OnMousePressed(event); // WARNING: we may have been deleted, don't use any View variables. - if (!enabled_) + if (!enabled) return result; if (drag_operations != ui::DragDropTypes::DRAG_NONE) { diff --git a/ui/views/view_unittest.cc b/ui/views/view_unittest.cc index f78e06f..8acd0bb 100644 --- a/ui/views/view_unittest.cc +++ b/ui/views/view_unittest.cc @@ -195,7 +195,7 @@ typedef ViewsTestBase ViewTest; // A derived class for testing purpose. class TestView : public View { public: - TestView() : View(), in_touch_sequence_(false) {} + TestView() : View(), delete_on_pressed_(false), in_touch_sequence_(false) {} virtual ~TestView() {} // Reset all test state @@ -235,6 +235,7 @@ class TestView : public View { gfx::Point location_; bool received_mouse_enter_; bool received_mouse_exit_; + bool delete_on_pressed_; // Painting. std::vector<gfx::Rect> scheduled_paint_rects_; @@ -326,6 +327,8 @@ TEST_F(ViewTest, OnBoundsChanged) { bool TestView::OnMousePressed(const MouseEvent& event) { last_mouse_event_type_ = event.type(); location_.SetPoint(event.x(), event.y()); + if (delete_on_pressed_) + delete this; return true; } @@ -407,6 +410,38 @@ TEST_F(ViewTest, MouseEvent) { widget->CloseNow(); } +// Confirm that a view can be deleted as part of processing a mouse press. +TEST_F(ViewTest, DeleteOnPressed) { + TestView* v1 = new TestView(); + v1->SetBoundsRect(gfx::Rect(0, 0, 300, 300)); + + TestView* v2 = new TestView(); + v2->SetBoundsRect(gfx::Rect(100, 100, 100, 100)); + + v1->Reset(); + v2->Reset(); + + scoped_ptr<Widget> widget(new Widget); + Widget::InitParams params(Widget::InitParams::TYPE_POPUP); + params.ownership = views::Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET; + params.bounds = gfx::Rect(50, 50, 650, 650); + widget->Init(params); + View* root = widget->GetRootView(); + + root->AddChildView(v1); + v1->AddChildView(v2); + + v2->delete_on_pressed_ = true; + MouseEvent pressed(ui::ET_MOUSE_PRESSED, + 110, + 120, + ui::EF_LEFT_MOUSE_BUTTON); + root->OnMousePressed(pressed); + EXPECT_EQ(0, v1->child_count()); + + widget->CloseNow(); +} + //////////////////////////////////////////////////////////////////////////////// // TouchEvent //////////////////////////////////////////////////////////////////////////////// |