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

Side by Side Diff: chrome/browser/ui/views/accessibility/accessibility_event_router_views.cc

Issue 13584005: Fix use-after-free of Profile after it's been destroyed. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Created 7 years, 8 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 | Annotate | Revision Log
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 "chrome/browser/ui/views/accessibility/accessibility_event_router_views .h" 5 #include "chrome/browser/ui/views/accessibility/accessibility_event_router_views .h"
6 6
7 #include "base/basictypes.h" 7 #include "base/basictypes.h"
8 #include "base/callback.h" 8 #include "base/callback.h"
9 #include "base/memory/singleton.h" 9 #include "base/memory/singleton.h"
10 #include "base/message_loop.h" 10 #include "base/message_loop.h"
11 #include "base/utf_string_conversions.h" 11 #include "base/utf_string_conversions.h"
12 #include "chrome/browser/accessibility/accessibility_extension_api.h" 12 #include "chrome/browser/accessibility/accessibility_extension_api.h"
13 #include "chrome/browser/browser_process.h" 13 #include "chrome/browser/browser_process.h"
14 #include "chrome/browser/profiles/profile.h" 14 #include "chrome/browser/profiles/profile.h"
15 #include "chrome/browser/profiles/profile_manager.h" 15 #include "chrome/browser/profiles/profile_manager.h"
16 #include "chrome/common/chrome_notification_types.h" 16 #include "chrome/common/chrome_notification_types.h"
17 #include "content/public/browser/notification_service.h"
18 #include "content/public/browser/notification_source.h"
17 #include "ui/base/accessibility/accessible_view_state.h" 19 #include "ui/base/accessibility/accessible_view_state.h"
18 #include "ui/views/controls/button/text_button.h" 20 #include "ui/views/controls/button/text_button.h"
19 #include "ui/views/controls/menu/menu_item_view.h" 21 #include "ui/views/controls/menu/menu_item_view.h"
20 #include "ui/views/controls/menu/submenu_view.h" 22 #include "ui/views/controls/menu/submenu_view.h"
21 #include "ui/views/view.h" 23 #include "ui/views/view.h"
22 #include "ui/views/widget/widget.h" 24 #include "ui/views/widget/widget.h"
23 25
24 using views::FocusManager; 26 using views::FocusManager;
25 27
26 AccessibilityEventRouterViews::AccessibilityEventRouterViews() 28 AccessibilityEventRouterViews::AccessibilityEventRouterViews()
27 : most_recent_profile_(NULL) { 29 : most_recent_profile_(NULL) {
30 registrar_.reset(new content::NotificationRegistrar);
31 // Register for notification when profile is destroyed to ensure that all
32 // observers are detatched at that time.
33 registrar_->Add(this, chrome::NOTIFICATION_PROFILE_DESTROYED,
34 content::NotificationService::AllSources());
28 } 35 }
29 36
30 AccessibilityEventRouterViews::~AccessibilityEventRouterViews() { 37 AccessibilityEventRouterViews::~AccessibilityEventRouterViews() {
31 } 38 }
32 39
33 // static 40 // static
34 AccessibilityEventRouterViews* AccessibilityEventRouterViews::GetInstance() { 41 AccessibilityEventRouterViews* AccessibilityEventRouterViews::GetInstance() {
35 return Singleton<AccessibilityEventRouterViews>::get(); 42 return Singleton<AccessibilityEventRouterViews>::get();
36 } 43 }
37 44
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after
93 AccessibilityMenuItemInfo info(most_recent_profile_, 100 AccessibilityMenuItemInfo info(most_recent_profile_,
94 UTF16ToUTF8(menu_item_name), 101 UTF16ToUTF8(menu_item_name),
95 UTF16ToUTF8(menu_name), 102 UTF16ToUTF8(menu_name),
96 has_submenu, 103 has_submenu,
97 item_index, 104 item_index,
98 item_count); 105 item_count);
99 SendAccessibilityNotification( 106 SendAccessibilityNotification(
100 chrome::NOTIFICATION_ACCESSIBILITY_CONTROL_FOCUSED, &info); 107 chrome::NOTIFICATION_ACCESSIBILITY_CONTROL_FOCUSED, &info);
101 } 108 }
102 109
110 void AccessibilityEventRouterViews::Observe(
111 int type,
112 const content::NotificationSource& source,
113 const content::NotificationDetails& details) {
114 if (type == chrome::NOTIFICATION_PROFILE_DESTROYED) {
Lei Zhang 2013/04/03 21:56:49 You can just DCHECK this.
dmazzoni 2013/04/03 22:02:29 Done.
115 Profile* profile = content::Source<Profile>(source).ptr();
116 if (profile == most_recent_profile_)
117 most_recent_profile_ = NULL;
118 }
119 }
120
103 // 121 //
104 // Private methods 122 // Private methods
105 // 123 //
106 124
107 void AccessibilityEventRouterViews::DispatchAccessibilityNotification( 125 void AccessibilityEventRouterViews::DispatchAccessibilityNotification(
108 views::View* view, int type) { 126 views::View* view, int type) {
109 // Get the profile associated with this view. If it's not found, use 127 // Get the profile associated with this view. If it's not found, use
110 // the most recent profile where accessibility events were sent, or 128 // the most recent profile where accessibility events were sent, or
111 // the default profile. 129 // the default profile.
112 Profile* profile = NULL; 130 Profile* profile = NULL;
113 views::Widget* widget = view->GetWidget(); 131 views::Widget* widget = view->GetWidget();
114 if (widget) { 132 if (widget) {
115 profile = reinterpret_cast<Profile*>( 133 profile = reinterpret_cast<Profile*>(
116 widget->GetNativeWindowProperty(Profile::kProfileKey)); 134 widget->GetNativeWindowProperty(Profile::kProfileKey));
117 } 135 }
118 if (!profile) 136 if (!profile)
119 profile = most_recent_profile_; 137 profile = most_recent_profile_;
120 if (!profile)
121 profile = g_browser_process->profile_manager()->GetLastUsedProfile();
122 if (!profile) { 138 if (!profile) {
123 NOTREACHED(); 139 if (g_browser_process->profile_manager())
140 profile = g_browser_process->profile_manager()->GetLastUsedProfile();
141 }
142 if (!profile) {
143 LOG(WARNING) << "Accessibility notification but no profile";
124 return; 144 return;
125 } 145 }
126 146
127 most_recent_profile_ = profile; 147 most_recent_profile_ = profile;
128 148
129 if (type == chrome::NOTIFICATION_ACCESSIBILITY_MENU_OPENED || 149 if (type == chrome::NOTIFICATION_ACCESSIBILITY_MENU_OPENED ||
130 type == chrome::NOTIFICATION_ACCESSIBILITY_MENU_CLOSED) { 150 type == chrome::NOTIFICATION_ACCESSIBILITY_MENU_CLOSED) {
131 SendMenuNotification(view, type, profile); 151 SendMenuNotification(view, type, profile);
132 return; 152 return;
133 } 153 }
(...skipping 306 matching lines...) Expand 10 before | Expand all | Expand 10 after
440 return UTF16ToUTF8(state.name); 460 return UTF16ToUTF8(state.name);
441 461
442 for (int i = 0; i < view->child_count(); ++i) { 462 for (int i = 0; i < view->child_count(); ++i) {
443 views::View* child = view->child_at(i); 463 views::View* child = view->child_at(i);
444 std::string result = RecursiveGetStaticText(child); 464 std::string result = RecursiveGetStaticText(child);
445 if (!result.empty()) 465 if (!result.empty())
446 return result; 466 return result;
447 } 467 }
448 return std::string(); 468 return std::string();
449 } 469 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698