LCOV - code coverage report
Current view: directory - dom/plugins/base - nsNPAPIPlugin.cpp (source / functions) Found Hit Coverage
Test: app.info Lines: 1084 4 0.4 %
Date: 2012-06-02 Functions: 103 1 1.0 %

       1                 : /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
       2                 : /* ***** BEGIN LICENSE BLOCK *****
       3                 :  * Version: MPL 1.1/GPL 2.0/LGPL 2.1
       4                 :  *
       5                 :  * The contents of this file are subject to the Mozilla Public License Version
       6                 :  * 1.1 (the "License"); you may not use this file except in compliance with
       7                 :  * the License. You may obtain a copy of the License at
       8                 :  * http://www.mozilla.org/MPL/
       9                 :  *
      10                 :  * Software distributed under the License is distributed on an "AS IS" basis,
      11                 :  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
      12                 :  * for the specific language governing rights and limitations under the
      13                 :  * License.
      14                 :  *
      15                 :  * The Original Code is mozilla.org code.
      16                 :  *
      17                 :  * The Initial Developer of the Original Code is
      18                 :  * Netscape Communications Corporation.
      19                 :  * Portions created by the Initial Developer are Copyright (C) 1998
      20                 :  * the Initial Developer. All Rights Reserved.
      21                 :  *
      22                 :  * Contributor(s):
      23                 :  *   Josh Aas <josh@mozilla.com>
      24                 :  *
      25                 :  * Alternatively, the contents of this file may be used under the terms of
      26                 :  * either the GNU General Public License Version 2 or later (the "GPL"), or
      27                 :  * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
      28                 :  * in which case the provisions of the GPL or the LGPL are applicable instead
      29                 :  * of those above. If you wish to allow use of your version of this file only
      30                 :  * under the terms of either the GPL or the LGPL, and not to allow others to
      31                 :  * use your version of this file under the terms of the MPL, indicate your
      32                 :  * decision by deleting the provisions above and replace them with the notice
      33                 :  * and other provisions required by the GPL or the LGPL. If you do not delete
      34                 :  * the provisions above, a recipient may use your version of this file under
      35                 :  * the terms of any one of the MPL, the GPL or the LGPL.
      36                 :  *
      37                 :  * ***** END LICENSE BLOCK ***** */
      38                 : 
      39                 : #ifdef MOZ_WIDGET_QT
      40                 : #include <QX11Info>
      41                 : #endif
      42                 : 
      43                 : #include "base/basictypes.h"
      44                 : 
      45                 : /* This must occur *after* layers/PLayers.h to avoid typedefs conflicts. */
      46                 : #include "mozilla/Util.h"
      47                 : 
      48                 : #include "prtypes.h"
      49                 : #include "prmem.h"
      50                 : #include "prenv.h"
      51                 : #include "prclist.h"
      52                 : 
      53                 : #include "jsfriendapi.h"
      54                 : 
      55                 : #include "nsPluginHost.h"
      56                 : #include "nsNPAPIPlugin.h"
      57                 : #include "nsNPAPIPluginInstance.h"
      58                 : #include "nsNPAPIPluginStreamListener.h"
      59                 : #include "nsIServiceManager.h"
      60                 : #include "nsThreadUtils.h"
      61                 : #include "nsIPrivateBrowsingService.h"
      62                 : 
      63                 : #include "nsIPluginStreamListener.h"
      64                 : #include "nsPluginsDir.h"
      65                 : #include "nsPluginSafety.h"
      66                 : #include "nsIPrefService.h"
      67                 : #include "nsIPrefBranch.h"
      68                 : #include "nsPluginLogging.h"
      69                 : 
      70                 : #include "nsIJSContextStack.h"
      71                 : 
      72                 : #include "nsIDOMElement.h"
      73                 : #include "nsIDOMDocument.h"
      74                 : #include "nsPIDOMWindow.h"
      75                 : #include "nsIDocument.h"
      76                 : #include "nsIContent.h"
      77                 : #include "nsIScriptGlobalObject.h"
      78                 : #include "nsIScriptContext.h"
      79                 : #include "nsIUnicodeNormalizer.h"
      80                 : #include "nsDOMJSUtils.h"
      81                 : #include "nsIPrincipal.h"
      82                 : #include "nsWildCard.h"
      83                 : #include "nsContentUtils.h"
      84                 : 
      85                 : #include "nsIXPConnect.h"
      86                 : 
      87                 : #include "nsIObserverService.h"
      88                 : #include <prinrval.h>
      89                 : 
      90                 : #ifdef MOZ_WIDGET_COCOA
      91                 : #include <Carbon/Carbon.h>
      92                 : #include <ApplicationServices/ApplicationServices.h>
      93                 : #include <OpenGL/OpenGL.h>
      94                 : #include "nsCocoaFeatures.h"
      95                 : #endif
      96                 : 
      97                 : // needed for nppdf plugin
      98                 : #ifdef MOZ_WIDGET_GTK2
      99                 : #include <gdk/gdk.h>
     100                 : #include <gdk/gdkx.h>
     101                 : #include "gtk2xtbin.h"
     102                 : #endif
     103                 : 
     104                 : #ifdef XP_OS2
     105                 : #define INCL_DOS
     106                 : #define INCL_DOSERRORS
     107                 : #include <os2.h>
     108                 : #endif
     109                 : 
     110                 : #include "nsJSNPRuntime.h"
     111                 : #include "nsIHttpAuthManager.h"
     112                 : #include "nsICookieService.h"
     113                 : 
     114                 : #include "nsNetUtil.h"
     115                 : 
     116                 : #include "mozilla/Mutex.h"
     117                 : #include "mozilla/PluginLibrary.h"
     118                 : using mozilla::PluginLibrary;
     119                 : 
     120                 : #include "mozilla/PluginPRLibrary.h"
     121                 : using mozilla::PluginPRLibrary;
     122                 : 
     123                 : #include "mozilla/plugins/PluginModuleParent.h"
     124                 : using mozilla::plugins::PluginModuleParent;
     125                 : 
     126                 : #ifdef MOZ_X11
     127                 : #include "mozilla/X11Util.h"
     128                 : #endif
     129                 : 
     130                 : #ifdef XP_WIN
     131                 : #include <windows.h>
     132                 : #endif
     133                 : 
     134                 : #ifdef MOZ_WIDGET_ANDROID
     135                 : #include <android/log.h>
     136                 : #include "android_npapi.h"
     137                 : #include "ANPBase.h"
     138                 : #include "AndroidBridge.h"
     139                 : #define LOG(args...)  __android_log_print(ANDROID_LOG_INFO, "GeckoPlugins" , ## args)
     140                 : #endif
     141                 : 
     142                 : using namespace mozilla;
     143                 : using namespace mozilla::plugins::parent;
     144                 : 
     145                 : // We should make this const...
     146                 : static NPNetscapeFuncs sBrowserFuncs = {
     147                 :   sizeof(sBrowserFuncs),
     148                 :   (NP_VERSION_MAJOR << 8) + NP_VERSION_MINOR,
     149                 :   _geturl,
     150                 :   _posturl,
     151                 :   _requestread,
     152                 :   _newstream,
     153                 :   _write,
     154                 :   _destroystream,
     155                 :   _status,
     156                 :   _useragent,
     157                 :   _memalloc,
     158                 :   _memfree,
     159                 :   _memflush,
     160                 :   _reloadplugins,
     161                 :   _getJavaEnv,
     162                 :   _getJavaPeer,
     163                 :   _geturlnotify,
     164                 :   _posturlnotify,
     165                 :   _getvalue,
     166                 :   _setvalue,
     167                 :   _invalidaterect,
     168                 :   _invalidateregion,
     169                 :   _forceredraw,
     170                 :   _getstringidentifier,
     171                 :   _getstringidentifiers,
     172                 :   _getintidentifier,
     173                 :   _identifierisstring,
     174                 :   _utf8fromidentifier,
     175                 :   _intfromidentifier,
     176                 :   _createobject,
     177                 :   _retainobject,
     178                 :   _releaseobject,
     179                 :   _invoke,
     180                 :   _invokeDefault,
     181                 :   _evaluate,
     182                 :   _getproperty,
     183                 :   _setproperty,
     184                 :   _removeproperty,
     185                 :   _hasproperty,
     186                 :   _hasmethod,
     187                 :   _releasevariantvalue,
     188                 :   _setexception,
     189                 :   _pushpopupsenabledstate,
     190                 :   _poppopupsenabledstate,
     191                 :   _enumerate,
     192                 :   _pluginthreadasynccall,
     193                 :   _construct,
     194                 :   _getvalueforurl,
     195                 :   _setvalueforurl,
     196                 :   _getauthenticationinfo,
     197                 :   _scheduletimer,
     198                 :   _unscheduletimer,
     199                 :   _popupcontextmenu,
     200                 :   _convertpoint,
     201                 :   NULL, // handleevent, unimplemented
     202                 :   NULL, // unfocusinstance, unimplemented
     203                 :   _urlredirectresponse,
     204                 :   _initasyncsurface,
     205                 :   _finalizeasyncsurface,
     206                 :   _setcurrentasyncsurface
     207                 : };
     208                 : 
     209                 : static Mutex *sPluginThreadAsyncCallLock = nsnull;
     210                 : static PRCList sPendingAsyncCalls = PR_INIT_STATIC_CLIST(&sPendingAsyncCalls);
     211                 : 
     212                 : // POST/GET stream type
     213                 : enum eNPPStreamTypeInternal {
     214                 :   eNPPStreamTypeInternal_Get,
     215                 :   eNPPStreamTypeInternal_Post
     216                 : };
     217                 : 
     218                 : static NS_DEFINE_IID(kMemoryCID, NS_MEMORY_CID);
     219                 : 
     220                 : // This function sends a notification using the observer service to any object
     221                 : // registered to listen to the "experimental-notify-plugin-call" subject.
     222                 : // Each "experimental-notify-plugin-call" notification carries with it the run
     223                 : // time value in milliseconds that the call took to execute.
     224               0 : void NS_NotifyPluginCall(PRIntervalTime startTime) 
     225                 : {
     226               0 :   PRIntervalTime endTime = PR_IntervalNow() - startTime;
     227                 :   nsCOMPtr<nsIObserverService> notifyUIService =
     228               0 :     mozilla::services::GetObserverService();
     229               0 :   if (!notifyUIService)
     230                 :     return;
     231                 : 
     232               0 :   float runTimeInSeconds = float(endTime) / PR_TicksPerSecond();
     233               0 :   nsAutoString runTimeString;
     234               0 :   runTimeString.AppendFloat(runTimeInSeconds);
     235               0 :   const PRUnichar* runTime = runTimeString.get();
     236               0 :   notifyUIService->NotifyObservers(nsnull, "experimental-notify-plugin-call",
     237               0 :                                    runTime);
     238                 : }
     239                 : 
     240               0 : static void CheckClassInitialized()
     241                 : {
     242                 :   static bool initialized = false;
     243                 : 
     244               0 :   if (initialized)
     245               0 :     return;
     246                 : 
     247               0 :   if (!sPluginThreadAsyncCallLock)
     248               0 :     sPluginThreadAsyncCallLock = new Mutex("nsNPAPIPlugin.sPluginThreadAsyncCallLock");
     249                 : 
     250               0 :   initialized = true;
     251                 : 
     252               0 :   NPN_PLUGIN_LOG(PLUGIN_LOG_NORMAL,("NPN callbacks initialized\n"));
     253                 : }
     254                 : 
     255               0 : NS_IMPL_ISUPPORTS0(nsNPAPIPlugin)
     256                 : 
     257               0 : nsNPAPIPlugin::nsNPAPIPlugin()
     258                 : {
     259               0 :   memset((void*)&mPluginFuncs, 0, sizeof(mPluginFuncs));
     260               0 :   mPluginFuncs.size = sizeof(mPluginFuncs);
     261               0 :   mPluginFuncs.version = (NP_VERSION_MAJOR << 8) | NP_VERSION_MINOR;
     262                 : 
     263               0 :   mLibrary = nsnull;
     264               0 : }
     265                 : 
     266               0 : nsNPAPIPlugin::~nsNPAPIPlugin()
     267                 : {
     268               0 :   delete mLibrary;
     269               0 :   mLibrary = nsnull;
     270               0 : }
     271                 : 
     272                 : void
     273               0 : nsNPAPIPlugin::PluginCrashed(const nsAString& pluginDumpID,
     274                 :                              const nsAString& browserDumpID)
     275                 : {
     276               0 :   nsRefPtr<nsPluginHost> host = dont_AddRef(nsPluginHost::GetInst());
     277               0 :   host->PluginCrashed(this, pluginDumpID, browserDumpID);
     278               0 : }
     279                 : 
     280                 : #if defined(XP_MACOSX) && defined(__i386__)
     281                 : static PRInt32 OSXVersion()
     282                 : {
     283                 :   static PRInt32 gOSXVersion = 0x0;
     284                 :   if (gOSXVersion == 0x0) {
     285                 :     OSErr err = ::Gestalt(gestaltSystemVersion, (SInt32*)&gOSXVersion);
     286                 :     if (err != noErr) {
     287                 :       // This should probably be changed when our minimum version changes
     288                 :       NS_ERROR("Couldn't determine OS X version, assuming 10.5");
     289                 :       gOSXVersion = 0x00001050;
     290                 :     }
     291                 :   }
     292                 :   return gOSXVersion;
     293                 : }
     294                 : 
     295                 : // Detects machines with Intel GMA9xx GPUs.
     296                 : // kCGLRendererIDMatchingMask and kCGLRendererIntel900ID are only defined in the 10.6 SDK.
     297                 : #define CGLRendererIDMatchingMask 0x00FE7F00
     298                 : #define CGLRendererIntel900ID 0x00024000
     299                 : static bool GMA9XXGraphics()
     300                 : {
     301                 :   bool hasIntelGMA9XX = false;
     302                 :   CGLRendererInfoObj renderer = 0;
     303                 :   GLint rendererCount = 0;
     304                 :   if (::CGLQueryRendererInfo(0xffffffff, &renderer, &rendererCount) == kCGLNoError) {
     305                 :     for (GLint c = 0; c < rendererCount; c++) {
     306                 :       GLint rendProp = 0;
     307                 :       if (::CGLDescribeRenderer(renderer, c, kCGLRPRendererID, &rendProp) == kCGLNoError) {
     308                 :         if ((rendProp & CGLRendererIDMatchingMask) == CGLRendererIntel900ID) {
     309                 :           hasIntelGMA9XX = true;
     310                 :           break;
     311                 :         }
     312                 :       }
     313                 :     }
     314                 :     ::CGLDestroyRendererInfo(renderer);
     315                 :   }
     316                 :   return hasIntelGMA9XX;
     317                 : }
     318                 : #endif
     319                 : 
     320                 : bool
     321               0 : nsNPAPIPlugin::RunPluginOOP(const nsPluginTag *aPluginTag)
     322                 : {
     323               0 :   if (PR_GetEnv("MOZ_DISABLE_OOP_PLUGINS")) {
     324               0 :     return false;
     325                 :   }
     326                 : 
     327               0 :   if (!aPluginTag) {
     328               0 :     return false;
     329                 :   }
     330                 : 
     331                 : #if defined(XP_MACOSX) && defined(__i386__)
     332                 :   // Only allow on Mac OS X 10.6 or higher.
     333                 :   if (OSXVersion() < 0x00001060) {
     334                 :     return false;
     335                 :   }
     336                 :   // Blacklist Flash 10.0 or lower since it may try to negotiate Carbon/Quickdraw
     337                 :   // which are not supported out of process. Also blacklist Flash 10.1 if this
     338                 :   // machine has an Intel GMA9XX GPU because Flash will negotiate Quickdraw graphics.
     339                 :   // Never blacklist Flash >= 10.2.
     340                 :   if (aPluginTag->mFileName.EqualsIgnoreCase("flash player.plugin")) {
     341                 :     // If the first '.' is before position 2 or the version 
     342                 :     // starts with 10.0 then we are dealing with Flash 10 or less.
     343                 :     if (aPluginTag->mVersion.FindChar('.') < 2) {
     344                 :       return false;
     345                 :     }
     346                 :     if (aPluginTag->mVersion.Length() >= 4) {
     347                 :       nsCString versionPrefix;
     348                 :       aPluginTag->mVersion.Left(versionPrefix, 4);
     349                 :       if (versionPrefix.EqualsASCII("10.0")) {
     350                 :         return false;
     351                 :       }
     352                 :       if (versionPrefix.EqualsASCII("10.1") && GMA9XXGraphics()) {
     353                 :         return false;
     354                 :       }
     355                 :     }
     356                 :   }
     357                 : #endif
     358                 : 
     359               0 :   nsCOMPtr<nsIPrefBranch> prefs = do_GetService(NS_PREFSERVICE_CONTRACTID);
     360               0 :   if (!prefs) {
     361               0 :     return false;
     362                 :   }
     363                 : 
     364                 :   // Get per-library whitelist/blacklist pref string
     365                 :   // "dom.ipc.plugins.enabled.filename.dll" and fall back to the default value
     366                 :   // of "dom.ipc.plugins.enabled"
     367                 :   // The "filename.dll" part can contain shell wildcard pattern
     368                 : 
     369               0 :   nsCAutoString prefFile(aPluginTag->mFullPath.get());
     370               0 :   PRInt32 slashPos = prefFile.RFindCharInSet("/\\");
     371               0 :   if (kNotFound == slashPos)
     372               0 :     return false;
     373               0 :   prefFile.Cut(0, slashPos + 1);
     374               0 :   ToLowerCase(prefFile);
     375                 : 
     376                 : #ifdef XP_MACOSX
     377                 : #if defined(__i386__)
     378                 :   nsCAutoString prefGroupKey("dom.ipc.plugins.enabled.i386.");
     379                 : #elif defined(__x86_64__)
     380                 :   nsCAutoString prefGroupKey("dom.ipc.plugins.enabled.x86_64.");
     381                 : #elif defined(__ppc__)
     382                 :   nsCAutoString prefGroupKey("dom.ipc.plugins.enabled.ppc.");
     383                 : #endif
     384                 : #else
     385               0 :   nsCAutoString prefGroupKey("dom.ipc.plugins.enabled.");
     386                 : #endif
     387                 : 
     388                 :   // Java plugins include a number of different file names,
     389                 :   // so use the mime type (mIsJavaPlugin) and a special pref.
     390                 :   bool javaIsEnabled;
     391               0 :   if (aPluginTag->mIsJavaPlugin &&
     392               0 :       NS_SUCCEEDED(prefs->GetBoolPref("dom.ipc.plugins.java.enabled", &javaIsEnabled)) &&
     393               0 :       !javaIsEnabled) {
     394               0 :     return false;
     395                 :   }
     396                 : 
     397                 :   PRUint32 prefCount;
     398                 :   char** prefNames;
     399               0 :   nsresult rv = prefs->GetChildList(prefGroupKey.get(),
     400               0 :                                     &prefCount, &prefNames);
     401                 : 
     402               0 :   bool oopPluginsEnabled = false;
     403               0 :   bool prefSet = false;
     404                 : 
     405               0 :   if (NS_SUCCEEDED(rv) && prefCount > 0) {
     406               0 :     PRUint32 prefixLength = prefGroupKey.Length();
     407               0 :     for (PRUint32 currentPref = 0; currentPref < prefCount; currentPref++) {
     408                 :       // Get the mask
     409               0 :       const char* maskStart = prefNames[currentPref] + prefixLength;
     410               0 :       bool match = false;
     411                 : 
     412               0 :       int valid = NS_WildCardValid(maskStart);
     413               0 :       if (valid == INVALID_SXP) {
     414               0 :          continue;
     415                 :       }
     416               0 :       else if(valid == NON_SXP) {
     417                 :         // mask is not a shell pattern, compare it as normal string
     418               0 :         match = (strcmp(prefFile.get(), maskStart) == 0);
     419                 :       }
     420                 :       else {
     421               0 :         match = (NS_WildCardMatch(prefFile.get(), maskStart, 0) == MATCH);
     422                 :       }
     423                 : 
     424               0 :       if (match && NS_SUCCEEDED(prefs->GetBoolPref(prefNames[currentPref],
     425                 :                                                    &oopPluginsEnabled))) {
     426               0 :         prefSet = true;
     427               0 :         break;
     428                 :       }
     429                 :     }
     430               0 :     NS_FREE_XPCOM_ALLOCATED_POINTER_ARRAY(prefCount, prefNames);
     431                 :   }
     432                 : 
     433               0 :   if (!prefSet) {
     434               0 :     oopPluginsEnabled = false;
     435                 : #ifdef XP_MACOSX
     436                 : #if defined(__i386__)
     437                 :     prefs->GetBoolPref("dom.ipc.plugins.enabled.i386", &oopPluginsEnabled);
     438                 : #elif defined(__x86_64__)
     439                 :     prefs->GetBoolPref("dom.ipc.plugins.enabled.x86_64", &oopPluginsEnabled);
     440                 : #elif defined(__ppc__)
     441                 :     prefs->GetBoolPref("dom.ipc.plugins.enabled.ppc", &oopPluginsEnabled);
     442                 : #endif
     443                 : #else
     444               0 :     prefs->GetBoolPref("dom.ipc.plugins.enabled", &oopPluginsEnabled);
     445                 : #endif
     446                 :   }
     447                 : 
     448               0 :   return oopPluginsEnabled;
     449                 : }
     450                 : 
     451                 : inline PluginLibrary*
     452               0 : GetNewPluginLibrary(nsPluginTag *aPluginTag)
     453                 : {
     454               0 :   if (!aPluginTag) {
     455               0 :     return nsnull;
     456                 :   }
     457                 : 
     458               0 :   if (nsNPAPIPlugin::RunPluginOOP(aPluginTag)) {
     459               0 :     return PluginModuleParent::LoadModule(aPluginTag->mFullPath.get());
     460                 :   }
     461               0 :   return new PluginPRLibrary(aPluginTag->mFullPath.get(), aPluginTag->mLibrary);
     462                 : }
     463                 : 
     464                 : // Creates an nsNPAPIPlugin object. One nsNPAPIPlugin object exists per plugin (not instance).
     465                 : nsresult
     466               0 : nsNPAPIPlugin::CreatePlugin(nsPluginTag *aPluginTag, nsNPAPIPlugin** aResult)
     467                 : {
     468               0 :   *aResult = nsnull;
     469                 : 
     470               0 :   if (!aPluginTag) {
     471               0 :     return NS_ERROR_FAILURE;
     472                 :   }
     473                 : 
     474               0 :   CheckClassInitialized();
     475                 : 
     476               0 :   nsRefPtr<nsNPAPIPlugin> plugin = new nsNPAPIPlugin();
     477               0 :   if (!plugin)
     478               0 :     return NS_ERROR_OUT_OF_MEMORY;
     479                 : 
     480               0 :   PluginLibrary* pluginLib = GetNewPluginLibrary(aPluginTag);
     481               0 :   if (!pluginLib) {
     482               0 :     return NS_ERROR_FAILURE;
     483                 :   }
     484                 : 
     485                 : #if defined(XP_MACOSX) || defined(MOZ_WIDGET_ANDROID)
     486                 :   if (!pluginLib->HasRequiredFunctions()) {
     487                 :     NS_WARNING("Not all necessary functions exposed by plugin, it will not load.");
     488                 :     return NS_ERROR_FAILURE;
     489                 :   }
     490                 : #endif
     491                 : 
     492               0 :   plugin->mLibrary = pluginLib;
     493               0 :   pluginLib->SetPlugin(plugin);
     494                 : 
     495                 :   NPError pluginCallError;
     496                 :   nsresult rv;
     497                 : 
     498                 : // Exchange NPAPI entry points.
     499                 : #if defined(XP_WIN) || defined(XP_OS2)
     500                 :   // NP_GetEntryPoints must be called before NP_Initialize on Windows.
     501                 :   rv = pluginLib->NP_GetEntryPoints(&plugin->mPluginFuncs, &pluginCallError);
     502                 :   if (rv != NS_OK || pluginCallError != NPERR_NO_ERROR) {
     503                 :     return NS_ERROR_FAILURE;
     504                 :   }
     505                 : 
     506                 :   // NP_Initialize must be called after NP_GetEntryPoints on Windows.
     507                 :   rv = pluginLib->NP_Initialize(&sBrowserFuncs, &pluginCallError);
     508                 :   if (rv != NS_OK || pluginCallError != NPERR_NO_ERROR) {
     509                 :     return NS_ERROR_FAILURE;
     510                 :   }
     511                 : #elif defined(XP_MACOSX)
     512                 :   // NP_Initialize must be called before NP_GetEntryPoints on Mac OS X.
     513                 :   // We need to match WebKit's behavior.
     514                 :   rv = pluginLib->NP_Initialize(&sBrowserFuncs, &pluginCallError);
     515                 :   if (rv != NS_OK || pluginCallError != NPERR_NO_ERROR) {
     516                 :     return NS_ERROR_FAILURE;
     517                 :   }
     518                 : 
     519                 :   rv = pluginLib->NP_GetEntryPoints(&plugin->mPluginFuncs, &pluginCallError);
     520                 :   if (rv != NS_OK || pluginCallError != NPERR_NO_ERROR) {
     521                 :     return NS_ERROR_FAILURE;
     522                 :   }
     523                 : #elif defined(MOZ_WIDGET_GONK)
     524                 : #else
     525               0 :   rv = pluginLib->NP_Initialize(&sBrowserFuncs, &plugin->mPluginFuncs, &pluginCallError);
     526               0 :   if (rv != NS_OK || pluginCallError != NPERR_NO_ERROR) {
     527               0 :     return NS_ERROR_FAILURE;
     528                 :   }
     529                 : #endif
     530                 : 
     531               0 :   *aResult = plugin.forget().get();
     532               0 :   return NS_OK;
     533                 : }
     534                 : 
     535                 : PluginLibrary*
     536               0 : nsNPAPIPlugin::GetLibrary()
     537                 : {
     538               0 :   return mLibrary;
     539                 : }
     540                 : 
     541                 : NPPluginFuncs*
     542               0 : nsNPAPIPlugin::PluginFuncs()
     543                 : {
     544               0 :   return &mPluginFuncs;
     545                 : }
     546                 : 
     547                 : nsresult
     548               0 : nsNPAPIPlugin::CreatePluginInstance(nsNPAPIPluginInstance **aResult)
     549                 : {
     550               0 :   if (!aResult)
     551               0 :     return NS_ERROR_NULL_POINTER;
     552                 : 
     553               0 :   *aResult = NULL;
     554                 : 
     555               0 :   nsRefPtr<nsNPAPIPluginInstance> inst = new nsNPAPIPluginInstance(this);
     556               0 :   if (!inst)
     557               0 :     return NS_ERROR_OUT_OF_MEMORY;
     558                 : 
     559               0 :   *aResult = inst;
     560               0 :   NS_ADDREF(*aResult);
     561               0 :   return NS_OK;
     562                 : }
     563                 : 
     564                 : nsresult
     565               0 : nsNPAPIPlugin::Shutdown()
     566                 : {
     567               0 :   NPP_PLUGIN_LOG(PLUGIN_LOG_BASIC,
     568                 :                  ("NPP Shutdown to be called: this=%p\n", this));
     569                 : 
     570                 :   NPError shutdownError;
     571               0 :   mLibrary->NP_Shutdown(&shutdownError);
     572                 : 
     573               0 :   return NS_OK;
     574                 : }
     575                 : 
     576                 : nsresult
     577               0 : nsNPAPIPlugin::RetainStream(NPStream *pstream, nsISupports **aRetainedPeer)
     578                 : {
     579               0 :   if (!aRetainedPeer)
     580               0 :     return NS_ERROR_NULL_POINTER;
     581                 : 
     582               0 :   *aRetainedPeer = NULL;
     583                 : 
     584               0 :   if (!pstream || !pstream->ndata)
     585               0 :     return NPERR_INVALID_PARAM;
     586                 : 
     587                 :   nsNPAPIPluginStreamListener* listener =
     588               0 :     static_cast<nsNPAPIPluginStreamListener*>(pstream->ndata);
     589               0 :   nsPluginStreamListenerPeer* peer = listener->GetStreamListenerPeer();
     590                 : 
     591               0 :   if (!peer)
     592               0 :     return NPERR_GENERIC_ERROR;
     593                 : 
     594               0 :   *aRetainedPeer = (nsISupports*) peer;
     595               0 :   NS_ADDREF(*aRetainedPeer);
     596               0 :   return NS_OK;
     597                 : }
     598                 : 
     599                 : // Create a new NPP GET or POST (given in the type argument) url
     600                 : // stream that may have a notify callback
     601                 : NPError
     602               0 : MakeNewNPAPIStreamInternal(NPP npp, const char *relativeURL, const char *target,
     603                 :                           eNPPStreamTypeInternal type,
     604                 :                           bool bDoNotify = false,
     605                 :                           void *notifyData = nsnull, uint32_t len = 0,
     606                 :                           const char *buf = nsnull, NPBool file = false)
     607                 : {
     608               0 :   if (!npp)
     609               0 :     return NPERR_INVALID_INSTANCE_ERROR;
     610                 : 
     611               0 :   PluginDestructionGuard guard(npp);
     612                 : 
     613               0 :   nsNPAPIPluginInstance *inst = (nsNPAPIPluginInstance *) npp->ndata;
     614               0 :   if (!inst || !inst->IsRunning())
     615               0 :     return NPERR_INVALID_INSTANCE_ERROR;
     616                 : 
     617               0 :   nsCOMPtr<nsIPluginHost> pluginHostCOM = do_GetService(MOZ_PLUGIN_HOST_CONTRACTID);
     618               0 :   nsPluginHost *pluginHost = static_cast<nsPluginHost*>(pluginHostCOM.get());
     619               0 :   if (!pluginHost) {
     620               0 :     return NPERR_GENERIC_ERROR;
     621                 :   }
     622                 : 
     623               0 :   nsCOMPtr<nsIPluginStreamListener> listener;
     624                 :   // Set aCallNotify here to false.  If pluginHost->GetURL or PostURL fail,
     625                 :   // the listener's destructor will do the notification while we are about to
     626                 :   // return a failure code.
     627                 :   // Call SetCallNotify(true) below after we are sure we cannot return a failure 
     628                 :   // code.
     629               0 :   if (!target) {
     630                 :     inst->NewStreamListener(relativeURL, notifyData,
     631               0 :                             getter_AddRefs(listener));
     632               0 :     if (listener) {
     633               0 :       static_cast<nsNPAPIPluginStreamListener*>(listener.get())->SetCallNotify(false);
     634                 :     }
     635                 :   }
     636                 : 
     637               0 :   switch (type) {
     638                 :   case eNPPStreamTypeInternal_Get:
     639                 :     {
     640               0 :       if (NS_FAILED(pluginHost->GetURL(inst, relativeURL, target, listener,
     641                 :                                        NULL, NULL, false)))
     642               0 :         return NPERR_GENERIC_ERROR;
     643               0 :       break;
     644                 :     }
     645                 :   case eNPPStreamTypeInternal_Post:
     646                 :     {
     647               0 :       if (NS_FAILED(pluginHost->PostURL(inst, relativeURL, len, buf, file, target, listener, NULL, NULL, false, 0, NULL)))
     648               0 :         return NPERR_GENERIC_ERROR;
     649               0 :       break;
     650                 :     }
     651                 :   default:
     652               0 :     NS_ERROR("how'd I get here");
     653                 :   }
     654                 : 
     655               0 :   if (listener) {
     656                 :     // SetCallNotify(bDoNotify) here, see comment above.
     657               0 :     static_cast<nsNPAPIPluginStreamListener*>(listener.get())->SetCallNotify(bDoNotify);
     658                 :   }
     659                 : 
     660               0 :   return NPERR_NO_ERROR;
     661                 : }
     662                 : 
     663                 : #if defined(MOZ_MEMORY_WINDOWS)
     664                 : extern "C" size_t malloc_usable_size(const void *ptr);
     665                 : #endif
     666                 : 
     667                 : namespace {
     668                 : 
     669                 : static char *gNPPException;
     670                 : 
     671                 : // A little helper class used to wrap up plugin manager streams (that is,
     672                 : // streams from the plugin to the browser).
     673                 : class nsNPAPIStreamWrapper : nsISupports
     674                 : {
     675                 : public:
     676                 :   NS_DECL_ISUPPORTS
     677                 : 
     678                 : protected:
     679                 :   nsIOutputStream *fStream;
     680                 :   NPStream        fNPStream;
     681                 : 
     682                 : public:
     683                 :   nsNPAPIStreamWrapper(nsIOutputStream* stream);
     684                 :   virtual ~nsNPAPIStreamWrapper();
     685                 : 
     686                 :   void GetStream(nsIOutputStream* &result);
     687               0 :   NPStream* GetNPStream() { return &fNPStream; }
     688                 : };
     689                 : 
     690                 : class nsPluginThreadRunnable : public nsRunnable,
     691                 :                                public PRCList
     692                 : {
     693                 : public:
     694                 :   nsPluginThreadRunnable(NPP instance, PluginThreadCallback func,
     695                 :                          void *userData);
     696                 :   virtual ~nsPluginThreadRunnable();
     697                 : 
     698                 :   NS_IMETHOD Run();
     699                 : 
     700               0 :   bool IsForInstance(NPP instance)
     701                 :   {
     702               0 :     return (mInstance == instance);
     703                 :   }
     704                 : 
     705               0 :   void Invalidate()
     706                 :   {
     707               0 :     mFunc = nsnull;
     708               0 :   }
     709                 : 
     710               0 :   bool IsValid()
     711                 :   {
     712               0 :     return (mFunc != nsnull);
     713                 :   }
     714                 : 
     715                 : private:  
     716                 :   NPP mInstance;
     717                 :   PluginThreadCallback mFunc;
     718                 :   void *mUserData;
     719                 : };
     720                 : 
     721                 : static nsIDocument *
     722               0 : GetDocumentFromNPP(NPP npp)
     723                 : {
     724               0 :   NS_ENSURE_TRUE(npp, nsnull);
     725                 : 
     726               0 :   nsNPAPIPluginInstance *inst = (nsNPAPIPluginInstance *)npp->ndata;
     727               0 :   NS_ENSURE_TRUE(inst, nsnull);
     728                 : 
     729               0 :   PluginDestructionGuard guard(inst);
     730                 : 
     731               0 :   nsCOMPtr<nsIPluginInstanceOwner> owner;
     732               0 :   inst->GetOwner(getter_AddRefs(owner));
     733               0 :   NS_ENSURE_TRUE(owner, nsnull);
     734                 : 
     735               0 :   nsCOMPtr<nsIDocument> doc;
     736               0 :   owner->GetDocument(getter_AddRefs(doc));
     737                 : 
     738               0 :   return doc;
     739                 : }
     740                 : 
     741                 : static JSContext *
     742               0 : GetJSContextFromDoc(nsIDocument *doc)
     743                 : {
     744               0 :   nsIScriptGlobalObject *sgo = doc->GetScriptGlobalObject();
     745               0 :   NS_ENSURE_TRUE(sgo, nsnull);
     746                 : 
     747               0 :   nsIScriptContext *scx = sgo->GetContext();
     748               0 :   NS_ENSURE_TRUE(scx, nsnull);
     749                 : 
     750               0 :   return scx->GetNativeContext();
     751                 : }
     752                 : 
     753                 : static JSContext *
     754               0 : GetJSContextFromNPP(NPP npp)
     755                 : {
     756               0 :   nsIDocument *doc = GetDocumentFromNPP(npp);
     757               0 :   NS_ENSURE_TRUE(doc, nsnull);
     758                 : 
     759               0 :   return GetJSContextFromDoc(doc);
     760                 : }
     761                 : 
     762                 : static NPIdentifier
     763               0 : doGetIdentifier(JSContext *cx, const NPUTF8* name)
     764                 : {
     765               0 :   NS_ConvertUTF8toUTF16 utf16name(name);
     766                 : 
     767               0 :   JSString *str = ::JS_InternUCStringN(cx, (jschar *)utf16name.get(),
     768               0 :                                        utf16name.Length());
     769                 : 
     770               0 :   if (!str)
     771               0 :     return NULL;
     772                 : 
     773               0 :   return StringToNPIdentifier(cx, str);
     774                 : }
     775                 : 
     776                 : #if defined(MOZ_MEMORY_WINDOWS)
     777                 : BOOL
     778                 : InHeap(HANDLE hHeap, LPVOID lpMem)
     779                 : {
     780                 :   BOOL success = FALSE;
     781                 :   PROCESS_HEAP_ENTRY he;
     782                 :   he.lpData = NULL;
     783                 :   while (HeapWalk(hHeap, &he) != 0) {
     784                 :     if (he.lpData == lpMem) {
     785                 :       success = TRUE;
     786                 :       break;
     787                 :     }
     788                 :   }
     789                 :   HeapUnlock(hHeap);
     790                 :   return success;
     791                 : }
     792                 : #endif
     793                 : 
     794                 : } /* anonymous namespace */
     795                 : 
     796               0 : NS_IMPL_ISUPPORTS1(nsNPAPIStreamWrapper, nsISupports)
     797                 : 
     798               0 : nsNPAPIStreamWrapper::nsNPAPIStreamWrapper(nsIOutputStream* stream)
     799               0 : : fStream(stream)
     800                 : {
     801               0 :   NS_ASSERTION(stream, "bad stream");
     802                 : 
     803               0 :   fStream = stream;
     804               0 :   NS_ADDREF(fStream);
     805                 : 
     806               0 :   memset(&fNPStream, 0, sizeof(fNPStream));
     807               0 :   fNPStream.ndata = (void*) this;
     808               0 : }
     809                 : 
     810               0 : nsNPAPIStreamWrapper::~nsNPAPIStreamWrapper()
     811                 : {
     812               0 :   fStream->Close();
     813               0 :   NS_IF_RELEASE(fStream);
     814               0 : }
     815                 : 
     816                 : void
     817               0 : nsNPAPIStreamWrapper::GetStream(nsIOutputStream* &result)
     818                 : {
     819               0 :   result = fStream;
     820               0 :   NS_IF_ADDREF(fStream);
     821               0 : }
     822                 : 
     823               0 : NPPExceptionAutoHolder::NPPExceptionAutoHolder()
     824               0 :   : mOldException(gNPPException)
     825                 : {
     826               0 :   gNPPException = nsnull;
     827               0 : }
     828                 : 
     829               0 : NPPExceptionAutoHolder::~NPPExceptionAutoHolder()
     830                 : {
     831               0 :   NS_ASSERTION(!gNPPException, "NPP exception not properly cleared!");
     832                 : 
     833               0 :   gNPPException = mOldException;
     834               0 : }
     835                 : 
     836               0 : nsPluginThreadRunnable::nsPluginThreadRunnable(NPP instance,
     837                 :                                                PluginThreadCallback func,
     838                 :                                                void *userData)
     839               0 :   : mInstance(instance), mFunc(func), mUserData(userData)
     840                 : {
     841               0 :   if (!sPluginThreadAsyncCallLock) {
     842                 :     // Failed to create lock, not much we can do here then...
     843               0 :     mFunc = nsnull;
     844                 : 
     845               0 :     return;
     846                 :   }
     847                 : 
     848               0 :   PR_INIT_CLIST(this);
     849                 : 
     850                 :   {
     851               0 :     MutexAutoLock lock(*sPluginThreadAsyncCallLock);
     852                 : 
     853               0 :     nsNPAPIPluginInstance *inst = (nsNPAPIPluginInstance *)instance->ndata;
     854               0 :     if (!inst || !inst->IsRunning()) {
     855                 :       // The plugin was stopped, ignore this async call.
     856               0 :       mFunc = nsnull;
     857                 : 
     858                 :       return;
     859                 :     }
     860                 : 
     861               0 :     PR_APPEND_LINK(this, &sPendingAsyncCalls);
     862                 :   }
     863                 : }
     864                 : 
     865               0 : nsPluginThreadRunnable::~nsPluginThreadRunnable()
     866                 : {
     867               0 :   if (!sPluginThreadAsyncCallLock) {
     868                 :     return;
     869                 :   }
     870                 : 
     871                 :   {
     872               0 :     MutexAutoLock lock(*sPluginThreadAsyncCallLock);
     873                 : 
     874               0 :     PR_REMOVE_LINK(this);
     875                 :   }
     876               0 : }
     877                 : 
     878                 : NS_IMETHODIMP
     879               0 : nsPluginThreadRunnable::Run()
     880                 : {
     881               0 :   if (mFunc) {
     882               0 :     PluginDestructionGuard guard(mInstance);
     883                 : 
     884               0 :     NS_TRY_SAFE_CALL_VOID(mFunc(mUserData), nsnull);
     885                 :   }
     886                 : 
     887               0 :   return NS_OK;
     888                 : }
     889                 : 
     890                 : void
     891               0 : OnPluginDestroy(NPP instance)
     892                 : {
     893               0 :   if (!sPluginThreadAsyncCallLock) {
     894               0 :     return;
     895                 :   }
     896                 : 
     897                 :   {
     898               0 :     MutexAutoLock lock(*sPluginThreadAsyncCallLock);
     899                 : 
     900               0 :     if (PR_CLIST_IS_EMPTY(&sPendingAsyncCalls)) {
     901                 :       return;
     902                 :     }
     903                 : 
     904                 :     nsPluginThreadRunnable *r =
     905               0 :       (nsPluginThreadRunnable *)PR_LIST_HEAD(&sPendingAsyncCalls);
     906                 : 
     907               0 :     do {
     908               0 :       if (r->IsForInstance(instance)) {
     909               0 :         r->Invalidate();
     910                 :       }
     911                 : 
     912               0 :       r = (nsPluginThreadRunnable *)PR_NEXT_LINK(r);
     913                 :     } while (r != &sPendingAsyncCalls);
     914                 :   }
     915                 : }
     916                 : 
     917                 : void
     918             173 : OnShutdown()
     919                 : {
     920             173 :   NS_ASSERTION(PR_CLIST_IS_EMPTY(&sPendingAsyncCalls),
     921                 :                "Pending async plugin call list not cleaned up!");
     922                 : 
     923             173 :   if (sPluginThreadAsyncCallLock) {
     924               0 :     delete sPluginThreadAsyncCallLock;
     925                 : 
     926               0 :     sPluginThreadAsyncCallLock = nsnull;
     927                 :   }
     928             173 : }
     929                 : 
     930               0 : AsyncCallbackAutoLock::AsyncCallbackAutoLock()
     931                 : {
     932               0 :   if (sPluginThreadAsyncCallLock) {
     933               0 :     sPluginThreadAsyncCallLock->Lock();
     934                 :   }
     935               0 : }
     936                 : 
     937               0 : AsyncCallbackAutoLock::~AsyncCallbackAutoLock()
     938                 : {
     939               0 :   if (sPluginThreadAsyncCallLock) {
     940               0 :     sPluginThreadAsyncCallLock->Unlock();
     941                 :   }
     942               0 : }
     943                 : 
     944                 : 
     945                 : NPP NPPStack::sCurrentNPP = nsnull;
     946                 : 
     947                 : const char *
     948               0 : PeekException()
     949                 : {
     950               0 :   return gNPPException;
     951                 : }
     952                 : 
     953                 : void
     954               0 : PopException()
     955                 : {
     956               0 :   NS_ASSERTION(gNPPException, "Uh, no NPP exception to pop!");
     957                 : 
     958               0 :   if (gNPPException) {
     959               0 :     free(gNPPException);
     960                 : 
     961               0 :     gNPPException = nsnull;
     962                 :   }
     963               0 : }
     964                 : 
     965                 : //
     966                 : // Static callbacks that get routed back through the new C++ API
     967                 : //
     968                 : 
     969                 : namespace mozilla {
     970                 : namespace plugins {
     971                 : namespace parent {
     972                 : 
     973                 : NPError NP_CALLBACK
     974               0 : _geturl(NPP npp, const char* relativeURL, const char* target)
     975                 : {
     976               0 :   if (!NS_IsMainThread()) {
     977               0 :     NPN_PLUGIN_LOG(PLUGIN_LOG_ALWAYS,("NPN_geturl called from the wrong thread\n"));
     978               0 :     return NPERR_INVALID_PARAM;
     979                 :   }
     980                 : 
     981               0 :   NPN_PLUGIN_LOG(PLUGIN_LOG_NORMAL,
     982                 :   ("NPN_GetURL: npp=%p, target=%s, url=%s\n", (void *)npp, target,
     983                 :    relativeURL));
     984                 : 
     985               0 :   PluginDestructionGuard guard(npp);
     986                 : 
     987                 :   // Block Adobe Acrobat from loading URLs that are not http:, https:,
     988                 :   // or ftp: URLs if the given target is null.
     989               0 :   if (!target && relativeURL &&
     990               0 :       (strncmp(relativeURL, "http:", 5) != 0) &&
     991               0 :       (strncmp(relativeURL, "https:", 6) != 0) &&
     992               0 :       (strncmp(relativeURL, "ftp:", 4) != 0)) {
     993               0 :     nsNPAPIPluginInstance *inst = (nsNPAPIPluginInstance *) npp->ndata;
     994                 : 
     995                 :     
     996               0 :     const char *name = nsnull;
     997               0 :     nsRefPtr<nsPluginHost> host = dont_AddRef(nsPluginHost::GetInst());
     998               0 :     host->GetPluginName(inst, &name);
     999                 : 
    1000               0 :     if (name && strstr(name, "Adobe") && strstr(name, "Acrobat")) {
    1001               0 :       return NPERR_NO_ERROR;
    1002                 :     }
    1003                 :   }
    1004                 : 
    1005                 :   return MakeNewNPAPIStreamInternal(npp, relativeURL, target,
    1006               0 :                                     eNPPStreamTypeInternal_Get);
    1007                 : }
    1008                 : 
    1009                 : NPError NP_CALLBACK
    1010               0 : _geturlnotify(NPP npp, const char* relativeURL, const char* target,
    1011                 :               void* notifyData)
    1012                 : {
    1013               0 :   if (!NS_IsMainThread()) {
    1014               0 :     NPN_PLUGIN_LOG(PLUGIN_LOG_ALWAYS,("NPN_geturlnotify called from the wrong thread\n"));
    1015               0 :     return NPERR_INVALID_PARAM;
    1016                 :   }
    1017                 : 
    1018               0 :   NPN_PLUGIN_LOG(PLUGIN_LOG_NORMAL,
    1019                 :     ("NPN_GetURLNotify: npp=%p, target=%s, notify=%p, url=%s\n", (void*)npp,
    1020                 :      target, notifyData, relativeURL));
    1021                 : 
    1022               0 :   PluginDestructionGuard guard(npp);
    1023                 : 
    1024                 :   return MakeNewNPAPIStreamInternal(npp, relativeURL, target,
    1025                 :                                     eNPPStreamTypeInternal_Get, true,
    1026               0 :                                     notifyData);
    1027                 : }
    1028                 : 
    1029                 : NPError NP_CALLBACK
    1030               0 : _posturlnotify(NPP npp, const char *relativeURL, const char *target,
    1031                 :                uint32_t len, const char *buf, NPBool file, void *notifyData)
    1032                 : {
    1033               0 :   if (!NS_IsMainThread()) {
    1034               0 :     NPN_PLUGIN_LOG(PLUGIN_LOG_ALWAYS,("NPN_posturlnotify called from the wrong thread\n"));
    1035               0 :     return NPERR_INVALID_PARAM;
    1036                 :   }
    1037               0 :   if (!buf)
    1038               0 :     return NPERR_INVALID_PARAM;
    1039                 : 
    1040               0 :   NPN_PLUGIN_LOG(PLUGIN_LOG_NORMAL,
    1041                 :                  ("NPN_PostURLNotify: npp=%p, target=%s, len=%d, file=%d, "
    1042                 :                   "notify=%p, url=%s, buf=%s\n",
    1043                 :                   (void*)npp, target, len, file, notifyData, relativeURL,
    1044                 :                   buf));
    1045                 : 
    1046               0 :   PluginDestructionGuard guard(npp);
    1047                 : 
    1048                 :   return MakeNewNPAPIStreamInternal(npp, relativeURL, target,
    1049                 :                                     eNPPStreamTypeInternal_Post, true,
    1050               0 :                                     notifyData, len, buf, file);
    1051                 : }
    1052                 : 
    1053                 : NPError NP_CALLBACK
    1054               0 : _posturl(NPP npp, const char *relativeURL, const char *target,
    1055                 :          uint32_t len, const char *buf, NPBool file)
    1056                 : {
    1057               0 :   if (!NS_IsMainThread()) {
    1058               0 :     NPN_PLUGIN_LOG(PLUGIN_LOG_ALWAYS,("NPN_posturl called from the wrong thread\n"));
    1059               0 :     return NPERR_INVALID_PARAM;
    1060                 :   }
    1061               0 :   NPN_PLUGIN_LOG(PLUGIN_LOG_NORMAL,
    1062                 :                  ("NPN_PostURL: npp=%p, target=%s, file=%d, len=%d, url=%s, "
    1063                 :                   "buf=%s\n",
    1064                 :                   (void*)npp, target, file, len, relativeURL, buf));
    1065                 : 
    1066               0 :   PluginDestructionGuard guard(npp);
    1067                 : 
    1068                 :   return MakeNewNPAPIStreamInternal(npp, relativeURL, target,
    1069                 :                                     eNPPStreamTypeInternal_Post, false, nsnull,
    1070               0 :                                     len, buf, file);
    1071                 : }
    1072                 : 
    1073                 : NPError NP_CALLBACK
    1074               0 : _newstream(NPP npp, NPMIMEType type, const char* target, NPStream* *result)
    1075                 : {
    1076               0 :   if (!NS_IsMainThread()) {
    1077               0 :     NPN_PLUGIN_LOG(PLUGIN_LOG_ALWAYS,("NPN_newstream called from the wrong thread\n"));
    1078               0 :     return NPERR_INVALID_PARAM;
    1079                 :   }
    1080               0 :   NPN_PLUGIN_LOG(PLUGIN_LOG_NORMAL,
    1081                 :   ("NPN_NewStream: npp=%p, type=%s, target=%s\n", (void*)npp,
    1082                 :    (const char *)type, target));
    1083                 : 
    1084               0 :   NPError err = NPERR_INVALID_INSTANCE_ERROR;
    1085               0 :   if (npp && npp->ndata) {
    1086               0 :     nsNPAPIPluginInstance *inst = (nsNPAPIPluginInstance*)npp->ndata;
    1087                 : 
    1088               0 :     PluginDestructionGuard guard(inst);
    1089                 : 
    1090               0 :     nsCOMPtr<nsIOutputStream> stream;
    1091               0 :     if (NS_SUCCEEDED(inst->NewStreamFromPlugin((const char*) type, target,
    1092                 :                                                getter_AddRefs(stream)))) {
    1093               0 :       nsNPAPIStreamWrapper* wrapper = new nsNPAPIStreamWrapper(stream);
    1094               0 :       if (wrapper) {
    1095               0 :         (*result) = wrapper->GetNPStream();
    1096               0 :         err = NPERR_NO_ERROR;
    1097                 :       } else {
    1098               0 :         err = NPERR_OUT_OF_MEMORY_ERROR;
    1099                 :       }
    1100                 :     } else {
    1101               0 :       err = NPERR_GENERIC_ERROR;
    1102                 :     }
    1103                 :   }
    1104               0 :   return err;
    1105                 : }
    1106                 : 
    1107                 : int32_t NP_CALLBACK
    1108               0 : _write(NPP npp, NPStream *pstream, int32_t len, void *buffer)
    1109                 : {
    1110               0 :   if (!NS_IsMainThread()) {
    1111               0 :     NPN_PLUGIN_LOG(PLUGIN_LOG_ALWAYS,("NPN_write called from the wrong thread\n"));
    1112               0 :     return 0;
    1113                 :   }
    1114               0 :   NPN_PLUGIN_LOG(PLUGIN_LOG_NORMAL,
    1115                 :                  ("NPN_Write: npp=%p, url=%s, len=%d, buffer=%s\n", (void*)npp,
    1116                 :                   pstream->url, len, (char*)buffer));
    1117                 : 
    1118                 :   // negative return indicates failure to the plugin
    1119               0 :   if (!npp)
    1120               0 :     return -1;
    1121                 : 
    1122               0 :   PluginDestructionGuard guard(npp);
    1123                 : 
    1124               0 :   nsNPAPIStreamWrapper* wrapper = (nsNPAPIStreamWrapper*) pstream->ndata;
    1125               0 :   NS_ASSERTION(wrapper, "null stream");
    1126               0 :   if (!wrapper)
    1127               0 :     return -1;
    1128                 : 
    1129                 :   nsIOutputStream* stream;
    1130               0 :   wrapper->GetStream(stream);
    1131                 : 
    1132               0 :   PRUint32 count = 0;
    1133               0 :   nsresult rv = stream->Write((char *)buffer, len, &count);
    1134               0 :   NS_RELEASE(stream);
    1135                 : 
    1136               0 :   if (rv != NS_OK)
    1137               0 :     return -1;
    1138                 : 
    1139               0 :   return (int32_t)count;
    1140                 : }
    1141                 : 
    1142                 : NPError NP_CALLBACK
    1143               0 : _destroystream(NPP npp, NPStream *pstream, NPError reason)
    1144                 : {
    1145               0 :   if (!NS_IsMainThread()) {
    1146               0 :     NPN_PLUGIN_LOG(PLUGIN_LOG_ALWAYS,("NPN_write called from the wrong thread\n"));
    1147               0 :     return NPERR_INVALID_PARAM;
    1148                 :   }
    1149               0 :   NPN_PLUGIN_LOG(PLUGIN_LOG_NORMAL,
    1150                 :                  ("NPN_DestroyStream: npp=%p, url=%s, reason=%d\n", (void*)npp,
    1151                 :                   pstream->url, (int)reason));
    1152                 : 
    1153               0 :   if (!npp)
    1154               0 :     return NPERR_INVALID_INSTANCE_ERROR;
    1155                 : 
    1156               0 :   PluginDestructionGuard guard(npp);
    1157                 : 
    1158                 :   nsCOMPtr<nsIPluginStreamListener> listener =
    1159               0 :     do_QueryInterface((nsISupports *)pstream->ndata);
    1160                 : 
    1161                 :   // DestroyStream can kill two kinds of streams: NPP derived and NPN derived.
    1162                 :   // check to see if they're trying to kill a NPP stream
    1163               0 :   if (listener) {
    1164                 :     // Tell the stream listner that the stream is now gone.
    1165               0 :     listener->OnStopBinding(nsnull, NS_BINDING_ABORTED);
    1166                 : 
    1167                 :     // FIXME: http://bugzilla.mozilla.org/show_bug.cgi?id=240131
    1168                 :     //
    1169                 :     // Is it ok to leave pstream->ndata set here, and who releases it
    1170                 :     // (or is it even properly ref counted)? And who closes the stream
    1171                 :     // etc?
    1172                 :   } else {
    1173               0 :     nsNPAPIStreamWrapper* wrapper = (nsNPAPIStreamWrapper *)pstream->ndata;
    1174               0 :     NS_ASSERTION(wrapper, "null wrapper");
    1175                 : 
    1176               0 :     if (!wrapper)
    1177               0 :       return NPERR_INVALID_PARAM;
    1178                 : 
    1179                 :     // This will release the wrapped nsIOutputStream.
    1180                 :     // pstream should always be a subobject of wrapper.  See bug 548441.
    1181               0 :     NS_ASSERTION((char*)wrapper <= (char*)pstream && 
    1182                 :                  ((char*)pstream) + sizeof(*pstream)
    1183                 :                      <= ((char*)wrapper) + sizeof(*wrapper),
    1184                 :                  "pstream is not a subobject of wrapper");
    1185               0 :     delete wrapper;
    1186                 :   }
    1187                 : 
    1188               0 :   return NPERR_NO_ERROR;
    1189                 : }
    1190                 : 
    1191                 : void NP_CALLBACK
    1192               0 : _status(NPP npp, const char *message)
    1193                 : {
    1194               0 :   if (!NS_IsMainThread()) {
    1195               0 :     NPN_PLUGIN_LOG(PLUGIN_LOG_ALWAYS,("NPN_status called from the wrong thread\n"));
    1196               0 :     return;
    1197                 :   }
    1198               0 :   NPN_PLUGIN_LOG(PLUGIN_LOG_NORMAL, ("NPN_Status: npp=%p, message=%s\n",
    1199                 :                                      (void*)npp, message));
    1200                 : 
    1201               0 :   if (!npp || !npp->ndata) {
    1202               0 :     NS_WARNING("_status: npp or npp->ndata == 0");
    1203               0 :     return;
    1204                 :   }
    1205                 : 
    1206               0 :   nsNPAPIPluginInstance *inst = (nsNPAPIPluginInstance*)npp->ndata;
    1207                 : 
    1208               0 :   PluginDestructionGuard guard(inst);
    1209                 : 
    1210               0 :   inst->ShowStatus(message);
    1211                 : }
    1212                 : 
    1213                 : void NP_CALLBACK
    1214               0 : _memfree (void *ptr)
    1215                 : {
    1216               0 :   if (!NS_IsMainThread()) {
    1217               0 :     NPN_PLUGIN_LOG(PLUGIN_LOG_ALWAYS,("NPN_memfree called from the wrong thread\n"));
    1218                 :   }
    1219               0 :   NPN_PLUGIN_LOG(PLUGIN_LOG_NOISY, ("NPN_MemFree: ptr=%p\n", ptr));
    1220                 : 
    1221               0 :   if (ptr)
    1222               0 :     nsMemory::Free(ptr);
    1223               0 : }
    1224                 : 
    1225                 : uint32_t NP_CALLBACK
    1226               0 : _memflush(uint32_t size)
    1227                 : {
    1228               0 :   if (!NS_IsMainThread()) {
    1229               0 :     NPN_PLUGIN_LOG(PLUGIN_LOG_ALWAYS,("NPN_memflush called from the wrong thread\n"));
    1230                 :   }
    1231               0 :   NPN_PLUGIN_LOG(PLUGIN_LOG_NOISY, ("NPN_MemFlush: size=%d\n", size));
    1232                 : 
    1233               0 :   nsMemory::HeapMinimize(true);
    1234               0 :   return 0;
    1235                 : }
    1236                 : 
    1237                 : void NP_CALLBACK
    1238               0 : _reloadplugins(NPBool reloadPages)
    1239                 : {
    1240               0 :   if (!NS_IsMainThread()) {
    1241               0 :     NPN_PLUGIN_LOG(PLUGIN_LOG_ALWAYS,("NPN_reloadplugins called from the wrong thread\n"));
    1242               0 :     return;
    1243                 :   }
    1244               0 :   NPN_PLUGIN_LOG(PLUGIN_LOG_NORMAL,
    1245                 :                  ("NPN_ReloadPlugins: reloadPages=%d\n", reloadPages));
    1246                 : 
    1247               0 :   nsCOMPtr<nsIPluginHost> pluginHost(do_GetService(MOZ_PLUGIN_HOST_CONTRACTID));
    1248               0 :   if (!pluginHost)
    1249                 :     return;
    1250                 : 
    1251               0 :   pluginHost->ReloadPlugins(reloadPages);
    1252                 : }
    1253                 : 
    1254                 : void NP_CALLBACK
    1255               0 : _invalidaterect(NPP npp, NPRect *invalidRect)
    1256                 : {
    1257               0 :   if (!NS_IsMainThread()) {
    1258               0 :     NPN_PLUGIN_LOG(PLUGIN_LOG_ALWAYS,("NPN_invalidaterect called from the wrong thread\n"));
    1259               0 :     return;
    1260                 :   }
    1261               0 :   NPN_PLUGIN_LOG(PLUGIN_LOG_NORMAL,
    1262                 :                  ("NPN_InvalidateRect: npp=%p, top=%d, left=%d, bottom=%d, "
    1263                 :                   "right=%d\n", (void *)npp, invalidRect->top,
    1264                 :                   invalidRect->left, invalidRect->bottom, invalidRect->right));
    1265                 : 
    1266               0 :   if (!npp || !npp->ndata) {
    1267               0 :     NS_WARNING("_invalidaterect: npp or npp->ndata == 0");
    1268               0 :     return;
    1269                 :   }
    1270                 : 
    1271               0 :   nsNPAPIPluginInstance *inst = (nsNPAPIPluginInstance*)npp->ndata;
    1272                 : 
    1273               0 :   PluginDestructionGuard guard(inst);
    1274                 : 
    1275               0 :   inst->InvalidateRect((NPRect *)invalidRect);
    1276                 : }
    1277                 : 
    1278                 : void NP_CALLBACK
    1279               0 : _invalidateregion(NPP npp, NPRegion invalidRegion)
    1280                 : {
    1281               0 :   if (!NS_IsMainThread()) {
    1282               0 :     NPN_PLUGIN_LOG(PLUGIN_LOG_ALWAYS,("NPN_invalidateregion called from the wrong thread\n"));
    1283               0 :     return;
    1284                 :   }
    1285               0 :   NPN_PLUGIN_LOG(PLUGIN_LOG_NORMAL,
    1286                 :                  ("NPN_InvalidateRegion: npp=%p, region=%p\n", (void*)npp,
    1287                 :                   (void*)invalidRegion));
    1288                 : 
    1289               0 :   if (!npp || !npp->ndata) {
    1290               0 :     NS_WARNING("_invalidateregion: npp or npp->ndata == 0");
    1291               0 :     return;
    1292                 :   }
    1293                 : 
    1294               0 :   nsNPAPIPluginInstance *inst = (nsNPAPIPluginInstance*)npp->ndata;
    1295                 : 
    1296               0 :   PluginDestructionGuard guard(inst);
    1297                 : 
    1298               0 :   inst->InvalidateRegion((NPRegion)invalidRegion);
    1299                 : }
    1300                 : 
    1301                 : void NP_CALLBACK
    1302               0 : _forceredraw(NPP npp)
    1303                 : {
    1304               0 : }
    1305                 : 
    1306                 : NPObject* NP_CALLBACK
    1307               0 : _getwindowobject(NPP npp)
    1308                 : {
    1309               0 :   if (!NS_IsMainThread()) {
    1310               0 :     NPN_PLUGIN_LOG(PLUGIN_LOG_ALWAYS,("NPN_getwindowobject called from the wrong thread\n"));
    1311               0 :     return nsnull;
    1312                 :   }
    1313               0 :   JSContext *cx = GetJSContextFromNPP(npp);
    1314               0 :   NS_ENSURE_TRUE(cx, nsnull);
    1315                 : 
    1316                 :   // Using ::JS_GetGlobalObject(cx) is ok here since the window we
    1317                 :   // want to return here is the outer window, *not* the inner (since
    1318                 :   // we don't know what the plugin will do with it).
    1319               0 :   return nsJSObjWrapper::GetNewOrUsed(npp, cx, ::JS_GetGlobalObject(cx));
    1320                 : }
    1321                 : 
    1322                 : NPObject* NP_CALLBACK
    1323               0 : _getpluginelement(NPP npp)
    1324                 : {
    1325               0 :   if (!NS_IsMainThread()) {
    1326               0 :     NPN_PLUGIN_LOG(PLUGIN_LOG_ALWAYS,("NPN_getpluginelement called from the wrong thread\n"));
    1327               0 :     return nsnull;
    1328                 :   }
    1329                 : 
    1330               0 :   nsNPAPIPluginInstance* inst = static_cast<nsNPAPIPluginInstance*>(npp->ndata);
    1331               0 :   if (!inst)
    1332               0 :     return nsnull;
    1333                 : 
    1334               0 :   nsCOMPtr<nsIDOMElement> element;
    1335               0 :   inst->GetDOMElement(getter_AddRefs(element));
    1336                 : 
    1337               0 :   if (!element)
    1338               0 :     return nsnull;
    1339                 : 
    1340               0 :   JSContext *cx = GetJSContextFromNPP(npp);
    1341               0 :   NS_ENSURE_TRUE(cx, nsnull);
    1342                 : 
    1343               0 :   nsCOMPtr<nsIXPConnect> xpc(do_GetService(nsIXPConnect::GetCID()));
    1344               0 :   NS_ENSURE_TRUE(xpc, nsnull);
    1345                 : 
    1346               0 :   nsCOMPtr<nsIXPConnectJSObjectHolder> holder;
    1347               0 :   xpc->WrapNative(cx, ::JS_GetGlobalObject(cx), element,
    1348                 :                   NS_GET_IID(nsIDOMElement),
    1349               0 :                   getter_AddRefs(holder));
    1350               0 :   NS_ENSURE_TRUE(holder, nsnull);
    1351                 : 
    1352               0 :   JSObject* obj = nsnull;
    1353               0 :   holder->GetJSObject(&obj);
    1354               0 :   NS_ENSURE_TRUE(obj, nsnull);
    1355                 : 
    1356               0 :   return nsJSObjWrapper::GetNewOrUsed(npp, cx, obj);
    1357                 : }
    1358                 : 
    1359                 : NPIdentifier NP_CALLBACK
    1360               0 : _getstringidentifier(const NPUTF8* name)
    1361                 : {
    1362               0 :   if (!name) {
    1363               0 :     NPN_PLUGIN_LOG(PLUGIN_LOG_ALWAYS, ("NPN_getstringidentifier: passed null name"));
    1364               0 :     return NULL;
    1365                 :   }
    1366               0 :   if (!NS_IsMainThread()) {
    1367               0 :     NPN_PLUGIN_LOG(PLUGIN_LOG_ALWAYS,("NPN_getstringidentifier called from the wrong thread\n"));
    1368                 :   }
    1369                 : 
    1370                 :   nsCOMPtr<nsIThreadJSContextStack> stack =
    1371               0 :     do_GetService("@mozilla.org/js/xpc/ContextStack;1");
    1372               0 :   if (!stack)
    1373               0 :     return NULL;
    1374                 : 
    1375               0 :   JSContext *cx = nsnull;
    1376               0 :   stack->GetSafeJSContext(&cx);
    1377               0 :   if (!cx)
    1378               0 :     return NULL;
    1379                 : 
    1380               0 :   JSAutoRequest ar(cx);
    1381               0 :   return doGetIdentifier(cx, name);
    1382                 : }
    1383                 : 
    1384                 : void NP_CALLBACK
    1385               0 : _getstringidentifiers(const NPUTF8** names, int32_t nameCount,
    1386                 :                       NPIdentifier *identifiers)
    1387                 : {
    1388               0 :   if (!NS_IsMainThread()) {
    1389               0 :     NPN_PLUGIN_LOG(PLUGIN_LOG_ALWAYS,("NPN_getstringidentifiers called from the wrong thread\n"));
    1390                 :   }
    1391                 :   nsCOMPtr<nsIThreadJSContextStack> stack =
    1392               0 :     do_GetService("@mozilla.org/js/xpc/ContextStack;1");
    1393               0 :   if (!stack)
    1394                 :     return;
    1395                 : 
    1396               0 :   JSContext *cx = nsnull;
    1397               0 :   stack->GetSafeJSContext(&cx);
    1398               0 :   if (!cx)
    1399                 :     return;
    1400                 : 
    1401               0 :   JSAutoRequest ar(cx);
    1402                 : 
    1403               0 :   for (int32_t i = 0; i < nameCount; ++i) {
    1404               0 :     if (names[i]) {
    1405               0 :       identifiers[i] = doGetIdentifier(cx, names[i]);
    1406                 :     } else {
    1407               0 :       NPN_PLUGIN_LOG(PLUGIN_LOG_ALWAYS, ("NPN_getstringidentifiers: passed null name"));
    1408               0 :       identifiers[i] = NULL;
    1409                 :     }
    1410                 :   }
    1411                 : }
    1412                 : 
    1413                 : NPIdentifier NP_CALLBACK
    1414               0 : _getintidentifier(int32_t intid)
    1415                 : {
    1416               0 :   if (!NS_IsMainThread()) {
    1417               0 :     NPN_PLUGIN_LOG(PLUGIN_LOG_ALWAYS,("NPN_getstringidentifier called from the wrong thread\n"));
    1418                 :   }
    1419               0 :   return IntToNPIdentifier(intid);
    1420                 : }
    1421                 : 
    1422                 : NPUTF8* NP_CALLBACK
    1423               0 : _utf8fromidentifier(NPIdentifier id)
    1424                 : {
    1425               0 :   if (!NS_IsMainThread()) {
    1426               0 :     NPN_PLUGIN_LOG(PLUGIN_LOG_ALWAYS,("NPN_utf8fromidentifier called from the wrong thread\n"));
    1427                 :   }
    1428               0 :   if (!id)
    1429               0 :     return NULL;
    1430                 : 
    1431               0 :   if (!NPIdentifierIsString(id)) {
    1432               0 :     return nsnull;
    1433                 :   }
    1434                 : 
    1435               0 :   JSString *str = NPIdentifierToString(id);
    1436                 : 
    1437                 :   return
    1438                 :     ToNewUTF8String(nsDependentString(::JS_GetInternedStringChars(str),
    1439               0 :                                       ::JS_GetStringLength(str)));
    1440                 : }
    1441                 : 
    1442                 : int32_t NP_CALLBACK
    1443               0 : _intfromidentifier(NPIdentifier id)
    1444                 : {
    1445               0 :   if (!NS_IsMainThread()) {
    1446               0 :     NPN_PLUGIN_LOG(PLUGIN_LOG_ALWAYS,("NPN_intfromidentifier called from the wrong thread\n"));
    1447                 :   }
    1448                 : 
    1449               0 :   if (!NPIdentifierIsInt(id)) {
    1450               0 :     return PR_INT32_MIN;
    1451                 :   }
    1452                 : 
    1453               0 :   return NPIdentifierToInt(id);
    1454                 : }
    1455                 : 
    1456                 : bool NP_CALLBACK
    1457               0 : _identifierisstring(NPIdentifier id)
    1458                 : {
    1459               0 :   if (!NS_IsMainThread()) {
    1460               0 :     NPN_PLUGIN_LOG(PLUGIN_LOG_ALWAYS,("NPN_identifierisstring called from the wrong thread\n"));
    1461                 :   }
    1462                 : 
    1463               0 :   return NPIdentifierIsString(id);
    1464                 : }
    1465                 : 
    1466                 : NPObject* NP_CALLBACK
    1467               0 : _createobject(NPP npp, NPClass* aClass)
    1468                 : {
    1469               0 :   if (!NS_IsMainThread()) {
    1470               0 :     NPN_PLUGIN_LOG(PLUGIN_LOG_ALWAYS,("NPN_createobject called from the wrong thread\n"));
    1471               0 :     return nsnull;
    1472                 :   }
    1473               0 :   if (!npp) {
    1474               0 :     NS_ERROR("Null npp passed to _createobject()!");
    1475                 : 
    1476               0 :     return nsnull;
    1477                 :   }
    1478                 : 
    1479               0 :   PluginDestructionGuard guard(npp);
    1480                 : 
    1481               0 :   if (!aClass) {
    1482               0 :     NS_ERROR("Null class passed to _createobject()!");
    1483                 : 
    1484               0 :     return nsnull;
    1485                 :   }
    1486                 : 
    1487               0 :   NPPAutoPusher nppPusher(npp);
    1488                 : 
    1489                 :   NPObject *npobj;
    1490                 : 
    1491               0 :   if (aClass->allocate) {
    1492               0 :     npobj = aClass->allocate(npp, aClass);
    1493                 :   } else {
    1494               0 :     npobj = (NPObject *)PR_Malloc(sizeof(NPObject));
    1495                 :   }
    1496                 : 
    1497               0 :   if (npobj) {
    1498               0 :     npobj->_class = aClass;
    1499               0 :     npobj->referenceCount = 1;
    1500               0 :     NS_LOG_ADDREF(npobj, 1, "BrowserNPObject", sizeof(NPObject));
    1501                 :   }
    1502                 : 
    1503               0 :   NPN_PLUGIN_LOG(PLUGIN_LOG_NOISY,
    1504                 :                  ("Created NPObject %p, NPClass %p\n", npobj, aClass));
    1505                 : 
    1506               0 :   return npobj;
    1507                 : }
    1508                 : 
    1509                 : NPObject* NP_CALLBACK
    1510               0 : _retainobject(NPObject* npobj)
    1511                 : {
    1512               0 :   if (!NS_IsMainThread()) {
    1513               0 :     NPN_PLUGIN_LOG(PLUGIN_LOG_ALWAYS,("NPN_retainobject called from the wrong thread\n"));
    1514                 :   }
    1515               0 :   if (npobj) {
    1516                 : #ifdef NS_BUILD_REFCNT_LOGGING
    1517                 :     int32_t refCnt =
    1518                 : #endif
    1519               0 :       PR_ATOMIC_INCREMENT((PRInt32*)&npobj->referenceCount);
    1520               0 :     NS_LOG_ADDREF(npobj, refCnt, "BrowserNPObject", sizeof(NPObject));
    1521                 :   }
    1522                 : 
    1523               0 :   return npobj;
    1524                 : }
    1525                 : 
    1526                 : void NP_CALLBACK
    1527               0 : _releaseobject(NPObject* npobj)
    1528                 : {
    1529               0 :   if (!NS_IsMainThread()) {
    1530               0 :     NPN_PLUGIN_LOG(PLUGIN_LOG_ALWAYS,("NPN_releaseobject called from the wrong thread\n"));
    1531                 :   }
    1532               0 :   if (!npobj)
    1533               0 :     return;
    1534                 : 
    1535               0 :   int32_t refCnt = PR_ATOMIC_DECREMENT((PRInt32*)&npobj->referenceCount);
    1536               0 :   NS_LOG_RELEASE(npobj, refCnt, "BrowserNPObject");
    1537                 : 
    1538               0 :   if (refCnt == 0) {
    1539               0 :     nsNPObjWrapper::OnDestroy(npobj);
    1540                 : 
    1541               0 :     NPN_PLUGIN_LOG(PLUGIN_LOG_NOISY,
    1542                 :                    ("Deleting NPObject %p, refcount hit 0\n", npobj));
    1543                 : 
    1544               0 :     if (npobj->_class && npobj->_class->deallocate) {
    1545               0 :       npobj->_class->deallocate(npobj);
    1546                 :     } else {
    1547               0 :       PR_Free(npobj);
    1548                 :     }
    1549                 :   }
    1550                 : }
    1551                 : 
    1552                 : bool NP_CALLBACK
    1553               0 : _invoke(NPP npp, NPObject* npobj, NPIdentifier method, const NPVariant *args,
    1554                 :         uint32_t argCount, NPVariant *result)
    1555                 : {
    1556               0 :   if (!NS_IsMainThread()) {
    1557               0 :     NPN_PLUGIN_LOG(PLUGIN_LOG_ALWAYS,("NPN_invoke called from the wrong thread\n"));
    1558               0 :     return false;
    1559                 :   }
    1560               0 :   if (!npp || !npobj || !npobj->_class || !npobj->_class->invoke)
    1561               0 :     return false;
    1562                 : 
    1563               0 :   PluginDestructionGuard guard(npp);
    1564                 : 
    1565               0 :   NPPExceptionAutoHolder nppExceptionHolder;
    1566               0 :   NPPAutoPusher nppPusher(npp);
    1567                 : 
    1568               0 :   NPN_PLUGIN_LOG(PLUGIN_LOG_NOISY,
    1569                 :                  ("NPN_Invoke(npp %p, npobj %p, method %p, args %d\n", npp,
    1570                 :                   npobj, method, argCount));
    1571                 : 
    1572               0 :   return npobj->_class->invoke(npobj, method, args, argCount, result);
    1573                 : }
    1574                 : 
    1575                 : bool NP_CALLBACK
    1576               0 : _invokeDefault(NPP npp, NPObject* npobj, const NPVariant *args,
    1577                 :                uint32_t argCount, NPVariant *result)
    1578                 : {
    1579               0 :   if (!NS_IsMainThread()) {
    1580               0 :     NPN_PLUGIN_LOG(PLUGIN_LOG_ALWAYS,("NPN_invokedefault called from the wrong thread\n"));
    1581               0 :     return false;
    1582                 :   }
    1583               0 :   if (!npp || !npobj || !npobj->_class || !npobj->_class->invokeDefault)
    1584               0 :     return false;
    1585                 : 
    1586               0 :   NPPExceptionAutoHolder nppExceptionHolder;
    1587               0 :   NPPAutoPusher nppPusher(npp);
    1588                 : 
    1589               0 :   NPN_PLUGIN_LOG(PLUGIN_LOG_NOISY,
    1590                 :                  ("NPN_InvokeDefault(npp %p, npobj %p, args %d\n", npp,
    1591                 :                   npobj, argCount));
    1592                 : 
    1593               0 :   return npobj->_class->invokeDefault(npobj, args, argCount, result);
    1594                 : }
    1595                 : 
    1596                 : bool NP_CALLBACK
    1597               0 : _evaluate(NPP npp, NPObject* npobj, NPString *script, NPVariant *result)
    1598                 : {
    1599               0 :   if (!NS_IsMainThread()) {
    1600               0 :     NPN_PLUGIN_LOG(PLUGIN_LOG_ALWAYS,("NPN_evaluate called from the wrong thread\n"));
    1601               0 :     return false;
    1602                 :   }
    1603               0 :   if (!npp)
    1604               0 :     return false;
    1605                 : 
    1606               0 :   NPPAutoPusher nppPusher(npp);
    1607                 : 
    1608               0 :   nsIDocument *doc = GetDocumentFromNPP(npp);
    1609               0 :   NS_ENSURE_TRUE(doc, false);
    1610                 : 
    1611               0 :   JSContext *cx = GetJSContextFromDoc(doc);
    1612               0 :   NS_ENSURE_TRUE(cx, false);
    1613                 : 
    1614               0 :   nsCOMPtr<nsIScriptContext> scx = GetScriptContextFromJSContext(cx);
    1615               0 :   NS_ENSURE_TRUE(scx, false);
    1616                 : 
    1617               0 :   JSAutoRequest req(cx);
    1618                 : 
    1619                 :   JSObject *obj =
    1620               0 :     nsNPObjWrapper::GetNewOrUsed(npp, cx, npobj);
    1621                 : 
    1622               0 :   if (!obj) {
    1623               0 :     return false;
    1624                 :   }
    1625                 : 
    1626               0 :   obj = JS_ObjectToInnerObject(cx, obj);
    1627               0 :   NS_ABORT_IF_FALSE(obj,
    1628                 :     "JS_ObjectToInnerObject should never return null with non-null input.");
    1629                 : 
    1630                 :   // Root obj and the rval (below).
    1631               0 :   jsval vec[] = { OBJECT_TO_JSVAL(obj), JSVAL_NULL };
    1632               0 :   JS::AutoArrayRooter tvr(cx, ArrayLength(vec), vec);
    1633               0 :   jsval *rval = &vec[1];
    1634                 : 
    1635               0 :   if (result) {
    1636                 :     // Initialize the out param to void
    1637               0 :     VOID_TO_NPVARIANT(*result);
    1638                 :   }
    1639                 : 
    1640               0 :   if (!script || !script->UTF8Length || !script->UTF8Characters) {
    1641                 :     // Nothing to evaluate.
    1642                 : 
    1643               0 :     return true;
    1644                 :   }
    1645                 : 
    1646                 :   NS_ConvertUTF8toUTF16 utf16script(script->UTF8Characters,
    1647               0 :                                     script->UTF8Length);
    1648                 : 
    1649               0 :   nsIPrincipal *principal = doc->NodePrincipal();
    1650                 : 
    1651               0 :   nsCAutoString specStr;
    1652                 :   const char *spec;
    1653                 : 
    1654               0 :   nsCOMPtr<nsIURI> uri;
    1655               0 :   principal->GetURI(getter_AddRefs(uri));
    1656                 : 
    1657               0 :   if (uri) {
    1658               0 :     uri->GetSpec(specStr);
    1659               0 :     spec = specStr.get();
    1660                 :   } else {
    1661                 :     // No URI in a principal means it's the system principal. If the
    1662                 :     // document URI is a chrome:// URI, pass that in as the URI of the
    1663                 :     // script, else pass in null for the filename as there's no way to
    1664                 :     // know where this document really came from. Passing in null here
    1665                 :     // also means that the script gets treated by XPConnect as if it
    1666                 :     // needs additional protection, which is what we want for unknown
    1667                 :     // chrome code anyways.
    1668                 : 
    1669               0 :     uri = doc->GetDocumentURI();
    1670               0 :     bool isChrome = false;
    1671                 : 
    1672               0 :     if (uri && NS_SUCCEEDED(uri->SchemeIs("chrome", &isChrome)) && isChrome) {
    1673               0 :       uri->GetSpec(specStr);
    1674               0 :       spec = specStr.get();
    1675                 :     } else {
    1676               0 :       spec = nsnull;
    1677                 :     }
    1678                 :   }
    1679                 : 
    1680               0 :   NPN_PLUGIN_LOG(PLUGIN_LOG_NOISY,
    1681                 :                  ("NPN_Evaluate(npp %p, npobj %p, script <<<%s>>>) called\n",
    1682                 :                   npp, npobj, script->UTF8Characters));
    1683                 : 
    1684               0 :   nsresult rv = scx->EvaluateStringWithValue(utf16script, obj, principal,
    1685               0 :                                              spec, 0, 0, rval, nsnull);
    1686                 : 
    1687               0 :   return NS_SUCCEEDED(rv) &&
    1688               0 :          (!result || JSValToNPVariant(npp, cx, *rval, result));
    1689                 : }
    1690                 : 
    1691                 : bool NP_CALLBACK
    1692               0 : _getproperty(NPP npp, NPObject* npobj, NPIdentifier property,
    1693                 :              NPVariant *result)
    1694                 : {
    1695               0 :   if (!NS_IsMainThread()) {
    1696               0 :     NPN_PLUGIN_LOG(PLUGIN_LOG_ALWAYS,("NPN_getproperty called from the wrong thread\n"));
    1697               0 :     return false;
    1698                 :   }
    1699               0 :   if (!npp || !npobj || !npobj->_class || !npobj->_class->getProperty)
    1700               0 :     return false;
    1701                 : 
    1702               0 :   NPPExceptionAutoHolder nppExceptionHolder;
    1703               0 :   NPPAutoPusher nppPusher(npp);
    1704                 : 
    1705               0 :   NPN_PLUGIN_LOG(PLUGIN_LOG_NOISY,
    1706                 :                  ("NPN_GetProperty(npp %p, npobj %p, property %p) called\n",
    1707                 :                   npp, npobj, property));
    1708                 : 
    1709               0 :   if (!npobj->_class->getProperty(npobj, property, result))
    1710               0 :     return false;
    1711                 : 
    1712                 :   // If a Java plugin tries to get the document.URL or document.documentURI
    1713                 :   // property from us, don't pass back a value that Java won't be able to
    1714                 :   // understand -- one that will make the URL(String) constructor throw a
    1715                 :   // MalformedURL exception.  Passing such a value causes Java Plugin2 to
    1716                 :   // crash (to throw a RuntimeException in Plugin2Manager.getDocumentBase()).
    1717                 :   // Also don't pass back a value that Java is likely to mishandle.
    1718                 : 
    1719               0 :   nsNPAPIPluginInstance* inst = (nsNPAPIPluginInstance*) npp->ndata;
    1720               0 :   if (!inst)
    1721               0 :     return false;
    1722               0 :   nsNPAPIPlugin* plugin = inst->GetPlugin();
    1723               0 :   if (!plugin)
    1724               0 :     return false;
    1725               0 :   nsRefPtr<nsPluginHost> host = dont_AddRef(nsPluginHost::GetInst());
    1726               0 :   nsPluginTag* pluginTag = host->TagForPlugin(plugin);
    1727               0 :   if (!pluginTag->mIsJavaPlugin)
    1728               0 :     return true;
    1729                 : 
    1730               0 :   if (!NPVARIANT_IS_STRING(*result))
    1731               0 :     return true;
    1732                 : 
    1733               0 :   NPUTF8* propertyName = _utf8fromidentifier(property);
    1734               0 :   if (!propertyName)
    1735               0 :     return true;
    1736                 :   bool notURL =
    1737               0 :     (PL_strcasecmp(propertyName, "URL") &&
    1738               0 :      PL_strcasecmp(propertyName, "documentURI"));
    1739               0 :   _memfree(propertyName);
    1740               0 :   if (notURL)
    1741               0 :     return true;
    1742                 : 
    1743               0 :   NPObject* window_obj = _getwindowobject(npp);
    1744               0 :   if (!window_obj)
    1745               0 :     return true;
    1746                 : 
    1747                 :   NPVariant doc_v;
    1748               0 :   NPObject* document_obj = nsnull;
    1749               0 :   NPIdentifier doc_id = _getstringidentifier("document");
    1750               0 :   bool ok = npobj->_class->getProperty(window_obj, doc_id, &doc_v);
    1751               0 :   _releaseobject(window_obj);
    1752               0 :   if (ok) {
    1753               0 :     if (NPVARIANT_IS_OBJECT(doc_v)) {
    1754               0 :       document_obj = NPVARIANT_TO_OBJECT(doc_v);
    1755                 :     } else {
    1756               0 :       _releasevariantvalue(&doc_v);
    1757               0 :       return true;
    1758                 :     }
    1759                 :   } else {
    1760               0 :     return true;
    1761                 :   }
    1762               0 :   _releaseobject(document_obj);
    1763               0 :   if (document_obj != npobj)
    1764               0 :     return true;
    1765                 : 
    1766               0 :   NPString urlnp = NPVARIANT_TO_STRING(*result);
    1767               0 :   nsXPIDLCString url;
    1768               0 :   url.Assign(urlnp.UTF8Characters, urlnp.UTF8Length);
    1769                 : 
    1770               0 :   bool javaCompatible = false;
    1771               0 :   if (NS_FAILED(NS_CheckIsJavaCompatibleURLString(url, &javaCompatible)))
    1772               0 :     javaCompatible = false;
    1773               0 :   if (javaCompatible)
    1774               0 :     return true;
    1775                 : 
    1776                 :   // If Java won't be able to interpret the original value of document.URL or
    1777                 :   // document.documentURI, or is likely to mishandle it, pass back something
    1778                 :   // that Java will understand but won't be able to use to access the network,
    1779                 :   // and for which same-origin checks will always fail.
    1780                 : 
    1781               0 :   if (inst->mFakeURL.IsVoid()) {
    1782                 :     // Abort (do an error return) if NS_MakeRandomInvalidURLString() fails.
    1783               0 :     if (NS_FAILED(NS_MakeRandomInvalidURLString(inst->mFakeURL))) {
    1784               0 :       _releasevariantvalue(result);
    1785               0 :       return false;
    1786                 :     }
    1787                 :   }
    1788                 : 
    1789               0 :   _releasevariantvalue(result);
    1790               0 :   char* fakeurl = (char *) _memalloc(inst->mFakeURL.Length() + 1);
    1791               0 :   strcpy(fakeurl, inst->mFakeURL);
    1792               0 :   STRINGZ_TO_NPVARIANT(fakeurl, *result);
    1793                 : 
    1794               0 :   return true;
    1795                 : }
    1796                 : 
    1797                 : bool NP_CALLBACK
    1798               0 : _setproperty(NPP npp, NPObject* npobj, NPIdentifier property,
    1799                 :              const NPVariant *value)
    1800                 : {
    1801               0 :   if (!NS_IsMainThread()) {
    1802               0 :     NPN_PLUGIN_LOG(PLUGIN_LOG_ALWAYS,("NPN_setproperty called from the wrong thread\n"));
    1803               0 :     return false;
    1804                 :   }
    1805               0 :   if (!npp || !npobj || !npobj->_class || !npobj->_class->setProperty)
    1806               0 :     return false;
    1807                 : 
    1808               0 :   NPPExceptionAutoHolder nppExceptionHolder;
    1809               0 :   NPPAutoPusher nppPusher(npp);
    1810                 : 
    1811               0 :   NPN_PLUGIN_LOG(PLUGIN_LOG_NOISY,
    1812                 :                  ("NPN_SetProperty(npp %p, npobj %p, property %p) called\n",
    1813                 :                   npp, npobj, property));
    1814                 : 
    1815               0 :   return npobj->_class->setProperty(npobj, property, value);
    1816                 : }
    1817                 : 
    1818                 : bool NP_CALLBACK
    1819               0 : _removeproperty(NPP npp, NPObject* npobj, NPIdentifier property)
    1820                 : {
    1821               0 :   if (!NS_IsMainThread()) {
    1822               0 :     NPN_PLUGIN_LOG(PLUGIN_LOG_ALWAYS,("NPN_removeproperty called from the wrong thread\n"));
    1823               0 :     return false;
    1824                 :   }
    1825               0 :   if (!npp || !npobj || !npobj->_class || !npobj->_class->removeProperty)
    1826               0 :     return false;
    1827                 : 
    1828               0 :   NPPExceptionAutoHolder nppExceptionHolder;
    1829               0 :   NPPAutoPusher nppPusher(npp);
    1830                 : 
    1831               0 :   NPN_PLUGIN_LOG(PLUGIN_LOG_NOISY,
    1832                 :                  ("NPN_RemoveProperty(npp %p, npobj %p, property %p) called\n",
    1833                 :                   npp, npobj, property));
    1834                 : 
    1835               0 :   return npobj->_class->removeProperty(npobj, property);
    1836                 : }
    1837                 : 
    1838                 : bool NP_CALLBACK
    1839               0 : _hasproperty(NPP npp, NPObject* npobj, NPIdentifier propertyName)
    1840                 : {
    1841               0 :   if (!NS_IsMainThread()) {
    1842               0 :     NPN_PLUGIN_LOG(PLUGIN_LOG_ALWAYS,("NPN_hasproperty called from the wrong thread\n"));
    1843               0 :     return false;
    1844                 :   }
    1845               0 :   if (!npp || !npobj || !npobj->_class || !npobj->_class->hasProperty)
    1846               0 :     return false;
    1847                 : 
    1848               0 :   NPPExceptionAutoHolder nppExceptionHolder;
    1849               0 :   NPPAutoPusher nppPusher(npp);
    1850                 : 
    1851               0 :   NPN_PLUGIN_LOG(PLUGIN_LOG_NOISY,
    1852                 :                  ("NPN_HasProperty(npp %p, npobj %p, property %p) called\n",
    1853                 :                   npp, npobj, propertyName));
    1854                 : 
    1855               0 :   return npobj->_class->hasProperty(npobj, propertyName);
    1856                 : }
    1857                 : 
    1858                 : bool NP_CALLBACK
    1859               0 : _hasmethod(NPP npp, NPObject* npobj, NPIdentifier methodName)
    1860                 : {
    1861               0 :   if (!NS_IsMainThread()) {
    1862               0 :     NPN_PLUGIN_LOG(PLUGIN_LOG_ALWAYS,("NPN_hasmethod called from the wrong thread\n"));
    1863               0 :     return false;
    1864                 :   }
    1865               0 :   if (!npp || !npobj || !npobj->_class || !npobj->_class->hasMethod)
    1866               0 :     return false;
    1867                 : 
    1868               0 :   NPPExceptionAutoHolder nppExceptionHolder;
    1869               0 :   NPPAutoPusher nppPusher(npp);
    1870                 : 
    1871               0 :   NPN_PLUGIN_LOG(PLUGIN_LOG_NOISY,
    1872                 :                  ("NPN_HasMethod(npp %p, npobj %p, property %p) called\n",
    1873                 :                   npp, npobj, methodName));
    1874                 : 
    1875               0 :   return npobj->_class->hasMethod(npobj, methodName);
    1876                 : }
    1877                 : 
    1878                 : bool NP_CALLBACK
    1879               0 : _enumerate(NPP npp, NPObject *npobj, NPIdentifier **identifier,
    1880                 :            uint32_t *count)
    1881                 : {
    1882               0 :   if (!NS_IsMainThread()) {
    1883               0 :     NPN_PLUGIN_LOG(PLUGIN_LOG_ALWAYS,("NPN_enumerate called from the wrong thread\n"));
    1884               0 :     return false;
    1885                 :   }
    1886               0 :   if (!npp || !npobj || !npobj->_class)
    1887               0 :     return false;
    1888                 : 
    1889               0 :   NPN_PLUGIN_LOG(PLUGIN_LOG_NOISY,
    1890                 :                  ("NPN_Enumerate(npp %p, npobj %p) called\n", npp, npobj));
    1891                 : 
    1892               0 :   if (!NP_CLASS_STRUCT_VERSION_HAS_ENUM(npobj->_class) ||
    1893               0 :       !npobj->_class->enumerate) {
    1894               0 :     *identifier = 0;
    1895               0 :     *count = 0;
    1896               0 :     return true;
    1897                 :   }
    1898                 : 
    1899               0 :   NPPExceptionAutoHolder nppExceptionHolder;
    1900               0 :   NPPAutoPusher nppPusher(npp);
    1901                 : 
    1902               0 :   return npobj->_class->enumerate(npobj, identifier, count);
    1903                 : }
    1904                 : 
    1905                 : bool NP_CALLBACK
    1906               0 : _construct(NPP npp, NPObject* npobj, const NPVariant *args,
    1907                 :                uint32_t argCount, NPVariant *result)
    1908                 : {
    1909               0 :   if (!NS_IsMainThread()) {
    1910               0 :     NPN_PLUGIN_LOG(PLUGIN_LOG_ALWAYS,("NPN_construct called from the wrong thread\n"));
    1911               0 :     return false;
    1912                 :   }
    1913               0 :   if (!npp || !npobj || !npobj->_class ||
    1914               0 :       !NP_CLASS_STRUCT_VERSION_HAS_CTOR(npobj->_class) ||
    1915               0 :       !npobj->_class->construct) {
    1916               0 :     return false;
    1917                 :   }
    1918                 : 
    1919               0 :   NPPExceptionAutoHolder nppExceptionHolder;
    1920               0 :   NPPAutoPusher nppPusher(npp);
    1921                 : 
    1922               0 :   return npobj->_class->construct(npobj, args, argCount, result);
    1923                 : }
    1924                 : 
    1925                 : void NP_CALLBACK
    1926               0 : _releasevariantvalue(NPVariant* variant)
    1927                 : {
    1928               0 :   if (!NS_IsMainThread()) {
    1929               0 :     NPN_PLUGIN_LOG(PLUGIN_LOG_ALWAYS,("NPN_releasevariantvalue called from the wrong thread\n"));
    1930                 :   }
    1931               0 :   switch (variant->type) {
    1932                 :   case NPVariantType_Void :
    1933                 :   case NPVariantType_Null :
    1934                 :   case NPVariantType_Bool :
    1935                 :   case NPVariantType_Int32 :
    1936                 :   case NPVariantType_Double :
    1937               0 :     break;
    1938                 :   case NPVariantType_String :
    1939                 :     {
    1940               0 :       const NPString *s = &NPVARIANT_TO_STRING(*variant);
    1941                 : 
    1942               0 :       if (s->UTF8Characters) {
    1943                 : #if defined(MOZ_MEMORY_WINDOWS)
    1944                 :         if (malloc_usable_size((void *)s->UTF8Characters) != 0) {
    1945                 :           PR_Free((void *)s->UTF8Characters);
    1946                 :         } else {
    1947                 :           void *p = (void *)s->UTF8Characters;
    1948                 :           DWORD nheaps = 0;
    1949                 :           nsAutoTArray<HANDLE, 50> heaps;
    1950                 :           nheaps = GetProcessHeaps(0, heaps.Elements());
    1951                 :           heaps.AppendElements(nheaps);
    1952                 :           GetProcessHeaps(nheaps, heaps.Elements());
    1953                 :           for (DWORD i = 0; i < nheaps; i++) {
    1954                 :             if (InHeap(heaps[i], p)) {
    1955                 :               HeapFree(heaps[i], 0, p);
    1956                 :               break;
    1957                 :             }
    1958                 :           }
    1959                 :         }
    1960                 : #else
    1961               0 :         NS_Free((void *)s->UTF8Characters);
    1962                 : #endif
    1963                 :       }
    1964               0 :       break;
    1965                 :     }
    1966                 :   case NPVariantType_Object:
    1967                 :     {
    1968               0 :       NPObject *npobj = NPVARIANT_TO_OBJECT(*variant);
    1969                 : 
    1970               0 :       if (npobj)
    1971               0 :         _releaseobject(npobj);
    1972                 : 
    1973               0 :       break;
    1974                 :     }
    1975                 :   default:
    1976               0 :     NS_ERROR("Unknown NPVariant type!");
    1977                 :   }
    1978                 : 
    1979               0 :   VOID_TO_NPVARIANT(*variant);
    1980               0 : }
    1981                 : 
    1982                 : void NP_CALLBACK
    1983               0 : _setexception(NPObject* npobj, const NPUTF8 *message)
    1984                 : {
    1985               0 :   if (!NS_IsMainThread()) {
    1986               0 :     NPN_PLUGIN_LOG(PLUGIN_LOG_ALWAYS,("NPN_setexception called from the wrong thread\n"));
    1987               0 :     return;
    1988                 :   }
    1989                 : 
    1990               0 :   if (!message) return;
    1991                 : 
    1992               0 :   if (gNPPException) {
    1993                 :     // If a plugin throws multiple exceptions, we'll only report the
    1994                 :     // last one for now.
    1995               0 :     free(gNPPException);
    1996                 :   }
    1997                 : 
    1998               0 :   gNPPException = strdup(message);
    1999                 : }
    2000                 : 
    2001                 : NPError NP_CALLBACK
    2002               0 : _getvalue(NPP npp, NPNVariable variable, void *result)
    2003                 : {
    2004               0 :   if (!NS_IsMainThread()) {
    2005               0 :     NPN_PLUGIN_LOG(PLUGIN_LOG_ALWAYS,("NPN_getvalue called from the wrong thread\n"));
    2006               0 :     return NPERR_INVALID_PARAM;
    2007                 :   }
    2008               0 :   NPN_PLUGIN_LOG(PLUGIN_LOG_NORMAL, ("NPN_GetValue: npp=%p, var=%d\n",
    2009                 :                                      (void*)npp, (int)variable));
    2010                 : 
    2011                 :   nsresult res;
    2012                 : 
    2013               0 :   PluginDestructionGuard guard(npp);
    2014                 : 
    2015               0 :   switch(variable) {
    2016                 : #if defined(XP_UNIX) && !defined(XP_MACOSX)
    2017                 :   case NPNVxDisplay : {
    2018                 : #if defined(MOZ_X11)
    2019               0 :     if (npp) {
    2020               0 :       nsNPAPIPluginInstance *inst = (nsNPAPIPluginInstance *) npp->ndata;
    2021               0 :       bool windowless = false;
    2022               0 :       inst->IsWindowless(&windowless);
    2023                 :       // The documentation on the types for many variables in NP(N|P)_GetValue
    2024                 :       // is vague.  Often boolean values are NPBool (1 byte), but
    2025                 :       // https://developer.mozilla.org/en/XEmbed_Extension_for_Mozilla_Plugins
    2026                 :       // treats NPPVpluginNeedsXEmbed as PRBool (int), and
    2027                 :       // on x86/32-bit, flash stores to this using |movl 0x1,&needsXEmbed|.
    2028                 :       // thus we can't use NPBool for needsXEmbed, or the three bytes above
    2029                 :       // it on the stack would get clobbered. so protect with the larger bool.
    2030               0 :       int needsXEmbed = 0;
    2031               0 :       if (!windowless) {
    2032               0 :         res = inst->GetValueFromPlugin(NPPVpluginNeedsXEmbed, &needsXEmbed);
    2033                 :         // If the call returned an error code make sure we still use our default value.
    2034               0 :         if (NS_FAILED(res)) {
    2035               0 :           needsXEmbed = 0;
    2036                 :         }
    2037                 :       }
    2038               0 :       if (windowless || needsXEmbed) {
    2039               0 :         (*(Display **)result) = mozilla::DefaultXDisplay();
    2040               0 :         return NPERR_NO_ERROR;
    2041                 :       }
    2042                 :     }
    2043                 : #ifdef MOZ_WIDGET_GTK2
    2044                 :     // adobe nppdf calls XtGetApplicationNameAndClass(display,
    2045                 :     // &instance, &class) we have to init Xt toolkit before get
    2046                 :     // XtDisplay just call gtk_xtbin_new(w,0) once
    2047                 :     static GtkWidget *gtkXtBinHolder = 0;
    2048               0 :     if (!gtkXtBinHolder) {
    2049               0 :       gtkXtBinHolder = gtk_xtbin_new(gdk_get_default_root_window(),0);
    2050                 :       // it crashes on destroy, let it leak
    2051                 :       // gtk_widget_destroy(gtkXtBinHolder);
    2052                 :     }
    2053               0 :     (*(Display **)result) =  GTK_XTBIN(gtkXtBinHolder)->xtdisplay;
    2054               0 :     return NPERR_NO_ERROR;
    2055                 : #endif
    2056                 : #endif
    2057                 :     return NPERR_GENERIC_ERROR;
    2058                 :   }
    2059                 : 
    2060                 :   case NPNVxtAppContext:
    2061               0 :     return NPERR_GENERIC_ERROR;
    2062                 : #endif
    2063                 : 
    2064                 : #if defined(XP_WIN) || defined(XP_OS2) || defined(MOZ_WIDGET_GTK2) \
    2065                 :  || defined(MOZ_WIDGET_QT)
    2066                 :   case NPNVnetscapeWindow: {
    2067               0 :     if (!npp || !npp->ndata)
    2068               0 :       return NPERR_INVALID_INSTANCE_ERROR;
    2069                 : 
    2070               0 :     nsNPAPIPluginInstance *inst = (nsNPAPIPluginInstance *) npp->ndata;
    2071                 : 
    2072               0 :     nsCOMPtr<nsIPluginInstanceOwner> owner;
    2073               0 :     inst->GetOwner(getter_AddRefs(owner));
    2074               0 :     NS_ENSURE_TRUE(owner, nsnull);
    2075                 : 
    2076               0 :     if (NS_SUCCEEDED(owner->GetNetscapeWindow(result))) {
    2077               0 :       return NPERR_NO_ERROR;
    2078                 :     }
    2079               0 :     return NPERR_GENERIC_ERROR;
    2080                 :   }
    2081                 : #endif
    2082                 : 
    2083                 :   case NPNVjavascriptEnabledBool: {
    2084               0 :     *(NPBool*)result = false;
    2085               0 :     nsCOMPtr<nsIPrefBranch> prefs(do_GetService(NS_PREFSERVICE_CONTRACTID));
    2086               0 :     if (prefs) {
    2087               0 :       bool js = false;;
    2088               0 :       res = prefs->GetBoolPref("javascript.enabled", &js);
    2089               0 :       if (NS_SUCCEEDED(res))
    2090               0 :         *(NPBool*)result = js;
    2091                 :     }
    2092               0 :     return NPERR_NO_ERROR;
    2093                 :   }
    2094                 : 
    2095                 :   case NPNVasdEnabledBool:
    2096               0 :     *(NPBool*)result = false;
    2097               0 :     return NPERR_NO_ERROR;
    2098                 : 
    2099                 :   case NPNVisOfflineBool: {
    2100               0 :     bool offline = false;
    2101                 :     nsCOMPtr<nsIIOService> ioservice =
    2102               0 :       do_GetService(NS_IOSERVICE_CONTRACTID, &res);
    2103               0 :     if (NS_SUCCEEDED(res))
    2104               0 :       res = ioservice->GetOffline(&offline);
    2105               0 :     if (NS_FAILED(res))
    2106               0 :       return NPERR_GENERIC_ERROR;
    2107                 : 
    2108               0 :     *(NPBool*)result = offline;
    2109               0 :     return NPERR_NO_ERROR;
    2110                 :   }
    2111                 : 
    2112                 :   case NPNVToolkit: {
    2113                 : #ifdef MOZ_WIDGET_GTK2
    2114               0 :     *((NPNToolkitType*)result) = NPNVGtk2;
    2115                 : #endif
    2116                 : 
    2117                 : #ifdef MOZ_WIDGET_QT
    2118                 :     /* Fake toolkit so flash plugin works */
    2119                 :     *((NPNToolkitType*)result) = NPNVGtk2;
    2120                 : #endif
    2121               0 :     if (*(NPNToolkitType*)result)
    2122               0 :         return NPERR_NO_ERROR;
    2123                 : 
    2124               0 :     return NPERR_GENERIC_ERROR;
    2125                 :   }
    2126                 : 
    2127                 :   case NPNVSupportsXEmbedBool: {
    2128                 : #ifdef MOZ_WIDGET_GTK2
    2129               0 :     *(NPBool*)result = true;
    2130                 : #elif defined(MOZ_WIDGET_QT)
    2131                 :     // Desktop Flash fail to initialize if browser does not support NPNVSupportsXEmbedBool
    2132                 :     // even when wmode!=windowed, lets return fake support
    2133                 :     fprintf(stderr, "Fake support for XEmbed plugins in Qt port\n");
    2134                 :     *(NPBool*)result = true;
    2135                 : #else
    2136                 :     *(NPBool*)result = false;
    2137                 : #endif
    2138               0 :     return NPERR_NO_ERROR;
    2139                 :   }
    2140                 : 
    2141                 :   case NPNVWindowNPObject: {
    2142               0 :     *(NPObject **)result = _getwindowobject(npp);
    2143                 : 
    2144               0 :     return *(NPObject **)result ? NPERR_NO_ERROR : NPERR_GENERIC_ERROR;
    2145                 :   }
    2146                 : 
    2147                 :   case NPNVPluginElementNPObject: {
    2148               0 :     *(NPObject **)result = _getpluginelement(npp);
    2149                 : 
    2150               0 :     return *(NPObject **)result ? NPERR_NO_ERROR : NPERR_GENERIC_ERROR;
    2151                 :   }
    2152                 : 
    2153                 :   case NPNVSupportsWindowless: {
    2154                 : #if defined(XP_WIN) || defined(XP_MACOSX) || \
    2155                 :     (defined(MOZ_X11) && (defined(MOZ_WIDGET_GTK2) || defined(MOZ_WIDGET_QT)))
    2156               0 :     *(NPBool*)result = true;
    2157                 : #else
    2158                 :     *(NPBool*)result = false;
    2159                 : #endif
    2160               0 :     return NPERR_NO_ERROR;
    2161                 :   }
    2162                 : 
    2163                 :   case NPNVprivateModeBool: {
    2164               0 :     nsCOMPtr<nsIPrivateBrowsingService> pbs = do_GetService(NS_PRIVATE_BROWSING_SERVICE_CONTRACTID);
    2165               0 :     if (pbs) {
    2166                 :       bool enabled;
    2167               0 :       pbs->GetPrivateBrowsingEnabled(&enabled);
    2168               0 :       *(NPBool*)result = (NPBool)enabled;
    2169               0 :       return NPERR_NO_ERROR;
    2170                 :     }
    2171               0 :     return NPERR_GENERIC_ERROR;
    2172                 :   }
    2173                 : 
    2174                 :   case NPNVdocumentOrigin: {
    2175               0 :     nsNPAPIPluginInstance *inst = (nsNPAPIPluginInstance *)npp->ndata;
    2176               0 :     if (!inst) {
    2177               0 :       return NPERR_GENERIC_ERROR;
    2178                 :     }
    2179                 : 
    2180               0 :     nsCOMPtr<nsIDOMElement> element;
    2181               0 :     inst->GetDOMElement(getter_AddRefs(element));
    2182               0 :     if (!element) {
    2183               0 :       return NPERR_GENERIC_ERROR;
    2184                 :     }
    2185                 : 
    2186               0 :     nsCOMPtr<nsIContent> content(do_QueryInterface(element));
    2187               0 :     if (!content) {
    2188               0 :       return NPERR_GENERIC_ERROR;
    2189                 :     }
    2190                 : 
    2191               0 :     nsIPrincipal* principal = content->NodePrincipal();
    2192                 : 
    2193               0 :     nsAutoString utf16Origin;
    2194               0 :     res = nsContentUtils::GetUTFOrigin(principal, utf16Origin);
    2195               0 :     if (NS_FAILED(res)) {
    2196               0 :       return NPERR_GENERIC_ERROR;
    2197                 :     }
    2198                 : 
    2199               0 :     nsCOMPtr<nsIUnicodeNormalizer> normalizer = do_GetService(NS_UNICODE_NORMALIZER_CONTRACTID);
    2200               0 :     if (!normalizer) {
    2201               0 :       return NPERR_GENERIC_ERROR;
    2202                 :     }
    2203                 : 
    2204               0 :     nsAutoString normalizedUTF16Origin;
    2205               0 :     res = normalizer->NormalizeUnicodeNFKC(utf16Origin, normalizedUTF16Origin);
    2206               0 :     if (NS_FAILED(res)) {
    2207               0 :       return NPERR_GENERIC_ERROR;
    2208                 :     }
    2209                 : 
    2210               0 :     *(char**)result = ToNewUTF8String(normalizedUTF16Origin);
    2211               0 :     return *(char**)result ? NPERR_NO_ERROR : NPERR_GENERIC_ERROR;
    2212                 :   }
    2213                 : 
    2214                 : #ifdef XP_MACOSX
    2215                 :   case NPNVpluginDrawingModel: {
    2216                 :     if (npp) {
    2217                 :       nsNPAPIPluginInstance *inst = (nsNPAPIPluginInstance*)npp->ndata;
    2218                 :       if (inst) {
    2219                 :         NPDrawingModel drawingModel;
    2220                 :         inst->GetDrawingModel((PRInt32*)&drawingModel);
    2221                 :         *(NPDrawingModel*)result = drawingModel;
    2222                 :         return NPERR_NO_ERROR;
    2223                 :       }
    2224                 :     }
    2225                 :     else {
    2226                 :       return NPERR_GENERIC_ERROR;
    2227                 :     }
    2228                 :   }
    2229                 : 
    2230                 : #ifndef NP_NO_QUICKDRAW
    2231                 :   case NPNVsupportsQuickDrawBool: {
    2232                 :     *(NPBool*)result = true;
    2233                 :     
    2234                 :     return NPERR_NO_ERROR;
    2235                 :   }
    2236                 : #endif
    2237                 : 
    2238                 :   case NPNVsupportsCoreGraphicsBool: {
    2239                 :     *(NPBool*)result = true;
    2240                 :     
    2241                 :     return NPERR_NO_ERROR;
    2242                 :   }
    2243                 : 
    2244                 :    case NPNVsupportsCoreAnimationBool: {
    2245                 :      *(NPBool*)result = nsCocoaFeatures::SupportCoreAnimationPlugins();
    2246                 : 
    2247                 :      return NPERR_NO_ERROR;
    2248                 :    }
    2249                 : 
    2250                 :    case NPNVsupportsInvalidatingCoreAnimationBool: {
    2251                 :      *(NPBool*)result = nsCocoaFeatures::SupportCoreAnimationPlugins();
    2252                 : 
    2253                 :      return NPERR_NO_ERROR;
    2254                 :    }
    2255                 : 
    2256                 : 
    2257                 : #ifndef NP_NO_CARBON
    2258                 :   case NPNVsupportsCarbonBool: {
    2259                 :     *(NPBool*)result = true;
    2260                 : 
    2261                 :     return NPERR_NO_ERROR;
    2262                 :   }
    2263                 : #endif
    2264                 :   case NPNVsupportsCocoaBool: {
    2265                 :     *(NPBool*)result = true;
    2266                 : 
    2267                 :     return NPERR_NO_ERROR;
    2268                 :   }
    2269                 : 
    2270                 :   case NPNVsupportsUpdatedCocoaTextInputBool: {
    2271                 :     *(NPBool*)result = true;
    2272                 :     return NPERR_NO_ERROR;
    2273                 :   }
    2274                 : #endif
    2275                 : 
    2276                 : #ifdef MOZ_WIDGET_ANDROID
    2277                 :     case kLogInterfaceV0_ANPGetValue: {
    2278                 :       LOG("get log interface");
    2279                 :       ANPLogInterfaceV0 *i = (ANPLogInterfaceV0 *) result;
    2280                 :       InitLogInterface(i);
    2281                 :       return NPERR_NO_ERROR;
    2282                 :     }
    2283                 : 
    2284                 :     case kBitmapInterfaceV0_ANPGetValue: {
    2285                 :       LOG("get bitmap interface");
    2286                 :       ANPBitmapInterfaceV0 *i = (ANPBitmapInterfaceV0 *) result;
    2287                 :       InitBitmapInterface(i);
    2288                 :       return NPERR_NO_ERROR;
    2289                 :     }
    2290                 : 
    2291                 :     case kMatrixInterfaceV0_ANPGetValue: {
    2292                 :       LOG("get matrix interface");
    2293                 :       ANPMatrixInterfaceV0 *i = (ANPMatrixInterfaceV0 *) result;
    2294                 :       InitMatrixInterface(i);
    2295                 :       return NPERR_NO_ERROR;
    2296                 :     }
    2297                 :       
    2298                 :     case kPathInterfaceV0_ANPGetValue: {
    2299                 :       LOG("get path interface");
    2300                 :       ANPPathInterfaceV0 *i = (ANPPathInterfaceV0 *) result;
    2301                 :       InitPathInterface(i);
    2302                 :       return NPERR_NO_ERROR;
    2303                 :     }
    2304                 :       
    2305                 :     case kTypefaceInterfaceV0_ANPGetValue: {
    2306                 :       LOG("get typeface interface");
    2307                 :       ANPTypefaceInterfaceV0 *i = (ANPTypefaceInterfaceV0 *) result;
    2308                 :       InitTypeFaceInterface(i);
    2309                 :       return NPERR_NO_ERROR;
    2310                 :     }
    2311                 : 
    2312                 :     case kPaintInterfaceV0_ANPGetValue: {
    2313                 :       LOG("get paint interface");
    2314                 :       ANPPaintInterfaceV0 *i = (ANPPaintInterfaceV0 *) result;
    2315                 :       InitPaintInterface(i);
    2316                 :       return NPERR_NO_ERROR;
    2317                 :     }
    2318                 : 
    2319                 :     case kCanvasInterfaceV0_ANPGetValue: {
    2320                 :       LOG("get canvas interface");
    2321                 :       ANPCanvasInterfaceV0 *i = (ANPCanvasInterfaceV0 *) result;
    2322                 :       InitCanvasInterface(i);
    2323                 :       return NPERR_NO_ERROR;
    2324                 :     }
    2325                 : 
    2326                 :     case kWindowInterfaceV0_ANPGetValue: {
    2327                 :       LOG("get window interface");
    2328                 :       ANPWindowInterfaceV0 *i = (ANPWindowInterfaceV0 *) result;
    2329                 :       InitWindowInterface(i);
    2330                 :       return NPERR_NO_ERROR;
    2331                 :     }
    2332                 : 
    2333                 :     case kAudioTrackInterfaceV0_ANPGetValue: {
    2334                 :       LOG("get audio interface");
    2335                 :       ANPAudioTrackInterfaceV0 *i = (ANPAudioTrackInterfaceV0 *) result;
    2336                 :       InitAudioTrackInterfaceV0(i);
    2337                 :       return NPERR_NO_ERROR;
    2338                 :     }
    2339                 : 
    2340                 :     case kEventInterfaceV0_ANPGetValue: {
    2341                 :       LOG("get event interface");
    2342                 :       ANPEventInterfaceV0 *i = (ANPEventInterfaceV0 *) result;
    2343                 :       InitEventInterface(i);
    2344                 :       return NPERR_NO_ERROR;
    2345                 :     }
    2346                 : 
    2347                 :     case kSystemInterfaceV0_ANPGetValue: {
    2348                 :       LOG("get system interface");
    2349                 :       ANPSystemInterfaceV0* i = reinterpret_cast<ANPSystemInterfaceV0*>(result);
    2350                 :       InitSystemInterface(i);
    2351                 :       return NPERR_NO_ERROR;
    2352                 :     }
    2353                 : 
    2354                 :     case kSurfaceInterfaceV0_ANPGetValue: {
    2355                 :       LOG("get surface interface");
    2356                 :       ANPSurfaceInterfaceV0 *i = (ANPSurfaceInterfaceV0 *) result;
    2357                 :       InitSurfaceInterface(i);
    2358                 :       return NPERR_NO_ERROR;
    2359                 :     }
    2360                 :       
    2361                 :     case kSupportedDrawingModel_ANPGetValue: {
    2362                 :       LOG("get supported drawing model");
    2363                 :       uint32_t* bits = reinterpret_cast<uint32_t*>(result);
    2364                 :       *bits = kBitmap_ANPDrawingModel && kSurface_ANPDrawingModel;
    2365                 :       return NPERR_NO_ERROR;
    2366                 :     }  
    2367                 : 
    2368                 :     case kJavaContext_ANPGetValue: {
    2369                 :       LOG("get context");
    2370                 :       JNIEnv* env = GetJNIForThread();
    2371                 :       if (!env)
    2372                 :         return NPERR_GENERIC_ERROR;
    2373                 : 
    2374                 :       jclass cls     = env->FindClass("org/mozilla/gecko/GeckoApp");
    2375                 :       jfieldID field = env->GetStaticFieldID(cls, "mAppContext",
    2376                 :                                              "Lorg/mozilla/gecko/GeckoApp;");
    2377                 :       jobject ret = env->GetStaticObjectField(cls, field);
    2378                 :       int32_t* i  = reinterpret_cast<int32_t*>(result);
    2379                 :       *i = reinterpret_cast<int32_t>(ret);
    2380                 :       return NPERR_NO_ERROR;
    2381                 :     }
    2382                 : 
    2383                 :     case kAudioTrackInterfaceV1_ANPGetValue: {
    2384                 :       LOG("get audio interface v1");
    2385                 :       ANPAudioTrackInterfaceV1 *i = (ANPAudioTrackInterfaceV1 *) result;
    2386                 :       InitAudioTrackInterfaceV1(i);
    2387                 :       return NPERR_NO_ERROR;
    2388                 :     }
    2389                 : 
    2390                 :     case kNativeWindowInterfaceV0_ANPGetValue: {
    2391                 :       LOG("get native window interface v0");
    2392                 :       ANPNativeWindowInterfaceV0* i = (ANPNativeWindowInterfaceV0 *) result;
    2393                 :       InitNativeWindowInterface(i);
    2394                 :       return NPERR_NO_ERROR;
    2395                 :     }
    2396                 : 
    2397                 :     case kOpenGLInterfaceV0_ANPGetValue: {
    2398                 :       LOG("get openGL interface");
    2399                 :       ANPOpenGLInterfaceV0 *i = (ANPOpenGLInterfaceV0*) result;
    2400                 :       InitOpenGLInterface(i);
    2401                 :       return NPERR_NO_ERROR;
    2402                 :     }
    2403                 : 
    2404                 :     case kWindowInterfaceV1_ANPGetValue: {
    2405                 :       LOG("get Window interface V1");
    2406                 :       ANPWindowInterfaceV1 *i = (ANPWindowInterfaceV1 *) result;
    2407                 :       InitWindowInterfaceV1(i);
    2408                 :       return NPERR_NO_ERROR;
    2409                 :     }
    2410                 : 
    2411                 :     case kWindowInterfaceV2_ANPGetValue: {
    2412                 :       LOG("get Window interface V2");
    2413                 :       ANPWindowInterfaceV2 *i = (ANPWindowInterfaceV2 *) result;
    2414                 :       InitWindowInterfaceV2(i);
    2415                 :       return NPERR_NO_ERROR;
    2416                 :     }
    2417                 : 
    2418                 :     case kVideoInterfaceV0_ANPGetValue: {
    2419                 :       LOG("get video interface");
    2420                 :       ANPVideoInterfaceV0 *i = (ANPVideoInterfaceV0*) result;
    2421                 :       InitVideoInterfaceV0(i);
    2422                 :       return NPERR_NO_ERROR;
    2423                 :     }
    2424                 : 
    2425                 :     case kVideoInterfaceV1_ANPGetValue: {
    2426                 :       LOG("get video interface");
    2427                 :       ANPVideoInterfaceV1 *i = (ANPVideoInterfaceV1*) result;
    2428                 :       InitVideoInterfaceV1(i);
    2429                 :       return NPERR_NO_ERROR;
    2430                 :     }
    2431                 : 
    2432                 : 
    2433                 :     case kSystemInterfaceV1_ANPGetValue: {
    2434                 :       LOG("get system interface v1");
    2435                 :       ANPSystemInterfaceV1* i = reinterpret_cast<ANPSystemInterfaceV1*>(result);
    2436                 :       InitSystemInterfaceV1(i);
    2437                 :       return NPERR_NO_ERROR;
    2438                 :     }
    2439                 : 
    2440                 :     case kSystemInterfaceV2_ANPGetValue: {
    2441                 :       LOG("get system interface v2");
    2442                 :       ANPSystemInterfaceV2* i = reinterpret_cast<ANPSystemInterfaceV2*>(result);
    2443                 :       InitSystemInterfaceV2(i);
    2444                 :       return NPERR_NO_ERROR;
    2445                 :     }
    2446                 : 
    2447                 : #endif
    2448                 : 
    2449                 :   // we no longer hand out any XPCOM objects
    2450                 :   case NPNVDOMElement:
    2451                 :     // fall through
    2452                 :   case NPNVDOMWindow:
    2453                 :     // fall through
    2454                 :   case NPNVserviceManager:
    2455                 :     // old XPCOM objects, no longer supported, but null out the out
    2456                 :     // param to avoid crashing plugins that still try to use this.
    2457               0 :     *(nsISupports**)result = nsnull;
    2458                 :     // fall through
    2459                 :   default:
    2460               0 :     NPN_PLUGIN_LOG(PLUGIN_LOG_NORMAL, ("NPN_getvalue unhandled get value: %d\n", variable));
    2461               0 :     return NPERR_GENERIC_ERROR;
    2462                 :   }
    2463                 : }
    2464                 : 
    2465                 : NPError NP_CALLBACK
    2466               0 : _setvalue(NPP npp, NPPVariable variable, void *result)
    2467                 : {
    2468               0 :   if (!NS_IsMainThread()) {
    2469               0 :     NPN_PLUGIN_LOG(PLUGIN_LOG_ALWAYS,("NPN_setvalue called from the wrong thread\n"));
    2470               0 :     return NPERR_INVALID_PARAM;
    2471                 :   }
    2472               0 :   NPN_PLUGIN_LOG(PLUGIN_LOG_NORMAL, ("NPN_SetValue: npp=%p, var=%d\n",
    2473                 :                                      (void*)npp, (int)variable));
    2474                 : 
    2475               0 :   if (!npp)
    2476               0 :     return NPERR_INVALID_INSTANCE_ERROR;
    2477                 : 
    2478               0 :   nsNPAPIPluginInstance *inst = (nsNPAPIPluginInstance *) npp->ndata;
    2479                 : 
    2480               0 :   NS_ASSERTION(inst, "null instance");
    2481                 : 
    2482               0 :   if (!inst)
    2483               0 :     return NPERR_INVALID_INSTANCE_ERROR;
    2484                 : 
    2485               0 :   PluginDestructionGuard guard(inst);
    2486                 : 
    2487               0 :   switch (variable) {
    2488                 : 
    2489                 :     // we should keep backward compatibility with NPAPI where the
    2490                 :     // actual pointer value is checked rather than its content
    2491                 :     // when passing booleans
    2492                 :     case NPPVpluginWindowBool: {
    2493                 : #ifdef XP_MACOSX
    2494                 :       // This setting doesn't apply to OS X (only to Windows and Unix/Linux).
    2495                 :       // See https://developer.mozilla.org/En/NPN_SetValue#section_5.  Return
    2496                 :       // NPERR_NO_ERROR here to conform to other browsers' behavior on OS X
    2497                 :       // (e.g. Safari and Opera).
    2498                 :       return NPERR_NO_ERROR;
    2499                 : #else
    2500               0 :       NPBool bWindowless = (result == nsnull);
    2501               0 :       return inst->SetWindowless(bWindowless);
    2502                 : #endif
    2503                 :     }
    2504                 :     case NPPVpluginTransparentBool: {
    2505               0 :       NPBool bTransparent = (result != nsnull);
    2506               0 :       return inst->SetTransparent(bTransparent);
    2507                 :     }
    2508                 : 
    2509                 :     case NPPVjavascriptPushCallerBool:
    2510                 :       {
    2511                 :         nsresult rv;
    2512                 :         nsCOMPtr<nsIJSContextStack> contextStack =
    2513               0 :           do_GetService("@mozilla.org/js/xpc/ContextStack;1", &rv);
    2514               0 :         if (NS_SUCCEEDED(rv)) {
    2515               0 :           NPBool bPushCaller = (result != nsnull);
    2516               0 :           if (bPushCaller) {
    2517                 :             JSContext *cx;
    2518               0 :             rv = inst->GetJSContext(&cx);
    2519               0 :             if (NS_SUCCEEDED(rv))
    2520               0 :               rv = contextStack->Push(cx);
    2521                 :           } else {
    2522               0 :             rv = contextStack->Pop(nsnull);
    2523                 :           }
    2524                 :         }
    2525               0 :         return NS_SUCCEEDED(rv) ? NPERR_NO_ERROR : NPERR_GENERIC_ERROR;
    2526                 :       }
    2527                 : 
    2528                 :     case NPPVpluginKeepLibraryInMemory: {
    2529               0 :       NPBool bCached = (result != nsnull);
    2530               0 :       return inst->SetCached(bCached);
    2531                 :     }
    2532                 : 
    2533                 :     case NPPVpluginUsesDOMForCursorBool: {
    2534               0 :       bool useDOMForCursor = (result != nsnull);
    2535               0 :       return inst->SetUsesDOMForCursor(useDOMForCursor);
    2536                 :     }
    2537                 : 
    2538                 : #ifndef MOZ_WIDGET_ANDROID
    2539                 :     // On android, their 'drawing model' uses the same constant!
    2540                 :     case NPPVpluginDrawingModel: {
    2541               0 :       if (inst) {
    2542               0 :         inst->SetDrawingModel((NPDrawingModel)NS_PTR_TO_INT32(result));
    2543               0 :         return NPERR_NO_ERROR;
    2544                 :       }
    2545                 :       else {
    2546               0 :         return NPERR_GENERIC_ERROR;
    2547                 :       }
    2548                 :     }
    2549                 : #endif
    2550                 : 
    2551                 : #ifdef XP_MACOSX
    2552                 :     case NPPVpluginEventModel: {
    2553                 :       if (inst) {
    2554                 :         inst->SetEventModel((NPEventModel)NS_PTR_TO_INT32(result));
    2555                 :         return NPERR_NO_ERROR;
    2556                 :       }
    2557                 :       else {
    2558                 :         return NPERR_GENERIC_ERROR;
    2559                 :       }
    2560                 :     }
    2561                 : #endif
    2562                 : #ifdef MOZ_WIDGET_ANDROID
    2563                 :   case kRequestDrawingModel_ANPSetValue:
    2564                 :     if (inst)
    2565                 :       inst->SetANPDrawingModel(NS_PTR_TO_INT32(result));
    2566                 :     return NPERR_NO_ERROR;
    2567                 :   case kAcceptEvents_ANPSetValue:
    2568                 :     return NPERR_NO_ERROR;
    2569                 : #endif
    2570                 :     default:
    2571               0 :       return NPERR_GENERIC_ERROR;
    2572                 :   }
    2573                 : }
    2574                 : 
    2575                 : NPError NP_CALLBACK
    2576               0 : _requestread(NPStream *pstream, NPByteRange *rangeList)
    2577                 : {
    2578               0 :   if (!NS_IsMainThread()) {
    2579               0 :     NPN_PLUGIN_LOG(PLUGIN_LOG_ALWAYS,("NPN_requestread called from the wrong thread\n"));
    2580               0 :     return NPERR_INVALID_PARAM;
    2581                 :   }
    2582               0 :   NPN_PLUGIN_LOG(PLUGIN_LOG_NORMAL, ("NPN_RequestRead: stream=%p\n",
    2583                 :                                      (void*)pstream));
    2584                 : 
    2585                 : #ifdef PLUGIN_LOGGING
    2586               0 :   for(NPByteRange * range = rangeList; range != nsnull; range = range->next)
    2587               0 :     PR_LOG(nsPluginLogging::gNPNLog,PLUGIN_LOG_NOISY,
    2588                 :     ("%i-%i", range->offset, range->offset + range->length - 1));
    2589                 : 
    2590               0 :   PR_LOG(nsPluginLogging::gNPNLog,PLUGIN_LOG_NOISY, ("\n\n"));
    2591               0 :   PR_LogFlush();
    2592                 : #endif
    2593                 : 
    2594               0 :   if (!pstream || !rangeList || !pstream->ndata)
    2595               0 :     return NPERR_INVALID_PARAM;
    2596                 : 
    2597               0 :   nsNPAPIPluginStreamListener* streamlistener = (nsNPAPIPluginStreamListener*)pstream->ndata;
    2598                 : 
    2599               0 :   PRInt32 streamtype = NP_NORMAL;
    2600                 : 
    2601               0 :   streamlistener->GetStreamType(&streamtype);
    2602                 : 
    2603               0 :   if (streamtype != NP_SEEK)
    2604               0 :     return NPERR_STREAM_NOT_SEEKABLE;
    2605                 : 
    2606               0 :   if (!streamlistener->mStreamInfo)
    2607               0 :     return NPERR_GENERIC_ERROR;
    2608                 : 
    2609                 :   nsresult rv = streamlistener->mStreamInfo
    2610               0 :     ->RequestRead((NPByteRange *)rangeList);
    2611               0 :   if (NS_FAILED(rv))
    2612               0 :     return NPERR_GENERIC_ERROR;
    2613                 : 
    2614               0 :   return NS_OK;
    2615                 : }
    2616                 : 
    2617                 : // Deprecated, only stubbed out
    2618                 : void* NP_CALLBACK /* OJI type: JRIEnv* */
    2619               0 : _getJavaEnv()
    2620                 : {
    2621               0 :   NPN_PLUGIN_LOG(PLUGIN_LOG_NORMAL, ("NPN_GetJavaEnv\n"));
    2622               0 :   return NULL;
    2623                 : }
    2624                 : 
    2625                 : const char * NP_CALLBACK
    2626               0 : _useragent(NPP npp)
    2627                 : {
    2628               0 :   if (!NS_IsMainThread()) {
    2629               0 :     NPN_PLUGIN_LOG(PLUGIN_LOG_ALWAYS,("NPN_useragent called from the wrong thread\n"));
    2630               0 :     return nsnull;
    2631                 :   }
    2632               0 :   NPN_PLUGIN_LOG(PLUGIN_LOG_NORMAL, ("NPN_UserAgent: npp=%p\n", (void*)npp));
    2633                 : 
    2634               0 :   nsCOMPtr<nsIPluginHost> pluginHostCOM(do_GetService(MOZ_PLUGIN_HOST_CONTRACTID));
    2635               0 :   nsPluginHost *pluginHost = static_cast<nsPluginHost*>(pluginHostCOM.get());
    2636               0 :   if (!pluginHost) {
    2637               0 :     return nsnull;
    2638                 :   }
    2639                 : 
    2640                 :   const char *retstr;
    2641               0 :   nsresult rv = pluginHost->UserAgent(&retstr);
    2642               0 :   if (NS_FAILED(rv))
    2643               0 :     return nsnull;
    2644                 : 
    2645               0 :   return retstr;
    2646                 : }
    2647                 : 
    2648                 : void * NP_CALLBACK
    2649               0 : _memalloc (uint32_t size)
    2650                 : {
    2651               0 :   if (!NS_IsMainThread()) {
    2652               0 :     NPN_PLUGIN_LOG(PLUGIN_LOG_NORMAL,("NPN_memalloc called from the wrong thread\n"));
    2653                 :   }
    2654               0 :   NPN_PLUGIN_LOG(PLUGIN_LOG_NOISY, ("NPN_MemAlloc: size=%d\n", size));
    2655               0 :   return nsMemory::Alloc(size);
    2656                 : }
    2657                 : 
    2658                 : // Deprecated, only stubbed out
    2659                 : void* NP_CALLBACK /* OJI type: jref */
    2660               0 : _getJavaPeer(NPP npp)
    2661                 : {
    2662               0 :   NPN_PLUGIN_LOG(PLUGIN_LOG_NORMAL, ("NPN_GetJavaPeer: npp=%p\n", (void*)npp));
    2663               0 :   return NULL;
    2664                 : }
    2665                 : 
    2666                 : void NP_CALLBACK
    2667               0 : _pushpopupsenabledstate(NPP npp, NPBool enabled)
    2668                 : {
    2669               0 :   if (!NS_IsMainThread()) {
    2670               0 :     NPN_PLUGIN_LOG(PLUGIN_LOG_ALWAYS,("NPN_pushpopupsenabledstate called from the wrong thread\n"));
    2671               0 :     return;
    2672                 :   }
    2673               0 :   nsNPAPIPluginInstance *inst = npp ? (nsNPAPIPluginInstance *)npp->ndata : NULL;
    2674               0 :   if (!inst)
    2675               0 :     return;
    2676                 : 
    2677               0 :   inst->PushPopupsEnabledState(enabled);
    2678                 : }
    2679                 : 
    2680                 : void NP_CALLBACK
    2681               0 : _poppopupsenabledstate(NPP npp)
    2682                 : {
    2683               0 :   if (!NS_IsMainThread()) {
    2684               0 :     NPN_PLUGIN_LOG(PLUGIN_LOG_ALWAYS,("NPN_poppopupsenabledstate called from the wrong thread\n"));
    2685               0 :     return;
    2686                 :   }
    2687               0 :   nsNPAPIPluginInstance *inst = npp ? (nsNPAPIPluginInstance *)npp->ndata : NULL;
    2688               0 :   if (!inst)
    2689               0 :     return;
    2690                 : 
    2691               0 :   inst->PopPopupsEnabledState();
    2692                 : }
    2693                 : 
    2694                 : void NP_CALLBACK
    2695               0 : _pluginthreadasynccall(NPP instance, PluginThreadCallback func, void *userData)
    2696                 : {
    2697               0 :   if (NS_IsMainThread()) {
    2698               0 :     NPN_PLUGIN_LOG(PLUGIN_LOG_NOISY,("NPN_pluginthreadasynccall called from the main thread\n"));
    2699                 :   } else {
    2700               0 :     NPN_PLUGIN_LOG(PLUGIN_LOG_NOISY,("NPN_pluginthreadasynccall called from a non main thread\n"));
    2701                 :   }
    2702                 :   nsRefPtr<nsPluginThreadRunnable> evt =
    2703               0 :     new nsPluginThreadRunnable(instance, func, userData);
    2704                 : 
    2705               0 :   if (evt && evt->IsValid()) {
    2706               0 :     NS_DispatchToMainThread(evt);
    2707                 :   }
    2708               0 : }
    2709                 : 
    2710                 : NPError NP_CALLBACK
    2711               0 : _getvalueforurl(NPP instance, NPNURLVariable variable, const char *url,
    2712                 :                 char **value, uint32_t *len)
    2713                 : {
    2714               0 :   if (!instance) {
    2715               0 :     return NPERR_INVALID_PARAM;
    2716                 :   }
    2717                 : 
    2718               0 :   if (!url || !*url || !len) {
    2719               0 :     return NPERR_INVALID_URL;
    2720                 :   }
    2721                 : 
    2722               0 :   *len = 0;
    2723                 : 
    2724               0 :   switch (variable) {
    2725                 :   case NPNURLVProxy:
    2726                 :     {
    2727               0 :       nsCOMPtr<nsIPluginHost> pluginHostCOM(do_GetService(MOZ_PLUGIN_HOST_CONTRACTID));
    2728               0 :       nsPluginHost *pluginHost = static_cast<nsPluginHost*>(pluginHostCOM.get());
    2729               0 :       if (pluginHost && NS_SUCCEEDED(pluginHost->FindProxyForURL(url, value))) {
    2730               0 :         *len = *value ? PL_strlen(*value) : 0;
    2731               0 :         return NPERR_NO_ERROR;
    2732                 :       }
    2733               0 :       break;
    2734                 :     }
    2735                 :   case NPNURLVCookie:
    2736                 :     {
    2737                 :       nsCOMPtr<nsICookieService> cookieService =
    2738               0 :         do_GetService(NS_COOKIESERVICE_CONTRACTID);
    2739                 : 
    2740               0 :       if (!cookieService)
    2741               0 :         return NPERR_GENERIC_ERROR;
    2742                 : 
    2743                 :       // Make an nsURI from the url argument
    2744               0 :       nsCOMPtr<nsIURI> uri;
    2745               0 :       if (NS_FAILED(NS_NewURI(getter_AddRefs(uri), nsDependentCString(url)))) {
    2746               0 :         return NPERR_GENERIC_ERROR;
    2747                 :       }
    2748                 : 
    2749               0 :       if (NS_FAILED(cookieService->GetCookieString(uri, nsnull, value)) ||
    2750               0 :           !*value) {
    2751               0 :         return NPERR_GENERIC_ERROR;
    2752                 :       }
    2753                 : 
    2754               0 :       *len = PL_strlen(*value);
    2755               0 :       return NPERR_NO_ERROR;
    2756                 :     }
    2757                 : 
    2758                 :     break;
    2759                 :   default:
    2760                 :     // Fall through and return an error...
    2761                 :     ;
    2762                 :   }
    2763                 : 
    2764               0 :   return NPERR_GENERIC_ERROR;
    2765                 : }
    2766                 : 
    2767                 : NPError NP_CALLBACK
    2768               0 : _setvalueforurl(NPP instance, NPNURLVariable variable, const char *url,
    2769                 :                 const char *value, uint32_t len)
    2770                 : {
    2771               0 :   if (!instance) {
    2772               0 :     return NPERR_INVALID_PARAM;
    2773                 :   }
    2774                 : 
    2775               0 :   if (!url || !*url) {
    2776               0 :     return NPERR_INVALID_URL;
    2777                 :   }
    2778                 : 
    2779               0 :   switch (variable) {
    2780                 :   case NPNURLVCookie:
    2781                 :     {
    2782               0 :       if (!url || !value || (0 >= len))
    2783               0 :         return NPERR_INVALID_PARAM;
    2784                 : 
    2785               0 :       nsresult rv = NS_ERROR_FAILURE;
    2786               0 :       nsCOMPtr<nsIIOService> ioService(do_GetService(NS_IOSERVICE_CONTRACTID, &rv));
    2787               0 :       if (NS_FAILED(rv))
    2788               0 :         return NPERR_GENERIC_ERROR;
    2789                 : 
    2790               0 :       nsCOMPtr<nsICookieService> cookieService = do_GetService(NS_COOKIESERVICE_CONTRACTID, &rv);
    2791               0 :       if (NS_FAILED(rv))
    2792               0 :         return NPERR_GENERIC_ERROR;
    2793                 : 
    2794               0 :       nsCOMPtr<nsIURI> uriIn;
    2795               0 :       rv = ioService->NewURI(nsDependentCString(url), nsnull, nsnull, getter_AddRefs(uriIn));
    2796               0 :       if (NS_FAILED(rv))
    2797               0 :         return NPERR_GENERIC_ERROR;
    2798                 : 
    2799               0 :       nsCOMPtr<nsIPrompt> prompt;
    2800               0 :       nsPluginHost::GetPrompt(nsnull, getter_AddRefs(prompt));
    2801                 : 
    2802               0 :       char *cookie = (char*)value;
    2803               0 :       char c = cookie[len];
    2804               0 :       cookie[len] = '\0';
    2805               0 :       rv = cookieService->SetCookieString(uriIn, prompt, cookie, nsnull);
    2806               0 :       cookie[len] = c;
    2807               0 :       if (NS_SUCCEEDED(rv))
    2808               0 :         return NPERR_NO_ERROR;
    2809                 :     }
    2810                 : 
    2811               0 :     break;
    2812                 :   case NPNURLVProxy:
    2813                 :     // We don't support setting proxy values, fall through...
    2814                 :   default:
    2815                 :     // Fall through and return an error...
    2816                 :     ;
    2817                 :   }
    2818                 : 
    2819               0 :   return NPERR_GENERIC_ERROR;
    2820                 : }
    2821                 : 
    2822                 : NPError NP_CALLBACK
    2823               0 : _getauthenticationinfo(NPP instance, const char *protocol, const char *host,
    2824                 :                        int32_t port, const char *scheme, const char *realm,
    2825                 :                        char **username, uint32_t *ulen, char **password,
    2826                 :                        uint32_t *plen)
    2827                 : {
    2828               0 :   if (!instance || !protocol || !host || !scheme || !realm || !username ||
    2829                 :       !ulen || !password || !plen)
    2830               0 :     return NPERR_INVALID_PARAM;
    2831                 : 
    2832               0 :   *username = nsnull;
    2833               0 :   *password = nsnull;
    2834               0 :   *ulen = 0;
    2835               0 :   *plen = 0;
    2836                 : 
    2837               0 :   nsDependentCString proto(protocol);
    2838                 : 
    2839               0 :   if (!proto.LowerCaseEqualsLiteral("http") &&
    2840               0 :       !proto.LowerCaseEqualsLiteral("https"))
    2841               0 :     return NPERR_GENERIC_ERROR;
    2842                 : 
    2843                 :   nsCOMPtr<nsIHttpAuthManager> authManager =
    2844               0 :     do_GetService("@mozilla.org/network/http-auth-manager;1");
    2845               0 :   if (!authManager)
    2846               0 :     return NPERR_GENERIC_ERROR;
    2847                 : 
    2848               0 :   nsAutoString unused, uname16, pwd16;
    2849               0 :   if (NS_FAILED(authManager->GetAuthIdentity(proto, nsDependentCString(host),
    2850                 :                                              port, nsDependentCString(scheme),
    2851                 :                                              nsDependentCString(realm),
    2852                 :                                              EmptyCString(), unused, uname16,
    2853                 :                                              pwd16))) {
    2854               0 :     return NPERR_GENERIC_ERROR;
    2855                 :   }
    2856                 : 
    2857               0 :   NS_ConvertUTF16toUTF8 uname8(uname16);
    2858               0 :   NS_ConvertUTF16toUTF8 pwd8(pwd16);
    2859                 : 
    2860               0 :   *username = ToNewCString(uname8);
    2861               0 :   *ulen = *username ? uname8.Length() : 0;
    2862                 : 
    2863               0 :   *password = ToNewCString(pwd8);
    2864               0 :   *plen = *password ? pwd8.Length() : 0;
    2865                 : 
    2866               0 :   return NPERR_NO_ERROR;
    2867                 : }
    2868                 : 
    2869                 : uint32_t NP_CALLBACK
    2870               0 : _scheduletimer(NPP instance, uint32_t interval, NPBool repeat, PluginTimerFunc timerFunc)
    2871                 : {
    2872               0 :   nsNPAPIPluginInstance *inst = (nsNPAPIPluginInstance *)instance->ndata;
    2873               0 :   if (!inst)
    2874               0 :     return 0;
    2875                 : 
    2876               0 :   return inst->ScheduleTimer(interval, repeat, timerFunc);
    2877                 : }
    2878                 : 
    2879                 : void NP_CALLBACK
    2880               0 : _unscheduletimer(NPP instance, uint32_t timerID)
    2881                 : {
    2882               0 :   nsNPAPIPluginInstance *inst = (nsNPAPIPluginInstance *)instance->ndata;
    2883               0 :   if (!inst)
    2884               0 :     return;
    2885                 : 
    2886               0 :   inst->UnscheduleTimer(timerID);
    2887                 : }
    2888                 : 
    2889                 : NPError NP_CALLBACK
    2890               0 : _popupcontextmenu(NPP instance, NPMenu* menu)
    2891                 : {
    2892               0 :   nsNPAPIPluginInstance *inst = (nsNPAPIPluginInstance *)instance->ndata;
    2893               0 :   if (!inst)
    2894               0 :     return NPERR_GENERIC_ERROR;
    2895                 : 
    2896               0 :   return inst->PopUpContextMenu(menu);
    2897                 : }
    2898                 : 
    2899                 : NPError NP_CALLBACK
    2900               0 : _initasyncsurface(NPP instance, NPSize *size, NPImageFormat format, void *initData, NPAsyncSurface *surface)
    2901                 : {
    2902               0 :   nsNPAPIPluginInstance *inst = (nsNPAPIPluginInstance *)instance->ndata;
    2903               0 :   if (!inst)
    2904               0 :     return NPERR_GENERIC_ERROR;
    2905                 : 
    2906               0 :   return inst->InitAsyncSurface(size, format, initData, surface);
    2907                 : }
    2908                 : 
    2909                 : NPError NP_CALLBACK
    2910               0 : _finalizeasyncsurface(NPP instance, NPAsyncSurface *surface)
    2911                 : {
    2912               0 :   nsNPAPIPluginInstance *inst = (nsNPAPIPluginInstance *)instance->ndata;
    2913               0 :   if (!inst)
    2914               0 :     return NPERR_GENERIC_ERROR;
    2915                 : 
    2916               0 :   return inst->FinalizeAsyncSurface(surface);
    2917                 : }
    2918                 : 
    2919                 : void NP_CALLBACK
    2920               0 : _setcurrentasyncsurface(NPP instance, NPAsyncSurface *surface, NPRect *changed)
    2921                 : {
    2922               0 :   nsNPAPIPluginInstance *inst = (nsNPAPIPluginInstance *)instance->ndata;
    2923               0 :   if (!inst)
    2924               0 :     return;
    2925                 : 
    2926               0 :   inst->SetCurrentAsyncSurface(surface, changed);
    2927                 : }
    2928                 : 
    2929                 : NPBool NP_CALLBACK
    2930               0 : _convertpoint(NPP instance, double sourceX, double sourceY, NPCoordinateSpace sourceSpace, double *destX, double *destY, NPCoordinateSpace destSpace)
    2931                 : {
    2932               0 :   nsNPAPIPluginInstance *inst = (nsNPAPIPluginInstance *)instance->ndata;
    2933               0 :   if (!inst)
    2934               0 :     return false;
    2935                 : 
    2936               0 :   return inst->ConvertPoint(sourceX, sourceY, sourceSpace, destX, destY, destSpace);
    2937                 : }
    2938                 : 
    2939                 : void NP_CALLBACK
    2940               0 : _urlredirectresponse(NPP instance, void* notifyData, NPBool allow)
    2941                 : {
    2942               0 :   nsNPAPIPluginInstance *inst = (nsNPAPIPluginInstance *)instance->ndata;
    2943               0 :   if (!inst) {
    2944               0 :     return;
    2945                 :   }
    2946                 : 
    2947               0 :   inst->URLRedirectResponse(notifyData, allow);
    2948                 : }
    2949                 : 
    2950                 : } /* namespace parent */
    2951                 : } /* namespace plugins */
    2952                 : } /* namespace mozilla */

Generated by: LCOV version 1.7