summaryrefslogtreecommitdiffstats
path: root/ui/base/events
diff options
context:
space:
mode:
authorjamescook@chromium.org <jamescook@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2012-10-30 22:55:31 +0000
committerjamescook@chromium.org <jamescook@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2012-10-30 22:55:31 +0000
commitcb03bc2910dd2675fdd66f171a95b90e04be9dfb (patch)
tree2074e62e390642496cac81afa1b6c305fa3439b2 /ui/base/events
parentbd182a69fc2c119cabff620795e705eafd2ef539 (diff)
downloadchromium_src-cb03bc2910dd2675fdd66f171a95b90e04be9dfb.zip
chromium_src-cb03bc2910dd2675fdd66f171a95b90e04be9dfb.tar.gz
chromium_src-cb03bc2910dd2675fdd66f171a95b90e04be9dfb.tar.bz2
Fix crash in ash::internal::WorkspaceEventHandler::OnMouseEvent
Stop event processing if the event target is invalidated or deleted during processing of a list of events. BUG=158332 TEST=added to ui_unittests:EventDispatcherTest Review URL: https://chromiumcodereview.appspot.com/11339052 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@165045 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'ui/base/events')
-rw-r--r--ui/base/events/event_dispatcher.h3
-rw-r--r--ui/base/events/event_dispatcher_unittest.cc52
2 files changed, 53 insertions, 2 deletions
diff --git a/ui/base/events/event_dispatcher.h b/ui/base/events/event_dispatcher.h
index ff58e3b..33cb043 100644
--- a/ui/base/events/event_dispatcher.h
+++ b/ui/base/events/event_dispatcher.h
@@ -91,6 +91,9 @@ class UI_EXPORT EventDispatcher {
// dispatching the event to the event handler.
template<class T>
int DispatchEvent(EventHandler* handler, T* event) {
+ // If the target has been invalidated or deleted, don't dispatch the event.
+ if (!CanDispatchToTarget(event->target()))
+ return ui::ER_CONSUMED;
bool destroyed = false;
set_on_destroy_ = &destroyed;
int result = DispatchEventToSingleHandler(handler, event);
diff --git a/ui/base/events/event_dispatcher_unittest.cc b/ui/base/events/event_dispatcher_unittest.cc
index 36cbd43..89285e4 100644
--- a/ui/base/events/event_dispatcher_unittest.cc
+++ b/ui/base/events/event_dispatcher_unittest.cc
@@ -12,11 +12,14 @@ namespace {
class TestTarget : public EventTarget {
public:
- TestTarget() : parent_(NULL) {}
+ TestTarget() : parent_(NULL), valid_(true) {}
virtual ~TestTarget() {}
void set_parent(TestTarget* parent) { parent_ = parent; }
+ bool valid() const { return valid_; }
+ void set_valid(bool valid) { valid_ = valid; }
+
void AddHandlerId(int id) {
handler_list_.push_back(id);
}
@@ -39,6 +42,7 @@ class TestTarget : public EventTarget {
TestTarget* parent_;
std::vector<int> handler_list_;
+ bool valid_;
DISALLOW_COPY_AND_ASSIGN(TestTarget);
};
@@ -132,6 +136,22 @@ class EventHandlerDestroyDispatcher : public TestEventHandler {
DISALLOW_COPY_AND_ASSIGN(EventHandlerDestroyDispatcher);
};
+// Invalidates the target when it receives any event.
+class InvalidateTargetEventHandler : public TestEventHandler {
+ public:
+ InvalidateTargetEventHandler(int id) : TestEventHandler(id) {}
+ virtual ~InvalidateTargetEventHandler() {}
+
+ private:
+ virtual void ReceivedEvent(Event* event) {
+ TestEventHandler::ReceivedEvent(event);
+ TestTarget* target = static_cast<TestTarget*>(event->target());
+ target->set_valid(false);
+ }
+
+ DISALLOW_COPY_AND_ASSIGN(InvalidateTargetEventHandler);
+};
+
class TestEventDispatcher : public EventDispatcher {
public:
TestEventDispatcher() {}
@@ -140,7 +160,8 @@ class TestEventDispatcher : public EventDispatcher {
private:
// Overridden from EventDispatcher:
virtual bool CanDispatchToTarget(EventTarget* target) OVERRIDE {
- return true;
+ TestTarget* test_target = static_cast<TestTarget*>(target);
+ return test_target->valid();
}
DISALLOW_COPY_AND_ASSIGN(TestEventDispatcher);
@@ -317,4 +338,31 @@ TEST(EventDispatcherTest, EventDispatcherDestroyTarget) {
}
}
+// Tests that a target becoming invalid in the middle of pre- or post-target
+// event processing aborts processing.
+TEST(EventDispatcherTest, EventDispatcherInvalidateTarget) {
+ TestEventDispatcher dispatcher;
+ TestTarget target;
+ TestEventHandler h1(1);
+ InvalidateTargetEventHandler invalidate_handler(2);
+ TestEventHandler h3(3);
+
+ target.AddPreTargetHandler(&h1);
+ target.AddPreTargetHandler(&invalidate_handler);
+ target.AddPreTargetHandler(&h3);
+
+ h1.set_expect_pre_target(true);
+ invalidate_handler.set_expect_pre_target(true);
+ // |h3| should not receive events as the target will be invalidated.
+ h3.set_expect_pre_target(false);
+
+ MouseEvent mouse(ui::ET_MOUSE_MOVED, gfx::Point(3, 4), gfx::Point(3, 4), 0);
+ int result = dispatcher.ProcessEvent(&target, &mouse);
+ EXPECT_FALSE(target.valid());
+ EXPECT_EQ(ER_CONSUMED, result);
+ EXPECT_EQ(2U, target.handler_list().size());
+ EXPECT_EQ(1, target.handler_list()[0]);
+ EXPECT_EQ(2, target.handler_list()[1]);
+}
+
} // namespace ui