1 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 /* This Source Code Form is subject to the terms of the Mozilla Public
3 * License, v. 2.0. If a copy of the MPL was not distributed with this
4 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
5
6 #include "base/basictypes.h"
7
8 /* This must occur *after* layers/PLayerTransaction.h to avoid typedefs
9 * conflicts. */
10 #include "mozilla/ArrayUtils.h"
11
12 #include "pratom.h"
13 #include "prenv.h"
14
15 #include "jsfriendapi.h"
16
17 #include "nsPluginHost.h"
18 #include "nsNPAPIPlugin.h"
19 #include "nsNPAPIPluginInstance.h"
20 #include "nsNPAPIPluginStreamListener.h"
21 #include "nsPluginStreamListenerPeer.h"
22 #include "nsThreadUtils.h"
23 #include "mozilla/CycleCollectedJSContext.h" // for nsAutoMicroTask
24 #include "mozilla/Preferences.h"
25 #include "nsPluginInstanceOwner.h"
26
27 #include "nsPluginsDir.h"
28 #include "nsPluginLogging.h"
29
30 #include "nsPIDOMWindow.h"
31 #include "nsGlobalWindow.h"
32 #include "mozilla/dom/Document.h"
33 #include "nsIContent.h"
34 #include "nsIIDNService.h"
35 #include "nsIScriptGlobalObject.h"
36 #include "nsIScriptContext.h"
37 #include "nsDOMJSUtils.h"
38 #include "nsIPrincipal.h"
39 #include "nsWildCard.h"
40 #include "nsContentUtils.h"
41 #include "mozilla/dom/Element.h"
42 #include "mozilla/dom/ScriptSettings.h"
43 #include "mozilla/dom/ToJSValue.h"
44 #include "nsIXPConnect.h"
45
46 #include <prinrval.h>
47
48 #ifdef MOZ_WIDGET_COCOA
49 # include <Carbon/Carbon.h>
50 # include <ApplicationServices/ApplicationServices.h>
51 # include <OpenGL/OpenGL.h>
52 # include "nsCocoaFeatures.h"
53 # include "PluginUtilsOSX.h"
54 #endif
55
56 // needed for nppdf plugin
57 #if (MOZ_WIDGET_GTK)
58 # include <gdk/gdk.h>
59 # include <gdk/gdkx.h>
60 #endif
61
62 #include "nsJSUtils.h"
63 #include "nsJSNPRuntime.h"
64
65 #include "nsNetUtil.h"
66 #include "nsNetCID.h"
67
68 #include "mozilla/Mutex.h"
69 #include "mozilla/PluginLibrary.h"
70 using mozilla::PluginLibrary;
71
72 #include "mozilla/plugins/PluginModuleParent.h"
73 using mozilla::plugins::PluginModuleChromeParent;
74 using mozilla::plugins::PluginModuleContentParent;
75
76 #ifdef MOZ_X11
77 # include "mozilla/X11Util.h"
78 #endif
79
80 #ifdef XP_WIN
81 # include <windows.h>
82 # include "mozilla/WindowsVersion.h"
83 # ifdef ACCESSIBILITY
84 # include "mozilla/a11y/Compatibility.h"
85 # endif
86 #endif
87
88 #include "AudioChannelService.h"
89
90 using namespace mozilla;
91 using namespace mozilla::plugins::parent;
92 using mozilla::dom::Document;
93
94 // We should make this const...
95 static NPNetscapeFuncs sBrowserFuncs = {
96 sizeof(sBrowserFuncs),
97 (NP_VERSION_MAJOR << 8) + NP_VERSION_MINOR,
98 _geturl,
99 _posturl,
100 _requestread,
101 nullptr, // _newstream, unimplemented
102 nullptr, // _write, unimplemented
103 nullptr, // _destroystream, unimplemented
104 _status,
105 _useragent,
106 _memalloc,
107 _memfree,
108 _memflush,
109 _reloadplugins,
110 _getJavaEnv,
111 _getJavaPeer,
112 _geturlnotify,
113 _posturlnotify,
114 _getvalue,
115 _setvalue,
116 _invalidaterect,
117 _invalidateregion,
118 _forceredraw,
119 _getstringidentifier,
120 _getstringidentifiers,
121 _getintidentifier,
122 _identifierisstring,
123 _utf8fromidentifier,
124 _intfromidentifier,
125 _createobject,
126 _retainobject,
127 _releaseobject,
128 _invoke,
129 _invokeDefault,
130 _evaluate,
131 _getproperty,
132 _setproperty,
133 _removeproperty,
134 _hasproperty,
135 _hasmethod,
136 _releasevariantvalue,
137 _setexception,
138 _pushpopupsenabledstate,
139 _poppopupsenabledstate,
140 _enumerate,
141 nullptr, // pluginthreadasynccall, not used
142 _construct,
143 _getvalueforurl,
144 _setvalueforurl,
145 nullptr, // NPN GetAuthenticationInfo, not supported
146 _scheduletimer,
147 _unscheduletimer,
148 _popupcontextmenu,
149 _convertpoint,
150 nullptr, // handleevent, unimplemented
151 nullptr, // unfocusinstance, unimplemented
152 _urlredirectresponse,
153 _initasyncsurface,
154 _finalizeasyncsurface,
155 _setcurrentasyncsurface};
156
157 // POST/GET stream type
158 enum eNPPStreamTypeInternal {
159 eNPPStreamTypeInternal_Get,
160 eNPPStreamTypeInternal_Post
161 };
162
NS_NotifyBeginPluginCall(NSPluginCallReentry aReentryState)163 void NS_NotifyBeginPluginCall(NSPluginCallReentry aReentryState) {
164 nsNPAPIPluginInstance::BeginPluginCall(aReentryState);
165 }
166
NS_NotifyPluginCall(NSPluginCallReentry aReentryState)167 void NS_NotifyPluginCall(NSPluginCallReentry aReentryState) {
168 nsNPAPIPluginInstance::EndPluginCall(aReentryState);
169 }
170
nsNPAPIPlugin()171 nsNPAPIPlugin::nsNPAPIPlugin() {
172 memset((void*)&mPluginFuncs, 0, sizeof(mPluginFuncs));
173 mPluginFuncs.size = sizeof(mPluginFuncs);
174 mPluginFuncs.version = (NP_VERSION_MAJOR << 8) | NP_VERSION_MINOR;
175
176 mLibrary = nullptr;
177 }
178
~nsNPAPIPlugin()179 nsNPAPIPlugin::~nsNPAPIPlugin() {
180 delete mLibrary;
181 mLibrary = nullptr;
182 }
183
PluginCrashed(const nsAString & aPluginDumpID,const nsACString & aAdditionalMinidumps)184 void nsNPAPIPlugin::PluginCrashed(const nsAString& aPluginDumpID,
185 const nsACString& aAdditionalMinidumps) {
186 RefPtr<nsPluginHost> host = nsPluginHost::GetInst();
187 host->PluginCrashed(this, aPluginDumpID, aAdditionalMinidumps);
188 }
189
GetNewPluginLibrary(nsPluginTag * aPluginTag)190 inline PluginLibrary* GetNewPluginLibrary(nsPluginTag* aPluginTag) {
191 AUTO_PROFILER_LABEL("GetNewPluginLibrary", OTHER);
192
193 if (!aPluginTag) {
194 return nullptr;
195 }
196
197 if (XRE_IsContentProcess()) {
198 return PluginModuleContentParent::LoadModule(aPluginTag->mId, aPluginTag);
199 }
200
201 return PluginModuleChromeParent::LoadModule(aPluginTag->mFullPath.get(),
202 aPluginTag->mId, aPluginTag);
203 }
204
205 // Creates an nsNPAPIPlugin object. One nsNPAPIPlugin object exists per plugin
206 // (not instance).
CreatePlugin(nsPluginTag * aPluginTag,nsNPAPIPlugin ** aResult)207 nsresult nsNPAPIPlugin::CreatePlugin(nsPluginTag* aPluginTag,
208 nsNPAPIPlugin** aResult) {
209 AUTO_PROFILER_LABEL("nsNPAPIPlugin::CreatePlugin", OTHER);
210 *aResult = nullptr;
211
212 if (!aPluginTag) {
213 return NS_ERROR_FAILURE;
214 }
215
216 RefPtr<nsNPAPIPlugin> plugin = new nsNPAPIPlugin();
217
218 PluginLibrary* pluginLib = GetNewPluginLibrary(aPluginTag);
219 if (!pluginLib) {
220 return NS_ERROR_FAILURE;
221 }
222
223 #if defined(XP_MACOSX)
224 if (!pluginLib->HasRequiredFunctions()) {
225 NS_WARNING(
226 "Not all necessary functions exposed by plugin, it will not load.");
227 delete pluginLib;
228 return NS_ERROR_FAILURE;
229 }
230 #endif
231
232 plugin->mLibrary = pluginLib;
233 pluginLib->SetPlugin(plugin);
234
235 // Exchange NPAPI entry points.
236 #if defined(XP_WIN)
237 // NP_GetEntryPoints must be called before NP_Initialize on Windows.
238 NPError pluginCallError;
239 nsresult rv =
240 pluginLib->NP_GetEntryPoints(&plugin->mPluginFuncs, &pluginCallError);
241 if (rv != NS_OK || pluginCallError != NPERR_NO_ERROR) {
242 return NS_ERROR_FAILURE;
243 }
244
245 // NP_Initialize must be called after NP_GetEntryPoints on Windows.
246 rv = pluginLib->NP_Initialize(&sBrowserFuncs, &pluginCallError);
247 if (rv != NS_OK || pluginCallError != NPERR_NO_ERROR) {
248 return NS_ERROR_FAILURE;
249 }
250 #elif defined(XP_MACOSX)
251 // NP_Initialize must be called before NP_GetEntryPoints on Mac OS X.
252 // We need to match WebKit's behavior.
253 NPError pluginCallError;
254 nsresult rv = pluginLib->NP_Initialize(&sBrowserFuncs, &pluginCallError);
255 if (rv != NS_OK || pluginCallError != NPERR_NO_ERROR) {
256 return NS_ERROR_FAILURE;
257 }
258
259 rv = pluginLib->NP_GetEntryPoints(&plugin->mPluginFuncs, &pluginCallError);
260 if (rv != NS_OK || pluginCallError != NPERR_NO_ERROR) {
261 return NS_ERROR_FAILURE;
262 }
263 #else
264 NPError pluginCallError;
265 nsresult rv = pluginLib->NP_Initialize(&sBrowserFuncs, &plugin->mPluginFuncs,
266 &pluginCallError);
267 if (rv != NS_OK || pluginCallError != NPERR_NO_ERROR) {
268 return NS_ERROR_FAILURE;
269 }
270 #endif
271
272 plugin.forget(aResult);
273 return NS_OK;
274 }
275
GetLibrary()276 PluginLibrary* nsNPAPIPlugin::GetLibrary() { return mLibrary; }
277
PluginFuncs()278 NPPluginFuncs* nsNPAPIPlugin::PluginFuncs() { return &mPluginFuncs; }
279
Shutdown()280 nsresult nsNPAPIPlugin::Shutdown() {
281 NPP_PLUGIN_LOG(PLUGIN_LOG_BASIC,
282 ("NPP Shutdown to be called: this=%p\n", this));
283
284 NPError shutdownError;
285 mLibrary->NP_Shutdown(&shutdownError);
286
287 return NS_OK;
288 }
289
RetainStream(NPStream * pstream,nsISupports ** aRetainedPeer)290 nsresult nsNPAPIPlugin::RetainStream(NPStream* pstream,
291 nsISupports** aRetainedPeer) {
292 if (!aRetainedPeer) return NS_ERROR_NULL_POINTER;
293
294 *aRetainedPeer = nullptr;
295
296 if (!pstream || !pstream->ndata) return NS_ERROR_NULL_POINTER;
297
298 nsNPAPIStreamWrapper* streamWrapper =
299 static_cast<nsNPAPIStreamWrapper*>(pstream->ndata);
300 nsNPAPIPluginStreamListener* listener = streamWrapper->GetStreamListener();
301 if (!listener) {
302 return NS_ERROR_NULL_POINTER;
303 }
304
305 nsIStreamListener* streamListener = listener->GetStreamListenerPeer();
306 if (!streamListener) {
307 return NS_ERROR_NULL_POINTER;
308 }
309
310 *aRetainedPeer = streamListener;
311 NS_ADDREF(*aRetainedPeer);
312 return NS_OK;
313 }
314
315 // Create a new NPP GET or POST (given in the type argument) url
316 // stream that may have a notify callback
MakeNewNPAPIStreamInternal(NPP npp,const char * relativeURL,const char * target,eNPPStreamTypeInternal type,bool bDoNotify=false,void * notifyData=nullptr,uint32_t len=0,const char * buf=nullptr)317 NPError MakeNewNPAPIStreamInternal(NPP npp, const char* relativeURL,
318 const char* target,
319 eNPPStreamTypeInternal type,
320 bool bDoNotify = false,
321 void* notifyData = nullptr, uint32_t len = 0,
322 const char* buf = nullptr) {
323 if (!npp) return NPERR_INVALID_INSTANCE_ERROR;
324
325 PluginDestructionGuard guard(npp);
326
327 nsNPAPIPluginInstance* inst = (nsNPAPIPluginInstance*)npp->ndata;
328 if (!inst || !inst->IsRunning()) return NPERR_INVALID_INSTANCE_ERROR;
329
330 nsCOMPtr<nsIPluginHost> pluginHostCOM =
331 do_GetService(MOZ_PLUGIN_HOST_CONTRACTID);
332 nsPluginHost* pluginHost = static_cast<nsPluginHost*>(pluginHostCOM.get());
333 if (!pluginHost) {
334 return NPERR_GENERIC_ERROR;
335 }
336
337 RefPtr<nsNPAPIPluginStreamListener> listener;
338 // Set aCallNotify here to false. If pluginHost->GetURL or PostURL fail,
339 // the listener's destructor will do the notification while we are about to
340 // return a failure code.
341 // Call SetCallNotify(true) below after we are sure we cannot return a failure
342 // code.
343 if (!target) {
344 inst->NewStreamListener(relativeURL, notifyData, getter_AddRefs(listener));
345 if (listener) {
346 listener->SetCallNotify(false);
347 }
348 }
349
350 switch (type) {
351 case eNPPStreamTypeInternal_Get: {
352 if (NS_FAILED(pluginHost->GetURL(inst, relativeURL, target, listener,
353 nullptr, nullptr, false)))
354 return NPERR_GENERIC_ERROR;
355 break;
356 }
357 case eNPPStreamTypeInternal_Post: {
358 if (NS_FAILED(pluginHost->PostURL(inst, relativeURL, len, buf, target,
359 listener, nullptr, nullptr, false, 0,
360 nullptr)))
361 return NPERR_GENERIC_ERROR;
362 break;
363 }
364 default:
365 NS_ERROR("how'd I get here");
366 }
367
368 if (listener) {
369 // SetCallNotify(bDoNotify) here, see comment above.
370 listener->SetCallNotify(bDoNotify);
371 }
372
373 return NPERR_NO_ERROR;
374 }
375
376 #if defined(MOZ_MEMORY) && defined(XP_WIN)
377 extern "C" size_t malloc_usable_size(const void* ptr);
378 #endif
379
380 namespace {
381
382 static char* gNPPException;
383
GetDocumentFromNPP(NPP npp)384 static Document* GetDocumentFromNPP(NPP npp) {
385 NS_ENSURE_TRUE(npp, nullptr);
386
387 nsNPAPIPluginInstance* inst = (nsNPAPIPluginInstance*)npp->ndata;
388 NS_ENSURE_TRUE(inst, nullptr);
389
390 PluginDestructionGuard guard(inst);
391
392 RefPtr<nsPluginInstanceOwner> owner = inst->GetOwner();
393 NS_ENSURE_TRUE(owner, nullptr);
394
395 nsCOMPtr<Document> doc;
396 owner->GetDocument(getter_AddRefs(doc));
397
398 return doc;
399 }
400
doGetIdentifier(JSContext * cx,const NPUTF8 * name)401 static NPIdentifier doGetIdentifier(JSContext* cx, const NPUTF8* name) {
402 NS_ConvertUTF8toUTF16 utf16name(name);
403
404 JSString* str =
405 ::JS_AtomizeAndPinUCStringN(cx, utf16name.get(), utf16name.Length());
406
407 if (!str) return nullptr;
408
409 return StringToNPIdentifier(cx, str);
410 }
411
412 #if defined(MOZ_MEMORY) && defined(XP_WIN)
InHeap(HANDLE hHeap,LPVOID lpMem)413 BOOL InHeap(HANDLE hHeap, LPVOID lpMem) {
414 BOOL success = FALSE;
415 PROCESS_HEAP_ENTRY he;
416 he.lpData = nullptr;
417 while (HeapWalk(hHeap, &he) != 0) {
418 if (he.lpData == lpMem) {
419 success = TRUE;
420 break;
421 }
422 }
423 HeapUnlock(hHeap);
424 return success;
425 }
426 #endif
427
428 } /* anonymous namespace */
429
NPPExceptionAutoHolder()430 NPPExceptionAutoHolder::NPPExceptionAutoHolder()
431 : mOldException(gNPPException) {
432 gNPPException = nullptr;
433 }
434
~NPPExceptionAutoHolder()435 NPPExceptionAutoHolder::~NPPExceptionAutoHolder() {
436 NS_ASSERTION(!gNPPException, "NPP exception not properly cleared!");
437
438 gNPPException = mOldException;
439 }
440
441 NPP NPPStack::sCurrentNPP = nullptr;
442
PeekException()443 const char* PeekException() { return gNPPException; }
444
PopException()445 void PopException() {
446 NS_ASSERTION(gNPPException, "Uh, no NPP exception to pop!");
447
448 if (gNPPException) {
449 free(gNPPException);
450
451 gNPPException = nullptr;
452 }
453 }
454
455 //
456 // Static callbacks that get routed back through the new C++ API
457 //
458
459 namespace mozilla::plugins::parent {
460
_geturl(NPP npp,const char * relativeURL,const char * target)461 NPError _geturl(NPP npp, const char* relativeURL, const char* target) {
462 if (!NS_IsMainThread()) {
463 NPN_PLUGIN_LOG(PLUGIN_LOG_ALWAYS,
464 ("NPN_geturl called from the wrong thread\n"));
465 return NPERR_INVALID_PARAM;
466 }
467
468 NPN_PLUGIN_LOG(PLUGIN_LOG_NORMAL, ("NPN_GetURL: npp=%p, target=%s, url=%s\n",
469 (void*)npp, target, relativeURL));
470
471 PluginDestructionGuard guard(npp);
472
473 return MakeNewNPAPIStreamInternal(npp, relativeURL, target,
474 eNPPStreamTypeInternal_Get);
475 }
476
_geturlnotify(NPP npp,const char * relativeURL,const char * target,void * notifyData)477 NPError _geturlnotify(NPP npp, const char* relativeURL, const char* target,
478 void* notifyData) {
479 if (!NS_IsMainThread()) {
480 NPN_PLUGIN_LOG(PLUGIN_LOG_ALWAYS,
481 ("NPN_geturlnotify called from the wrong thread\n"));
482 return NPERR_INVALID_PARAM;
483 }
484
485 NPN_PLUGIN_LOG(PLUGIN_LOG_NORMAL,
486 ("NPN_GetURLNotify: npp=%p, target=%s, notify=%p, url=%s\n",
487 (void*)npp, target, notifyData, relativeURL));
488
489 PluginDestructionGuard guard(npp);
490
491 return MakeNewNPAPIStreamInternal(
492 npp, relativeURL, target, eNPPStreamTypeInternal_Get, true, notifyData);
493 }
494
_posturlnotify(NPP npp,const char * relativeURL,const char * target,uint32_t len,const char * buf,NPBool file,void * notifyData)495 NPError _posturlnotify(NPP npp, const char* relativeURL, const char* target,
496 uint32_t len, const char* buf, NPBool file,
497 void* notifyData) {
498 if (!NS_IsMainThread()) {
499 NPN_PLUGIN_LOG(PLUGIN_LOG_ALWAYS,
500 ("NPN_posturlnotify called from the wrong thread\n"));
501 return NPERR_INVALID_PARAM;
502 }
503 if (!buf) return NPERR_INVALID_PARAM;
504
505 NPN_PLUGIN_LOG(PLUGIN_LOG_NORMAL,
506 ("NPN_PostURLNotify: npp=%p, target=%s, len=%d, file=%d, "
507 "notify=%p, url=%s, buf=%s\n",
508 (void*)npp, target, len, file, notifyData, relativeURL, buf));
509
510 PluginDestructionGuard guard(npp);
511
512 return MakeNewNPAPIStreamInternal(npp, relativeURL, target,
513 eNPPStreamTypeInternal_Post, true,
514 notifyData, len, buf);
515 }
516
_posturl(NPP npp,const char * relativeURL,const char * target,uint32_t len,const char * buf,NPBool file)517 NPError _posturl(NPP npp, const char* relativeURL, const char* target,
518 uint32_t len, const char* buf, NPBool file) {
519 if (!NS_IsMainThread()) {
520 NPN_PLUGIN_LOG(PLUGIN_LOG_ALWAYS,
521 ("NPN_posturl called from the wrong thread\n"));
522 return NPERR_INVALID_PARAM;
523 }
524 NPN_PLUGIN_LOG(PLUGIN_LOG_NORMAL,
525 ("NPN_PostURL: npp=%p, target=%s, file=%d, len=%d, url=%s, "
526 "buf=%s\n",
527 (void*)npp, target, file, len, relativeURL, buf));
528
529 PluginDestructionGuard guard(npp);
530
531 return MakeNewNPAPIStreamInternal(npp, relativeURL, target,
532 eNPPStreamTypeInternal_Post, false, nullptr,
533 len, buf);
534 }
535
_status(NPP npp,const char * message)536 void _status(NPP npp, const char* message) {
537 // NPN_Status is no longer supported.
538 }
539
_memfree(void * ptr)540 void _memfree(void* ptr) {
541 if (!NS_IsMainThread()) {
542 NPN_PLUGIN_LOG(PLUGIN_LOG_ALWAYS,
543 ("NPN_memfree called from the wrong thread\n"));
544 }
545 NPN_PLUGIN_LOG(PLUGIN_LOG_NOISY, ("NPN_MemFree: ptr=%p\n", ptr));
546
547 if (ptr) free(ptr);
548 }
549
_memflush(uint32_t size)550 uint32_t _memflush(uint32_t size) {
551 if (!NS_IsMainThread()) {
552 NPN_PLUGIN_LOG(PLUGIN_LOG_ALWAYS,
553 ("NPN_memflush called from the wrong thread\n"));
554 }
555 NPN_PLUGIN_LOG(PLUGIN_LOG_NOISY, ("NPN_MemFlush: size=%d\n", size));
556
557 nsMemory::HeapMinimize(true);
558 return 0;
559 }
560
_reloadplugins(NPBool reloadPages)561 void _reloadplugins(NPBool reloadPages) {
562 if (!NS_IsMainThread()) {
563 NPN_PLUGIN_LOG(PLUGIN_LOG_ALWAYS,
564 ("NPN_reloadplugins called from the wrong thread\n"));
565 return;
566 }
567 NPN_PLUGIN_LOG(PLUGIN_LOG_NORMAL,
568 ("NPN_ReloadPlugins: reloadPages=%d\n", reloadPages));
569
570 nsCOMPtr<nsIPluginHost> pluginHost(do_GetService(MOZ_PLUGIN_HOST_CONTRACTID));
571 if (!pluginHost) return;
572
573 pluginHost->ReloadPlugins();
574 }
575
_invalidaterect(NPP npp,NPRect * invalidRect)576 void _invalidaterect(NPP npp, NPRect* invalidRect) {
577 if (!NS_IsMainThread()) {
578 NPN_PLUGIN_LOG(PLUGIN_LOG_ALWAYS,
579 ("NPN_invalidaterect called from the wrong thread\n"));
580 return;
581 }
582 NPN_PLUGIN_LOG(PLUGIN_LOG_NORMAL,
583 ("NPN_InvalidateRect: npp=%p, top=%d, left=%d, bottom=%d, "
584 "right=%d\n",
585 (void*)npp, invalidRect->top, invalidRect->left,
586 invalidRect->bottom, invalidRect->right));
587
588 if (!npp || !npp->ndata) {
589 NS_WARNING("_invalidaterect: npp or npp->ndata == 0");
590 return;
591 }
592
593 nsNPAPIPluginInstance* inst = (nsNPAPIPluginInstance*)npp->ndata;
594
595 PluginDestructionGuard guard(inst);
596
597 inst->InvalidateRect((NPRect*)invalidRect);
598 }
599
_invalidateregion(NPP npp,NPRegion invalidRegion)600 void _invalidateregion(NPP npp, NPRegion invalidRegion) {
601 if (!NS_IsMainThread()) {
602 NPN_PLUGIN_LOG(PLUGIN_LOG_ALWAYS,
603 ("NPN_invalidateregion called from the wrong thread\n"));
604 return;
605 }
606 NPN_PLUGIN_LOG(PLUGIN_LOG_NORMAL,
607 ("NPN_InvalidateRegion: npp=%p, region=%p\n", (void*)npp,
608 (void*)invalidRegion));
609
610 if (!npp || !npp->ndata) {
611 NS_WARNING("_invalidateregion: npp or npp->ndata == 0");
612 return;
613 }
614
615 nsNPAPIPluginInstance* inst = (nsNPAPIPluginInstance*)npp->ndata;
616
617 PluginDestructionGuard guard(inst);
618
619 inst->InvalidateRegion((NPRegion)invalidRegion);
620 }
621
_forceredraw(NPP npp)622 void _forceredraw(NPP npp) {}
623
_getwindowobject(NPP npp)624 NPObject* _getwindowobject(NPP npp) {
625 if (!NS_IsMainThread()) {
626 NPN_PLUGIN_LOG(PLUGIN_LOG_ALWAYS,
627 ("NPN_getwindowobject called from the wrong thread\n"));
628 return nullptr;
629 }
630
631 // The window want to return here is the outer window, *not* the inner (since
632 // we don't know what the plugin will do with it).
633 Document* doc = GetDocumentFromNPP(npp);
634 NS_ENSURE_TRUE(doc, nullptr);
635 nsCOMPtr<nsPIDOMWindowOuter> outer = doc->GetWindow();
636 NS_ENSURE_TRUE(outer, nullptr);
637
638 JS::Rooted<JSObject*> windowProxy(
639 dom::RootingCx(), nsGlobalWindowOuter::Cast(outer)->GetGlobalJSObject());
640 JS::Rooted<JSObject*> global(dom::RootingCx(),
641 JS::GetNonCCWObjectGlobal(windowProxy));
642 return nsJSObjWrapper::GetNewOrUsed(npp, windowProxy, global);
643 }
644
_getpluginelement(NPP npp)645 NPObject* _getpluginelement(NPP npp) {
646 if (!NS_IsMainThread()) {
647 NPN_PLUGIN_LOG(PLUGIN_LOG_ALWAYS,
648 ("NPN_getpluginelement called from the wrong thread\n"));
649 return nullptr;
650 }
651
652 nsNPAPIPluginInstance* inst = static_cast<nsNPAPIPluginInstance*>(npp->ndata);
653 if (!inst) return nullptr;
654
655 RefPtr<dom::Element> element;
656 inst->GetDOMElement(getter_AddRefs(element));
657
658 if (!element) return nullptr;
659
660 Document* doc = GetDocumentFromNPP(npp);
661 if (NS_WARN_IF(!doc)) {
662 return nullptr;
663 }
664
665 dom::AutoJSAPI jsapi;
666 if (NS_WARN_IF(!jsapi.Init(doc->GetInnerWindow()))) {
667 return nullptr;
668 }
669 JSContext* cx = jsapi.cx();
670
671 nsCOMPtr<nsIXPConnect> xpc(nsIXPConnect::XPConnect());
672 NS_ENSURE_TRUE(xpc, nullptr);
673
674 JS::RootedValue val(cx);
675 if (!ToJSValue(cx, element, &val)) {
676 return nullptr;
677 }
678
679 if (NS_WARN_IF(!val.isObject())) {
680 return nullptr;
681 }
682
683 JS::RootedObject obj(cx, &val.toObject());
684 JS::RootedObject global(cx, JS::CurrentGlobalOrNull(cx));
685 return nsJSObjWrapper::GetNewOrUsed(npp, obj, global);
686 }
687
_getstringidentifier(const NPUTF8 * name)688 NPIdentifier _getstringidentifier(const NPUTF8* name) {
689 if (!name) {
690 NPN_PLUGIN_LOG(PLUGIN_LOG_ALWAYS,
691 ("NPN_getstringidentifier: passed null name"));
692 return nullptr;
693 }
694 if (!NS_IsMainThread()) {
695 NPN_PLUGIN_LOG(PLUGIN_LOG_ALWAYS,
696 ("NPN_getstringidentifier called from the wrong thread\n"));
697 }
698
699 AutoSafeJSContext cx;
700 return doGetIdentifier(cx, name);
701 }
702
_getstringidentifiers(const NPUTF8 ** names,int32_t nameCount,NPIdentifier * identifiers)703 void _getstringidentifiers(const NPUTF8** names, int32_t nameCount,
704 NPIdentifier* identifiers) {
705 if (!NS_IsMainThread()) {
706 NPN_PLUGIN_LOG(PLUGIN_LOG_ALWAYS,
707 ("NPN_getstringidentifiers called from the wrong thread\n"));
708 }
709
710 AutoSafeJSContext cx;
711
712 for (int32_t i = 0; i < nameCount; ++i) {
713 if (names[i]) {
714 identifiers[i] = doGetIdentifier(cx, names[i]);
715 } else {
716 NPN_PLUGIN_LOG(PLUGIN_LOG_ALWAYS,
717 ("NPN_getstringidentifiers: passed null name"));
718 identifiers[i] = nullptr;
719 }
720 }
721 }
722
_getintidentifier(int32_t intid)723 NPIdentifier _getintidentifier(int32_t intid) {
724 if (!NS_IsMainThread()) {
725 NPN_PLUGIN_LOG(PLUGIN_LOG_ALWAYS,
726 ("NPN_getstringidentifier called from the wrong thread\n"));
727 }
728 return IntToNPIdentifier(intid);
729 }
730
_utf8fromidentifier(NPIdentifier id)731 NPUTF8* _utf8fromidentifier(NPIdentifier id) {
732 if (!NS_IsMainThread()) {
733 NPN_PLUGIN_LOG(PLUGIN_LOG_ALWAYS,
734 ("NPN_utf8fromidentifier called from the wrong thread\n"));
735 }
736 if (!id) return nullptr;
737
738 if (!NPIdentifierIsString(id)) {
739 return nullptr;
740 }
741
742 JSString* str = NPIdentifierToString(id);
743 nsAutoString autoStr;
744 AssignJSLinearString(autoStr, JS_ASSERT_STRING_IS_LINEAR(str));
745
746 return ToNewUTF8String(autoStr);
747 }
748
_intfromidentifier(NPIdentifier id)749 int32_t _intfromidentifier(NPIdentifier id) {
750 if (!NS_IsMainThread()) {
751 NPN_PLUGIN_LOG(PLUGIN_LOG_ALWAYS,
752 ("NPN_intfromidentifier called from the wrong thread\n"));
753 }
754
755 if (!NPIdentifierIsInt(id)) {
756 return INT32_MIN;
757 }
758
759 return NPIdentifierToInt(id);
760 }
761
_identifierisstring(NPIdentifier id)762 bool _identifierisstring(NPIdentifier id) {
763 if (!NS_IsMainThread()) {
764 NPN_PLUGIN_LOG(PLUGIN_LOG_ALWAYS,
765 ("NPN_identifierisstring called from the wrong thread\n"));
766 }
767
768 return NPIdentifierIsString(id);
769 }
770
_createobject(NPP npp,NPClass * aClass)771 NPObject* _createobject(NPP npp, NPClass* aClass) {
772 if (!NS_IsMainThread()) {
773 NPN_PLUGIN_LOG(PLUGIN_LOG_ALWAYS,
774 ("NPN_createobject called from the wrong thread\n"));
775 return nullptr;
776 }
777 if (!npp) {
778 NS_ERROR("Null npp passed to _createobject()!");
779
780 return nullptr;
781 }
782
783 PluginDestructionGuard guard(npp);
784
785 if (!aClass) {
786 NS_ERROR("Null class passed to _createobject()!");
787
788 return nullptr;
789 }
790
791 NPPAutoPusher nppPusher(npp);
792
793 NPObject* npobj;
794
795 if (aClass->allocate) {
796 npobj = aClass->allocate(npp, aClass);
797 } else {
798 npobj = (NPObject*)malloc(sizeof(NPObject));
799 }
800
801 if (npobj) {
802 npobj->_class = aClass;
803 npobj->referenceCount = 1;
804 NS_LOG_ADDREF(npobj, 1, "BrowserNPObject", sizeof(NPObject));
805 }
806
807 NPN_PLUGIN_LOG(PLUGIN_LOG_NOISY,
808 ("Created NPObject %p, NPClass %p\n", npobj, aClass));
809
810 return npobj;
811 }
812
_retainobject(NPObject * npobj)813 NPObject* _retainobject(NPObject* npobj) {
814 if (!NS_IsMainThread()) {
815 NPN_PLUGIN_LOG(PLUGIN_LOG_ALWAYS,
816 ("NPN_retainobject called from the wrong thread\n"));
817 }
818 if (npobj) {
819 #ifdef NS_BUILD_REFCNT_LOGGING
820 int32_t refCnt =
821 #endif
822 PR_ATOMIC_INCREMENT((int32_t*)&npobj->referenceCount);
823 NS_LOG_ADDREF(npobj, refCnt, "BrowserNPObject", sizeof(NPObject));
824 }
825
826 return npobj;
827 }
828
_releaseobject(NPObject * npobj)829 void _releaseobject(NPObject* npobj) {
830 // If nothing is passed, just return, even if we're on the wrong thread.
831 if (!npobj) {
832 return;
833 }
834
835 int32_t refCnt = PR_ATOMIC_DECREMENT((int32_t*)&npobj->referenceCount);
836 NS_LOG_RELEASE(npobj, refCnt, "BrowserNPObject");
837
838 if (refCnt == 0) {
839 nsNPObjWrapper::OnDestroy(npobj);
840
841 NPN_PLUGIN_LOG(PLUGIN_LOG_NOISY,
842 ("Deleting NPObject %p, refcount hit 0\n", npobj));
843
844 if (npobj->_class && npobj->_class->deallocate) {
845 npobj->_class->deallocate(npobj);
846 } else {
847 free(npobj);
848 }
849 }
850 }
851
_invoke(NPP npp,NPObject * npobj,NPIdentifier method,const NPVariant * args,uint32_t argCount,NPVariant * result)852 bool _invoke(NPP npp, NPObject* npobj, NPIdentifier method,
853 const NPVariant* args, uint32_t argCount, NPVariant* result) {
854 if (!NS_IsMainThread()) {
855 NPN_PLUGIN_LOG(PLUGIN_LOG_ALWAYS,
856 ("NPN_invoke called from the wrong thread\n"));
857 return false;
858 }
859 if (!npp || !npobj || !npobj->_class || !npobj->_class->invoke) return false;
860
861 PluginDestructionGuard guard(npp);
862
863 NPPExceptionAutoHolder nppExceptionHolder;
864 NPPAutoPusher nppPusher(npp);
865
866 NPN_PLUGIN_LOG(PLUGIN_LOG_NOISY,
867 ("NPN_Invoke(npp %p, npobj %p, method %p, args %d\n", npp,
868 npobj, method, argCount));
869
870 return npobj->_class->invoke(npobj, method, args, argCount, result);
871 }
872
_invokeDefault(NPP npp,NPObject * npobj,const NPVariant * args,uint32_t argCount,NPVariant * result)873 bool _invokeDefault(NPP npp, NPObject* npobj, const NPVariant* args,
874 uint32_t argCount, NPVariant* result) {
875 if (!NS_IsMainThread()) {
876 NPN_PLUGIN_LOG(PLUGIN_LOG_ALWAYS,
877 ("NPN_invokedefault called from the wrong thread\n"));
878 return false;
879 }
880 if (!npp || !npobj || !npobj->_class || !npobj->_class->invokeDefault)
881 return false;
882
883 NPPExceptionAutoHolder nppExceptionHolder;
884 NPPAutoPusher nppPusher(npp);
885
886 NPN_PLUGIN_LOG(
887 PLUGIN_LOG_NOISY,
888 ("NPN_InvokeDefault(npp %p, npobj %p, args %d\n", npp, npobj, argCount));
889
890 return npobj->_class->invokeDefault(npobj, args, argCount, result);
891 }
892
_evaluate(NPP npp,NPObject * npobj,NPString * script,NPVariant * result)893 bool _evaluate(NPP npp, NPObject* npobj, NPString* script, NPVariant* result) {
894 if (!NS_IsMainThread()) {
895 NPN_PLUGIN_LOG(PLUGIN_LOG_ALWAYS,
896 ("NPN_evaluate called from the wrong thread\n"));
897 return false;
898 }
899 if (!npp) return false;
900
901 NPPAutoPusher nppPusher(npp);
902
903 Document* doc = GetDocumentFromNPP(npp);
904 NS_ENSURE_TRUE(doc, false);
905
906 nsGlobalWindowInner* win = nsGlobalWindowInner::Cast(doc->GetInnerWindow());
907 if (NS_WARN_IF(!win || !win->HasJSGlobal())) {
908 return false;
909 }
910
911 nsAutoMicroTask mt;
912 dom::AutoEntryScript aes(win, "NPAPI NPN_evaluate");
913 JSContext* cx = aes.cx();
914
915 JS::Rooted<JSObject*> obj(cx, nsNPObjWrapper::GetNewOrUsed(npp, cx, npobj));
916
917 if (!obj) {
918 return false;
919 }
920
921 obj = js::ToWindowIfWindowProxy(obj);
922 MOZ_ASSERT(obj, "ToWindowIfWindowProxy should never return null");
923
924 if (result) {
925 // Initialize the out param to void
926 VOID_TO_NPVARIANT(*result);
927 }
928
929 if (!script || !script->UTF8Length || !script->UTF8Characters) {
930 // Nothing to evaluate.
931
932 return true;
933 }
934
935 NS_ConvertUTF8toUTF16 utf16script(script->UTF8Characters, script->UTF8Length);
936
937 nsIPrincipal* principal = doc->NodePrincipal();
938
939 nsCString specStr;
940 const char* spec;
941
942 principal->GetAsciiSpec(specStr);
943 spec = specStr.get();
944
945 if (specStr.IsEmpty()) {
946 // No URI in a principal means it's the system principal. If the
947 // document URI is a chrome:// URI, pass that in as the URI of the
948 // script, else pass in null for the filename as there's no way to
949 // know where this document really came from. Passing in null here
950 // also means that the script gets treated by XPConnect as if it
951 // needs additional protection, which is what we want for unknown
952 // chrome code anyways.
953 nsCOMPtr<nsIURI> uri = doc->GetDocumentURI();
954 if (uri && uri->SchemeIs("chrome")) {
955 uri->GetSpec(specStr);
956 spec = specStr.get();
957 } else {
958 spec = nullptr;
959 }
960 }
961
962 NPN_PLUGIN_LOG(PLUGIN_LOG_NOISY,
963 ("NPN_Evaluate(npp %p, npobj %p, script <<<%s>>>) called\n",
964 npp, npobj, script->UTF8Characters));
965
966 JS::CompileOptions options(cx);
967 options.setFileAndLine(spec, 0);
968 JS::Rooted<JS::Value> rval(cx);
969 JS::RootedVector<JSObject*> scopeChain(cx);
970 if (!JS_IsGlobalObject(obj) && !scopeChain.append(obj)) {
971 return false;
972 }
973 // nsNPObjWrapper::GetNewOrUsed returns an object in the current compartment
974 // of the JSContext (it might be a CCW).
975 MOZ_RELEASE_ASSERT(
976 js::GetObjectCompartment(obj) == js::GetContextCompartment(cx),
977 "nsNPObjWrapper::GetNewOrUsed must wrap its return value");
978 obj = JS::CurrentGlobalOrNull(cx);
979 MOZ_ASSERT(obj);
980 nsresult rv = NS_OK;
981 {
982 nsJSUtils::ExecutionContext exec(cx, obj);
983 exec.SetScopeChain(scopeChain);
984 exec.Compile(options, utf16script);
985 rv = exec.ExecScript(&rval);
986 }
987
988 if (!JS_WrapValue(cx, &rval)) {
989 return false;
990 }
991
992 return NS_SUCCEEDED(rv) &&
993 (!result || JSValToNPVariant(npp, cx, rval, result));
994 }
995
_getproperty(NPP npp,NPObject * npobj,NPIdentifier property,NPVariant * result)996 bool _getproperty(NPP npp, NPObject* npobj, NPIdentifier property,
997 NPVariant* result) {
998 if (!NS_IsMainThread()) {
999 NPN_PLUGIN_LOG(PLUGIN_LOG_ALWAYS,
1000 ("NPN_getproperty called from the wrong thread\n"));
1001 return false;
1002 }
1003 if (!npp || !npobj || !npobj->_class || !npobj->_class->getProperty)
1004 return false;
1005
1006 NPPExceptionAutoHolder nppExceptionHolder;
1007 NPPAutoPusher nppPusher(npp);
1008
1009 NPN_PLUGIN_LOG(PLUGIN_LOG_NOISY,
1010 ("NPN_GetProperty(npp %p, npobj %p, property %p) called\n",
1011 npp, npobj, property));
1012
1013 if (!npobj->_class->getProperty(npobj, property, result)) return false;
1014
1015 return true;
1016 }
1017
_setproperty(NPP npp,NPObject * npobj,NPIdentifier property,const NPVariant * value)1018 bool _setproperty(NPP npp, NPObject* npobj, NPIdentifier property,
1019 const NPVariant* value) {
1020 if (!NS_IsMainThread()) {
1021 NPN_PLUGIN_LOG(PLUGIN_LOG_ALWAYS,
1022 ("NPN_setproperty called from the wrong thread\n"));
1023 return false;
1024 }
1025 if (!npp || !npobj || !npobj->_class || !npobj->_class->setProperty)
1026 return false;
1027
1028 NPPExceptionAutoHolder nppExceptionHolder;
1029 NPPAutoPusher nppPusher(npp);
1030
1031 NPN_PLUGIN_LOG(PLUGIN_LOG_NOISY,
1032 ("NPN_SetProperty(npp %p, npobj %p, property %p) called\n",
1033 npp, npobj, property));
1034
1035 return npobj->_class->setProperty(npobj, property, value);
1036 }
1037
_removeproperty(NPP npp,NPObject * npobj,NPIdentifier property)1038 bool _removeproperty(NPP npp, NPObject* npobj, NPIdentifier property) {
1039 if (!NS_IsMainThread()) {
1040 NPN_PLUGIN_LOG(PLUGIN_LOG_ALWAYS,
1041 ("NPN_removeproperty called from the wrong thread\n"));
1042 return false;
1043 }
1044 if (!npp || !npobj || !npobj->_class || !npobj->_class->removeProperty)
1045 return false;
1046
1047 NPPExceptionAutoHolder nppExceptionHolder;
1048 NPPAutoPusher nppPusher(npp);
1049
1050 NPN_PLUGIN_LOG(PLUGIN_LOG_NOISY,
1051 ("NPN_RemoveProperty(npp %p, npobj %p, property %p) called\n",
1052 npp, npobj, property));
1053
1054 return npobj->_class->removeProperty(npobj, property);
1055 }
1056
_hasproperty(NPP npp,NPObject * npobj,NPIdentifier propertyName)1057 bool _hasproperty(NPP npp, NPObject* npobj, NPIdentifier propertyName) {
1058 if (!NS_IsMainThread()) {
1059 NPN_PLUGIN_LOG(PLUGIN_LOG_ALWAYS,
1060 ("NPN_hasproperty called from the wrong thread\n"));
1061 return false;
1062 }
1063 if (!npp || !npobj || !npobj->_class || !npobj->_class->hasProperty)
1064 return false;
1065
1066 NPPExceptionAutoHolder nppExceptionHolder;
1067 NPPAutoPusher nppPusher(npp);
1068
1069 NPN_PLUGIN_LOG(PLUGIN_LOG_NOISY,
1070 ("NPN_HasProperty(npp %p, npobj %p, property %p) called\n",
1071 npp, npobj, propertyName));
1072
1073 return npobj->_class->hasProperty(npobj, propertyName);
1074 }
1075
_hasmethod(NPP npp,NPObject * npobj,NPIdentifier methodName)1076 bool _hasmethod(NPP npp, NPObject* npobj, NPIdentifier methodName) {
1077 if (!NS_IsMainThread()) {
1078 NPN_PLUGIN_LOG(PLUGIN_LOG_ALWAYS,
1079 ("NPN_hasmethod called from the wrong thread\n"));
1080 return false;
1081 }
1082 if (!npp || !npobj || !npobj->_class || !npobj->_class->hasMethod)
1083 return false;
1084
1085 NPPExceptionAutoHolder nppExceptionHolder;
1086 NPPAutoPusher nppPusher(npp);
1087
1088 NPN_PLUGIN_LOG(PLUGIN_LOG_NOISY,
1089 ("NPN_HasMethod(npp %p, npobj %p, property %p) called\n", npp,
1090 npobj, methodName));
1091
1092 return npobj->_class->hasMethod(npobj, methodName);
1093 }
1094
_enumerate(NPP npp,NPObject * npobj,NPIdentifier ** identifier,uint32_t * count)1095 bool _enumerate(NPP npp, NPObject* npobj, NPIdentifier** identifier,
1096 uint32_t* count) {
1097 if (!NS_IsMainThread()) {
1098 NPN_PLUGIN_LOG(PLUGIN_LOG_ALWAYS,
1099 ("NPN_enumerate called from the wrong thread\n"));
1100 return false;
1101 }
1102 if (!npp || !npobj || !npobj->_class) return false;
1103
1104 NPN_PLUGIN_LOG(PLUGIN_LOG_NOISY,
1105 ("NPN_Enumerate(npp %p, npobj %p) called\n", npp, npobj));
1106
1107 if (!NP_CLASS_STRUCT_VERSION_HAS_ENUM(npobj->_class) ||
1108 !npobj->_class->enumerate) {
1109 *identifier = 0;
1110 *count = 0;
1111 return true;
1112 }
1113
1114 NPPExceptionAutoHolder nppExceptionHolder;
1115 NPPAutoPusher nppPusher(npp);
1116
1117 return npobj->_class->enumerate(npobj, identifier, count);
1118 }
1119
_construct(NPP npp,NPObject * npobj,const NPVariant * args,uint32_t argCount,NPVariant * result)1120 bool _construct(NPP npp, NPObject* npobj, const NPVariant* args,
1121 uint32_t argCount, NPVariant* result) {
1122 if (!NS_IsMainThread()) {
1123 NPN_PLUGIN_LOG(PLUGIN_LOG_ALWAYS,
1124 ("NPN_construct called from the wrong thread\n"));
1125 return false;
1126 }
1127 if (!npp || !npobj || !npobj->_class ||
1128 !NP_CLASS_STRUCT_VERSION_HAS_CTOR(npobj->_class) ||
1129 !npobj->_class->construct) {
1130 return false;
1131 }
1132
1133 NPPExceptionAutoHolder nppExceptionHolder;
1134 NPPAutoPusher nppPusher(npp);
1135
1136 return npobj->_class->construct(npobj, args, argCount, result);
1137 }
1138
_releasevariantvalue(NPVariant * variant)1139 void _releasevariantvalue(NPVariant* variant) {
1140 if (!NS_IsMainThread()) {
1141 NPN_PLUGIN_LOG(PLUGIN_LOG_ALWAYS,
1142 ("NPN_releasevariantvalue called from the wrong thread\n"));
1143 }
1144 switch (variant->type) {
1145 case NPVariantType_Void:
1146 case NPVariantType_Null:
1147 case NPVariantType_Bool:
1148 case NPVariantType_Int32:
1149 case NPVariantType_Double:
1150 break;
1151 case NPVariantType_String: {
1152 const NPString* s = &NPVARIANT_TO_STRING(*variant);
1153
1154 if (s->UTF8Characters) {
1155 #if defined(MOZ_MEMORY) && defined(XP_WIN)
1156 if (malloc_usable_size((void*)s->UTF8Characters) != 0) {
1157 free((void*)s->UTF8Characters);
1158 } else {
1159 void* p = (void*)s->UTF8Characters;
1160 DWORD nheaps = 0;
1161 AutoTArray<HANDLE, 50> heaps;
1162 nheaps = GetProcessHeaps(0, heaps.Elements());
1163 heaps.AppendElements(nheaps);
1164 GetProcessHeaps(nheaps, heaps.Elements());
1165 for (DWORD i = 0; i < nheaps; i++) {
1166 if (InHeap(heaps[i], p)) {
1167 HeapFree(heaps[i], 0, p);
1168 break;
1169 }
1170 }
1171 }
1172 #else
1173 free((void*)s->UTF8Characters);
1174 #endif
1175 }
1176 break;
1177 }
1178 case NPVariantType_Object: {
1179 NPObject* npobj = NPVARIANT_TO_OBJECT(*variant);
1180
1181 if (npobj) _releaseobject(npobj);
1182
1183 break;
1184 }
1185 default:
1186 NS_ERROR("Unknown NPVariant type!");
1187 }
1188
1189 VOID_TO_NPVARIANT(*variant);
1190 }
1191
_setexception(NPObject * npobj,const NPUTF8 * message)1192 void _setexception(NPObject* npobj, const NPUTF8* message) {
1193 if (!NS_IsMainThread()) {
1194 NPN_PLUGIN_LOG(PLUGIN_LOG_ALWAYS,
1195 ("NPN_setexception called from the wrong thread\n"));
1196 return;
1197 }
1198
1199 if (!message) return;
1200
1201 if (gNPPException) {
1202 // If a plugin throws multiple exceptions, we'll only report the
1203 // last one for now.
1204 free(gNPPException);
1205 }
1206
1207 gNPPException = strdup(message);
1208 }
1209
_getvalue(NPP npp,NPNVariable variable,void * result)1210 NPError _getvalue(NPP npp, NPNVariable variable, void* result) {
1211 if (!NS_IsMainThread()) {
1212 NPN_PLUGIN_LOG(PLUGIN_LOG_ALWAYS,
1213 ("NPN_getvalue called from the wrong thread\n"));
1214 return NPERR_INVALID_PARAM;
1215 }
1216 NPN_PLUGIN_LOG(PLUGIN_LOG_NORMAL,
1217 ("NPN_GetValue: npp=%p, var=%d\n", (void*)npp, (int)variable));
1218
1219 nsresult res;
1220
1221 PluginDestructionGuard guard(npp);
1222
1223 // Cast NPNVariable enum to int to avoid warnings about including switch
1224 // cases for android_npapi.h's non-standard ANPInterface values.
1225 switch (static_cast<int>(variable)) {
1226 #if defined(XP_UNIX) && !defined(XP_MACOSX)
1227 case NPNVxDisplay: {
1228 # if defined(MOZ_X11)
1229 if (npp) {
1230 nsNPAPIPluginInstance* inst = (nsNPAPIPluginInstance*)npp->ndata;
1231 bool windowless = false;
1232 inst->IsWindowless(&windowless);
1233 // The documentation on the types for many variables in NP(N|P)_GetValue
1234 // is vague. Often boolean values are NPBool (1 byte), but
1235 // https://developer.mozilla.org/en/XEmbed_Extension_for_Mozilla_Plugins
1236 // treats NPPVpluginNeedsXEmbed as PRBool (int), and
1237 // on x86/32-bit, flash stores to this using |movl 0x1,&needsXEmbed|.
1238 // thus we can't use NPBool for needsXEmbed, or the three bytes above
1239 // it on the stack would get clobbered. so protect with the larger bool.
1240 int needsXEmbed = 0;
1241 if (!windowless) {
1242 res = inst->GetValueFromPlugin(NPPVpluginNeedsXEmbed, &needsXEmbed);
1243 // If the call returned an error code make sure we still use our
1244 // default value.
1245 if (NS_FAILED(res)) {
1246 needsXEmbed = 0;
1247 }
1248 }
1249 if (windowless || needsXEmbed) {
1250 (*(Display**)result) = mozilla::DefaultXDisplay();
1251 return NPERR_NO_ERROR;
1252 }
1253 }
1254 # endif
1255 return NPERR_GENERIC_ERROR;
1256 }
1257
1258 case NPNVxtAppContext:
1259 return NPERR_GENERIC_ERROR;
1260 #endif
1261
1262 #if defined(XP_WIN) || defined(MOZ_WIDGET_GTK)
1263 case NPNVnetscapeWindow: {
1264 if (!npp || !npp->ndata) return NPERR_INVALID_INSTANCE_ERROR;
1265
1266 nsNPAPIPluginInstance* inst = (nsNPAPIPluginInstance*)npp->ndata;
1267
1268 RefPtr<nsPluginInstanceOwner> owner = inst->GetOwner();
1269 NS_ENSURE_TRUE(owner, NPERR_NO_ERROR);
1270
1271 if (NS_SUCCEEDED(owner->GetNetscapeWindow(result))) {
1272 return NPERR_NO_ERROR;
1273 }
1274 return NPERR_GENERIC_ERROR;
1275 }
1276 #endif
1277
1278 case NPNVjavascriptEnabledBool: {
1279 *(NPBool*)result = false;
1280 bool js = false;
1281 res = Preferences::GetBool("javascript.enabled", &js);
1282 if (NS_SUCCEEDED(res)) {
1283 *(NPBool*)result = js;
1284 }
1285 return NPERR_NO_ERROR;
1286 }
1287
1288 case NPNVasdEnabledBool:
1289 *(NPBool*)result = false;
1290 return NPERR_NO_ERROR;
1291
1292 case NPNVisOfflineBool: {
1293 bool offline = false;
1294 nsCOMPtr<nsIIOService> ioservice =
1295 do_GetService(NS_IOSERVICE_CONTRACTID, &res);
1296 if (NS_SUCCEEDED(res)) res = ioservice->GetOffline(&offline);
1297 if (NS_FAILED(res)) return NPERR_GENERIC_ERROR;
1298
1299 *(NPBool*)result = offline;
1300 return NPERR_NO_ERROR;
1301 }
1302
1303 case NPNVToolkit: {
1304 #ifdef MOZ_WIDGET_GTK
1305 *((NPNToolkitType*)result) = NPNVGtk2;
1306 #endif
1307
1308 if (*(NPNToolkitType*)result) return NPERR_NO_ERROR;
1309
1310 return NPERR_GENERIC_ERROR;
1311 }
1312
1313 case NPNVSupportsXEmbedBool: {
1314 #ifdef MOZ_WIDGET_GTK
1315 *(NPBool*)result = true;
1316 #else
1317 *(NPBool*)result = false;
1318 #endif
1319 return NPERR_NO_ERROR;
1320 }
1321
1322 case NPNVWindowNPObject: {
1323 *(NPObject**)result = _getwindowobject(npp);
1324
1325 return *(NPObject**)result ? NPERR_NO_ERROR : NPERR_GENERIC_ERROR;
1326 }
1327
1328 case NPNVPluginElementNPObject: {
1329 *(NPObject**)result = _getpluginelement(npp);
1330
1331 return *(NPObject**)result ? NPERR_NO_ERROR : NPERR_GENERIC_ERROR;
1332 }
1333
1334 case NPNVSupportsWindowless: {
1335 #if defined(XP_WIN) || defined(XP_MACOSX) || \
1336 (defined(MOZ_X11) && defined(MOZ_WIDGET_GTK))
1337 *(NPBool*)result = true;
1338 #else
1339 *(NPBool*)result = false;
1340 #endif
1341 return NPERR_NO_ERROR;
1342 }
1343
1344 case NPNVprivateModeBool: {
1345 bool privacy;
1346 nsNPAPIPluginInstance* inst =
1347 static_cast<nsNPAPIPluginInstance*>(npp->ndata);
1348 if (!inst) return NPERR_GENERIC_ERROR;
1349
1350 nsresult rv = inst->IsPrivateBrowsing(&privacy);
1351 if (NS_FAILED(rv)) return NPERR_GENERIC_ERROR;
1352 *(NPBool*)result = (NPBool)privacy;
1353 return NPERR_NO_ERROR;
1354 }
1355
1356 case NPNVdocumentOrigin: {
1357 nsNPAPIPluginInstance* inst = (nsNPAPIPluginInstance*)npp->ndata;
1358 if (!inst) {
1359 return NPERR_GENERIC_ERROR;
1360 }
1361
1362 RefPtr<dom::Element> element;
1363 inst->GetDOMElement(getter_AddRefs(element));
1364 if (!element) {
1365 return NPERR_GENERIC_ERROR;
1366 }
1367
1368 nsIPrincipal* principal = element->NodePrincipal();
1369
1370 nsAutoString utf16Origin;
1371 res = nsContentUtils::GetUTFOrigin(principal, utf16Origin);
1372 if (NS_FAILED(res)) {
1373 return NPERR_GENERIC_ERROR;
1374 }
1375
1376 nsCOMPtr<nsIIDNService> idnService =
1377 do_GetService(NS_IDNSERVICE_CONTRACTID);
1378 if (!idnService) {
1379 return NPERR_GENERIC_ERROR;
1380 }
1381
1382 // This is a bit messy: we convert to UTF-8 here, but then
1383 // nsIDNService::Normalize will convert back to UTF-16 for processing,
1384 // and back to UTF-8 again to return the result.
1385 // Alternative: perhaps we should add a NormalizeUTF16 version of the API,
1386 // and just convert to UTF-8 for the final return (resulting in one
1387 // encoding form conversion instead of three).
1388 NS_ConvertUTF16toUTF8 utf8Origin(utf16Origin);
1389 nsAutoCString normalizedUTF8Origin;
1390 res = idnService->Normalize(utf8Origin, normalizedUTF8Origin);
1391 if (NS_FAILED(res)) {
1392 return NPERR_GENERIC_ERROR;
1393 }
1394
1395 *(char**)result = ToNewCString(normalizedUTF8Origin);
1396 return *(char**)result ? NPERR_NO_ERROR : NPERR_GENERIC_ERROR;
1397 }
1398
1399 #ifdef XP_MACOSX
1400 case NPNVpluginDrawingModel: {
1401 if (npp) {
1402 nsNPAPIPluginInstance* inst = (nsNPAPIPluginInstance*)npp->ndata;
1403 if (inst) {
1404 NPDrawingModel drawingModel;
1405 inst->GetDrawingModel((int32_t*)&drawingModel);
1406 *(NPDrawingModel*)result = drawingModel;
1407 return NPERR_NO_ERROR;
1408 }
1409 }
1410 return NPERR_GENERIC_ERROR;
1411 }
1412
1413 # ifndef NP_NO_QUICKDRAW
1414 case NPNVsupportsQuickDrawBool: {
1415 *(NPBool*)result = false;
1416
1417 return NPERR_NO_ERROR;
1418 }
1419 # endif
1420
1421 case NPNVsupportsCoreGraphicsBool: {
1422 *(NPBool*)result = true;
1423
1424 return NPERR_NO_ERROR;
1425 }
1426
1427 case NPNVsupportsCoreAnimationBool: {
1428 *(NPBool*)result = true;
1429
1430 return NPERR_NO_ERROR;
1431 }
1432
1433 case NPNVsupportsInvalidatingCoreAnimationBool: {
1434 *(NPBool*)result = true;
1435
1436 return NPERR_NO_ERROR;
1437 }
1438
1439 case NPNVsupportsCompositingCoreAnimationPluginsBool: {
1440 *(NPBool*)result = PR_TRUE;
1441
1442 return NPERR_NO_ERROR;
1443 }
1444
1445 # ifndef NP_NO_CARBON
1446 case NPNVsupportsCarbonBool: {
1447 *(NPBool*)result = false;
1448
1449 return NPERR_NO_ERROR;
1450 }
1451 # endif
1452 case NPNVsupportsCocoaBool: {
1453 *(NPBool*)result = true;
1454
1455 return NPERR_NO_ERROR;
1456 }
1457
1458 case NPNVsupportsUpdatedCocoaTextInputBool: {
1459 *(NPBool*)result = true;
1460 return NPERR_NO_ERROR;
1461 }
1462 #endif
1463
1464 #if defined(XP_MACOSX) || defined(XP_WIN)
1465 case NPNVcontentsScaleFactor: {
1466 nsNPAPIPluginInstance* inst =
1467 (nsNPAPIPluginInstance*)(npp ? npp->ndata : nullptr);
1468 double scaleFactor = inst ? inst->GetContentsScaleFactor() : 1.0;
1469 *(double*)result = scaleFactor;
1470 return NPERR_NO_ERROR;
1471 }
1472 #endif
1473
1474 case NPNVCSSZoomFactor: {
1475 nsNPAPIPluginInstance* inst =
1476 (nsNPAPIPluginInstance*)(npp ? npp->ndata : nullptr);
1477 double scaleFactor = inst ? inst->GetCSSZoomFactor() : 1.0;
1478 *(double*)result = scaleFactor;
1479 return NPERR_NO_ERROR;
1480 }
1481
1482 // we no longer hand out any XPCOM objects
1483 case NPNVDOMElement:
1484 case NPNVDOMWindow:
1485 case NPNVserviceManager:
1486 // old XPCOM objects, no longer supported, but null out the out
1487 // param to avoid crashing plugins that still try to use this.
1488 *(nsISupports**)result = nullptr;
1489 [[fallthrough]];
1490
1491 default:
1492 NPN_PLUGIN_LOG(PLUGIN_LOG_NORMAL,
1493 ("NPN_getvalue unhandled get value: %d\n", variable));
1494 return NPERR_GENERIC_ERROR;
1495 }
1496 }
1497
_setvalue(NPP npp,NPPVariable variable,void * result)1498 NPError _setvalue(NPP npp, NPPVariable variable, void* result) {
1499 if (!NS_IsMainThread()) {
1500 NPN_PLUGIN_LOG(PLUGIN_LOG_ALWAYS,
1501 ("NPN_setvalue called from the wrong thread\n"));
1502 return NPERR_INVALID_PARAM;
1503 }
1504 NPN_PLUGIN_LOG(PLUGIN_LOG_NORMAL,
1505 ("NPN_SetValue: npp=%p, var=%d\n", (void*)npp, (int)variable));
1506
1507 if (!npp) return NPERR_INVALID_INSTANCE_ERROR;
1508
1509 nsNPAPIPluginInstance* inst = (nsNPAPIPluginInstance*)npp->ndata;
1510
1511 NS_ASSERTION(inst, "null instance");
1512
1513 if (!inst) return NPERR_INVALID_INSTANCE_ERROR;
1514
1515 PluginDestructionGuard guard(inst);
1516
1517 // Cast NPNVariable enum to int to avoid warnings about including switch
1518 // cases for android_npapi.h's non-standard ANPInterface values.
1519 switch (static_cast<int>(variable)) {
1520 // we should keep backward compatibility with NPAPI where the
1521 // actual pointer value is checked rather than its content
1522 // when passing booleans
1523 case NPPVpluginWindowBool: {
1524 #ifdef XP_MACOSX
1525 // This setting doesn't apply to OS X (only to Windows and Unix/Linux).
1526 // See https://developer.mozilla.org/En/NPN_SetValue#section_5. Return
1527 // NPERR_NO_ERROR here to conform to other browsers' behavior on OS X
1528 // (e.g. Safari and Opera).
1529 return NPERR_NO_ERROR;
1530 #else
1531 NPBool bWindowless = (result == nullptr);
1532 return inst->SetWindowless(bWindowless);
1533 #endif
1534 }
1535 case NPPVpluginTransparentBool: {
1536 NPBool bTransparent = (result != nullptr);
1537 return inst->SetTransparent(bTransparent);
1538 }
1539
1540 case NPPVjavascriptPushCallerBool: {
1541 return NPERR_NO_ERROR;
1542 }
1543
1544 case NPPVpluginKeepLibraryInMemory: {
1545 NPBool bCached = (result != nullptr);
1546 inst->SetCached(bCached);
1547 return NPERR_NO_ERROR;
1548 }
1549
1550 case NPPVpluginUsesDOMForCursorBool: {
1551 bool useDOMForCursor = (result != nullptr);
1552 return inst->SetUsesDOMForCursor(useDOMForCursor);
1553 }
1554
1555 case NPPVpluginIsPlayingAudio: {
1556 const bool isPlaying = result;
1557
1558 nsNPAPIPluginInstance* inst = (nsNPAPIPluginInstance*)npp->ndata;
1559 MOZ_ASSERT(inst);
1560
1561 if (!isPlaying && !inst->HasAudioChannelAgent()) {
1562 return NPERR_NO_ERROR;
1563 }
1564
1565 if (isPlaying) {
1566 inst->NotifyStartedPlaying();
1567 } else {
1568 inst->NotifyStoppedPlaying();
1569 }
1570
1571 return NPERR_NO_ERROR;
1572 }
1573
1574 case NPPVpluginDrawingModel: {
1575 if (inst) {
1576 inst->SetDrawingModel((NPDrawingModel)NS_PTR_TO_INT32(result));
1577 return NPERR_NO_ERROR;
1578 }
1579 return NPERR_GENERIC_ERROR;
1580 }
1581
1582 #ifdef XP_MACOSX
1583 case NPPVpluginEventModel: {
1584 if (inst) {
1585 inst->SetEventModel((NPEventModel)NS_PTR_TO_INT32(result));
1586 return NPERR_NO_ERROR;
1587 } else {
1588 return NPERR_GENERIC_ERROR;
1589 }
1590 }
1591 #endif
1592 default:
1593 return NPERR_GENERIC_ERROR;
1594 }
1595 }
1596
_requestread(NPStream * pstream,NPByteRange * rangeList)1597 NPError _requestread(NPStream* pstream, NPByteRange* rangeList) {
1598 return NPERR_STREAM_NOT_SEEKABLE;
1599 }
1600
1601 // Deprecated, only stubbed out
1602 void* /* OJI type: JRIEnv* */
_getJavaEnv()1603 _getJavaEnv() {
1604 NPN_PLUGIN_LOG(PLUGIN_LOG_NORMAL, ("NPN_GetJavaEnv\n"));
1605 return nullptr;
1606 }
1607
_useragent(NPP npp)1608 const char* _useragent(NPP npp) {
1609 if (!NS_IsMainThread()) {
1610 NPN_PLUGIN_LOG(PLUGIN_LOG_ALWAYS,
1611 ("NPN_useragent called from the wrong thread\n"));
1612 return nullptr;
1613 }
1614 NPN_PLUGIN_LOG(PLUGIN_LOG_NORMAL, ("NPN_UserAgent: npp=%p\n", (void*)npp));
1615
1616 nsCOMPtr<nsIPluginHost> pluginHostCOM(
1617 do_GetService(MOZ_PLUGIN_HOST_CONTRACTID));
1618 nsPluginHost* pluginHost = static_cast<nsPluginHost*>(pluginHostCOM.get());
1619 if (!pluginHost) {
1620 return nullptr;
1621 }
1622
1623 const char* retstr;
1624 nsresult rv = pluginHost->UserAgent(&retstr);
1625 if (NS_FAILED(rv)) return nullptr;
1626
1627 return retstr;
1628 }
1629
_memalloc(uint32_t size)1630 void* _memalloc(uint32_t size) {
1631 if (!NS_IsMainThread()) {
1632 NPN_PLUGIN_LOG(PLUGIN_LOG_NORMAL,
1633 ("NPN_memalloc called from the wrong thread\n"));
1634 }
1635 NPN_PLUGIN_LOG(PLUGIN_LOG_NOISY, ("NPN_MemAlloc: size=%d\n", size));
1636 return moz_xmalloc(size);
1637 }
1638
1639 // Deprecated, only stubbed out
1640 void* /* OJI type: jref */
_getJavaPeer(NPP npp)1641 _getJavaPeer(NPP npp) {
1642 NPN_PLUGIN_LOG(PLUGIN_LOG_NORMAL, ("NPN_GetJavaPeer: npp=%p\n", (void*)npp));
1643 return nullptr;
1644 }
1645
_pushpopupsenabledstate(NPP npp,NPBool enabled)1646 void _pushpopupsenabledstate(NPP npp, NPBool enabled) {
1647 if (!NS_IsMainThread()) {
1648 NPN_PLUGIN_LOG(
1649 PLUGIN_LOG_ALWAYS,
1650 ("NPN_pushpopupsenabledstate called from the wrong thread\n"));
1651 return;
1652 }
1653 nsNPAPIPluginInstance* inst =
1654 npp ? (nsNPAPIPluginInstance*)npp->ndata : nullptr;
1655 if (!inst) return;
1656
1657 inst->PushPopupsEnabledState(enabled);
1658 }
1659
_poppopupsenabledstate(NPP npp)1660 void _poppopupsenabledstate(NPP npp) {
1661 if (!NS_IsMainThread()) {
1662 NPN_PLUGIN_LOG(
1663 PLUGIN_LOG_ALWAYS,
1664 ("NPN_poppopupsenabledstate called from the wrong thread\n"));
1665 return;
1666 }
1667 nsNPAPIPluginInstance* inst =
1668 npp ? (nsNPAPIPluginInstance*)npp->ndata : nullptr;
1669 if (!inst) return;
1670
1671 inst->PopPopupsEnabledState();
1672 }
1673
_getvalueforurl(NPP instance,NPNURLVariable variable,const char * url,char ** value,uint32_t * len)1674 NPError _getvalueforurl(NPP instance, NPNURLVariable variable, const char* url,
1675 char** value, uint32_t* len) {
1676 if (!NS_IsMainThread()) {
1677 NPN_PLUGIN_LOG(PLUGIN_LOG_ALWAYS,
1678 ("NPN_getvalueforurl called from the wrong thread\n"));
1679 return NPERR_GENERIC_ERROR;
1680 }
1681
1682 if (!instance) {
1683 return NPERR_INVALID_PARAM;
1684 }
1685
1686 if (!url || !*url || !len) {
1687 return NPERR_INVALID_URL;
1688 }
1689
1690 *len = 0;
1691
1692 switch (variable) {
1693 case NPNURLVProxy:
1694 // NPNURLVProxy is no longer supported.
1695 *value = nullptr;
1696 return NPERR_GENERIC_ERROR;
1697
1698 case NPNURLVCookie:
1699 // NPNURLVCookie is no longer supported.
1700 *value = nullptr;
1701 return NPERR_GENERIC_ERROR;
1702
1703 default:
1704 // Fall through and return an error...
1705 ;
1706 }
1707
1708 return NPERR_GENERIC_ERROR;
1709 }
1710
_setvalueforurl(NPP instance,NPNURLVariable variable,const char * url,const char * value,uint32_t len)1711 NPError _setvalueforurl(NPP instance, NPNURLVariable variable, const char* url,
1712 const char* value, uint32_t len) {
1713 if (!NS_IsMainThread()) {
1714 NPN_PLUGIN_LOG(PLUGIN_LOG_ALWAYS,
1715 ("NPN_setvalueforurl called from the wrong thread\n"));
1716 return NPERR_GENERIC_ERROR;
1717 }
1718
1719 if (!instance) {
1720 return NPERR_INVALID_PARAM;
1721 }
1722
1723 if (!url || !*url) {
1724 return NPERR_INVALID_URL;
1725 }
1726
1727 switch (variable) {
1728 case NPNURLVCookie:
1729 // NPNURLVCookie is no longer supported.
1730 return NPERR_GENERIC_ERROR;
1731
1732 case NPNURLVProxy:
1733 // We don't support setting proxy values, fall through...
1734 default:
1735 // Fall through and return an error...
1736 ;
1737 }
1738
1739 return NPERR_GENERIC_ERROR;
1740 }
1741
_scheduletimer(NPP instance,uint32_t interval,NPBool repeat,PluginTimerFunc timerFunc)1742 uint32_t _scheduletimer(NPP instance, uint32_t interval, NPBool repeat,
1743 PluginTimerFunc timerFunc) {
1744 if (!NS_IsMainThread()) {
1745 NPN_PLUGIN_LOG(PLUGIN_LOG_ALWAYS,
1746 ("NPN_scheduletimer called from the wrong thread\n"));
1747 return 0;
1748 }
1749
1750 nsNPAPIPluginInstance* inst = (nsNPAPIPluginInstance*)instance->ndata;
1751 if (!inst) return 0;
1752
1753 return inst->ScheduleTimer(interval, repeat, timerFunc);
1754 }
1755
_unscheduletimer(NPP instance,uint32_t timerID)1756 void _unscheduletimer(NPP instance, uint32_t timerID) {
1757 if (!NS_IsMainThread()) {
1758 NPN_PLUGIN_LOG(PLUGIN_LOG_ALWAYS,
1759 ("NPN_unscheduletimer called from the wrong thread\n"));
1760 return;
1761 }
1762
1763 nsNPAPIPluginInstance* inst = (nsNPAPIPluginInstance*)instance->ndata;
1764 if (!inst) return;
1765
1766 inst->UnscheduleTimer(timerID);
1767 }
1768
_popupcontextmenu(NPP instance,NPMenu * menu)1769 NPError _popupcontextmenu(NPP instance, NPMenu* menu) {
1770 if (!NS_IsMainThread()) {
1771 NPN_PLUGIN_LOG(PLUGIN_LOG_ALWAYS,
1772 ("NPN_popupcontextmenu called from the wrong thread\n"));
1773 return 0;
1774 }
1775
1776 #ifdef MOZ_WIDGET_COCOA
1777 nsNPAPIPluginInstance* inst = (nsNPAPIPluginInstance*)instance->ndata;
1778
1779 double pluginX, pluginY;
1780 double screenX, screenY;
1781
1782 const NPCocoaEvent* currentEvent =
1783 static_cast<NPCocoaEvent*>(inst->GetCurrentEvent());
1784 if (!currentEvent) {
1785 return NPERR_GENERIC_ERROR;
1786 }
1787
1788 // Ensure that the events has an x/y value.
1789 if (currentEvent->type != NPCocoaEventMouseDown &&
1790 currentEvent->type != NPCocoaEventMouseUp &&
1791 currentEvent->type != NPCocoaEventMouseMoved &&
1792 currentEvent->type != NPCocoaEventMouseEntered &&
1793 currentEvent->type != NPCocoaEventMouseExited &&
1794 currentEvent->type != NPCocoaEventMouseDragged) {
1795 return NPERR_GENERIC_ERROR;
1796 }
1797
1798 pluginX = currentEvent->data.mouse.pluginX;
1799 pluginY = currentEvent->data.mouse.pluginY;
1800
1801 if ((pluginX < 0.0) || (pluginY < 0.0)) return NPERR_GENERIC_ERROR;
1802
1803 NPBool success =
1804 _convertpoint(instance, pluginX, pluginY, NPCoordinateSpacePlugin,
1805 &screenX, &screenY, NPCoordinateSpaceScreen);
1806
1807 if (success) {
1808 return mozilla::plugins::PluginUtilsOSX::ShowCocoaContextMenu(
1809 menu, screenX, screenY, nullptr, nullptr);
1810 } else {
1811 NS_WARNING("Convertpoint failed, could not created contextmenu.");
1812 return NPERR_GENERIC_ERROR;
1813 }
1814 #else
1815 NS_WARNING("Not supported on this platform!");
1816 return NPERR_GENERIC_ERROR;
1817 #endif
1818 }
1819
_convertpoint(NPP instance,double sourceX,double sourceY,NPCoordinateSpace sourceSpace,double * destX,double * destY,NPCoordinateSpace destSpace)1820 NPBool _convertpoint(NPP instance, double sourceX, double sourceY,
1821 NPCoordinateSpace sourceSpace, double* destX,
1822 double* destY, NPCoordinateSpace destSpace) {
1823 if (!NS_IsMainThread()) {
1824 NPN_PLUGIN_LOG(PLUGIN_LOG_ALWAYS,
1825 ("NPN_convertpoint called from the wrong thread\n"));
1826 return 0;
1827 }
1828
1829 nsNPAPIPluginInstance* inst = (nsNPAPIPluginInstance*)instance->ndata;
1830 if (!inst) return false;
1831
1832 return inst->ConvertPoint(sourceX, sourceY, sourceSpace, destX, destY,
1833 destSpace);
1834 }
1835
_urlredirectresponse(NPP instance,void * notifyData,NPBool allow)1836 void _urlredirectresponse(NPP instance, void* notifyData, NPBool allow) {
1837 if (!NS_IsMainThread()) {
1838 NPN_PLUGIN_LOG(PLUGIN_LOG_ALWAYS,
1839 ("NPN_convertpoint called from the wrong thread\n"));
1840 return;
1841 }
1842
1843 nsNPAPIPluginInstance* inst = (nsNPAPIPluginInstance*)instance->ndata;
1844 if (!inst) {
1845 return;
1846 }
1847
1848 inst->URLRedirectResponse(notifyData, allow);
1849 }
1850
_initasyncsurface(NPP instance,NPSize * size,NPImageFormat format,void * initData,NPAsyncSurface * surface)1851 NPError _initasyncsurface(NPP instance, NPSize* size, NPImageFormat format,
1852 void* initData, NPAsyncSurface* surface) {
1853 nsNPAPIPluginInstance* inst = (nsNPAPIPluginInstance*)instance->ndata;
1854 if (!inst) {
1855 return NPERR_GENERIC_ERROR;
1856 }
1857
1858 return inst->InitAsyncSurface(size, format, initData, surface);
1859 }
1860
_finalizeasyncsurface(NPP instance,NPAsyncSurface * surface)1861 NPError _finalizeasyncsurface(NPP instance, NPAsyncSurface* surface) {
1862 nsNPAPIPluginInstance* inst = (nsNPAPIPluginInstance*)instance->ndata;
1863 if (!inst) {
1864 return NPERR_GENERIC_ERROR;
1865 }
1866
1867 return inst->FinalizeAsyncSurface(surface);
1868 }
1869
_setcurrentasyncsurface(NPP instance,NPAsyncSurface * surface,NPRect * changed)1870 void _setcurrentasyncsurface(NPP instance, NPAsyncSurface* surface,
1871 NPRect* changed) {
1872 nsNPAPIPluginInstance* inst = (nsNPAPIPluginInstance*)instance->ndata;
1873 if (!inst) {
1874 return;
1875 }
1876
1877 inst->SetCurrentAsyncSurface(surface, changed);
1878 }
1879
1880 } // namespace mozilla::plugins::parent
1881