LCOV - code coverage report
Current view: top level - dom/plugins/base - nsNPAPIPlugin.cpp (source / functions) Hit Total Coverage
Test: output.info Lines: 0 909 0.0 %
Date: 2017-07-14 16:53:18 Functions: 0 85 0.0 %
Legend: Lines: hit not hit

          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 */

Generated by: LCOV version 1.13