LCOV - app.info - dom/plugins/base/nsNPAPIPlugin.cpp

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-07-07 | 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