Line data Source code
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 conflicts. */
9 : #include "mozilla/ArrayUtils.h"
10 :
11 : #include "pratom.h"
12 : #include "prenv.h"
13 : #include "prclist.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 "nsIServiceManager.h"
23 : #include "nsThreadUtils.h"
24 : #include "mozilla/Preferences.h"
25 : #include "nsPluginInstanceOwner.h"
26 :
27 : #include "nsPluginsDir.h"
28 : #include "nsPluginLogging.h"
29 :
30 : #include "nsIDOMElement.h"
31 : #include "nsPIDOMWindow.h"
32 : #include "nsGlobalWindow.h"
33 : #include "nsIDocument.h"
34 : #include "nsIContent.h"
35 : #include "nsIIDNService.h"
36 : #include "nsIScriptGlobalObject.h"
37 : #include "nsIScriptContext.h"
38 : #include "nsDOMJSUtils.h"
39 : #include "nsIPrincipal.h"
40 : #include "nsWildCard.h"
41 : #include "nsContentUtils.h"
42 : #include "mozilla/dom/ScriptSettings.h"
43 : #include "nsIXULRuntime.h"
44 : #include "nsIXPConnect.h"
45 :
46 : #include "nsIObserverService.h"
47 : #include <prinrval.h>
48 :
49 : #ifdef MOZ_WIDGET_COCOA
50 : #include <Carbon/Carbon.h>
51 : #include <ApplicationServices/ApplicationServices.h>
52 : #include <OpenGL/OpenGL.h>
53 : #include "nsCocoaFeatures.h"
54 : #include "PluginUtilsOSX.h"
55 : #endif
56 :
57 : // needed for nppdf plugin
58 : #if (MOZ_WIDGET_GTK)
59 : #include <gdk/gdk.h>
60 : #include <gdk/gdkx.h>
61 : #if (MOZ_WIDGET_GTK == 2)
62 : #include "gtk2xtbin.h"
63 : #endif
64 : #endif
65 :
66 : #include "nsJSUtils.h"
67 : #include "nsJSNPRuntime.h"
68 : #include "nsIHttpAuthManager.h"
69 : #include "nsICookieService.h"
70 : #include "nsILoadContext.h"
71 : #include "nsIDocShell.h"
72 :
73 : #include "nsNetUtil.h"
74 : #include "nsNetCID.h"
75 :
76 : #include "mozilla/Mutex.h"
77 : #include "mozilla/PluginLibrary.h"
78 : using mozilla::PluginLibrary;
79 :
80 : #include "mozilla/PluginPRLibrary.h"
81 : using mozilla::PluginPRLibrary;
82 :
83 : #include "mozilla/plugins/PluginModuleParent.h"
84 : using mozilla::plugins::PluginModuleChromeParent;
85 : using mozilla::plugins::PluginModuleContentParent;
86 :
87 : #ifdef MOZ_X11
88 : #include "mozilla/X11Util.h"
89 : #endif
90 :
91 : #ifdef XP_WIN
92 : #include <windows.h>
93 : #include "mozilla/WindowsVersion.h"
94 : #ifdef ACCESSIBILITY
95 : #include "mozilla/a11y/Compatibility.h"
96 : #endif
97 : #endif
98 :
99 : #ifdef MOZ_WIDGET_ANDROID
100 : #include <android/log.h>
101 : #include "android_npapi.h"
102 : #include "ANPBase.h"
103 : #include "FennecJNIWrappers.h"
104 : #include "GeneratedJNIWrappers.h"
105 : #undef LOG
106 : #define LOG(args...) __android_log_print(ANDROID_LOG_INFO, "GeckoPlugins" , ## args)
107 : #endif
108 :
109 : #include "nsIAudioChannelAgent.h"
110 : #include "AudioChannelService.h"
111 :
112 : using namespace mozilla;
113 : using namespace mozilla::plugins::parent;
114 :
115 : // We should make this const...
116 : static NPNetscapeFuncs sBrowserFuncs = {
117 : sizeof(sBrowserFuncs),
118 : (NP_VERSION_MAJOR << 8) + NP_VERSION_MINOR,
119 : _geturl,
120 : _posturl,
121 : _requestread,
122 : nullptr,
123 : nullptr,
124 : nullptr,
125 : _status,
126 : _useragent,
127 : _memalloc,
128 : _memfree,
129 : _memflush,
130 : _reloadplugins,
131 : _getJavaEnv,
132 : _getJavaPeer,
133 : _geturlnotify,
134 : _posturlnotify,
135 : _getvalue,
136 : _setvalue,
137 : _invalidaterect,
138 : _invalidateregion,
139 : _forceredraw,
140 : _getstringidentifier,
141 : _getstringidentifiers,
142 : _getintidentifier,
143 : _identifierisstring,
144 : _utf8fromidentifier,
145 : _intfromidentifier,
146 : _createobject,
147 : _retainobject,
148 : _releaseobject,
149 : _invoke,
150 : _invokeDefault,
151 : _evaluate,
152 : _getproperty,
153 : _setproperty,
154 : _removeproperty,
155 : _hasproperty,
156 : _hasmethod,
157 : _releasevariantvalue,
158 : _setexception,
159 : _pushpopupsenabledstate,
160 : _poppopupsenabledstate,
161 : _enumerate,
162 : _pluginthreadasynccall,
163 : _construct,
164 : _getvalueforurl,
165 : _setvalueforurl,
166 : nullptr, //NPN GetAuthenticationInfo, not supported
167 : _scheduletimer,
168 : _unscheduletimer,
169 : _popupcontextmenu,
170 : _convertpoint,
171 : nullptr, // handleevent, unimplemented
172 : nullptr, // unfocusinstance, unimplemented
173 : _urlredirectresponse,
174 : _initasyncsurface,
175 : _finalizeasyncsurface,
176 : _setcurrentasyncsurface
177 : };
178 :
179 : static Mutex *sPluginThreadAsyncCallLock = nullptr;
180 : static PRCList sPendingAsyncCalls = PR_INIT_STATIC_CLIST(&sPendingAsyncCalls);
181 :
182 : // POST/GET stream type
183 : enum eNPPStreamTypeInternal {
184 : eNPPStreamTypeInternal_Get,
185 : eNPPStreamTypeInternal_Post
186 : };
187 :
188 0 : void NS_NotifyBeginPluginCall(NSPluginCallReentry aReentryState)
189 : {
190 0 : nsNPAPIPluginInstance::BeginPluginCall(aReentryState);
191 0 : }
192 :
193 0 : void NS_NotifyPluginCall(NSPluginCallReentry aReentryState)
194 : {
195 0 : nsNPAPIPluginInstance::EndPluginCall(aReentryState);
196 0 : }
197 :
198 0 : static void CheckClassInitialized()
199 : {
200 : static bool initialized = false;
201 :
202 0 : if (initialized)
203 0 : return;
204 :
205 0 : if (!sPluginThreadAsyncCallLock)
206 0 : sPluginThreadAsyncCallLock = new Mutex("nsNPAPIPlugin.sPluginThreadAsyncCallLock");
207 :
208 0 : initialized = true;
209 :
210 0 : NPN_PLUGIN_LOG(PLUGIN_LOG_NORMAL,("NPN callbacks initialized\n"));
211 : }
212 :
213 0 : nsNPAPIPlugin::nsNPAPIPlugin()
214 : {
215 0 : memset((void*)&mPluginFuncs, 0, sizeof(mPluginFuncs));
216 0 : mPluginFuncs.size = sizeof(mPluginFuncs);
217 0 : mPluginFuncs.version = (NP_VERSION_MAJOR << 8) | NP_VERSION_MINOR;
218 :
219 0 : mLibrary = nullptr;
220 0 : }
221 :
222 0 : nsNPAPIPlugin::~nsNPAPIPlugin()
223 : {
224 0 : delete mLibrary;
225 0 : mLibrary = nullptr;
226 0 : }
227 :
228 : void
229 0 : nsNPAPIPlugin::PluginCrashed(const nsAString& pluginDumpID,
230 : const nsAString& browserDumpID)
231 : {
232 0 : RefPtr<nsPluginHost> host = nsPluginHost::GetInst();
233 0 : host->PluginCrashed(this, pluginDumpID, browserDumpID);
234 0 : }
235 :
236 : bool
237 0 : nsNPAPIPlugin::RunPluginOOP(const nsPluginTag *aPluginTag)
238 : {
239 : #ifdef MOZ_WIDGET_ANDROID
240 : return false;
241 : #else
242 0 : return true;
243 : #endif
244 : }
245 :
246 : inline PluginLibrary*
247 0 : GetNewPluginLibrary(nsPluginTag *aPluginTag)
248 : {
249 0 : AUTO_PROFILER_LABEL("GetNewPluginLibrary", OTHER);
250 :
251 0 : if (!aPluginTag) {
252 0 : return nullptr;
253 : }
254 :
255 0 : if (XRE_IsContentProcess()) {
256 0 : return PluginModuleContentParent::LoadModule(aPluginTag->mId, aPluginTag);
257 : }
258 :
259 0 : if (nsNPAPIPlugin::RunPluginOOP(aPluginTag)) {
260 0 : return PluginModuleChromeParent::LoadModule(aPluginTag->mFullPath.get(), aPluginTag->mId, aPluginTag);
261 : }
262 0 : return new PluginPRLibrary(aPluginTag->mFullPath.get(), aPluginTag->mLibrary);
263 : }
264 :
265 : // Creates an nsNPAPIPlugin object. One nsNPAPIPlugin object exists per plugin (not instance).
266 : nsresult
267 0 : nsNPAPIPlugin::CreatePlugin(nsPluginTag *aPluginTag, nsNPAPIPlugin** aResult)
268 : {
269 0 : AUTO_PROFILER_LABEL("nsNPAPIPlugin::CreatePlugin", OTHER);
270 0 : *aResult = nullptr;
271 :
272 0 : if (!aPluginTag) {
273 0 : return NS_ERROR_FAILURE;
274 : }
275 :
276 0 : CheckClassInitialized();
277 :
278 0 : RefPtr<nsNPAPIPlugin> plugin = new nsNPAPIPlugin();
279 :
280 0 : PluginLibrary* pluginLib = GetNewPluginLibrary(aPluginTag);
281 0 : if (!pluginLib) {
282 0 : return NS_ERROR_FAILURE;
283 : }
284 :
285 : #if defined(XP_MACOSX) || defined(MOZ_WIDGET_ANDROID)
286 : if (!pluginLib->HasRequiredFunctions()) {
287 : NS_WARNING("Not all necessary functions exposed by plugin, it will not load.");
288 : delete pluginLib;
289 : return NS_ERROR_FAILURE;
290 : }
291 : #endif
292 :
293 0 : plugin->mLibrary = pluginLib;
294 0 : pluginLib->SetPlugin(plugin);
295 :
296 : // Exchange NPAPI entry points.
297 : #if defined(XP_WIN)
298 : // NP_GetEntryPoints must be called before NP_Initialize on Windows.
299 : NPError pluginCallError;
300 : nsresult rv = pluginLib->NP_GetEntryPoints(&plugin->mPluginFuncs, &pluginCallError);
301 : if (rv != NS_OK || pluginCallError != NPERR_NO_ERROR) {
302 : return NS_ERROR_FAILURE;
303 : }
304 :
305 : // NP_Initialize must be called after NP_GetEntryPoints on Windows.
306 : rv = pluginLib->NP_Initialize(&sBrowserFuncs, &pluginCallError);
307 : if (rv != NS_OK || pluginCallError != NPERR_NO_ERROR) {
308 : return NS_ERROR_FAILURE;
309 : }
310 : #elif defined(XP_MACOSX)
311 : // NP_Initialize must be called before NP_GetEntryPoints on Mac OS X.
312 : // We need to match WebKit's behavior.
313 : NPError pluginCallError;
314 : nsresult rv = pluginLib->NP_Initialize(&sBrowserFuncs, &pluginCallError);
315 : if (rv != NS_OK || pluginCallError != NPERR_NO_ERROR) {
316 : return NS_ERROR_FAILURE;
317 : }
318 :
319 : rv = pluginLib->NP_GetEntryPoints(&plugin->mPluginFuncs, &pluginCallError);
320 : if (rv != NS_OK || pluginCallError != NPERR_NO_ERROR) {
321 : return NS_ERROR_FAILURE;
322 : }
323 : #elif defined(MOZ_WIDGET_GONK)
324 : #else
325 : NPError pluginCallError;
326 0 : nsresult rv = pluginLib->NP_Initialize(&sBrowserFuncs, &plugin->mPluginFuncs, &pluginCallError);
327 0 : if (rv != NS_OK || pluginCallError != NPERR_NO_ERROR) {
328 0 : return NS_ERROR_FAILURE;
329 : }
330 : #endif
331 :
332 0 : plugin.forget(aResult);
333 0 : return NS_OK;
334 : }
335 :
336 : PluginLibrary*
337 0 : nsNPAPIPlugin::GetLibrary()
338 : {
339 0 : return mLibrary;
340 : }
341 :
342 : NPPluginFuncs*
343 0 : nsNPAPIPlugin::PluginFuncs()
344 : {
345 0 : return &mPluginFuncs;
346 : }
347 :
348 : nsresult
349 0 : nsNPAPIPlugin::Shutdown()
350 : {
351 0 : NPP_PLUGIN_LOG(PLUGIN_LOG_BASIC,
352 : ("NPP Shutdown to be called: this=%p\n", this));
353 :
354 : NPError shutdownError;
355 0 : mLibrary->NP_Shutdown(&shutdownError);
356 :
357 0 : return NS_OK;
358 : }
359 :
360 : nsresult
361 0 : nsNPAPIPlugin::RetainStream(NPStream *pstream, nsISupports **aRetainedPeer)
362 : {
363 0 : if (!aRetainedPeer)
364 0 : return NS_ERROR_NULL_POINTER;
365 :
366 0 : *aRetainedPeer = nullptr;
367 :
368 0 : if (!pstream || !pstream->ndata)
369 0 : return NS_ERROR_NULL_POINTER;
370 :
371 0 : nsNPAPIStreamWrapper* streamWrapper = static_cast<nsNPAPIStreamWrapper*>(pstream->ndata);
372 0 : nsNPAPIPluginStreamListener* listener = streamWrapper->GetStreamListener();
373 0 : if (!listener) {
374 0 : return NS_ERROR_NULL_POINTER;
375 : }
376 :
377 0 : nsIStreamListener* streamListener = listener->GetStreamListenerPeer();
378 0 : if (!streamListener) {
379 0 : return NS_ERROR_NULL_POINTER;
380 : }
381 :
382 0 : *aRetainedPeer = streamListener;
383 0 : NS_ADDREF(*aRetainedPeer);
384 0 : return NS_OK;
385 : }
386 :
387 : // Create a new NPP GET or POST (given in the type argument) url
388 : // stream that may have a notify callback
389 : NPError
390 0 : MakeNewNPAPIStreamInternal(NPP npp, const char *relativeURL, const char *target,
391 : eNPPStreamTypeInternal type,
392 : bool bDoNotify = false,
393 : void *notifyData = nullptr, uint32_t len = 0,
394 : const char *buf = nullptr)
395 : {
396 0 : if (!npp)
397 0 : return NPERR_INVALID_INSTANCE_ERROR;
398 :
399 0 : PluginDestructionGuard guard(npp);
400 :
401 0 : nsNPAPIPluginInstance *inst = (nsNPAPIPluginInstance *) npp->ndata;
402 0 : if (!inst || !inst->IsRunning())
403 0 : return NPERR_INVALID_INSTANCE_ERROR;
404 :
405 0 : nsCOMPtr<nsIPluginHost> pluginHostCOM = do_GetService(MOZ_PLUGIN_HOST_CONTRACTID);
406 0 : nsPluginHost *pluginHost = static_cast<nsPluginHost*>(pluginHostCOM.get());
407 0 : if (!pluginHost) {
408 0 : return NPERR_GENERIC_ERROR;
409 : }
410 :
411 0 : RefPtr<nsNPAPIPluginStreamListener> listener;
412 : // Set aCallNotify here to false. If pluginHost->GetURL or PostURL fail,
413 : // the listener's destructor will do the notification while we are about to
414 : // return a failure code.
415 : // Call SetCallNotify(true) below after we are sure we cannot return a failure
416 : // code.
417 0 : if (!target) {
418 0 : inst->NewStreamListener(relativeURL, notifyData,
419 0 : getter_AddRefs(listener));
420 0 : if (listener) {
421 0 : listener->SetCallNotify(false);
422 : }
423 : }
424 :
425 0 : switch (type) {
426 : case eNPPStreamTypeInternal_Get:
427 : {
428 0 : if (NS_FAILED(pluginHost->GetURL(inst, relativeURL, target, listener,
429 : nullptr, nullptr, false)))
430 0 : return NPERR_GENERIC_ERROR;
431 0 : break;
432 : }
433 : case eNPPStreamTypeInternal_Post:
434 : {
435 0 : if (NS_FAILED(pluginHost->PostURL(inst, relativeURL, len, buf,
436 : target, listener, nullptr, nullptr,
437 : false, 0, nullptr)))
438 0 : return NPERR_GENERIC_ERROR;
439 0 : break;
440 : }
441 : default:
442 0 : NS_ERROR("how'd I get here");
443 : }
444 :
445 0 : if (listener) {
446 : // SetCallNotify(bDoNotify) here, see comment above.
447 0 : listener->SetCallNotify(bDoNotify);
448 : }
449 :
450 0 : return NPERR_NO_ERROR;
451 : }
452 :
453 : #if defined(MOZ_MEMORY_WINDOWS)
454 : extern "C" size_t malloc_usable_size(const void *ptr);
455 : #endif
456 :
457 : namespace {
458 :
459 : static char *gNPPException;
460 :
461 : class nsPluginThreadRunnable : public Runnable,
462 : public PRCList
463 : {
464 : public:
465 : nsPluginThreadRunnable(NPP instance, PluginThreadCallback func,
466 : void *userData);
467 : ~nsPluginThreadRunnable() override;
468 :
469 : NS_IMETHOD Run() override;
470 :
471 0 : bool IsForInstance(NPP instance)
472 : {
473 0 : return (mInstance == instance);
474 : }
475 :
476 0 : void Invalidate()
477 : {
478 0 : mFunc = nullptr;
479 0 : }
480 :
481 0 : bool IsValid()
482 : {
483 0 : return (mFunc != nullptr);
484 : }
485 :
486 : private:
487 : NPP mInstance;
488 : PluginThreadCallback mFunc;
489 : void *mUserData;
490 : };
491 :
492 : static nsIDocument *
493 0 : GetDocumentFromNPP(NPP npp)
494 : {
495 0 : NS_ENSURE_TRUE(npp, nullptr);
496 :
497 0 : nsNPAPIPluginInstance *inst = (nsNPAPIPluginInstance *)npp->ndata;
498 0 : NS_ENSURE_TRUE(inst, nullptr);
499 :
500 0 : PluginDestructionGuard guard(inst);
501 :
502 0 : RefPtr<nsPluginInstanceOwner> owner = inst->GetOwner();
503 0 : NS_ENSURE_TRUE(owner, nullptr);
504 :
505 0 : nsCOMPtr<nsIDocument> doc;
506 0 : owner->GetDocument(getter_AddRefs(doc));
507 :
508 0 : return doc;
509 : }
510 :
511 : static NPIdentifier
512 0 : doGetIdentifier(JSContext *cx, const NPUTF8* name)
513 : {
514 0 : NS_ConvertUTF8toUTF16 utf16name(name);
515 :
516 0 : JSString *str = ::JS_AtomizeAndPinUCStringN(cx, utf16name.get(), utf16name.Length());
517 :
518 0 : if (!str)
519 0 : return nullptr;
520 :
521 0 : return StringToNPIdentifier(cx, str);
522 : }
523 :
524 : #if defined(MOZ_MEMORY_WINDOWS)
525 : BOOL
526 : InHeap(HANDLE hHeap, LPVOID lpMem)
527 : {
528 : BOOL success = FALSE;
529 : PROCESS_HEAP_ENTRY he;
530 : he.lpData = nullptr;
531 : while (HeapWalk(hHeap, &he) != 0) {
532 : if (he.lpData == lpMem) {
533 : success = TRUE;
534 : break;
535 : }
536 : }
537 : HeapUnlock(hHeap);
538 : return success;
539 : }
540 : #endif
541 :
542 : } /* anonymous namespace */
543 :
544 0 : NPPExceptionAutoHolder::NPPExceptionAutoHolder()
545 0 : : mOldException(gNPPException)
546 : {
547 0 : gNPPException = nullptr;
548 0 : }
549 :
550 0 : NPPExceptionAutoHolder::~NPPExceptionAutoHolder()
551 : {
552 0 : NS_ASSERTION(!gNPPException, "NPP exception not properly cleared!");
553 :
554 0 : gNPPException = mOldException;
555 0 : }
556 :
557 0 : nsPluginThreadRunnable::nsPluginThreadRunnable(NPP instance,
558 : PluginThreadCallback func,
559 0 : void *userData)
560 : : Runnable("nsPluginThreadRunnable"),
561 : mInstance(instance),
562 : mFunc(func),
563 0 : mUserData(userData)
564 : {
565 0 : if (!sPluginThreadAsyncCallLock) {
566 : // Failed to create lock, not much we can do here then...
567 0 : mFunc = nullptr;
568 :
569 0 : return;
570 : }
571 :
572 0 : PR_INIT_CLIST(this);
573 :
574 : {
575 0 : MutexAutoLock lock(*sPluginThreadAsyncCallLock);
576 :
577 0 : nsNPAPIPluginInstance *inst = (nsNPAPIPluginInstance *)instance->ndata;
578 0 : if (!inst || !inst->IsRunning()) {
579 : // The plugin was stopped, ignore this async call.
580 0 : mFunc = nullptr;
581 :
582 0 : return;
583 : }
584 :
585 0 : PR_APPEND_LINK(this, &sPendingAsyncCalls);
586 : }
587 : }
588 :
589 0 : nsPluginThreadRunnable::~nsPluginThreadRunnable()
590 : {
591 0 : if (!sPluginThreadAsyncCallLock) {
592 0 : return;
593 : }
594 :
595 : {
596 0 : MutexAutoLock lock(*sPluginThreadAsyncCallLock);
597 :
598 0 : PR_REMOVE_LINK(this);
599 : }
600 0 : }
601 :
602 : NS_IMETHODIMP
603 0 : nsPluginThreadRunnable::Run()
604 : {
605 0 : if (mFunc) {
606 0 : PluginDestructionGuard guard(mInstance);
607 :
608 0 : NS_TRY_SAFE_CALL_VOID(mFunc(mUserData), nullptr,
609 : NS_PLUGIN_CALL_SAFE_TO_REENTER_GECKO);
610 : }
611 :
612 0 : return NS_OK;
613 : }
614 :
615 : void
616 0 : OnPluginDestroy(NPP instance)
617 : {
618 0 : if (!sPluginThreadAsyncCallLock) {
619 0 : return;
620 : }
621 :
622 : {
623 0 : MutexAutoLock lock(*sPluginThreadAsyncCallLock);
624 :
625 0 : if (PR_CLIST_IS_EMPTY(&sPendingAsyncCalls)) {
626 0 : return;
627 : }
628 :
629 : nsPluginThreadRunnable *r =
630 0 : (nsPluginThreadRunnable *)PR_LIST_HEAD(&sPendingAsyncCalls);
631 :
632 0 : do {
633 0 : if (r->IsForInstance(instance)) {
634 0 : r->Invalidate();
635 : }
636 :
637 0 : r = (nsPluginThreadRunnable *)PR_NEXT_LINK(r);
638 0 : } while (r != &sPendingAsyncCalls);
639 : }
640 : }
641 :
642 : void
643 0 : OnShutdown()
644 : {
645 0 : NS_ASSERTION(PR_CLIST_IS_EMPTY(&sPendingAsyncCalls),
646 : "Pending async plugin call list not cleaned up!");
647 :
648 0 : if (sPluginThreadAsyncCallLock) {
649 0 : delete sPluginThreadAsyncCallLock;
650 :
651 0 : sPluginThreadAsyncCallLock = nullptr;
652 : }
653 0 : }
654 :
655 0 : AsyncCallbackAutoLock::AsyncCallbackAutoLock()
656 : {
657 0 : if (sPluginThreadAsyncCallLock) {
658 0 : sPluginThreadAsyncCallLock->Lock();
659 : }
660 0 : }
661 :
662 0 : AsyncCallbackAutoLock::~AsyncCallbackAutoLock()
663 : {
664 0 : if (sPluginThreadAsyncCallLock) {
665 0 : sPluginThreadAsyncCallLock->Unlock();
666 : }
667 0 : }
668 :
669 : NPP NPPStack::sCurrentNPP = nullptr;
670 :
671 : const char *
672 0 : PeekException()
673 : {
674 0 : return gNPPException;
675 : }
676 :
677 : void
678 0 : PopException()
679 : {
680 0 : NS_ASSERTION(gNPPException, "Uh, no NPP exception to pop!");
681 :
682 0 : if (gNPPException) {
683 0 : free(gNPPException);
684 :
685 0 : gNPPException = nullptr;
686 : }
687 0 : }
688 :
689 : //
690 : // Static callbacks that get routed back through the new C++ API
691 : //
692 :
693 : namespace mozilla {
694 : namespace plugins {
695 : namespace parent {
696 :
697 : NPError
698 0 : _geturl(NPP npp, const char* relativeURL, const char* target)
699 : {
700 0 : if (!NS_IsMainThread()) {
701 0 : NPN_PLUGIN_LOG(PLUGIN_LOG_ALWAYS,("NPN_geturl called from the wrong thread\n"));
702 0 : return NPERR_INVALID_PARAM;
703 : }
704 :
705 0 : NPN_PLUGIN_LOG(PLUGIN_LOG_NORMAL,
706 : ("NPN_GetURL: npp=%p, target=%s, url=%s\n", (void *)npp, target,
707 : relativeURL));
708 :
709 0 : PluginDestructionGuard guard(npp);
710 :
711 : return MakeNewNPAPIStreamInternal(npp, relativeURL, target,
712 0 : eNPPStreamTypeInternal_Get);
713 : }
714 :
715 : NPError
716 0 : _geturlnotify(NPP npp, const char* relativeURL, const char* target,
717 : void* notifyData)
718 : {
719 0 : if (!NS_IsMainThread()) {
720 0 : NPN_PLUGIN_LOG(PLUGIN_LOG_ALWAYS,("NPN_geturlnotify called from the wrong thread\n"));
721 0 : return NPERR_INVALID_PARAM;
722 : }
723 :
724 0 : NPN_PLUGIN_LOG(PLUGIN_LOG_NORMAL,
725 : ("NPN_GetURLNotify: npp=%p, target=%s, notify=%p, url=%s\n", (void*)npp,
726 : target, notifyData, relativeURL));
727 :
728 0 : PluginDestructionGuard guard(npp);
729 :
730 : return MakeNewNPAPIStreamInternal(npp, relativeURL, target,
731 : eNPPStreamTypeInternal_Get, true,
732 0 : notifyData);
733 : }
734 :
735 : NPError
736 0 : _posturlnotify(NPP npp, const char *relativeURL, const char *target,
737 : uint32_t len, const char *buf, NPBool file, void *notifyData)
738 : {
739 0 : if (!NS_IsMainThread()) {
740 0 : NPN_PLUGIN_LOG(PLUGIN_LOG_ALWAYS,("NPN_posturlnotify called from the wrong thread\n"));
741 0 : return NPERR_INVALID_PARAM;
742 : }
743 0 : if (!buf)
744 0 : return NPERR_INVALID_PARAM;
745 :
746 0 : NPN_PLUGIN_LOG(PLUGIN_LOG_NORMAL,
747 : ("NPN_PostURLNotify: npp=%p, target=%s, len=%d, file=%d, "
748 : "notify=%p, url=%s, buf=%s\n",
749 : (void*)npp, target, len, file, notifyData, relativeURL,
750 : buf));
751 :
752 0 : PluginDestructionGuard guard(npp);
753 :
754 : return MakeNewNPAPIStreamInternal(npp, relativeURL, target,
755 : eNPPStreamTypeInternal_Post, true,
756 0 : notifyData, len, buf);
757 : }
758 :
759 : NPError
760 0 : _posturl(NPP npp, const char *relativeURL, const char *target,
761 : uint32_t len, const char *buf, NPBool file)
762 : {
763 0 : if (!NS_IsMainThread()) {
764 0 : NPN_PLUGIN_LOG(PLUGIN_LOG_ALWAYS,("NPN_posturl called from the wrong thread\n"));
765 0 : return NPERR_INVALID_PARAM;
766 : }
767 0 : NPN_PLUGIN_LOG(PLUGIN_LOG_NORMAL,
768 : ("NPN_PostURL: npp=%p, target=%s, file=%d, len=%d, url=%s, "
769 : "buf=%s\n",
770 : (void*)npp, target, file, len, relativeURL, buf));
771 :
772 0 : PluginDestructionGuard guard(npp);
773 :
774 : return MakeNewNPAPIStreamInternal(npp, relativeURL, target,
775 : eNPPStreamTypeInternal_Post, false, nullptr,
776 0 : len, buf);
777 : }
778 :
779 : void
780 0 : _status(NPP npp, const char *message)
781 : {
782 : // NPN_Status is no longer supported.
783 0 : }
784 :
785 : void
786 0 : _memfree (void *ptr)
787 : {
788 0 : if (!NS_IsMainThread()) {
789 0 : NPN_PLUGIN_LOG(PLUGIN_LOG_ALWAYS,("NPN_memfree called from the wrong thread\n"));
790 : }
791 0 : NPN_PLUGIN_LOG(PLUGIN_LOG_NOISY, ("NPN_MemFree: ptr=%p\n", ptr));
792 :
793 0 : if (ptr)
794 0 : free(ptr);
795 0 : }
796 :
797 : uint32_t
798 0 : _memflush(uint32_t size)
799 : {
800 0 : if (!NS_IsMainThread()) {
801 0 : NPN_PLUGIN_LOG(PLUGIN_LOG_ALWAYS,("NPN_memflush called from the wrong thread\n"));
802 : }
803 0 : NPN_PLUGIN_LOG(PLUGIN_LOG_NOISY, ("NPN_MemFlush: size=%d\n", size));
804 :
805 0 : nsMemory::HeapMinimize(true);
806 0 : return 0;
807 : }
808 :
809 : void
810 0 : _reloadplugins(NPBool reloadPages)
811 : {
812 0 : if (!NS_IsMainThread()) {
813 0 : NPN_PLUGIN_LOG(PLUGIN_LOG_ALWAYS,("NPN_reloadplugins called from the wrong thread\n"));
814 0 : return;
815 : }
816 0 : NPN_PLUGIN_LOG(PLUGIN_LOG_NORMAL,
817 : ("NPN_ReloadPlugins: reloadPages=%d\n", reloadPages));
818 :
819 0 : nsCOMPtr<nsIPluginHost> pluginHost(do_GetService(MOZ_PLUGIN_HOST_CONTRACTID));
820 0 : if (!pluginHost)
821 0 : return;
822 :
823 0 : pluginHost->ReloadPlugins();
824 : }
825 :
826 : void
827 0 : _invalidaterect(NPP npp, NPRect *invalidRect)
828 : {
829 0 : if (!NS_IsMainThread()) {
830 0 : NPN_PLUGIN_LOG(PLUGIN_LOG_ALWAYS,("NPN_invalidaterect called from the wrong thread\n"));
831 0 : return;
832 : }
833 0 : NPN_PLUGIN_LOG(PLUGIN_LOG_NORMAL,
834 : ("NPN_InvalidateRect: npp=%p, top=%d, left=%d, bottom=%d, "
835 : "right=%d\n", (void *)npp, invalidRect->top,
836 : invalidRect->left, invalidRect->bottom, invalidRect->right));
837 :
838 0 : if (!npp || !npp->ndata) {
839 0 : NS_WARNING("_invalidaterect: npp or npp->ndata == 0");
840 0 : return;
841 : }
842 :
843 0 : nsNPAPIPluginInstance *inst = (nsNPAPIPluginInstance*)npp->ndata;
844 :
845 0 : PluginDestructionGuard guard(inst);
846 :
847 0 : inst->InvalidateRect((NPRect *)invalidRect);
848 : }
849 :
850 : void
851 0 : _invalidateregion(NPP npp, NPRegion invalidRegion)
852 : {
853 0 : if (!NS_IsMainThread()) {
854 0 : NPN_PLUGIN_LOG(PLUGIN_LOG_ALWAYS,("NPN_invalidateregion called from the wrong thread\n"));
855 0 : return;
856 : }
857 0 : NPN_PLUGIN_LOG(PLUGIN_LOG_NORMAL,
858 : ("NPN_InvalidateRegion: npp=%p, region=%p\n", (void*)npp,
859 : (void*)invalidRegion));
860 :
861 0 : if (!npp || !npp->ndata) {
862 0 : NS_WARNING("_invalidateregion: npp or npp->ndata == 0");
863 0 : return;
864 : }
865 :
866 0 : nsNPAPIPluginInstance *inst = (nsNPAPIPluginInstance*)npp->ndata;
867 :
868 0 : PluginDestructionGuard guard(inst);
869 :
870 0 : inst->InvalidateRegion((NPRegion)invalidRegion);
871 : }
872 :
873 : void
874 0 : _forceredraw(NPP npp)
875 : {
876 0 : }
877 :
878 : NPObject*
879 0 : _getwindowobject(NPP npp)
880 : {
881 0 : if (!NS_IsMainThread()) {
882 0 : NPN_PLUGIN_LOG(PLUGIN_LOG_ALWAYS,("NPN_getwindowobject called from the wrong thread\n"));
883 0 : return nullptr;
884 : }
885 :
886 : // The window want to return here is the outer window, *not* the inner (since
887 : // we don't know what the plugin will do with it).
888 0 : nsIDocument* doc = GetDocumentFromNPP(npp);
889 0 : NS_ENSURE_TRUE(doc, nullptr);
890 0 : nsCOMPtr<nsPIDOMWindowOuter> outer = doc->GetWindow();
891 0 : NS_ENSURE_TRUE(outer, nullptr);
892 :
893 0 : JS::Rooted<JSObject*> global(dom::RootingCx(),
894 0 : nsGlobalWindow::Cast(outer)->GetGlobalJSObject());
895 0 : return nsJSObjWrapper::GetNewOrUsed(npp, global);
896 : }
897 :
898 : NPObject*
899 0 : _getpluginelement(NPP npp)
900 : {
901 0 : if (!NS_IsMainThread()) {
902 0 : NPN_PLUGIN_LOG(PLUGIN_LOG_ALWAYS,("NPN_getpluginelement called from the wrong thread\n"));
903 0 : return nullptr;
904 : }
905 :
906 0 : nsNPAPIPluginInstance* inst = static_cast<nsNPAPIPluginInstance*>(npp->ndata);
907 0 : if (!inst)
908 0 : return nullptr;
909 :
910 0 : nsCOMPtr<nsIDOMElement> element;
911 0 : inst->GetDOMElement(getter_AddRefs(element));
912 :
913 0 : if (!element)
914 0 : return nullptr;
915 :
916 0 : nsIDocument *doc = GetDocumentFromNPP(npp);
917 0 : if (NS_WARN_IF(!doc)) {
918 0 : return nullptr;
919 : }
920 :
921 0 : dom::AutoJSAPI jsapi;
922 0 : if (NS_WARN_IF(!jsapi.Init(doc->GetInnerWindow()))) {
923 0 : return nullptr;
924 : }
925 0 : JSContext* cx = jsapi.cx();
926 :
927 0 : nsCOMPtr<nsIXPConnect> xpc(do_GetService(nsIXPConnect::GetCID()));
928 0 : NS_ENSURE_TRUE(xpc, nullptr);
929 :
930 0 : JS::RootedObject obj(cx);
931 0 : xpc->WrapNative(cx, ::JS::CurrentGlobalOrNull(cx), element,
932 0 : NS_GET_IID(nsIDOMElement), obj.address());
933 0 : NS_ENSURE_TRUE(obj, nullptr);
934 :
935 0 : return nsJSObjWrapper::GetNewOrUsed(npp, obj);
936 : }
937 :
938 : NPIdentifier
939 0 : _getstringidentifier(const NPUTF8* name)
940 : {
941 0 : if (!name) {
942 0 : NPN_PLUGIN_LOG(PLUGIN_LOG_ALWAYS, ("NPN_getstringidentifier: passed null name"));
943 0 : return nullptr;
944 : }
945 0 : if (!NS_IsMainThread()) {
946 0 : NPN_PLUGIN_LOG(PLUGIN_LOG_ALWAYS,("NPN_getstringidentifier called from the wrong thread\n"));
947 : }
948 :
949 0 : AutoSafeJSContext cx;
950 0 : return doGetIdentifier(cx, name);
951 : }
952 :
953 : void
954 0 : _getstringidentifiers(const NPUTF8** names, int32_t nameCount,
955 : NPIdentifier *identifiers)
956 : {
957 0 : if (!NS_IsMainThread()) {
958 0 : NPN_PLUGIN_LOG(PLUGIN_LOG_ALWAYS,("NPN_getstringidentifiers called from the wrong thread\n"));
959 : }
960 :
961 0 : AutoSafeJSContext cx;
962 :
963 0 : for (int32_t i = 0; i < nameCount; ++i) {
964 0 : if (names[i]) {
965 0 : identifiers[i] = doGetIdentifier(cx, names[i]);
966 : } else {
967 0 : NPN_PLUGIN_LOG(PLUGIN_LOG_ALWAYS, ("NPN_getstringidentifiers: passed null name"));
968 0 : identifiers[i] = nullptr;
969 : }
970 : }
971 0 : }
972 :
973 : NPIdentifier
974 0 : _getintidentifier(int32_t intid)
975 : {
976 0 : if (!NS_IsMainThread()) {
977 0 : NPN_PLUGIN_LOG(PLUGIN_LOG_ALWAYS,("NPN_getstringidentifier called from the wrong thread\n"));
978 : }
979 0 : return IntToNPIdentifier(intid);
980 : }
981 :
982 : NPUTF8*
983 0 : _utf8fromidentifier(NPIdentifier id)
984 : {
985 0 : if (!NS_IsMainThread()) {
986 0 : NPN_PLUGIN_LOG(PLUGIN_LOG_ALWAYS,("NPN_utf8fromidentifier called from the wrong thread\n"));
987 : }
988 0 : if (!id)
989 0 : return nullptr;
990 :
991 0 : if (!NPIdentifierIsString(id)) {
992 0 : return nullptr;
993 : }
994 :
995 0 : JSString *str = NPIdentifierToString(id);
996 0 : nsAutoString autoStr;
997 0 : AssignJSFlatString(autoStr, JS_ASSERT_STRING_IS_FLAT(str));
998 :
999 0 : return ToNewUTF8String(autoStr);
1000 : }
1001 :
1002 : int32_t
1003 0 : _intfromidentifier(NPIdentifier id)
1004 : {
1005 0 : if (!NS_IsMainThread()) {
1006 0 : NPN_PLUGIN_LOG(PLUGIN_LOG_ALWAYS,("NPN_intfromidentifier called from the wrong thread\n"));
1007 : }
1008 :
1009 0 : if (!NPIdentifierIsInt(id)) {
1010 0 : return INT32_MIN;
1011 : }
1012 :
1013 0 : return NPIdentifierToInt(id);
1014 : }
1015 :
1016 : bool
1017 0 : _identifierisstring(NPIdentifier id)
1018 : {
1019 0 : if (!NS_IsMainThread()) {
1020 0 : NPN_PLUGIN_LOG(PLUGIN_LOG_ALWAYS,("NPN_identifierisstring called from the wrong thread\n"));
1021 : }
1022 :
1023 0 : return NPIdentifierIsString(id);
1024 : }
1025 :
1026 : NPObject*
1027 0 : _createobject(NPP npp, NPClass* aClass)
1028 : {
1029 0 : if (!NS_IsMainThread()) {
1030 0 : NPN_PLUGIN_LOG(PLUGIN_LOG_ALWAYS,("NPN_createobject called from the wrong thread\n"));
1031 0 : return nullptr;
1032 : }
1033 0 : if (!npp) {
1034 0 : NS_ERROR("Null npp passed to _createobject()!");
1035 :
1036 0 : return nullptr;
1037 : }
1038 :
1039 0 : PluginDestructionGuard guard(npp);
1040 :
1041 0 : if (!aClass) {
1042 0 : NS_ERROR("Null class passed to _createobject()!");
1043 :
1044 0 : return nullptr;
1045 : }
1046 :
1047 0 : NPPAutoPusher nppPusher(npp);
1048 :
1049 : NPObject *npobj;
1050 :
1051 0 : if (aClass->allocate) {
1052 0 : npobj = aClass->allocate(npp, aClass);
1053 : } else {
1054 0 : npobj = (NPObject*) malloc(sizeof(NPObject));
1055 : }
1056 :
1057 0 : if (npobj) {
1058 0 : npobj->_class = aClass;
1059 0 : npobj->referenceCount = 1;
1060 0 : NS_LOG_ADDREF(npobj, 1, "BrowserNPObject", sizeof(NPObject));
1061 : }
1062 :
1063 0 : NPN_PLUGIN_LOG(PLUGIN_LOG_NOISY,
1064 : ("Created NPObject %p, NPClass %p\n", npobj, aClass));
1065 :
1066 0 : return npobj;
1067 : }
1068 :
1069 : NPObject*
1070 0 : _retainobject(NPObject* npobj)
1071 : {
1072 0 : if (!NS_IsMainThread()) {
1073 0 : NPN_PLUGIN_LOG(PLUGIN_LOG_ALWAYS,("NPN_retainobject called from the wrong thread\n"));
1074 : }
1075 0 : if (npobj) {
1076 : #ifdef NS_BUILD_REFCNT_LOGGING
1077 : int32_t refCnt =
1078 : #endif
1079 0 : PR_ATOMIC_INCREMENT((int32_t*)&npobj->referenceCount);
1080 0 : NS_LOG_ADDREF(npobj, refCnt, "BrowserNPObject", sizeof(NPObject));
1081 : }
1082 :
1083 0 : return npobj;
1084 : }
1085 :
1086 : void
1087 0 : _releaseobject(NPObject* npobj)
1088 : {
1089 : // If nothing is passed, just return, even if we're on the wrong thread.
1090 0 : if (!npobj) {
1091 0 : return;
1092 : }
1093 :
1094 : // THIS IS A KNOWN LEAK. SEE BUG 1221448.
1095 : // If releaseobject is called off the main thread and we have a valid pointer,
1096 : // we at least know it was created on the main thread (see _createobject
1097 : // implementation). However, forwarding the deletion back to the main thread
1098 : // without careful checking could cause bad memory management races. So, for
1099 : // now, we leak by warning and then just returning early. But it should fix
1100 : // java 7 crashes.
1101 0 : if (!NS_IsMainThread()) {
1102 0 : NPN_PLUGIN_LOG(PLUGIN_LOG_ALWAYS,("NPN_releaseobject called from the wrong thread\n"));
1103 0 : return;
1104 : }
1105 :
1106 0 : int32_t refCnt = PR_ATOMIC_DECREMENT((int32_t*)&npobj->referenceCount);
1107 0 : NS_LOG_RELEASE(npobj, refCnt, "BrowserNPObject");
1108 :
1109 0 : if (refCnt == 0) {
1110 0 : nsNPObjWrapper::OnDestroy(npobj);
1111 :
1112 0 : NPN_PLUGIN_LOG(PLUGIN_LOG_NOISY,
1113 : ("Deleting NPObject %p, refcount hit 0\n", npobj));
1114 :
1115 0 : if (npobj->_class && npobj->_class->deallocate) {
1116 0 : npobj->_class->deallocate(npobj);
1117 : } else {
1118 0 : free(npobj);
1119 : }
1120 : }
1121 : }
1122 :
1123 : bool
1124 0 : _invoke(NPP npp, NPObject* npobj, NPIdentifier method, const NPVariant *args,
1125 : uint32_t argCount, NPVariant *result)
1126 : {
1127 0 : if (!NS_IsMainThread()) {
1128 0 : NPN_PLUGIN_LOG(PLUGIN_LOG_ALWAYS,("NPN_invoke called from the wrong thread\n"));
1129 0 : return false;
1130 : }
1131 0 : if (!npp || !npobj || !npobj->_class || !npobj->_class->invoke)
1132 0 : return false;
1133 :
1134 0 : PluginDestructionGuard guard(npp);
1135 :
1136 0 : NPPExceptionAutoHolder nppExceptionHolder;
1137 0 : NPPAutoPusher nppPusher(npp);
1138 :
1139 0 : NPN_PLUGIN_LOG(PLUGIN_LOG_NOISY,
1140 : ("NPN_Invoke(npp %p, npobj %p, method %p, args %d\n", npp,
1141 : npobj, method, argCount));
1142 :
1143 0 : return npobj->_class->invoke(npobj, method, args, argCount, result);
1144 : }
1145 :
1146 : bool
1147 0 : _invokeDefault(NPP npp, NPObject* npobj, const NPVariant *args,
1148 : uint32_t argCount, NPVariant *result)
1149 : {
1150 0 : if (!NS_IsMainThread()) {
1151 0 : NPN_PLUGIN_LOG(PLUGIN_LOG_ALWAYS,("NPN_invokedefault called from the wrong thread\n"));
1152 0 : return false;
1153 : }
1154 0 : if (!npp || !npobj || !npobj->_class || !npobj->_class->invokeDefault)
1155 0 : return false;
1156 :
1157 0 : NPPExceptionAutoHolder nppExceptionHolder;
1158 0 : NPPAutoPusher nppPusher(npp);
1159 :
1160 0 : NPN_PLUGIN_LOG(PLUGIN_LOG_NOISY,
1161 : ("NPN_InvokeDefault(npp %p, npobj %p, args %d\n", npp,
1162 : npobj, argCount));
1163 :
1164 0 : return npobj->_class->invokeDefault(npobj, args, argCount, result);
1165 : }
1166 :
1167 : bool
1168 0 : _evaluate(NPP npp, NPObject* npobj, NPString *script, NPVariant *result)
1169 : {
1170 0 : if (!NS_IsMainThread()) {
1171 0 : NPN_PLUGIN_LOG(PLUGIN_LOG_ALWAYS,("NPN_evaluate called from the wrong thread\n"));
1172 0 : return false;
1173 : }
1174 0 : if (!npp)
1175 0 : return false;
1176 :
1177 0 : NPPAutoPusher nppPusher(npp);
1178 :
1179 0 : nsIDocument *doc = GetDocumentFromNPP(npp);
1180 0 : NS_ENSURE_TRUE(doc, false);
1181 :
1182 0 : nsGlobalWindow* win = nsGlobalWindow::Cast(doc->GetInnerWindow());
1183 0 : if (NS_WARN_IF(!win || !win->FastGetGlobalJSObject())) {
1184 0 : return false;
1185 : }
1186 :
1187 0 : nsAutoMicroTask mt;
1188 0 : dom::AutoEntryScript aes(win, "NPAPI NPN_evaluate");
1189 0 : JSContext* cx = aes.cx();
1190 :
1191 0 : JS::Rooted<JSObject*> obj(cx, nsNPObjWrapper::GetNewOrUsed(npp, cx, npobj));
1192 :
1193 0 : if (!obj) {
1194 0 : return false;
1195 : }
1196 :
1197 0 : obj = js::ToWindowIfWindowProxy(obj);
1198 0 : MOZ_ASSERT(obj, "ToWindowIfWindowProxy should never return null");
1199 :
1200 0 : if (result) {
1201 : // Initialize the out param to void
1202 0 : VOID_TO_NPVARIANT(*result);
1203 : }
1204 :
1205 0 : if (!script || !script->UTF8Length || !script->UTF8Characters) {
1206 : // Nothing to evaluate.
1207 :
1208 0 : return true;
1209 : }
1210 :
1211 : NS_ConvertUTF8toUTF16 utf16script(script->UTF8Characters,
1212 0 : script->UTF8Length);
1213 :
1214 0 : nsIPrincipal *principal = doc->NodePrincipal();
1215 :
1216 0 : nsAutoCString specStr;
1217 : const char *spec;
1218 :
1219 0 : nsCOMPtr<nsIURI> uri;
1220 0 : principal->GetURI(getter_AddRefs(uri));
1221 :
1222 0 : if (uri) {
1223 0 : uri->GetSpec(specStr);
1224 0 : spec = specStr.get();
1225 : } else {
1226 : // No URI in a principal means it's the system principal. If the
1227 : // document URI is a chrome:// URI, pass that in as the URI of the
1228 : // script, else pass in null for the filename as there's no way to
1229 : // know where this document really came from. Passing in null here
1230 : // also means that the script gets treated by XPConnect as if it
1231 : // needs additional protection, which is what we want for unknown
1232 : // chrome code anyways.
1233 :
1234 0 : uri = doc->GetDocumentURI();
1235 0 : bool isChrome = false;
1236 :
1237 0 : if (uri && NS_SUCCEEDED(uri->SchemeIs("chrome", &isChrome)) && isChrome) {
1238 0 : uri->GetSpec(specStr);
1239 0 : spec = specStr.get();
1240 : } else {
1241 0 : spec = nullptr;
1242 : }
1243 : }
1244 :
1245 0 : NPN_PLUGIN_LOG(PLUGIN_LOG_NOISY,
1246 : ("NPN_Evaluate(npp %p, npobj %p, script <<<%s>>>) called\n",
1247 : npp, npobj, script->UTF8Characters));
1248 :
1249 0 : JS::CompileOptions options(cx);
1250 0 : options.setFileAndLine(spec, 0)
1251 0 : .setVersion(JSVERSION_DEFAULT);
1252 0 : JS::Rooted<JS::Value> rval(cx);
1253 0 : JS::AutoObjectVector scopeChain(cx);
1254 0 : if (obj != js::GetGlobalForObjectCrossCompartment(obj) &&
1255 0 : !scopeChain.append(obj)) {
1256 0 : return false;
1257 : }
1258 0 : obj = js::GetGlobalForObjectCrossCompartment(obj);
1259 0 : nsresult rv = NS_OK;
1260 : {
1261 0 : nsJSUtils::ExecutionContext exec(cx, obj);
1262 0 : exec.SetScopeChain(scopeChain);
1263 0 : exec.CompileAndExec(options, utf16script);
1264 0 : rv = exec.ExtractReturnValue(&rval);
1265 : }
1266 :
1267 0 : if (!JS_WrapValue(cx, &rval)) {
1268 0 : return false;
1269 : }
1270 :
1271 0 : return NS_SUCCEEDED(rv) &&
1272 0 : (!result || JSValToNPVariant(npp, cx, rval, result));
1273 : }
1274 :
1275 : bool
1276 0 : _getproperty(NPP npp, NPObject* npobj, NPIdentifier property,
1277 : NPVariant *result)
1278 : {
1279 0 : if (!NS_IsMainThread()) {
1280 0 : NPN_PLUGIN_LOG(PLUGIN_LOG_ALWAYS,("NPN_getproperty called from the wrong thread\n"));
1281 0 : return false;
1282 : }
1283 0 : if (!npp || !npobj || !npobj->_class || !npobj->_class->getProperty)
1284 0 : return false;
1285 :
1286 0 : NPPExceptionAutoHolder nppExceptionHolder;
1287 0 : NPPAutoPusher nppPusher(npp);
1288 :
1289 0 : NPN_PLUGIN_LOG(PLUGIN_LOG_NOISY,
1290 : ("NPN_GetProperty(npp %p, npobj %p, property %p) called\n",
1291 : npp, npobj, property));
1292 :
1293 0 : if (!npobj->_class->getProperty(npobj, property, result))
1294 0 : return false;
1295 :
1296 : // If a Java plugin tries to get the document.URL or document.documentURI
1297 : // property from us, don't pass back a value that Java won't be able to
1298 : // understand -- one that will make the URL(String) constructor throw a
1299 : // MalformedURL exception. Passing such a value causes Java Plugin2 to
1300 : // crash (to throw a RuntimeException in Plugin2Manager.getDocumentBase()).
1301 : // Also don't pass back a value that Java is likely to mishandle.
1302 :
1303 0 : nsNPAPIPluginInstance* inst = (nsNPAPIPluginInstance*) npp->ndata;
1304 0 : if (!inst)
1305 0 : return false;
1306 0 : nsNPAPIPlugin* plugin = inst->GetPlugin();
1307 0 : if (!plugin)
1308 0 : return false;
1309 0 : RefPtr<nsPluginHost> host = nsPluginHost::GetInst();
1310 0 : nsPluginTag* pluginTag = host->TagForPlugin(plugin);
1311 0 : if (!pluginTag->mIsJavaPlugin)
1312 0 : return true;
1313 :
1314 0 : if (!NPVARIANT_IS_STRING(*result))
1315 0 : return true;
1316 :
1317 0 : NPUTF8* propertyName = _utf8fromidentifier(property);
1318 0 : if (!propertyName)
1319 0 : return true;
1320 : bool notURL =
1321 0 : (PL_strcasecmp(propertyName, "URL") &&
1322 0 : PL_strcasecmp(propertyName, "documentURI"));
1323 0 : _memfree(propertyName);
1324 0 : if (notURL)
1325 0 : return true;
1326 :
1327 0 : NPObject* window_obj = _getwindowobject(npp);
1328 0 : if (!window_obj)
1329 0 : return true;
1330 :
1331 : NPVariant doc_v;
1332 0 : NPObject* document_obj = nullptr;
1333 0 : NPIdentifier doc_id = _getstringidentifier("document");
1334 0 : bool ok = npobj->_class->getProperty(window_obj, doc_id, &doc_v);
1335 0 : _releaseobject(window_obj);
1336 0 : if (ok) {
1337 0 : if (NPVARIANT_IS_OBJECT(doc_v)) {
1338 0 : document_obj = NPVARIANT_TO_OBJECT(doc_v);
1339 : } else {
1340 0 : _releasevariantvalue(&doc_v);
1341 0 : return true;
1342 : }
1343 : } else {
1344 0 : return true;
1345 : }
1346 0 : _releaseobject(document_obj);
1347 0 : if (document_obj != npobj)
1348 0 : return true;
1349 :
1350 0 : NPString urlnp = NPVARIANT_TO_STRING(*result);
1351 0 : nsXPIDLCString url;
1352 0 : url.Assign(urlnp.UTF8Characters, urlnp.UTF8Length);
1353 :
1354 0 : bool javaCompatible = false;
1355 0 : if (NS_FAILED(NS_CheckIsJavaCompatibleURLString(url, &javaCompatible)))
1356 0 : javaCompatible = false;
1357 0 : if (javaCompatible)
1358 0 : return true;
1359 :
1360 : // If Java won't be able to interpret the original value of document.URL or
1361 : // document.documentURI, or is likely to mishandle it, pass back something
1362 : // that Java will understand but won't be able to use to access the network,
1363 : // and for which same-origin checks will always fail.
1364 :
1365 0 : if (inst->mFakeURL.IsVoid()) {
1366 : // Abort (do an error return) if NS_MakeRandomInvalidURLString() fails.
1367 0 : if (NS_FAILED(NS_MakeRandomInvalidURLString(inst->mFakeURL))) {
1368 0 : _releasevariantvalue(result);
1369 0 : return false;
1370 : }
1371 : }
1372 :
1373 0 : _releasevariantvalue(result);
1374 0 : char* fakeurl = (char *) _memalloc(inst->mFakeURL.Length() + 1);
1375 0 : strcpy(fakeurl, inst->mFakeURL);
1376 0 : STRINGZ_TO_NPVARIANT(fakeurl, *result);
1377 :
1378 0 : return true;
1379 : }
1380 :
1381 : bool
1382 0 : _setproperty(NPP npp, NPObject* npobj, NPIdentifier property,
1383 : const NPVariant *value)
1384 : {
1385 0 : if (!NS_IsMainThread()) {
1386 0 : NPN_PLUGIN_LOG(PLUGIN_LOG_ALWAYS,("NPN_setproperty called from the wrong thread\n"));
1387 0 : return false;
1388 : }
1389 0 : if (!npp || !npobj || !npobj->_class || !npobj->_class->setProperty)
1390 0 : return false;
1391 :
1392 0 : NPPExceptionAutoHolder nppExceptionHolder;
1393 0 : NPPAutoPusher nppPusher(npp);
1394 :
1395 0 : NPN_PLUGIN_LOG(PLUGIN_LOG_NOISY,
1396 : ("NPN_SetProperty(npp %p, npobj %p, property %p) called\n",
1397 : npp, npobj, property));
1398 :
1399 0 : return npobj->_class->setProperty(npobj, property, value);
1400 : }
1401 :
1402 : bool
1403 0 : _removeproperty(NPP npp, NPObject* npobj, NPIdentifier property)
1404 : {
1405 0 : if (!NS_IsMainThread()) {
1406 0 : NPN_PLUGIN_LOG(PLUGIN_LOG_ALWAYS,("NPN_removeproperty called from the wrong thread\n"));
1407 0 : return false;
1408 : }
1409 0 : if (!npp || !npobj || !npobj->_class || !npobj->_class->removeProperty)
1410 0 : return false;
1411 :
1412 0 : NPPExceptionAutoHolder nppExceptionHolder;
1413 0 : NPPAutoPusher nppPusher(npp);
1414 :
1415 0 : NPN_PLUGIN_LOG(PLUGIN_LOG_NOISY,
1416 : ("NPN_RemoveProperty(npp %p, npobj %p, property %p) called\n",
1417 : npp, npobj, property));
1418 :
1419 0 : return npobj->_class->removeProperty(npobj, property);
1420 : }
1421 :
1422 : bool
1423 0 : _hasproperty(NPP npp, NPObject* npobj, NPIdentifier propertyName)
1424 : {
1425 0 : if (!NS_IsMainThread()) {
1426 0 : NPN_PLUGIN_LOG(PLUGIN_LOG_ALWAYS,("NPN_hasproperty called from the wrong thread\n"));
1427 0 : return false;
1428 : }
1429 0 : if (!npp || !npobj || !npobj->_class || !npobj->_class->hasProperty)
1430 0 : return false;
1431 :
1432 0 : NPPExceptionAutoHolder nppExceptionHolder;
1433 0 : NPPAutoPusher nppPusher(npp);
1434 :
1435 0 : NPN_PLUGIN_LOG(PLUGIN_LOG_NOISY,
1436 : ("NPN_HasProperty(npp %p, npobj %p, property %p) called\n",
1437 : npp, npobj, propertyName));
1438 :
1439 0 : return npobj->_class->hasProperty(npobj, propertyName);
1440 : }
1441 :
1442 : bool
1443 0 : _hasmethod(NPP npp, NPObject* npobj, NPIdentifier methodName)
1444 : {
1445 0 : if (!NS_IsMainThread()) {
1446 0 : NPN_PLUGIN_LOG(PLUGIN_LOG_ALWAYS,("NPN_hasmethod called from the wrong thread\n"));
1447 0 : return false;
1448 : }
1449 0 : if (!npp || !npobj || !npobj->_class || !npobj->_class->hasMethod)
1450 0 : return false;
1451 :
1452 0 : NPPExceptionAutoHolder nppExceptionHolder;
1453 0 : NPPAutoPusher nppPusher(npp);
1454 :
1455 0 : NPN_PLUGIN_LOG(PLUGIN_LOG_NOISY,
1456 : ("NPN_HasMethod(npp %p, npobj %p, property %p) called\n",
1457 : npp, npobj, methodName));
1458 :
1459 0 : return npobj->_class->hasMethod(npobj, methodName);
1460 : }
1461 :
1462 : bool
1463 0 : _enumerate(NPP npp, NPObject *npobj, NPIdentifier **identifier,
1464 : uint32_t *count)
1465 : {
1466 0 : if (!NS_IsMainThread()) {
1467 0 : NPN_PLUGIN_LOG(PLUGIN_LOG_ALWAYS,("NPN_enumerate called from the wrong thread\n"));
1468 0 : return false;
1469 : }
1470 0 : if (!npp || !npobj || !npobj->_class)
1471 0 : return false;
1472 :
1473 0 : NPN_PLUGIN_LOG(PLUGIN_LOG_NOISY,
1474 : ("NPN_Enumerate(npp %p, npobj %p) called\n", npp, npobj));
1475 :
1476 0 : if (!NP_CLASS_STRUCT_VERSION_HAS_ENUM(npobj->_class) ||
1477 0 : !npobj->_class->enumerate) {
1478 0 : *identifier = 0;
1479 0 : *count = 0;
1480 0 : return true;
1481 : }
1482 :
1483 0 : NPPExceptionAutoHolder nppExceptionHolder;
1484 0 : NPPAutoPusher nppPusher(npp);
1485 :
1486 0 : return npobj->_class->enumerate(npobj, identifier, count);
1487 : }
1488 :
1489 : bool
1490 0 : _construct(NPP npp, NPObject* npobj, const NPVariant *args,
1491 : uint32_t argCount, NPVariant *result)
1492 : {
1493 0 : if (!NS_IsMainThread()) {
1494 0 : NPN_PLUGIN_LOG(PLUGIN_LOG_ALWAYS,("NPN_construct called from the wrong thread\n"));
1495 0 : return false;
1496 : }
1497 0 : if (!npp || !npobj || !npobj->_class ||
1498 0 : !NP_CLASS_STRUCT_VERSION_HAS_CTOR(npobj->_class) ||
1499 0 : !npobj->_class->construct) {
1500 0 : return false;
1501 : }
1502 :
1503 0 : NPPExceptionAutoHolder nppExceptionHolder;
1504 0 : NPPAutoPusher nppPusher(npp);
1505 :
1506 0 : return npobj->_class->construct(npobj, args, argCount, result);
1507 : }
1508 :
1509 : void
1510 0 : _releasevariantvalue(NPVariant* variant)
1511 : {
1512 0 : if (!NS_IsMainThread()) {
1513 0 : NPN_PLUGIN_LOG(PLUGIN_LOG_ALWAYS,("NPN_releasevariantvalue called from the wrong thread\n"));
1514 : }
1515 0 : switch (variant->type) {
1516 : case NPVariantType_Void :
1517 : case NPVariantType_Null :
1518 : case NPVariantType_Bool :
1519 : case NPVariantType_Int32 :
1520 : case NPVariantType_Double :
1521 0 : break;
1522 : case NPVariantType_String :
1523 : {
1524 0 : const NPString *s = &NPVARIANT_TO_STRING(*variant);
1525 :
1526 0 : if (s->UTF8Characters) {
1527 : #if defined(MOZ_MEMORY_WINDOWS)
1528 : if (malloc_usable_size((void *)s->UTF8Characters) != 0) {
1529 : free((void*)s->UTF8Characters);
1530 : } else {
1531 : void *p = (void *)s->UTF8Characters;
1532 : DWORD nheaps = 0;
1533 : AutoTArray<HANDLE, 50> heaps;
1534 : nheaps = GetProcessHeaps(0, heaps.Elements());
1535 : heaps.AppendElements(nheaps);
1536 : GetProcessHeaps(nheaps, heaps.Elements());
1537 : for (DWORD i = 0; i < nheaps; i++) {
1538 : if (InHeap(heaps[i], p)) {
1539 : HeapFree(heaps[i], 0, p);
1540 : break;
1541 : }
1542 : }
1543 : }
1544 : #else
1545 0 : free((void *)s->UTF8Characters);
1546 : #endif
1547 : }
1548 0 : break;
1549 : }
1550 : case NPVariantType_Object:
1551 : {
1552 0 : NPObject *npobj = NPVARIANT_TO_OBJECT(*variant);
1553 :
1554 0 : if (npobj)
1555 0 : _releaseobject(npobj);
1556 :
1557 0 : break;
1558 : }
1559 : default:
1560 0 : NS_ERROR("Unknown NPVariant type!");
1561 : }
1562 :
1563 0 : VOID_TO_NPVARIANT(*variant);
1564 0 : }
1565 :
1566 : void
1567 0 : _setexception(NPObject* npobj, const NPUTF8 *message)
1568 : {
1569 0 : if (!NS_IsMainThread()) {
1570 0 : NPN_PLUGIN_LOG(PLUGIN_LOG_ALWAYS,("NPN_setexception called from the wrong thread\n"));
1571 0 : return;
1572 : }
1573 :
1574 0 : if (!message) return;
1575 :
1576 0 : if (gNPPException) {
1577 : // If a plugin throws multiple exceptions, we'll only report the
1578 : // last one for now.
1579 0 : free(gNPPException);
1580 : }
1581 :
1582 0 : gNPPException = strdup(message);
1583 : }
1584 :
1585 : NPError
1586 0 : _getvalue(NPP npp, NPNVariable variable, void *result)
1587 : {
1588 0 : if (!NS_IsMainThread()) {
1589 0 : NPN_PLUGIN_LOG(PLUGIN_LOG_ALWAYS,("NPN_getvalue called from the wrong thread\n"));
1590 0 : return NPERR_INVALID_PARAM;
1591 : }
1592 0 : NPN_PLUGIN_LOG(PLUGIN_LOG_NORMAL, ("NPN_GetValue: npp=%p, var=%d\n",
1593 : (void*)npp, (int)variable));
1594 :
1595 : nsresult res;
1596 :
1597 0 : PluginDestructionGuard guard(npp);
1598 :
1599 : // Cast NPNVariable enum to int to avoid warnings about including switch
1600 : // cases for android_npapi.h's non-standard ANPInterface values.
1601 0 : switch (static_cast<int>(variable)) {
1602 :
1603 : #if defined(XP_UNIX) && !defined(XP_MACOSX)
1604 : case NPNVxDisplay : {
1605 : #if defined(MOZ_X11)
1606 0 : if (npp) {
1607 0 : nsNPAPIPluginInstance *inst = (nsNPAPIPluginInstance *) npp->ndata;
1608 0 : bool windowless = false;
1609 0 : inst->IsWindowless(&windowless);
1610 : // The documentation on the types for many variables in NP(N|P)_GetValue
1611 : // is vague. Often boolean values are NPBool (1 byte), but
1612 : // https://developer.mozilla.org/en/XEmbed_Extension_for_Mozilla_Plugins
1613 : // treats NPPVpluginNeedsXEmbed as PRBool (int), and
1614 : // on x86/32-bit, flash stores to this using |movl 0x1,&needsXEmbed|.
1615 : // thus we can't use NPBool for needsXEmbed, or the three bytes above
1616 : // it on the stack would get clobbered. so protect with the larger bool.
1617 0 : int needsXEmbed = 0;
1618 0 : if (!windowless) {
1619 0 : res = inst->GetValueFromPlugin(NPPVpluginNeedsXEmbed, &needsXEmbed);
1620 : // If the call returned an error code make sure we still use our default value.
1621 0 : if (NS_FAILED(res)) {
1622 0 : needsXEmbed = 0;
1623 : }
1624 : }
1625 0 : if (windowless || needsXEmbed) {
1626 0 : (*(Display **)result) = mozilla::DefaultXDisplay();
1627 0 : return NPERR_NO_ERROR;
1628 : }
1629 : }
1630 : #if (MOZ_WIDGET_GTK == 2)
1631 : // adobe nppdf calls XtGetApplicationNameAndClass(display,
1632 : // &instance, &class) we have to init Xt toolkit before get
1633 : // XtDisplay just call gtk_xtbin_new(w,0) once
1634 : static GtkWidget *gtkXtBinHolder = 0;
1635 : if (!gtkXtBinHolder) {
1636 : gtkXtBinHolder = gtk_xtbin_new(gdk_get_default_root_window(),0);
1637 : // it crashes on destroy, let it leak
1638 : // gtk_widget_destroy(gtkXtBinHolder);
1639 : }
1640 : (*(Display **)result) = GTK_XTBIN(gtkXtBinHolder)->xtdisplay;
1641 : return NPERR_NO_ERROR;
1642 : #endif
1643 : #endif
1644 0 : return NPERR_GENERIC_ERROR;
1645 : }
1646 :
1647 : case NPNVxtAppContext:
1648 0 : return NPERR_GENERIC_ERROR;
1649 : #endif
1650 :
1651 : #if defined(XP_WIN) || defined(MOZ_WIDGET_GTK)
1652 : case NPNVnetscapeWindow: {
1653 0 : if (!npp || !npp->ndata)
1654 0 : return NPERR_INVALID_INSTANCE_ERROR;
1655 :
1656 0 : nsNPAPIPluginInstance *inst = (nsNPAPIPluginInstance *) npp->ndata;
1657 :
1658 0 : RefPtr<nsPluginInstanceOwner> owner = inst->GetOwner();
1659 0 : NS_ENSURE_TRUE(owner, NPERR_NO_ERROR);
1660 :
1661 0 : if (NS_SUCCEEDED(owner->GetNetscapeWindow(result))) {
1662 0 : return NPERR_NO_ERROR;
1663 : }
1664 0 : return NPERR_GENERIC_ERROR;
1665 : }
1666 : #endif
1667 :
1668 : case NPNVjavascriptEnabledBool: {
1669 0 : *(NPBool*)result = false;
1670 0 : bool js = false;
1671 0 : res = Preferences::GetBool("javascript.enabled", &js);
1672 0 : if (NS_SUCCEEDED(res)) {
1673 0 : *(NPBool*)result = js;
1674 : }
1675 0 : return NPERR_NO_ERROR;
1676 : }
1677 :
1678 : case NPNVasdEnabledBool:
1679 0 : *(NPBool*)result = false;
1680 0 : return NPERR_NO_ERROR;
1681 :
1682 : case NPNVisOfflineBool: {
1683 0 : bool offline = false;
1684 : nsCOMPtr<nsIIOService> ioservice =
1685 0 : do_GetService(NS_IOSERVICE_CONTRACTID, &res);
1686 0 : if (NS_SUCCEEDED(res))
1687 0 : res = ioservice->GetOffline(&offline);
1688 0 : if (NS_FAILED(res))
1689 0 : return NPERR_GENERIC_ERROR;
1690 :
1691 0 : *(NPBool*)result = offline;
1692 0 : return NPERR_NO_ERROR;
1693 : }
1694 :
1695 : case NPNVToolkit: {
1696 : #ifdef MOZ_WIDGET_GTK
1697 0 : *((NPNToolkitType*)result) = NPNVGtk2;
1698 : #endif
1699 :
1700 0 : if (*(NPNToolkitType*)result)
1701 0 : return NPERR_NO_ERROR;
1702 :
1703 0 : return NPERR_GENERIC_ERROR;
1704 : }
1705 :
1706 : case NPNVSupportsXEmbedBool: {
1707 : #ifdef MOZ_WIDGET_GTK
1708 0 : *(NPBool*)result = true;
1709 : #else
1710 : *(NPBool*)result = false;
1711 : #endif
1712 0 : return NPERR_NO_ERROR;
1713 : }
1714 :
1715 : case NPNVWindowNPObject: {
1716 0 : *(NPObject **)result = _getwindowobject(npp);
1717 :
1718 0 : return *(NPObject **)result ? NPERR_NO_ERROR : NPERR_GENERIC_ERROR;
1719 : }
1720 :
1721 : case NPNVPluginElementNPObject: {
1722 0 : *(NPObject **)result = _getpluginelement(npp);
1723 :
1724 0 : return *(NPObject **)result ? NPERR_NO_ERROR : NPERR_GENERIC_ERROR;
1725 : }
1726 :
1727 : case NPNVSupportsWindowless: {
1728 : #if defined(XP_WIN) || defined(XP_MACOSX) || \
1729 : (defined(MOZ_X11) && defined(MOZ_WIDGET_GTK))
1730 0 : *(NPBool*)result = true;
1731 : #else
1732 : *(NPBool*)result = false;
1733 : #endif
1734 0 : return NPERR_NO_ERROR;
1735 : }
1736 :
1737 : case NPNVprivateModeBool: {
1738 : bool privacy;
1739 0 : nsNPAPIPluginInstance *inst = static_cast<nsNPAPIPluginInstance*>(npp->ndata);
1740 0 : if (!inst)
1741 0 : return NPERR_GENERIC_ERROR;
1742 :
1743 0 : nsresult rv = inst->IsPrivateBrowsing(&privacy);
1744 0 : if (NS_FAILED(rv))
1745 0 : return NPERR_GENERIC_ERROR;
1746 0 : *(NPBool*)result = (NPBool)privacy;
1747 0 : return NPERR_NO_ERROR;
1748 : }
1749 :
1750 : case NPNVdocumentOrigin: {
1751 0 : nsNPAPIPluginInstance *inst = (nsNPAPIPluginInstance *)npp->ndata;
1752 0 : if (!inst) {
1753 0 : return NPERR_GENERIC_ERROR;
1754 : }
1755 :
1756 0 : nsCOMPtr<nsIDOMElement> element;
1757 0 : inst->GetDOMElement(getter_AddRefs(element));
1758 0 : if (!element) {
1759 0 : return NPERR_GENERIC_ERROR;
1760 : }
1761 :
1762 0 : nsCOMPtr<nsIContent> content(do_QueryInterface(element));
1763 0 : if (!content) {
1764 0 : return NPERR_GENERIC_ERROR;
1765 : }
1766 :
1767 0 : nsIPrincipal* principal = content->NodePrincipal();
1768 :
1769 0 : nsAutoString utf16Origin;
1770 0 : res = nsContentUtils::GetUTFOrigin(principal, utf16Origin);
1771 0 : if (NS_FAILED(res)) {
1772 0 : return NPERR_GENERIC_ERROR;
1773 : }
1774 :
1775 0 : nsCOMPtr<nsIIDNService> idnService = do_GetService(NS_IDNSERVICE_CONTRACTID);
1776 0 : if (!idnService) {
1777 0 : return NPERR_GENERIC_ERROR;
1778 : }
1779 :
1780 : // This is a bit messy: we convert to UTF-8 here, but then
1781 : // nsIDNService::Normalize will convert back to UTF-16 for processing,
1782 : // and back to UTF-8 again to return the result.
1783 : // Alternative: perhaps we should add a NormalizeUTF16 version of the API,
1784 : // and just convert to UTF-8 for the final return (resulting in one
1785 : // encoding form conversion instead of three).
1786 0 : NS_ConvertUTF16toUTF8 utf8Origin(utf16Origin);
1787 0 : nsAutoCString normalizedUTF8Origin;
1788 0 : res = idnService->Normalize(utf8Origin, normalizedUTF8Origin);
1789 0 : if (NS_FAILED(res)) {
1790 0 : return NPERR_GENERIC_ERROR;
1791 : }
1792 :
1793 0 : *(char**)result = ToNewCString(normalizedUTF8Origin);
1794 0 : return *(char**)result ? NPERR_NO_ERROR : NPERR_GENERIC_ERROR;
1795 : }
1796 :
1797 : #ifdef XP_MACOSX
1798 : case NPNVpluginDrawingModel: {
1799 : if (npp) {
1800 : nsNPAPIPluginInstance *inst = (nsNPAPIPluginInstance*)npp->ndata;
1801 : if (inst) {
1802 : NPDrawingModel drawingModel;
1803 : inst->GetDrawingModel((int32_t*)&drawingModel);
1804 : *(NPDrawingModel*)result = drawingModel;
1805 : return NPERR_NO_ERROR;
1806 : }
1807 : }
1808 : return NPERR_GENERIC_ERROR;
1809 : }
1810 :
1811 : #ifndef NP_NO_QUICKDRAW
1812 : case NPNVsupportsQuickDrawBool: {
1813 : *(NPBool*)result = false;
1814 :
1815 : return NPERR_NO_ERROR;
1816 : }
1817 : #endif
1818 :
1819 : case NPNVsupportsCoreGraphicsBool: {
1820 : *(NPBool*)result = true;
1821 :
1822 : return NPERR_NO_ERROR;
1823 : }
1824 :
1825 : case NPNVsupportsCoreAnimationBool: {
1826 : *(NPBool*)result = true;
1827 :
1828 : return NPERR_NO_ERROR;
1829 : }
1830 :
1831 : case NPNVsupportsInvalidatingCoreAnimationBool: {
1832 : *(NPBool*)result = true;
1833 :
1834 : return NPERR_NO_ERROR;
1835 : }
1836 :
1837 : case NPNVsupportsCompositingCoreAnimationPluginsBool: {
1838 : *(NPBool*)result = PR_TRUE;
1839 :
1840 : return NPERR_NO_ERROR;
1841 : }
1842 :
1843 : #ifndef NP_NO_CARBON
1844 : case NPNVsupportsCarbonBool: {
1845 : *(NPBool*)result = false;
1846 :
1847 : return NPERR_NO_ERROR;
1848 : }
1849 : #endif
1850 : case NPNVsupportsCocoaBool: {
1851 : *(NPBool*)result = true;
1852 :
1853 : return NPERR_NO_ERROR;
1854 : }
1855 :
1856 : case NPNVsupportsUpdatedCocoaTextInputBool: {
1857 : *(NPBool*)result = true;
1858 : return NPERR_NO_ERROR;
1859 : }
1860 : #endif
1861 :
1862 : #if defined(XP_MACOSX) || defined(XP_WIN)
1863 : case NPNVcontentsScaleFactor: {
1864 : nsNPAPIPluginInstance *inst =
1865 : (nsNPAPIPluginInstance *) (npp ? npp->ndata : nullptr);
1866 : double scaleFactor = inst ? inst->GetContentsScaleFactor() : 1.0;
1867 : *(double*)result = scaleFactor;
1868 : return NPERR_NO_ERROR;
1869 : }
1870 : #endif
1871 :
1872 : case NPNVCSSZoomFactor: {
1873 : nsNPAPIPluginInstance *inst =
1874 0 : (nsNPAPIPluginInstance *) (npp ? npp->ndata : nullptr);
1875 0 : double scaleFactor = inst ? inst->GetCSSZoomFactor() : 1.0;
1876 0 : *(double*)result = scaleFactor;
1877 0 : return NPERR_NO_ERROR;
1878 : }
1879 :
1880 : #ifdef MOZ_WIDGET_ANDROID
1881 : case kLogInterfaceV0_ANPGetValue: {
1882 : LOG("get log interface");
1883 : ANPLogInterfaceV0 *i = (ANPLogInterfaceV0 *) result;
1884 : InitLogInterface(i);
1885 : return NPERR_NO_ERROR;
1886 : }
1887 :
1888 : case kBitmapInterfaceV0_ANPGetValue: {
1889 : LOG("get bitmap interface");
1890 : return NPERR_GENERIC_ERROR;
1891 : }
1892 :
1893 : case kMatrixInterfaceV0_ANPGetValue: {
1894 : LOG("get matrix interface");
1895 : return NPERR_GENERIC_ERROR;
1896 : }
1897 :
1898 : case kPathInterfaceV0_ANPGetValue: {
1899 : LOG("get path interface");
1900 : return NPERR_GENERIC_ERROR;
1901 : }
1902 :
1903 : case kTypefaceInterfaceV0_ANPGetValue: {
1904 : LOG("get typeface interface");
1905 : ANPTypefaceInterfaceV0 *i = (ANPTypefaceInterfaceV0 *) result;
1906 : InitTypeFaceInterface(i);
1907 : return NPERR_NO_ERROR;
1908 : }
1909 :
1910 : case kPaintInterfaceV0_ANPGetValue: {
1911 : LOG("get paint interface");
1912 : ANPPaintInterfaceV0 *i = (ANPPaintInterfaceV0 *) result;
1913 : InitPaintInterface(i);
1914 : return NPERR_NO_ERROR;
1915 : }
1916 :
1917 : case kCanvasInterfaceV0_ANPGetValue: {
1918 : LOG("get canvas interface");
1919 : ANPCanvasInterfaceV0 *i = (ANPCanvasInterfaceV0 *) result;
1920 : InitCanvasInterface(i);
1921 : return NPERR_NO_ERROR;
1922 : }
1923 :
1924 : case kWindowInterfaceV0_ANPGetValue: {
1925 : LOG("get window interface");
1926 : ANPWindowInterfaceV0 *i = (ANPWindowInterfaceV0 *) result;
1927 : InitWindowInterface(i);
1928 : return NPERR_NO_ERROR;
1929 : }
1930 :
1931 : case kAudioTrackInterfaceV0_ANPGetValue: {
1932 : LOG("get audio interface");
1933 : ANPAudioTrackInterfaceV0 *i = (ANPAudioTrackInterfaceV0 *) result;
1934 : InitAudioTrackInterfaceV0(i);
1935 : return NPERR_NO_ERROR;
1936 : }
1937 :
1938 : case kEventInterfaceV0_ANPGetValue: {
1939 : LOG("get event interface");
1940 : ANPEventInterfaceV0 *i = (ANPEventInterfaceV0 *) result;
1941 : InitEventInterface(i);
1942 : return NPERR_NO_ERROR;
1943 : }
1944 :
1945 : case kSystemInterfaceV0_ANPGetValue: {
1946 : LOG("get system interface");
1947 : return NPERR_GENERIC_ERROR;
1948 : }
1949 :
1950 : case kSurfaceInterfaceV0_ANPGetValue: {
1951 : LOG("get surface interface");
1952 : ANPSurfaceInterfaceV0 *i = (ANPSurfaceInterfaceV0 *) result;
1953 : InitSurfaceInterface(i);
1954 : return NPERR_NO_ERROR;
1955 : }
1956 :
1957 : case kSupportedDrawingModel_ANPGetValue: {
1958 : LOG("get supported drawing model");
1959 : return NPERR_GENERIC_ERROR;
1960 : }
1961 :
1962 : case kJavaContext_ANPGetValue: {
1963 : LOG("get java context");
1964 :
1965 : auto ret = npp && jni::IsFennec()
1966 : ? java::GeckoApp::GetPluginContext()
1967 : : java::GeckoAppShell::GetApplicationContext();
1968 : if (!ret) {
1969 : return NPERR_GENERIC_ERROR;
1970 : }
1971 : *static_cast<jobject*>(result) = ret.Forget();
1972 : return NPERR_NO_ERROR;
1973 : }
1974 :
1975 : case kAudioTrackInterfaceV1_ANPGetValue: {
1976 : LOG("get audio interface v1");
1977 : ANPAudioTrackInterfaceV1 *i = (ANPAudioTrackInterfaceV1 *) result;
1978 : InitAudioTrackInterfaceV1(i);
1979 : return NPERR_NO_ERROR;
1980 : }
1981 :
1982 : case kNativeWindowInterfaceV0_ANPGetValue: {
1983 : LOG("get native window interface v0");
1984 : ANPNativeWindowInterfaceV0* i = (ANPNativeWindowInterfaceV0 *) result;
1985 : InitNativeWindowInterface(i);
1986 : return NPERR_NO_ERROR;
1987 : }
1988 :
1989 : case kOpenGLInterfaceV0_ANPGetValue: {
1990 : LOG("get openGL interface");
1991 : return NPERR_GENERIC_ERROR;
1992 : }
1993 :
1994 : case kWindowInterfaceV1_ANPGetValue: {
1995 : LOG("get Window interface V1");
1996 : return NPERR_GENERIC_ERROR;
1997 : }
1998 :
1999 : case kWindowInterfaceV2_ANPGetValue: {
2000 : LOG("get Window interface V2");
2001 : ANPWindowInterfaceV2 *i = (ANPWindowInterfaceV2 *) result;
2002 : InitWindowInterfaceV2(i);
2003 : return NPERR_NO_ERROR;
2004 : }
2005 :
2006 : case kVideoInterfaceV0_ANPGetValue: {
2007 : LOG("get video interface V0");
2008 : return NPERR_GENERIC_ERROR;
2009 : }
2010 :
2011 : case kVideoInterfaceV1_ANPGetValue: {
2012 : LOG("get video interface V1");
2013 : ANPVideoInterfaceV1 *i = (ANPVideoInterfaceV1*) result;
2014 : InitVideoInterfaceV1(i);
2015 : return NPERR_NO_ERROR;
2016 : }
2017 :
2018 : case kSystemInterfaceV1_ANPGetValue: {
2019 : LOG("get system interface v1");
2020 : ANPSystemInterfaceV1* i = reinterpret_cast<ANPSystemInterfaceV1*>(result);
2021 : InitSystemInterfaceV1(i);
2022 : return NPERR_NO_ERROR;
2023 : }
2024 :
2025 : case kSystemInterfaceV2_ANPGetValue: {
2026 : LOG("get system interface v2");
2027 : ANPSystemInterfaceV2* i = reinterpret_cast<ANPSystemInterfaceV2*>(result);
2028 : InitSystemInterfaceV2(i);
2029 : return NPERR_NO_ERROR;
2030 : }
2031 : #endif
2032 :
2033 : // we no longer hand out any XPCOM objects
2034 : case NPNVDOMElement:
2035 : case NPNVDOMWindow:
2036 : case NPNVserviceManager:
2037 : // old XPCOM objects, no longer supported, but null out the out
2038 : // param to avoid crashing plugins that still try to use this.
2039 0 : *(nsISupports**)result = nullptr;
2040 : MOZ_FALLTHROUGH;
2041 :
2042 : default:
2043 0 : NPN_PLUGIN_LOG(PLUGIN_LOG_NORMAL, ("NPN_getvalue unhandled get value: %d\n", variable));
2044 0 : return NPERR_GENERIC_ERROR;
2045 : }
2046 : }
2047 :
2048 : NPError
2049 0 : _setvalue(NPP npp, NPPVariable variable, void *result)
2050 : {
2051 0 : if (!NS_IsMainThread()) {
2052 0 : NPN_PLUGIN_LOG(PLUGIN_LOG_ALWAYS,("NPN_setvalue called from the wrong thread\n"));
2053 0 : return NPERR_INVALID_PARAM;
2054 : }
2055 0 : NPN_PLUGIN_LOG(PLUGIN_LOG_NORMAL, ("NPN_SetValue: npp=%p, var=%d\n",
2056 : (void*)npp, (int)variable));
2057 :
2058 0 : if (!npp)
2059 0 : return NPERR_INVALID_INSTANCE_ERROR;
2060 :
2061 0 : nsNPAPIPluginInstance *inst = (nsNPAPIPluginInstance *) npp->ndata;
2062 :
2063 0 : NS_ASSERTION(inst, "null instance");
2064 :
2065 0 : if (!inst)
2066 0 : return NPERR_INVALID_INSTANCE_ERROR;
2067 :
2068 0 : PluginDestructionGuard guard(inst);
2069 :
2070 : // Cast NPNVariable enum to int to avoid warnings about including switch
2071 : // cases for android_npapi.h's non-standard ANPInterface values.
2072 0 : switch (static_cast<int>(variable)) {
2073 :
2074 : // we should keep backward compatibility with NPAPI where the
2075 : // actual pointer value is checked rather than its content
2076 : // when passing booleans
2077 : case NPPVpluginWindowBool: {
2078 : #ifdef XP_MACOSX
2079 : // This setting doesn't apply to OS X (only to Windows and Unix/Linux).
2080 : // See https://developer.mozilla.org/En/NPN_SetValue#section_5. Return
2081 : // NPERR_NO_ERROR here to conform to other browsers' behavior on OS X
2082 : // (e.g. Safari and Opera).
2083 : return NPERR_NO_ERROR;
2084 : #else
2085 0 : NPBool bWindowless = (result == nullptr);
2086 0 : return inst->SetWindowless(bWindowless);
2087 : #endif
2088 : }
2089 : case NPPVpluginTransparentBool: {
2090 0 : NPBool bTransparent = (result != nullptr);
2091 0 : return inst->SetTransparent(bTransparent);
2092 : }
2093 :
2094 : case NPPVjavascriptPushCallerBool: {
2095 0 : return NPERR_NO_ERROR;
2096 : }
2097 :
2098 : case NPPVpluginKeepLibraryInMemory: {
2099 0 : NPBool bCached = (result != nullptr);
2100 0 : inst->SetCached(bCached);
2101 0 : return NPERR_NO_ERROR;
2102 : }
2103 :
2104 : case NPPVpluginUsesDOMForCursorBool: {
2105 0 : bool useDOMForCursor = (result != nullptr);
2106 0 : return inst->SetUsesDOMForCursor(useDOMForCursor);
2107 : }
2108 :
2109 : case NPPVpluginIsPlayingAudio: {
2110 0 : const bool isPlaying = result;
2111 :
2112 0 : nsNPAPIPluginInstance* inst = (nsNPAPIPluginInstance*) npp->ndata;
2113 0 : MOZ_ASSERT(inst);
2114 :
2115 0 : if (!isPlaying && !inst->HasAudioChannelAgent()) {
2116 0 : return NPERR_NO_ERROR;
2117 : }
2118 :
2119 0 : if (isPlaying) {
2120 0 : inst->NotifyStartedPlaying();
2121 : } else {
2122 0 : inst->NotifyStoppedPlaying();
2123 : }
2124 :
2125 0 : return NPERR_NO_ERROR;
2126 : }
2127 :
2128 : #ifndef MOZ_WIDGET_ANDROID
2129 : // On android, their 'drawing model' uses the same constant!
2130 : case NPPVpluginDrawingModel: {
2131 0 : if (inst) {
2132 0 : inst->SetDrawingModel((NPDrawingModel)NS_PTR_TO_INT32(result));
2133 0 : return NPERR_NO_ERROR;
2134 : }
2135 0 : return NPERR_GENERIC_ERROR;
2136 : }
2137 : #endif
2138 :
2139 : #ifdef XP_MACOSX
2140 : case NPPVpluginEventModel: {
2141 : if (inst) {
2142 : inst->SetEventModel((NPEventModel)NS_PTR_TO_INT32(result));
2143 : return NPERR_NO_ERROR;
2144 : }
2145 : else {
2146 : return NPERR_GENERIC_ERROR;
2147 : }
2148 : }
2149 : #endif
2150 : #ifdef MOZ_WIDGET_ANDROID
2151 : case kRequestDrawingModel_ANPSetValue:
2152 : if (inst)
2153 : inst->SetANPDrawingModel(NS_PTR_TO_INT32(result));
2154 : return NPERR_NO_ERROR;
2155 : case kAcceptEvents_ANPSetValue:
2156 : return NPERR_NO_ERROR;
2157 : #endif
2158 : default:
2159 0 : return NPERR_GENERIC_ERROR;
2160 : }
2161 : }
2162 :
2163 : NPError
2164 0 : _requestread(NPStream *pstream, NPByteRange *rangeList)
2165 : {
2166 0 : if (!NS_IsMainThread()) {
2167 0 : NPN_PLUGIN_LOG(PLUGIN_LOG_ALWAYS,("NPN_requestread called from the wrong thread\n"));
2168 0 : return NPERR_INVALID_PARAM;
2169 : }
2170 0 : NPN_PLUGIN_LOG(PLUGIN_LOG_NORMAL, ("NPN_RequestRead: stream=%p\n",
2171 : (void*)pstream));
2172 :
2173 : #ifdef PLUGIN_LOGGING
2174 : for(NPByteRange * range = rangeList; range != nullptr; range = range->next)
2175 : MOZ_LOG(nsPluginLogging::gNPNLog,PLUGIN_LOG_NOISY,
2176 : ("%i-%i", range->offset, range->offset + range->length - 1));
2177 :
2178 : MOZ_LOG(nsPluginLogging::gNPNLog,PLUGIN_LOG_NOISY, ("\n\n"));
2179 : PR_LogFlush();
2180 : #endif
2181 :
2182 0 : if (!pstream || !rangeList || !pstream->ndata)
2183 0 : return NPERR_INVALID_PARAM;
2184 :
2185 0 : nsNPAPIStreamWrapper* streamWrapper = static_cast<nsNPAPIStreamWrapper*>(pstream->ndata);
2186 0 : nsNPAPIPluginStreamListener* streamlistener = streamWrapper->GetStreamListener();
2187 0 : if (!streamlistener) {
2188 0 : return NPERR_GENERIC_ERROR;
2189 : }
2190 :
2191 0 : int32_t streamtype = NP_NORMAL;
2192 :
2193 0 : streamlistener->GetStreamType(&streamtype);
2194 :
2195 0 : if (streamtype != NP_SEEK)
2196 0 : return NPERR_STREAM_NOT_SEEKABLE;
2197 :
2198 0 : if (!streamlistener->mStreamListenerPeer)
2199 0 : return NPERR_GENERIC_ERROR;
2200 :
2201 0 : nsresult rv = streamlistener->mStreamListenerPeer->RequestRead((NPByteRange *)rangeList);
2202 0 : if (NS_FAILED(rv))
2203 0 : return NPERR_GENERIC_ERROR;
2204 :
2205 0 : return NPERR_NO_ERROR;
2206 : }
2207 :
2208 : // Deprecated, only stubbed out
2209 : void* /* OJI type: JRIEnv* */
2210 0 : _getJavaEnv()
2211 : {
2212 0 : NPN_PLUGIN_LOG(PLUGIN_LOG_NORMAL, ("NPN_GetJavaEnv\n"));
2213 0 : return nullptr;
2214 : }
2215 :
2216 : const char *
2217 0 : _useragent(NPP npp)
2218 : {
2219 0 : if (!NS_IsMainThread()) {
2220 0 : NPN_PLUGIN_LOG(PLUGIN_LOG_ALWAYS,("NPN_useragent called from the wrong thread\n"));
2221 0 : return nullptr;
2222 : }
2223 0 : NPN_PLUGIN_LOG(PLUGIN_LOG_NORMAL, ("NPN_UserAgent: npp=%p\n", (void*)npp));
2224 :
2225 0 : nsCOMPtr<nsIPluginHost> pluginHostCOM(do_GetService(MOZ_PLUGIN_HOST_CONTRACTID));
2226 0 : nsPluginHost *pluginHost = static_cast<nsPluginHost*>(pluginHostCOM.get());
2227 0 : if (!pluginHost) {
2228 0 : return nullptr;
2229 : }
2230 :
2231 : const char *retstr;
2232 0 : nsresult rv = pluginHost->UserAgent(&retstr);
2233 0 : if (NS_FAILED(rv))
2234 0 : return nullptr;
2235 :
2236 0 : return retstr;
2237 : }
2238 :
2239 : void *
2240 0 : _memalloc (uint32_t size)
2241 : {
2242 0 : if (!NS_IsMainThread()) {
2243 0 : NPN_PLUGIN_LOG(PLUGIN_LOG_NORMAL,("NPN_memalloc called from the wrong thread\n"));
2244 : }
2245 0 : NPN_PLUGIN_LOG(PLUGIN_LOG_NOISY, ("NPN_MemAlloc: size=%d\n", size));
2246 0 : return moz_xmalloc(size);
2247 : }
2248 :
2249 : // Deprecated, only stubbed out
2250 : void* /* OJI type: jref */
2251 0 : _getJavaPeer(NPP npp)
2252 : {
2253 0 : NPN_PLUGIN_LOG(PLUGIN_LOG_NORMAL, ("NPN_GetJavaPeer: npp=%p\n", (void*)npp));
2254 0 : return nullptr;
2255 : }
2256 :
2257 : void
2258 0 : _pushpopupsenabledstate(NPP npp, NPBool enabled)
2259 : {
2260 0 : if (!NS_IsMainThread()) {
2261 0 : NPN_PLUGIN_LOG(PLUGIN_LOG_ALWAYS,("NPN_pushpopupsenabledstate called from the wrong thread\n"));
2262 0 : return;
2263 : }
2264 0 : nsNPAPIPluginInstance *inst = npp ? (nsNPAPIPluginInstance *)npp->ndata : nullptr;
2265 0 : if (!inst)
2266 0 : return;
2267 :
2268 0 : inst->PushPopupsEnabledState(enabled);
2269 : }
2270 :
2271 : void
2272 0 : _poppopupsenabledstate(NPP npp)
2273 : {
2274 0 : if (!NS_IsMainThread()) {
2275 0 : NPN_PLUGIN_LOG(PLUGIN_LOG_ALWAYS,("NPN_poppopupsenabledstate called from the wrong thread\n"));
2276 0 : return;
2277 : }
2278 0 : nsNPAPIPluginInstance *inst = npp ? (nsNPAPIPluginInstance *)npp->ndata : nullptr;
2279 0 : if (!inst)
2280 0 : return;
2281 :
2282 0 : inst->PopPopupsEnabledState();
2283 : }
2284 :
2285 : void
2286 0 : _pluginthreadasynccall(NPP instance, PluginThreadCallback func, void *userData)
2287 : {
2288 0 : if (NS_IsMainThread()) {
2289 0 : NPN_PLUGIN_LOG(PLUGIN_LOG_NOISY,("NPN_pluginthreadasynccall called from the main thread\n"));
2290 : } else {
2291 0 : NPN_PLUGIN_LOG(PLUGIN_LOG_NOISY,("NPN_pluginthreadasynccall called from a non main thread\n"));
2292 : }
2293 : RefPtr<nsPluginThreadRunnable> evt =
2294 0 : new nsPluginThreadRunnable(instance, func, userData);
2295 :
2296 0 : if (evt && evt->IsValid()) {
2297 0 : NS_DispatchToMainThread(evt);
2298 : }
2299 0 : }
2300 :
2301 : NPError
2302 0 : _getvalueforurl(NPP instance, NPNURLVariable variable, const char *url,
2303 : char **value, uint32_t *len)
2304 : {
2305 0 : if (!NS_IsMainThread()) {
2306 0 : NPN_PLUGIN_LOG(PLUGIN_LOG_ALWAYS,("NPN_getvalueforurl called from the wrong thread\n"));
2307 0 : return NPERR_GENERIC_ERROR;
2308 : }
2309 :
2310 0 : if (!instance) {
2311 0 : return NPERR_INVALID_PARAM;
2312 : }
2313 :
2314 0 : if (!url || !*url || !len) {
2315 0 : return NPERR_INVALID_URL;
2316 : }
2317 :
2318 0 : *len = 0;
2319 :
2320 0 : switch (variable) {
2321 : case NPNURLVProxy:
2322 : // NPNURLVProxy is no longer supported.
2323 0 : *value = nullptr;
2324 0 : return NPERR_GENERIC_ERROR;
2325 :
2326 : case NPNURLVCookie:
2327 : // NPNURLVCookie is no longer supported.
2328 0 : *value = nullptr;
2329 0 : return NPERR_GENERIC_ERROR;
2330 :
2331 : default:
2332 : // Fall through and return an error...
2333 : ;
2334 : }
2335 :
2336 0 : return NPERR_GENERIC_ERROR;
2337 : }
2338 :
2339 : NPError
2340 0 : _setvalueforurl(NPP instance, NPNURLVariable variable, const char *url,
2341 : const char *value, uint32_t len)
2342 : {
2343 0 : if (!NS_IsMainThread()) {
2344 0 : NPN_PLUGIN_LOG(PLUGIN_LOG_ALWAYS,("NPN_setvalueforurl called from the wrong thread\n"));
2345 0 : return NPERR_GENERIC_ERROR;
2346 : }
2347 :
2348 0 : if (!instance) {
2349 0 : return NPERR_INVALID_PARAM;
2350 : }
2351 :
2352 0 : if (!url || !*url) {
2353 0 : return NPERR_INVALID_URL;
2354 : }
2355 :
2356 0 : switch (variable) {
2357 : case NPNURLVCookie:
2358 : // NPNURLVCookie is no longer supported.
2359 0 : return NPERR_GENERIC_ERROR;
2360 :
2361 : case NPNURLVProxy:
2362 : // We don't support setting proxy values, fall through...
2363 : default:
2364 : // Fall through and return an error...
2365 : ;
2366 : }
2367 :
2368 0 : return NPERR_GENERIC_ERROR;
2369 : }
2370 :
2371 : uint32_t
2372 0 : _scheduletimer(NPP instance, uint32_t interval, NPBool repeat, PluginTimerFunc timerFunc)
2373 : {
2374 0 : if (!NS_IsMainThread()) {
2375 0 : NPN_PLUGIN_LOG(PLUGIN_LOG_ALWAYS,("NPN_scheduletimer called from the wrong thread\n"));
2376 0 : return 0;
2377 : }
2378 :
2379 0 : nsNPAPIPluginInstance *inst = (nsNPAPIPluginInstance *)instance->ndata;
2380 0 : if (!inst)
2381 0 : return 0;
2382 :
2383 0 : return inst->ScheduleTimer(interval, repeat, timerFunc);
2384 : }
2385 :
2386 : void
2387 0 : _unscheduletimer(NPP instance, uint32_t timerID)
2388 : {
2389 0 : if (!NS_IsMainThread()) {
2390 0 : NPN_PLUGIN_LOG(PLUGIN_LOG_ALWAYS,("NPN_unscheduletimer called from the wrong thread\n"));
2391 0 : return;
2392 : }
2393 :
2394 : #ifdef MOZ_WIDGET_ANDROID
2395 : // Sometimes Flash calls this with a dead NPP instance. Ensure the one we have
2396 : // here is valid and maps to a nsNPAPIPluginInstance.
2397 : nsNPAPIPluginInstance *inst = nsNPAPIPluginInstance::GetFromNPP(instance);
2398 : #else
2399 0 : nsNPAPIPluginInstance *inst = (nsNPAPIPluginInstance *)instance->ndata;
2400 : #endif
2401 0 : if (!inst)
2402 0 : return;
2403 :
2404 0 : inst->UnscheduleTimer(timerID);
2405 : }
2406 :
2407 : NPError
2408 0 : _popupcontextmenu(NPP instance, NPMenu* menu)
2409 : {
2410 0 : if (!NS_IsMainThread()) {
2411 0 : NPN_PLUGIN_LOG(PLUGIN_LOG_ALWAYS,("NPN_popupcontextmenu called from the wrong thread\n"));
2412 0 : return 0;
2413 : }
2414 :
2415 : #ifdef MOZ_WIDGET_COCOA
2416 : nsNPAPIPluginInstance *inst = (nsNPAPIPluginInstance *)instance->ndata;
2417 :
2418 : double pluginX, pluginY;
2419 : double screenX, screenY;
2420 :
2421 : const NPCocoaEvent* currentEvent = static_cast<NPCocoaEvent*>(inst->GetCurrentEvent());
2422 : if (!currentEvent) {
2423 : return NPERR_GENERIC_ERROR;
2424 : }
2425 :
2426 : // Ensure that the events has an x/y value.
2427 : if (currentEvent->type != NPCocoaEventMouseDown &&
2428 : currentEvent->type != NPCocoaEventMouseUp &&
2429 : currentEvent->type != NPCocoaEventMouseMoved &&
2430 : currentEvent->type != NPCocoaEventMouseEntered &&
2431 : currentEvent->type != NPCocoaEventMouseExited &&
2432 : currentEvent->type != NPCocoaEventMouseDragged) {
2433 : return NPERR_GENERIC_ERROR;
2434 : }
2435 :
2436 : pluginX = currentEvent->data.mouse.pluginX;
2437 : pluginY = currentEvent->data.mouse.pluginY;
2438 :
2439 : if ((pluginX < 0.0) || (pluginY < 0.0))
2440 : return NPERR_GENERIC_ERROR;
2441 :
2442 : NPBool success = _convertpoint(instance,
2443 : pluginX, pluginY, NPCoordinateSpacePlugin,
2444 : &screenX, &screenY, NPCoordinateSpaceScreen);
2445 :
2446 : if (success) {
2447 : return mozilla::plugins::PluginUtilsOSX::ShowCocoaContextMenu(menu,
2448 : screenX, screenY,
2449 : nullptr,
2450 : nullptr);
2451 : } else {
2452 : NS_WARNING("Convertpoint failed, could not created contextmenu.");
2453 : return NPERR_GENERIC_ERROR;
2454 : }
2455 : #else
2456 0 : NS_WARNING("Not supported on this platform!");
2457 0 : return NPERR_GENERIC_ERROR;
2458 : #endif
2459 : }
2460 :
2461 : NPBool
2462 0 : _convertpoint(NPP instance, double sourceX, double sourceY, NPCoordinateSpace sourceSpace, double *destX, double *destY, NPCoordinateSpace destSpace)
2463 : {
2464 0 : if (!NS_IsMainThread()) {
2465 0 : NPN_PLUGIN_LOG(PLUGIN_LOG_ALWAYS,("NPN_convertpoint called from the wrong thread\n"));
2466 0 : return 0;
2467 : }
2468 :
2469 0 : nsNPAPIPluginInstance *inst = (nsNPAPIPluginInstance *)instance->ndata;
2470 0 : if (!inst)
2471 0 : return false;
2472 :
2473 0 : return inst->ConvertPoint(sourceX, sourceY, sourceSpace, destX, destY, destSpace);
2474 : }
2475 :
2476 : void
2477 0 : _urlredirectresponse(NPP instance, void* notifyData, NPBool allow)
2478 : {
2479 0 : if (!NS_IsMainThread()) {
2480 0 : NPN_PLUGIN_LOG(PLUGIN_LOG_ALWAYS,("NPN_convertpoint called from the wrong thread\n"));
2481 0 : return;
2482 : }
2483 :
2484 0 : nsNPAPIPluginInstance *inst = (nsNPAPIPluginInstance *)instance->ndata;
2485 0 : if (!inst) {
2486 0 : return;
2487 : }
2488 :
2489 0 : inst->URLRedirectResponse(notifyData, allow);
2490 : }
2491 :
2492 : NPError
2493 0 : _initasyncsurface(NPP instance, NPSize *size, NPImageFormat format, void *initData, NPAsyncSurface *surface)
2494 : {
2495 0 : nsNPAPIPluginInstance *inst = (nsNPAPIPluginInstance *)instance->ndata;
2496 0 : if (!inst) {
2497 0 : return NPERR_GENERIC_ERROR;
2498 : }
2499 :
2500 0 : return inst->InitAsyncSurface(size, format, initData, surface);
2501 : }
2502 :
2503 : NPError
2504 0 : _finalizeasyncsurface(NPP instance, NPAsyncSurface *surface)
2505 : {
2506 0 : nsNPAPIPluginInstance *inst = (nsNPAPIPluginInstance *)instance->ndata;
2507 0 : if (!inst) {
2508 0 : return NPERR_GENERIC_ERROR;
2509 : }
2510 :
2511 0 : return inst->FinalizeAsyncSurface(surface);
2512 : }
2513 :
2514 : void
2515 0 : _setcurrentasyncsurface(NPP instance, NPAsyncSurface *surface, NPRect *changed)
2516 : {
2517 0 : nsNPAPIPluginInstance *inst = (nsNPAPIPluginInstance *)instance->ndata;
2518 0 : if (!inst) {
2519 0 : return;
2520 : }
2521 :
2522 0 : inst->SetCurrentAsyncSurface(surface, changed);
2523 : }
2524 :
2525 : } /* namespace parent */
2526 : } /* namespace plugins */
2527 : } /* namespace mozilla */
|