Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(72)

Side by Side Diff: ui/views/controls/menu/menu_controller.cc

Issue 2641983003: Reland Fix MenuController Heap-use-after-free (Closed)
Patch Set: Apply Fix Created 3 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « no previous file | ui/views/controls/menu/menu_controller_unittest.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "ui/views/controls/menu/menu_controller.h" 5 #include "ui/views/controls/menu/menu_controller.h"
6 6
7 #include "base/i18n/case_conversion.h" 7 #include "base/i18n/case_conversion.h"
8 #include "base/i18n/rtl.h" 8 #include "base/i18n/rtl.h"
9 #include "base/macros.h" 9 #include "base/macros.h"
10 #include "base/strings/utf_string_conversions.h" 10 #include "base/strings/utf_string_conversions.h"
(...skipping 2557 matching lines...) Expand 10 before | Expand all | Expand 10 after
2568 message_loop_->QuitNow(); 2568 message_loop_->QuitNow();
2569 return quit_now; 2569 return quit_now;
2570 } 2570 }
2571 2571
2572 void MenuController::ExitAsyncRun() { 2572 void MenuController::ExitAsyncRun() {
2573 if (!async_run_) 2573 if (!async_run_)
2574 return; 2574 return;
2575 bool nested = delegate_stack_.size() > 1; 2575 bool nested = delegate_stack_.size() > 1;
2576 // ExitMenuRun unwinds nested delegates 2576 // ExitMenuRun unwinds nested delegates
2577 internal::MenuControllerDelegate* delegate = delegate_; 2577 internal::MenuControllerDelegate* delegate = delegate_;
2578 // MenuController may have been deleted when releasing ViewsDelegate ref.
2579 // However as |delegate| can outlive this, it must still be notified of the
2580 // menu closing so that it can perform teardown.
2581 int accept_event_flags = accept_event_flags_;
2578 MenuItemView* result = ExitMenuRun(); 2582 MenuItemView* result = ExitMenuRun();
2579 delegate->OnMenuClosed(internal::MenuControllerDelegate::NOTIFY_DELEGATE, 2583 delegate->OnMenuClosed(internal::MenuControllerDelegate::NOTIFY_DELEGATE,
2580 result, accept_event_flags_); 2584 result, accept_event_flags);
2581 // MenuController may have been deleted by |delegate|. 2585 // MenuController may have been deleted by |delegate|.
2582 if (GetActiveInstance() && nested && exit_type_ == EXIT_ALL) 2586 if (GetActiveInstance() && nested && exit_type_ == EXIT_ALL)
2583 ExitAsyncRun(); 2587 ExitAsyncRun();
2584 } 2588 }
2585 2589
2586 MenuItemView* MenuController::ExitMenuRun() { 2590 MenuItemView* MenuController::ExitMenuRun() {
2587 // Release the lock which prevents Chrome from shutting down while the menu is 2591 // Release the lock which prevents Chrome from shutting down while the menu is
2588 // showing. 2592 // showing.
2589 if (async_run_ && ViewsDelegate::GetInstance()) 2593 if (async_run_ && ViewsDelegate::GetInstance())
2590 ViewsDelegate::GetInstance()->ReleaseRef(); 2594 ViewsDelegate::GetInstance()->ReleaseRef();
2591 2595
2596 // Releasing the lock can result in Chrome shutting down, deleting this.
2597 if (!GetActiveInstance())
2598 return nullptr;
2599
2592 // Close any open menus. 2600 // Close any open menus.
2593 SetSelection(nullptr, SELECTION_UPDATE_IMMEDIATELY | SELECTION_EXIT); 2601 SetSelection(nullptr, SELECTION_UPDATE_IMMEDIATELY | SELECTION_EXIT);
2594 2602
2595 #if defined(OS_WIN) 2603 #if defined(OS_WIN)
2596 // On Windows, if we select the menu item by touch and if the window at the 2604 // On Windows, if we select the menu item by touch and if the window at the
2597 // location is another window on the same thread, that window gets a 2605 // location is another window on the same thread, that window gets a
2598 // WM_MOUSEACTIVATE message and ends up activating itself, which is not 2606 // WM_MOUSEACTIVATE message and ends up activating itself, which is not
2599 // correct. We workaround this by setting a property on the window at the 2607 // correct. We workaround this by setting a property on the window at the
2600 // current cursor location. We check for this property in our 2608 // current cursor location. We check for this property in our
2601 // WM_MOUSEACTIVATE handler and don't activate the window if the property is 2609 // WM_MOUSEACTIVATE handler and don't activate the window if the property is
(...skipping 122 matching lines...) Expand 10 before | Expand all | Expand 10 after
2724 if (hot_button_) 2732 if (hot_button_)
2725 hot_button_->SetHotTracked(false); 2733 hot_button_->SetHotTracked(false);
2726 hot_button_ = hot_button; 2734 hot_button_ = hot_button;
2727 if (hot_button) { 2735 if (hot_button) {
2728 hot_button->SetHotTracked(true); 2736 hot_button->SetHotTracked(true);
2729 hot_button->NotifyAccessibilityEvent(ui::AX_EVENT_SELECTION, true); 2737 hot_button->NotifyAccessibilityEvent(ui::AX_EVENT_SELECTION, true);
2730 } 2738 }
2731 } 2739 }
2732 2740
2733 } // namespace views 2741 } // namespace views
OLDNEW
« no previous file with comments | « no previous file | ui/views/controls/menu/menu_controller_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698