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

Side by Side Diff: plugin/cross/main.cc

Issue 4957002: - Check for a NULL PluginObject at all NPAPI entry points. This fixes a crash in Chrome where ... (Closed) Base URL: svn://chrome-svn/chrome/trunk/src/o3d/
Patch Set: '' Created 10 years, 1 month 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
« no previous file with comments | « plugin/cross/main.h ('k') | plugin/cross/plugin_logging.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 /* 1 /*
2 * Copyright 2009, Google Inc. 2 * Copyright 2009, Google Inc.
3 * All rights reserved. 3 * All rights reserved.
4 * 4 *
5 * Redistribution and use in source and binary forms, with or without 5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are 6 * modification, are permitted provided that the following conditions are
7 * met: 7 * met:
8 * 8 *
9 * * Redistributions of source code must retain the above copyright 9 * * Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer. 10 * notice, this list of conditions and the following disclaimer.
(...skipping 14 matching lines...) Expand all
25 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 25 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
26 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 26 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
27 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 27 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
28 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 28 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
29 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 29 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30 */ 30 */
31 31
32 32
33 #include "plugin/cross/main.h" 33 #include "plugin/cross/main.h"
34 34
35 #include "base/at_exit.h"
36 #include "base/command_line.h"
37 #include "base/file_util.h"
38 #include "plugin/cross/config.h"
39 #include "plugin/cross/out_of_memory.h"
40 #include "plugin/cross/whitelist.h"
41 #ifdef OS_WIN
42 #include "breakpad/win/bluescreen_detector.h"
43 #endif
44
35 using glue::_o3d::PluginObject; 45 using glue::_o3d::PluginObject;
36 using glue::StreamManager; 46 using glue::StreamManager;
37 47
38 #if !defined(O3D_INTERNAL_PLUGIN) 48 #if !defined(O3D_INTERNAL_PLUGIN)
39 49
50 #ifdef OS_WIN
51 #define O3D_DEBUG_LOG_FILENAME L"debug.log"
52 #else
53 #define O3D_DEBUG_LOG_FILENAME "debug.log"
54 #endif
55
56 #if defined(OS_WIN) || defined(OS_MACOSX)
57 o3d::PluginLogging *g_logger = NULL;
58 static bool g_logging_initialized = false;
59 #ifdef OS_WIN
60 static o3d::BluescreenDetector *g_bluescreen_detector = NULL;
61 #endif // OS_WIN
62 #endif // OS_WIN || OS_MACOSX
63
64 // We would normally make this a stack variable in main(), but in a
65 // plugin, that's not possible, so we make it a global. When the DLL is loaded
66 // this it gets constructed and when it is unlooaded it is destructed. Note
67 // that this cannot be done in NP_Initialize and NP_Shutdown because those
68 // calls do not necessarily signify the DLL being loaded and unloaded. If the
69 // DLL is not unloaded then the values of global variables are preserved.
70 static base::AtExitManager g_at_exit_manager;
71
40 int BreakpadEnabler::scope_count_ = 0; 72 int BreakpadEnabler::scope_count_ = 0;
41 73
42 // Used for breakpad crash handling
43 ExceptionManager *g_exception_manager = NULL;
44
45 #endif // O3D_INTERNAL_PLUGIN 74 #endif // O3D_INTERNAL_PLUGIN
46 75
47 namespace o3d { 76 namespace o3d {
48 77
49 NPError NP_GetValue(void *instance, NPPVariable variable, void *value) { 78 NPError NP_GetValue(NPPVariable variable, void *value) {
50 switch (variable) { 79 switch (variable) {
51 case NPPVpluginNameString: 80 case NPPVpluginNameString:
52 *static_cast<char **>(value) = const_cast<char*>(O3D_PLUGIN_NAME); 81 *static_cast<char **>(value) = const_cast<char*>(O3D_PLUGIN_NAME);
53 break; 82 break;
54 case NPPVpluginDescriptionString: 83 case NPPVpluginDescriptionString:
55 *static_cast<char **>(value) = const_cast<char*>(O3D_PLUGIN_DESCRIPTION); 84 *static_cast<char **>(value) = const_cast<char*>(O3D_PLUGIN_DESCRIPTION);
56 break; 85 break;
57 default: 86 default:
58 return NPERR_INVALID_PARAM; 87 return NPERR_INVALID_PARAM;
59 break; 88 break;
60 } 89 }
61 return NPERR_NO_ERROR; 90 return NPERR_NO_ERROR;
62 } 91 }
63 92
64 NPError NPP_NewStream(NPP instance, NPMIMEType type, NPStream *stream, 93 int16 NPP_HandleEvent(NPP instance, void *event) {
65 NPBool seekable, uint16 *stype) {
66 HANDLE_CRASHES; 94 HANDLE_CRASHES;
67 PluginObject *obj = static_cast<PluginObject*>(instance->pdata); 95 PluginObject *obj = static_cast<PluginObject *>(instance->pdata);
96 if (!obj) {
97 return 0;
98 }
99
100 return PlatformNPPHandleEvent(instance, obj, event);
101 }
102
103 NPError NPP_NewStream(NPP instance,
104 NPMIMEType type,
105 NPStream *stream,
106 NPBool seekable,
107 uint16 *stype) {
108 HANDLE_CRASHES;
109 PluginObject *obj = static_cast<PluginObject *>(instance->pdata);
110 if (!obj) {
111 return NPERR_INVALID_PARAM;
112 }
113
68 StreamManager *stream_manager = obj->stream_manager(); 114 StreamManager *stream_manager = obj->stream_manager();
69 if (stream_manager->NewStream(stream, stype)) { 115 if (stream_manager->NewStream(stream, stype)) {
70 return NPERR_NO_ERROR; 116 return NPERR_NO_ERROR;
71 } else { 117 } else {
72 // TODO: find out which error we should return 118 // TODO: find out which error we should return
73 return NPERR_INVALID_PARAM; 119 return NPERR_INVALID_PARAM;
74 } 120 }
75 } 121 }
76 122
77 NPError NPP_DestroyStream(NPP instance, NPStream *stream, NPReason reason) { 123 NPError NPP_DestroyStream(NPP instance, NPStream *stream, NPReason reason) {
78 HANDLE_CRASHES; 124 HANDLE_CRASHES;
79 PluginObject *obj = static_cast<PluginObject*>(instance->pdata); 125 PluginObject *obj = static_cast<PluginObject *>(instance->pdata);
126 if (!obj) {
127 return NPERR_NO_ERROR;
128 }
129
80 StreamManager *stream_manager = obj->stream_manager(); 130 StreamManager *stream_manager = obj->stream_manager();
81 if (stream_manager->DestroyStream(stream, reason)) { 131 if (stream_manager->DestroyStream(stream, reason)) {
82 return NPERR_NO_ERROR; 132 return NPERR_NO_ERROR;
83 } else { 133 } else {
84 // TODO: find out which error we should return 134 // TODO: find out which error we should return
85 return NPERR_INVALID_PARAM; 135 return NPERR_INVALID_PARAM;
86 } 136 }
87 } 137 }
88 138
89 int32 NPP_WriteReady(NPP instance, NPStream *stream) { 139 int32 NPP_WriteReady(NPP instance, NPStream *stream) {
90 HANDLE_CRASHES; 140 HANDLE_CRASHES;
91 PluginObject *obj = static_cast<PluginObject*>(instance->pdata); 141 PluginObject *obj = static_cast<PluginObject *>(instance->pdata);
142 if (!obj) {
143 return 0;
144 }
145
92 StreamManager *stream_manager = obj->stream_manager(); 146 StreamManager *stream_manager = obj->stream_manager();
93 return stream_manager->WriteReady(stream); 147 return stream_manager->WriteReady(stream);
94 } 148 }
95 149
96 int32 NPP_Write(NPP instance, NPStream *stream, int32 offset, int32 len, 150 int32 NPP_Write(NPP instance, NPStream *stream, int32 offset, int32 len,
97 void *buffer) { 151 void *buffer) {
98 HANDLE_CRASHES; 152 HANDLE_CRASHES;
99 PluginObject *obj = static_cast<PluginObject*>(instance->pdata); 153 PluginObject *obj = static_cast<PluginObject *>(instance->pdata);
154 if (!obj) {
155 return 0;
156 }
157
100 StreamManager *stream_manager = obj->stream_manager(); 158 StreamManager *stream_manager = obj->stream_manager();
101 return stream_manager->Write(stream, offset, len, buffer); 159 return stream_manager->Write(stream, offset, len, buffer);
102 } 160 }
103 161
104 void NPP_Print(NPP instance, NPPrint *platformPrint) { 162 void NPP_Print(NPP instance, NPPrint *platformPrint) {
105 HANDLE_CRASHES; 163 HANDLE_CRASHES;
106 } 164 }
107 165
108 void NPP_URLNotify(NPP instance, const char *url, NPReason reason, 166 void NPP_URLNotify(NPP instance, const char *url, NPReason reason,
109 void *notifyData) { 167 void *notifyData) {
110 HANDLE_CRASHES; 168 HANDLE_CRASHES;
111 PluginObject *obj = static_cast<PluginObject*>(instance->pdata); 169 PluginObject *obj = static_cast<PluginObject *>(instance->pdata);
112 // Make sure the plugin hasn't been destroyed already. 170 if (!obj) {
113 if (obj) { 171 return;
114 StreamManager *stream_manager = obj->stream_manager();
115 stream_manager->URLNotify(url, reason, notifyData);
116 } 172 }
173
174 StreamManager *stream_manager = obj->stream_manager();
175 stream_manager->URLNotify(url, reason, notifyData);
117 } 176 }
118 177
119 NPError NPP_GetValue(NPP instance, NPPVariable variable, void *value) { 178 NPError NPP_GetValue(NPP instance, NPPVariable variable, void *value) {
120 HANDLE_CRASHES; 179 HANDLE_CRASHES;
180 PluginObject *obj = static_cast<PluginObject *>(instance->pdata);
181 if (!obj) {
182 return NPERR_INVALID_PARAM;
183 }
184
121 switch (variable) { 185 switch (variable) {
122 case NPPVpluginScriptableNPObject: { 186 case NPPVpluginScriptableNPObject: {
123 void **v = static_cast<void **>(value); 187 void **v = static_cast<void **>(value);
124 PluginObject *obj = static_cast<PluginObject *>(instance->pdata);
125 // Return value is expected to be retained 188 // Return value is expected to be retained
126 GLUE_PROFILE_START(instance, "retainobject"); 189 GLUE_PROFILE_START(instance, "retainobject");
127 NPN_RetainObject(obj); 190 NPN_RetainObject(obj);
128 GLUE_PROFILE_STOP(instance, "retainobject"); 191 GLUE_PROFILE_STOP(instance, "retainobject");
129 *v = obj; 192 *v = obj;
130 break; 193 break;
131 } 194 }
132 default: { 195 default: {
133 NPError ret = PlatformNPPGetValue(instance, variable, value); 196 NPError ret = PlatformNPPGetValue(obj, variable, value);
134 if (ret == NPERR_INVALID_PARAM) 197 if (ret == NPERR_INVALID_PARAM)
135 ret = o3d::NP_GetValue(instance, variable, value); 198 ret = o3d::NP_GetValue(variable, value);
136 return ret; 199 return ret;
137 } 200 }
138 } 201 }
139 return NPERR_NO_ERROR; 202 return NPERR_NO_ERROR;
140 } 203 }
141 204
205 NPError NPP_New(NPMIMEType pluginType,
206 NPP instance,
207 uint16 mode,
208 int16 argc,
209 char *argn[],
210 char *argv[],
211 NPSavedData *saved) {
212 HANDLE_CRASHES;
213
214 #if !defined(O3D_INTERNAL_PLUGIN) && (defined(OS_WIN) || defined(OS_MACOSX))
215 // TODO(tschmelcher): Support this on Linux?
216 if (!g_logging_initialized) {
217 // Get user config metrics. These won't be stored though unless the user
218 // opts-in for usagestats logging
219 GetUserAgentMetrics(instance);
220 GetUserConfigMetrics();
221 // Create usage stats logs object
222 g_logger = o3d::PluginLogging::InitializeUsageStatsLogging();
223 #ifdef OS_WIN
224 if (g_logger) {
225 // Setup blue-screen detection
226 g_bluescreen_detector = new o3d::BluescreenDetector();
227 g_bluescreen_detector->Start();
228 }
229 #endif
230 g_logging_initialized = true;
231 }
232 #endif
233
234 if (!IsDomainAuthorized(instance)) {
235 return NPERR_INVALID_URL;
236 }
237
238 PluginObject *obj = glue::_o3d::PluginObject::Create(instance);
239 instance->pdata = obj;
240 glue::_o3d::InitializeGlue(instance);
241 obj->Init(argc, argn, argv);
242 return PlatformNPPNew(instance, obj);
243 }
244
245 NPError NPP_Destroy(NPP instance, NPSavedData **save) {
246 HANDLE_CRASHES;
247 PluginObject *obj = static_cast<PluginObject *>(instance->pdata);
248 if (!obj) {
249 return NPERR_NO_ERROR;
250 }
251
252 NPError err = PlatformNPPDestroy(instance, obj);
253
254 NPN_ReleaseObject(obj);
255 instance->pdata = NULL;
256
257 return err;
258 }
259
142 NPError NPP_SetValue(NPP instance, NPNVariable variable, void *value) { 260 NPError NPP_SetValue(NPP instance, NPNVariable variable, void *value) {
143 HANDLE_CRASHES; 261 HANDLE_CRASHES;
144 return NPERR_GENERIC_ERROR; 262 return NPERR_GENERIC_ERROR;
145 } 263 }
264
265 NPError NPP_SetWindow(NPP instance, NPWindow* window) {
266 HANDLE_CRASHES;
267 PluginObject *obj = static_cast<PluginObject *>(instance->pdata);
268 if (!obj) {
269 return NPERR_NO_ERROR;
270 }
271
272 return PlatformNPPSetWindow(instance, obj, window);
273 }
274
275 // Called when the browser has finished attempting to stream data to
276 // a file as requested. If fname == NULL the attempt was not successful.
277 void NPP_StreamAsFile(NPP instance, NPStream *stream, const char *fname) {
278 HANDLE_CRASHES;
279 PluginObject *obj = static_cast<PluginObject *>(instance->pdata);
280 if (!obj) {
281 return;
282 }
283
284 StreamManager *stream_manager = obj->stream_manager();
285 PlatformNPPStreamAsFile(stream_manager, stream, fname);
286 }
287
146 } // namespace o3d 288 } // namespace o3d
147 289
148 #if defined(O3D_INTERNAL_PLUGIN) 290 #if defined(O3D_INTERNAL_PLUGIN)
149 namespace o3d { 291 namespace o3d {
150 #else 292 #else
151 extern "C" { 293 extern "C" {
152 #endif 294 #endif
153 295
296 NPError EXPORT_SYMBOL OSCALL NP_Initialize(NPNetscapeFuncs *browserFuncs
297 #ifdef OS_LINUX
298 ,
299 NPPluginFuncs *pluginFuncs
300 #endif
301 ) {
302 HANDLE_CRASHES;
303 NPError err = InitializeNPNApi(browserFuncs);
304 if (err != NPERR_NO_ERROR) {
305 return err;
306 }
307
308 #ifdef OS_LINUX
309 NP_GetEntryPoints(pluginFuncs);
310 #endif // OS_LINUX
311
312 #if !defined(O3D_INTERNAL_PLUGIN)
313 if (!o3d::SetupOutOfMemoryHandler())
314 return NPERR_MODULE_LOAD_FAILED_ERROR;
315 #endif // O3D_INTERNAL_PLUGIN
316
317 err = o3d::PlatformPreNPInitialize();
318 if (err != NPERR_NO_ERROR) {
319 return err;
320 }
321
322 #if !defined(O3D_INTERNAL_PLUGIN)
323 // Turn on the logging.
324 CommandLine::Init(0, NULL);
325
326 FilePath log;
327 file_util::GetTempDir(&log);
328 log.Append(O3D_DEBUG_LOG_FILENAME);
329
330 InitLogging(log.value().c_str(),
331 logging::LOG_TO_BOTH_FILE_AND_SYSTEM_DEBUG_LOG,
332 logging::DONT_LOCK_LOG_FILE,
333 logging::APPEND_TO_OLD_LOG_FILE);
334 #endif // O3D_INTERNAL_PLUGIN
335
336 DLOG(INFO) << "NP_Initialize";
337
338 return o3d::PlatformPostNPInitialize();
339 }
340
341 NPError EXPORT_SYMBOL OSCALL NP_Shutdown(void) {
342 HANDLE_CRASHES;
343 DLOG(INFO) << "NP_Shutdown";
344
345 NPError err = o3d::PlatformPreNPShutdown();
346 if (err != NPERR_NO_ERROR) {
347 return err;
348 }
349
350 #if !defined(O3D_INTERNAL_PLUGIN)
351 #if defined(OS_WIN) || defined(OS_MACOSX)
352 if (g_logger) {
353 // Do a last sweep to aggregate metrics before we shut down
354 g_logger->ProcessMetrics(true, false, false);
355 delete g_logger;
356 g_logger = NULL;
357 g_logging_initialized = false;
358 stats_report::g_global_metrics.Uninitialize();
359 }
360 #endif // OS_WIN || OS_MACOSX
361
362 CommandLine::Reset();
363
364 #ifdef OS_WIN
365 // Strictly speaking, on windows, it's not really necessary to call
366 // Stop(), but we do so for completeness
367 if (g_bluescreen_detector) {
368 g_bluescreen_detector->Stop();
369 delete g_bluescreen_detector;
370 g_bluescreen_detector = NULL;
371 }
372 #endif // OS_WIN
373 #endif // O3D_INTERNAL_PLUGIN
374
375 return o3d::PlatformPostNPShutdown();
376 }
377
154 NPError EXPORT_SYMBOL OSCALL NP_GetEntryPoints(NPPluginFuncs *pluginFuncs) { 378 NPError EXPORT_SYMBOL OSCALL NP_GetEntryPoints(NPPluginFuncs *pluginFuncs) {
155 HANDLE_CRASHES; 379 HANDLE_CRASHES;
156 pluginFuncs->version = 11; 380 pluginFuncs->version = 11;
157 pluginFuncs->size = sizeof(*pluginFuncs); 381 pluginFuncs->size = sizeof(*pluginFuncs);
158 pluginFuncs->newp = o3d::NPP_New; 382 pluginFuncs->newp = o3d::NPP_New;
159 pluginFuncs->destroy = o3d::NPP_Destroy; 383 pluginFuncs->destroy = o3d::NPP_Destroy;
160 pluginFuncs->setwindow = o3d::NPP_SetWindow; 384 pluginFuncs->setwindow = o3d::NPP_SetWindow;
161 pluginFuncs->newstream = o3d::NPP_NewStream; 385 pluginFuncs->newstream = o3d::NPP_NewStream;
162 pluginFuncs->destroystream = o3d::NPP_DestroyStream; 386 pluginFuncs->destroystream = o3d::NPP_DestroyStream;
163 pluginFuncs->asfile = o3d::NPP_StreamAsFile; 387 pluginFuncs->asfile = o3d::NPP_StreamAsFile;
(...skipping 11 matching lines...) Expand all
175 char* NP_GetMIMEDescription(void) { 399 char* NP_GetMIMEDescription(void) {
176 return const_cast<char*>(O3D_PLUGIN_NPAPI_MIMETYPE "::O3D MIME"); 400 return const_cast<char*>(O3D_PLUGIN_NPAPI_MIMETYPE "::O3D MIME");
177 } 401 }
178 402
179 } // namespace o3d / extern "C" 403 } // namespace o3d / extern "C"
180 404
181 #if !defined(O3D_INTERNAL_PLUGIN) 405 #if !defined(O3D_INTERNAL_PLUGIN)
182 extern "C" { 406 extern "C" {
183 NPError EXPORT_SYMBOL NP_GetValue(void *instance, NPPVariable variable, 407 NPError EXPORT_SYMBOL NP_GetValue(void *instance, NPPVariable variable,
184 void *value) { 408 void *value) {
185 return o3d::NP_GetValue(instance, variable, value); 409 return o3d::NP_GetValue(variable, value);
186 } 410 }
187 } 411 }
188 #endif 412 #endif
OLDNEW
« no previous file with comments | « plugin/cross/main.h ('k') | plugin/cross/plugin_logging.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698