summaryrefslogtreecommitdiffstats
path: root/ui/aura/root_window.cc
diff options
context:
space:
mode:
authorsky@chromium.org <sky@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2013-10-31 09:29:02 +0000
committersky@chromium.org <sky@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2013-10-31 09:29:02 +0000
commit2199cbd7583618efaf11b27a728fa8e7f3bc1b6d (patch)
tree97d036ba5a825c89588276ef70f96f1fa599d289 /ui/aura/root_window.cc
parentb5a12c3a60bca96f6bd6f8d5db5d8baaaaf98c9f (diff)
downloadchromium_src-2199cbd7583618efaf11b27a728fa8e7f3bc1b6d.zip
chromium_src-2199cbd7583618efaf11b27a728fa8e7f3bc1b6d.tar.gz
chromium_src-2199cbd7583618efaf11b27a728fa8e7f3bc1b6d.tar.bz2
Fixes possible use after free in RootWindow::DispatchHeldEvents
Code needs to handle the case of RootWindow being deleted during DispatchHeldEvents. BUG=309768 TEST=covered by test now R=ben@chromium.org Review URL: https://codereview.chromium.org/52543002 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@232062 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'ui/aura/root_window.cc')
-rw-r--r--ui/aura/root_window.cc24
1 files changed, 13 insertions, 11 deletions
diff --git a/ui/aura/root_window.cc b/ui/aura/root_window.cc
index e79f8ac..d25cd17 100644
--- a/ui/aura/root_window.cc
+++ b/ui/aura/root_window.cc
@@ -148,9 +148,8 @@ RootWindow::RootWindow(const CreateParams& params)
event_dispatch_target_(NULL),
synthesize_mouse_move_(false),
move_hold_count_(0),
- event_factory_(this),
- held_event_factory_(this),
- repostable_event_factory_(this) {
+ weak_factory_(this),
+ held_event_factory_(this) {
set_dispatcher(this);
SetName("RootWindow");
@@ -235,7 +234,7 @@ void RootWindow::RepostEvent(const ui::LocatedEvent& event) {
base::MessageLoop::current()->PostTask(
FROM_HERE,
base::Bind(&RootWindow::DispatchHeldEvents,
- repostable_event_factory_.GetWeakPtr()));
+ weak_factory_.GetWeakPtr()));
} else {
DCHECK(event.type() == ui::ET_GESTURE_TAP_DOWN);
held_repostable_event_.reset();
@@ -967,15 +966,14 @@ bool RootWindow::DispatchMouseEventToTarget(ui::MouseEvent* event,
ui::EF_RIGHT_MOUSE_BUTTON;
// WARNING: because of nested message loops |this| may be deleted after
// dispatching any event. Do not use AutoReset or the like here.
- WindowTracker destroyed_tracker;
- destroyed_tracker.Add(this);
+ base::WeakPtr<RootWindow> ref(weak_factory_.GetWeakPtr());
SetLastMouseLocation(this, event->location());
synthesize_mouse_move_ = false;
switch (event->type()) {
case ui::ET_MOUSE_EXITED:
if (!target) {
DispatchMouseEnterOrExit(*event, ui::ET_MOUSE_EXITED);
- if (!destroyed_tracker.Contains(this))
+ if (!ref)
return false;
mouse_moved_handler_ = NULL;
}
@@ -986,10 +984,11 @@ bool RootWindow::DispatchMouseEventToTarget(ui::MouseEvent* event,
// dispatch.
if (target != mouse_moved_handler_) {
aura::Window* old_mouse_moved_handler = mouse_moved_handler_;
+ WindowTracker destroyed_tracker;
if (target)
destroyed_tracker.Add(target);
DispatchMouseEnterOrExit(*event, ui::ET_MOUSE_EXITED);
- if (!destroyed_tracker.Contains(this))
+ if (!ref)
return false;
// If the |mouse_moved_handler_| changes out from under us, assume a
// nested message loop ran and we don't need to do anything.
@@ -999,7 +998,7 @@ bool RootWindow::DispatchMouseEventToTarget(ui::MouseEvent* event,
destroyed_tracker.Remove(target);
mouse_moved_handler_ = target;
DispatchMouseEnterOrExit(*event, ui::ET_MOUSE_ENTERED);
- if (!destroyed_tracker.Contains(this))
+ if (!ref)
return false;
} else {
mouse_moved_handler_ = NULL;
@@ -1031,7 +1030,7 @@ bool RootWindow::DispatchMouseEventToTarget(ui::MouseEvent* event,
if (IsNonClientLocation(target, event->location()))
event->set_flags(event->flags() | ui::EF_IS_NON_CLIENT);
ProcessEvent(target, event);
- if (!destroyed_tracker.Contains(this))
+ if (!ref)
return false;
result = event->handled();
} else {
@@ -1108,6 +1107,7 @@ bool RootWindow::DispatchTouchEventImpl(ui::TouchEvent* event) {
void RootWindow::DispatchHeldEvents() {
if (held_repostable_event_) {
+ base::WeakPtr<RootWindow> ref(weak_factory_.GetWeakPtr());
if (held_repostable_event_->type() == ui::ET_MOUSE_PRESSED) {
scoped_ptr<ui::MouseEvent> mouse_event(
static_cast<ui::MouseEvent*>(held_repostable_event_.release()));
@@ -1116,6 +1116,8 @@ void RootWindow::DispatchHeldEvents() {
// TODO(rbyers): GESTURE_TAP_DOWN not yet supported: crbug.com/170987.
NOTREACHED();
}
+ if (!ref)
+ return;
}
if (held_move_event_ && held_move_event_->IsMouseEvent()) {
// If a mouse move has been synthesized, the target location is suspect,
@@ -1138,7 +1140,7 @@ void RootWindow::PostMouseMoveEventAfterWindowChange() {
base::MessageLoop::current()->PostTask(
FROM_HERE,
base::Bind(&RootWindow::SynthesizeMouseMoveEvent,
- event_factory_.GetWeakPtr()));
+ weak_factory_.GetWeakPtr()));
}
void RootWindow::SynthesizeMouseMoveEvent() {