dom/plugins/base/nsNPAPIPlugin.cpp

changeset 0
6474c204b198
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/dom/plugins/base/nsNPAPIPlugin.cpp	Wed Dec 31 06:09:35 2014 +0100
     1.3 @@ -0,0 +1,2842 @@
     1.4 +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
     1.5 +/* This Source Code Form is subject to the terms of the Mozilla Public
     1.6 + * License, v. 2.0. If a copy of the MPL was not distributed with this
     1.7 + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
     1.8 +
     1.9 +#include "base/basictypes.h"
    1.10 +
    1.11 +/* This must occur *after* layers/PLayerTransaction.h to avoid typedefs conflicts. */
    1.12 +#include "mozilla/ArrayUtils.h"
    1.13 +
    1.14 +#include "pratom.h"
    1.15 +#include "prmem.h"
    1.16 +#include "prenv.h"
    1.17 +#include "prclist.h"
    1.18 +
    1.19 +#include "jsfriendapi.h"
    1.20 +
    1.21 +#include "nsPluginHost.h"
    1.22 +#include "nsNPAPIPlugin.h"
    1.23 +#include "nsNPAPIPluginInstance.h"
    1.24 +#include "nsNPAPIPluginStreamListener.h"
    1.25 +#include "nsPluginStreamListenerPeer.h"
    1.26 +#include "nsIServiceManager.h"
    1.27 +#include "nsThreadUtils.h"
    1.28 +#include "mozilla/Preferences.h"
    1.29 +#include "nsPluginInstanceOwner.h"
    1.30 +
    1.31 +#include "nsPluginsDir.h"
    1.32 +#include "nsPluginLogging.h"
    1.33 +
    1.34 +#include "nsIDOMElement.h"
    1.35 +#include "nsPIDOMWindow.h"
    1.36 +#include "nsGlobalWindow.h"
    1.37 +#include "nsIDocument.h"
    1.38 +#include "nsIContent.h"
    1.39 +#include "nsIScriptGlobalObject.h"
    1.40 +#include "nsIScriptContext.h"
    1.41 +#include "nsIUnicodeNormalizer.h"
    1.42 +#include "nsDOMJSUtils.h"
    1.43 +#include "nsIPrincipal.h"
    1.44 +#include "nsWildCard.h"
    1.45 +#include "nsContentUtils.h"
    1.46 +#include "nsCxPusher.h"
    1.47 +
    1.48 +#include "nsIXPConnect.h"
    1.49 +
    1.50 +#include "nsIObserverService.h"
    1.51 +#include <prinrval.h>
    1.52 +
    1.53 +#ifdef MOZ_WIDGET_COCOA
    1.54 +#include <Carbon/Carbon.h>
    1.55 +#include <ApplicationServices/ApplicationServices.h>
    1.56 +#include <OpenGL/OpenGL.h>
    1.57 +#include "nsCocoaFeatures.h"
    1.58 +#endif
    1.59 +
    1.60 +// needed for nppdf plugin
    1.61 +#if (MOZ_WIDGET_GTK)
    1.62 +#include <gdk/gdk.h>
    1.63 +#include <gdk/gdkx.h>
    1.64 +#if (MOZ_WIDGET_GTK == 2)
    1.65 +#include "gtk2xtbin.h"
    1.66 +#endif
    1.67 +#endif
    1.68 +
    1.69 +#include "nsJSUtils.h"
    1.70 +#include "nsJSNPRuntime.h"
    1.71 +#include "nsIHttpAuthManager.h"
    1.72 +#include "nsICookieService.h"
    1.73 +#include "nsILoadContext.h"
    1.74 +#include "nsIDocShell.h"
    1.75 +
    1.76 +#include "nsNetUtil.h"
    1.77 +
    1.78 +#include "mozilla/Mutex.h"
    1.79 +#include "mozilla/PluginLibrary.h"
    1.80 +using mozilla::PluginLibrary;
    1.81 +
    1.82 +#include "mozilla/PluginPRLibrary.h"
    1.83 +using mozilla::PluginPRLibrary;
    1.84 +
    1.85 +#include "mozilla/plugins/PluginModuleParent.h"
    1.86 +using mozilla::plugins::PluginModuleParent;
    1.87 +
    1.88 +#ifdef MOZ_X11
    1.89 +#include "mozilla/X11Util.h"
    1.90 +#endif
    1.91 +
    1.92 +#ifdef XP_WIN
    1.93 +#include <windows.h>
    1.94 +#include "mozilla/WindowsVersion.h"
    1.95 +#ifdef ACCESSIBILITY
    1.96 +#include "mozilla/a11y/Compatibility.h"
    1.97 +#endif
    1.98 +#endif
    1.99 +
   1.100 +#ifdef MOZ_WIDGET_ANDROID
   1.101 +#include <android/log.h>
   1.102 +#include "android_npapi.h"
   1.103 +#include "ANPBase.h"
   1.104 +#include "AndroidBridge.h"
   1.105 +#undef LOG
   1.106 +#define LOG(args...)  __android_log_print(ANDROID_LOG_INFO, "GeckoPlugins" , ## args)
   1.107 +#endif
   1.108 +
   1.109 +using namespace mozilla;
   1.110 +using namespace mozilla::plugins::parent;
   1.111 +
   1.112 +// We should make this const...
   1.113 +static NPNetscapeFuncs sBrowserFuncs = {
   1.114 +  sizeof(sBrowserFuncs),
   1.115 +  (NP_VERSION_MAJOR << 8) + NP_VERSION_MINOR,
   1.116 +  _geturl,
   1.117 +  _posturl,
   1.118 +  _requestread,
   1.119 +  _newstream,
   1.120 +  _write,
   1.121 +  _destroystream,
   1.122 +  _status,
   1.123 +  _useragent,
   1.124 +  _memalloc,
   1.125 +  _memfree,
   1.126 +  _memflush,
   1.127 +  _reloadplugins,
   1.128 +  _getJavaEnv,
   1.129 +  _getJavaPeer,
   1.130 +  _geturlnotify,
   1.131 +  _posturlnotify,
   1.132 +  _getvalue,
   1.133 +  _setvalue,
   1.134 +  _invalidaterect,
   1.135 +  _invalidateregion,
   1.136 +  _forceredraw,
   1.137 +  _getstringidentifier,
   1.138 +  _getstringidentifiers,
   1.139 +  _getintidentifier,
   1.140 +  _identifierisstring,
   1.141 +  _utf8fromidentifier,
   1.142 +  _intfromidentifier,
   1.143 +  _createobject,
   1.144 +  _retainobject,
   1.145 +  _releaseobject,
   1.146 +  _invoke,
   1.147 +  _invokeDefault,
   1.148 +  _evaluate,
   1.149 +  _getproperty,
   1.150 +  _setproperty,
   1.151 +  _removeproperty,
   1.152 +  _hasproperty,
   1.153 +  _hasmethod,
   1.154 +  _releasevariantvalue,
   1.155 +  _setexception,
   1.156 +  _pushpopupsenabledstate,
   1.157 +  _poppopupsenabledstate,
   1.158 +  _enumerate,
   1.159 +  _pluginthreadasynccall,
   1.160 +  _construct,
   1.161 +  _getvalueforurl,
   1.162 +  _setvalueforurl,
   1.163 +  _getauthenticationinfo,
   1.164 +  _scheduletimer,
   1.165 +  _unscheduletimer,
   1.166 +  _popupcontextmenu,
   1.167 +  _convertpoint,
   1.168 +  nullptr, // handleevent, unimplemented
   1.169 +  nullptr, // unfocusinstance, unimplemented
   1.170 +  _urlredirectresponse,
   1.171 +  _initasyncsurface,
   1.172 +  _finalizeasyncsurface,
   1.173 +  _setcurrentasyncsurface
   1.174 +};
   1.175 +
   1.176 +static Mutex *sPluginThreadAsyncCallLock = nullptr;
   1.177 +static PRCList sPendingAsyncCalls = PR_INIT_STATIC_CLIST(&sPendingAsyncCalls);
   1.178 +
   1.179 +// POST/GET stream type
   1.180 +enum eNPPStreamTypeInternal {
   1.181 +  eNPPStreamTypeInternal_Get,
   1.182 +  eNPPStreamTypeInternal_Post
   1.183 +};
   1.184 +
   1.185 +PRIntervalTime NS_NotifyBeginPluginCall(NSPluginCallReentry aReentryState)
   1.186 +{
   1.187 +  nsNPAPIPluginInstance::BeginPluginCall(aReentryState);
   1.188 +  return PR_IntervalNow();
   1.189 +}
   1.190 +
   1.191 +// This function sends a notification using the observer service to any object
   1.192 +// registered to listen to the "experimental-notify-plugin-call" subject.
   1.193 +// Each "experimental-notify-plugin-call" notification carries with it the run
   1.194 +// time value in milliseconds that the call took to execute.
   1.195 +void NS_NotifyPluginCall(PRIntervalTime startTime, NSPluginCallReentry aReentryState)
   1.196 +{
   1.197 +  nsNPAPIPluginInstance::EndPluginCall(aReentryState);
   1.198 +
   1.199 +  PRIntervalTime endTime = PR_IntervalNow() - startTime;
   1.200 +  nsCOMPtr<nsIObserverService> notifyUIService =
   1.201 +    mozilla::services::GetObserverService();
   1.202 +  if (!notifyUIService)
   1.203 +    return;
   1.204 +
   1.205 +  float runTimeInSeconds = float(endTime) / PR_TicksPerSecond();
   1.206 +  nsAutoString runTimeString;
   1.207 +  runTimeString.AppendFloat(runTimeInSeconds);
   1.208 +  const char16_t* runTime = runTimeString.get();
   1.209 +  notifyUIService->NotifyObservers(nullptr, "experimental-notify-plugin-call",
   1.210 +                                   runTime);
   1.211 +}
   1.212 +
   1.213 +static void CheckClassInitialized()
   1.214 +{
   1.215 +  static bool initialized = false;
   1.216 +
   1.217 +  if (initialized)
   1.218 +    return;
   1.219 +
   1.220 +  if (!sPluginThreadAsyncCallLock)
   1.221 +    sPluginThreadAsyncCallLock = new Mutex("nsNPAPIPlugin.sPluginThreadAsyncCallLock");
   1.222 +
   1.223 +  initialized = true;
   1.224 +
   1.225 +  NPN_PLUGIN_LOG(PLUGIN_LOG_NORMAL,("NPN callbacks initialized\n"));
   1.226 +}
   1.227 +
   1.228 +NS_IMPL_ISUPPORTS0(nsNPAPIPlugin)
   1.229 +
   1.230 +nsNPAPIPlugin::nsNPAPIPlugin()
   1.231 +{
   1.232 +  memset((void*)&mPluginFuncs, 0, sizeof(mPluginFuncs));
   1.233 +  mPluginFuncs.size = sizeof(mPluginFuncs);
   1.234 +  mPluginFuncs.version = (NP_VERSION_MAJOR << 8) | NP_VERSION_MINOR;
   1.235 +
   1.236 +  mLibrary = nullptr;
   1.237 +}
   1.238 +
   1.239 +nsNPAPIPlugin::~nsNPAPIPlugin()
   1.240 +{
   1.241 +  delete mLibrary;
   1.242 +  mLibrary = nullptr;
   1.243 +}
   1.244 +
   1.245 +void
   1.246 +nsNPAPIPlugin::PluginCrashed(const nsAString& pluginDumpID,
   1.247 +                             const nsAString& browserDumpID)
   1.248 +{
   1.249 +  nsRefPtr<nsPluginHost> host = nsPluginHost::GetInst();
   1.250 +  host->PluginCrashed(this, pluginDumpID, browserDumpID);
   1.251 +}
   1.252 +
   1.253 +bool
   1.254 +nsNPAPIPlugin::RunPluginOOP(const nsPluginTag *aPluginTag)
   1.255 +{
   1.256 +  if (PR_GetEnv("MOZ_DISABLE_OOP_PLUGINS")) {
   1.257 +    return false;
   1.258 +  }
   1.259 +
   1.260 +  if (!aPluginTag) {
   1.261 +    return false;
   1.262 +  }
   1.263 +
   1.264 +#ifdef ACCESSIBILITY
   1.265 +  // Certain assistive technologies don't want oop Flash, thus we have a special
   1.266 +  // pref for them to disable oop Flash (refer to bug 785047 for details).
   1.267 +  bool useA11yPref = false;
   1.268 +#ifdef XP_WIN
   1.269 +  useA11yPref =  a11y::Compatibility::IsJAWS();
   1.270 +#endif
   1.271 +#endif
   1.272 +
   1.273 +#ifdef XP_WIN
   1.274 +  // On Windows Vista+, we force Flash to run in OOPP mode because Adobe
   1.275 +  // doesn't test Flash in-process and there are known stability bugs.
   1.276 +  if (aPluginTag->mIsFlashPlugin && IsVistaOrLater()) {
   1.277 +#ifdef ACCESSIBILITY
   1.278 +    if (!useA11yPref)
   1.279 +      return true;
   1.280 +#else
   1.281 +    return true;
   1.282 +#endif
   1.283 +  }
   1.284 +#endif
   1.285 +
   1.286 +  nsIPrefBranch* prefs = Preferences::GetRootBranch();
   1.287 +  if (!prefs) {
   1.288 +    return false;
   1.289 +  }
   1.290 +
   1.291 +  // Get per-library whitelist/blacklist pref string
   1.292 +  // "dom.ipc.plugins.enabled.filename.dll" and fall back to the default value
   1.293 +  // of "dom.ipc.plugins.enabled"
   1.294 +  // The "filename.dll" part can contain shell wildcard pattern
   1.295 +
   1.296 +  nsAutoCString prefFile(aPluginTag->mFullPath.get());
   1.297 +  int32_t slashPos = prefFile.RFindCharInSet("/\\");
   1.298 +  if (kNotFound == slashPos)
   1.299 +    return false;
   1.300 +  prefFile.Cut(0, slashPos + 1);
   1.301 +  ToLowerCase(prefFile);
   1.302 +
   1.303 +#ifdef XP_MACOSX
   1.304 +#if defined(__i386__)
   1.305 +  nsAutoCString prefGroupKey("dom.ipc.plugins.enabled.i386.");
   1.306 +#elif defined(__x86_64__)
   1.307 +  nsAutoCString prefGroupKey("dom.ipc.plugins.enabled.x86_64.");
   1.308 +#elif defined(__ppc__)
   1.309 +  nsAutoCString prefGroupKey("dom.ipc.plugins.enabled.ppc.");
   1.310 +#endif
   1.311 +#else
   1.312 +  nsAutoCString prefGroupKey("dom.ipc.plugins.enabled.");
   1.313 +#endif
   1.314 +
   1.315 +#ifdef ACCESSIBILITY
   1.316 +  if (useA11yPref)
   1.317 +    prefGroupKey.AssignLiteral("dom.ipc.plugins.enabled.a11y.");
   1.318 +#endif
   1.319 +
   1.320 +  // Java plugins include a number of different file names,
   1.321 +  // so use the mime type (mIsJavaPlugin) and a special pref.
   1.322 +  if (aPluginTag->mIsJavaPlugin &&
   1.323 +      !Preferences::GetBool("dom.ipc.plugins.java.enabled", true)) {
   1.324 +    return false;
   1.325 +  }
   1.326 +
   1.327 +  uint32_t prefCount;
   1.328 +  char** prefNames;
   1.329 +  nsresult rv = prefs->GetChildList(prefGroupKey.get(),
   1.330 +                                    &prefCount, &prefNames);
   1.331 +
   1.332 +  bool oopPluginsEnabled = false;
   1.333 +  bool prefSet = false;
   1.334 +
   1.335 +  if (NS_SUCCEEDED(rv) && prefCount > 0) {
   1.336 +    uint32_t prefixLength = prefGroupKey.Length();
   1.337 +    for (uint32_t currentPref = 0; currentPref < prefCount; currentPref++) {
   1.338 +      // Get the mask
   1.339 +      const char* maskStart = prefNames[currentPref] + prefixLength;
   1.340 +      bool match = false;
   1.341 +
   1.342 +      int valid = NS_WildCardValid(maskStart);
   1.343 +      if (valid == INVALID_SXP) {
   1.344 +         continue;
   1.345 +      }
   1.346 +      else if(valid == NON_SXP) {
   1.347 +        // mask is not a shell pattern, compare it as normal string
   1.348 +        match = (strcmp(prefFile.get(), maskStart) == 0);
   1.349 +      }
   1.350 +      else {
   1.351 +        match = (NS_WildCardMatch(prefFile.get(), maskStart, 0) == MATCH);
   1.352 +      }
   1.353 +
   1.354 +      if (match && NS_SUCCEEDED(Preferences::GetBool(prefNames[currentPref],
   1.355 +                                                     &oopPluginsEnabled))) {
   1.356 +        prefSet = true;
   1.357 +        break;
   1.358 +      }
   1.359 +    }
   1.360 +    NS_FREE_XPCOM_ALLOCATED_POINTER_ARRAY(prefCount, prefNames);
   1.361 +  }
   1.362 +
   1.363 +  if (!prefSet) {
   1.364 +    oopPluginsEnabled =
   1.365 +#ifdef XP_MACOSX
   1.366 +#if defined(__i386__)
   1.367 +    Preferences::GetBool("dom.ipc.plugins.enabled.i386", false);
   1.368 +#elif defined(__x86_64__)
   1.369 +    Preferences::GetBool("dom.ipc.plugins.enabled.x86_64", false);
   1.370 +#elif defined(__ppc__)
   1.371 +    Preferences::GetBool("dom.ipc.plugins.enabled.ppc", false);
   1.372 +#endif
   1.373 +#else
   1.374 +#ifdef ACCESSIBILITY
   1.375 +    useA11yPref ? Preferences::GetBool("dom.ipc.plugins.enabled.a11y", false) :
   1.376 +#endif
   1.377 +    Preferences::GetBool("dom.ipc.plugins.enabled", false);
   1.378 +#endif
   1.379 +  }
   1.380 +
   1.381 +  return oopPluginsEnabled;
   1.382 +}
   1.383 +
   1.384 +inline PluginLibrary*
   1.385 +GetNewPluginLibrary(nsPluginTag *aPluginTag)
   1.386 +{
   1.387 +  if (!aPluginTag) {
   1.388 +    return nullptr;
   1.389 +  }
   1.390 +
   1.391 +  if (nsNPAPIPlugin::RunPluginOOP(aPluginTag)) {
   1.392 +    return PluginModuleParent::LoadModule(aPluginTag->mFullPath.get());
   1.393 +  }
   1.394 +  return new PluginPRLibrary(aPluginTag->mFullPath.get(), aPluginTag->mLibrary);
   1.395 +}
   1.396 +
   1.397 +// Creates an nsNPAPIPlugin object. One nsNPAPIPlugin object exists per plugin (not instance).
   1.398 +nsresult
   1.399 +nsNPAPIPlugin::CreatePlugin(nsPluginTag *aPluginTag, nsNPAPIPlugin** aResult)
   1.400 +{
   1.401 +  *aResult = nullptr;
   1.402 +
   1.403 +  if (!aPluginTag) {
   1.404 +    return NS_ERROR_FAILURE;
   1.405 +  }
   1.406 +
   1.407 +  CheckClassInitialized();
   1.408 +
   1.409 +  nsRefPtr<nsNPAPIPlugin> plugin = new nsNPAPIPlugin();
   1.410 +  if (!plugin)
   1.411 +    return NS_ERROR_OUT_OF_MEMORY;
   1.412 +
   1.413 +  PluginLibrary* pluginLib = GetNewPluginLibrary(aPluginTag);
   1.414 +  if (!pluginLib) {
   1.415 +    return NS_ERROR_FAILURE;
   1.416 +  }
   1.417 +
   1.418 +#if defined(XP_MACOSX) || defined(MOZ_WIDGET_ANDROID)
   1.419 +  if (!pluginLib->HasRequiredFunctions()) {
   1.420 +    NS_WARNING("Not all necessary functions exposed by plugin, it will not load.");
   1.421 +    return NS_ERROR_FAILURE;
   1.422 +  }
   1.423 +#endif
   1.424 +
   1.425 +  plugin->mLibrary = pluginLib;
   1.426 +  pluginLib->SetPlugin(plugin);
   1.427 +
   1.428 +  NPError pluginCallError;
   1.429 +  nsresult rv;
   1.430 +
   1.431 +// Exchange NPAPI entry points.
   1.432 +#if defined(XP_WIN)
   1.433 +  // NP_GetEntryPoints must be called before NP_Initialize on Windows.
   1.434 +  rv = pluginLib->NP_GetEntryPoints(&plugin->mPluginFuncs, &pluginCallError);
   1.435 +  if (rv != NS_OK || pluginCallError != NPERR_NO_ERROR) {
   1.436 +    return NS_ERROR_FAILURE;
   1.437 +  }
   1.438 +
   1.439 +  // NP_Initialize must be called after NP_GetEntryPoints on Windows.
   1.440 +  rv = pluginLib->NP_Initialize(&sBrowserFuncs, &pluginCallError);
   1.441 +  if (rv != NS_OK || pluginCallError != NPERR_NO_ERROR) {
   1.442 +    return NS_ERROR_FAILURE;
   1.443 +  }
   1.444 +#elif defined(XP_MACOSX)
   1.445 +  // NP_Initialize must be called before NP_GetEntryPoints on Mac OS X.
   1.446 +  // We need to match WebKit's behavior.
   1.447 +  rv = pluginLib->NP_Initialize(&sBrowserFuncs, &pluginCallError);
   1.448 +  if (rv != NS_OK || pluginCallError != NPERR_NO_ERROR) {
   1.449 +    return NS_ERROR_FAILURE;
   1.450 +  }
   1.451 +
   1.452 +  rv = pluginLib->NP_GetEntryPoints(&plugin->mPluginFuncs, &pluginCallError);
   1.453 +  if (rv != NS_OK || pluginCallError != NPERR_NO_ERROR) {
   1.454 +    return NS_ERROR_FAILURE;
   1.455 +  }
   1.456 +#elif defined(MOZ_WIDGET_GONK)
   1.457 +#else
   1.458 +  rv = pluginLib->NP_Initialize(&sBrowserFuncs, &plugin->mPluginFuncs, &pluginCallError);
   1.459 +  if (rv != NS_OK || pluginCallError != NPERR_NO_ERROR) {
   1.460 +    return NS_ERROR_FAILURE;
   1.461 +  }
   1.462 +#endif
   1.463 +
   1.464 +  plugin.forget(aResult);
   1.465 +  return NS_OK;
   1.466 +}
   1.467 +
   1.468 +PluginLibrary*
   1.469 +nsNPAPIPlugin::GetLibrary()
   1.470 +{
   1.471 +  return mLibrary;
   1.472 +}
   1.473 +
   1.474 +NPPluginFuncs*
   1.475 +nsNPAPIPlugin::PluginFuncs()
   1.476 +{
   1.477 +  return &mPluginFuncs;
   1.478 +}
   1.479 +
   1.480 +nsresult
   1.481 +nsNPAPIPlugin::Shutdown()
   1.482 +{
   1.483 +  NPP_PLUGIN_LOG(PLUGIN_LOG_BASIC,
   1.484 +                 ("NPP Shutdown to be called: this=%p\n", this));
   1.485 +
   1.486 +  NPError shutdownError;
   1.487 +  mLibrary->NP_Shutdown(&shutdownError);
   1.488 +
   1.489 +  return NS_OK;
   1.490 +}
   1.491 +
   1.492 +nsresult
   1.493 +nsNPAPIPlugin::RetainStream(NPStream *pstream, nsISupports **aRetainedPeer)
   1.494 +{
   1.495 +  if (!aRetainedPeer)
   1.496 +    return NS_ERROR_NULL_POINTER;
   1.497 +
   1.498 +  *aRetainedPeer = nullptr;
   1.499 +
   1.500 +  if (!pstream || !pstream->ndata)
   1.501 +    return NS_ERROR_NULL_POINTER;
   1.502 +
   1.503 +  nsNPAPIStreamWrapper* streamWrapper = static_cast<nsNPAPIStreamWrapper*>(pstream->ndata);
   1.504 +  nsNPAPIPluginStreamListener* listener = streamWrapper->GetStreamListener();
   1.505 +  if (!listener) {
   1.506 +    return NS_ERROR_NULL_POINTER;
   1.507 +  }
   1.508 +
   1.509 +  nsIStreamListener* streamListener = listener->GetStreamListenerPeer();
   1.510 +  if (!streamListener) {
   1.511 +    return NS_ERROR_NULL_POINTER;
   1.512 +  }
   1.513 +
   1.514 +  *aRetainedPeer = streamListener;
   1.515 +  NS_ADDREF(*aRetainedPeer);
   1.516 +  return NS_OK;
   1.517 +}
   1.518 +
   1.519 +// Create a new NPP GET or POST (given in the type argument) url
   1.520 +// stream that may have a notify callback
   1.521 +NPError
   1.522 +MakeNewNPAPIStreamInternal(NPP npp, const char *relativeURL, const char *target,
   1.523 +                          eNPPStreamTypeInternal type,
   1.524 +                          bool bDoNotify = false,
   1.525 +                          void *notifyData = nullptr, uint32_t len = 0,
   1.526 +                          const char *buf = nullptr, NPBool file = false)
   1.527 +{
   1.528 +  if (!npp)
   1.529 +    return NPERR_INVALID_INSTANCE_ERROR;
   1.530 +
   1.531 +  PluginDestructionGuard guard(npp);
   1.532 +
   1.533 +  nsNPAPIPluginInstance *inst = (nsNPAPIPluginInstance *) npp->ndata;
   1.534 +  if (!inst || !inst->IsRunning())
   1.535 +    return NPERR_INVALID_INSTANCE_ERROR;
   1.536 +
   1.537 +  nsCOMPtr<nsIPluginHost> pluginHostCOM = do_GetService(MOZ_PLUGIN_HOST_CONTRACTID);
   1.538 +  nsPluginHost *pluginHost = static_cast<nsPluginHost*>(pluginHostCOM.get());
   1.539 +  if (!pluginHost) {
   1.540 +    return NPERR_GENERIC_ERROR;
   1.541 +  }
   1.542 +
   1.543 +  nsRefPtr<nsNPAPIPluginStreamListener> listener;
   1.544 +  // Set aCallNotify here to false.  If pluginHost->GetURL or PostURL fail,
   1.545 +  // the listener's destructor will do the notification while we are about to
   1.546 +  // return a failure code.
   1.547 +  // Call SetCallNotify(true) below after we are sure we cannot return a failure
   1.548 +  // code.
   1.549 +  if (!target) {
   1.550 +    inst->NewStreamListener(relativeURL, notifyData,
   1.551 +                            getter_AddRefs(listener));
   1.552 +    if (listener) {
   1.553 +      listener->SetCallNotify(false);
   1.554 +    }
   1.555 +  }
   1.556 +
   1.557 +  switch (type) {
   1.558 +  case eNPPStreamTypeInternal_Get:
   1.559 +    {
   1.560 +      if (NS_FAILED(pluginHost->GetURL(inst, relativeURL, target, listener,
   1.561 +                                       nullptr, nullptr, false)))
   1.562 +        return NPERR_GENERIC_ERROR;
   1.563 +      break;
   1.564 +    }
   1.565 +  case eNPPStreamTypeInternal_Post:
   1.566 +    {
   1.567 +      if (NS_FAILED(pluginHost->PostURL(inst, relativeURL, len, buf, file,
   1.568 +                                        target, listener, nullptr, nullptr,
   1.569 +                                        false, 0, nullptr)))
   1.570 +        return NPERR_GENERIC_ERROR;
   1.571 +      break;
   1.572 +    }
   1.573 +  default:
   1.574 +    NS_ERROR("how'd I get here");
   1.575 +  }
   1.576 +
   1.577 +  if (listener) {
   1.578 +    // SetCallNotify(bDoNotify) here, see comment above.
   1.579 +    listener->SetCallNotify(bDoNotify);
   1.580 +  }
   1.581 +
   1.582 +  return NPERR_NO_ERROR;
   1.583 +}
   1.584 +
   1.585 +#if defined(MOZ_MEMORY_WINDOWS)
   1.586 +extern "C" size_t malloc_usable_size(const void *ptr);
   1.587 +#endif
   1.588 +
   1.589 +namespace {
   1.590 +
   1.591 +static char *gNPPException;
   1.592 +
   1.593 +class nsPluginThreadRunnable : public nsRunnable,
   1.594 +                               public PRCList
   1.595 +{
   1.596 +public:
   1.597 +  nsPluginThreadRunnable(NPP instance, PluginThreadCallback func,
   1.598 +                         void *userData);
   1.599 +  virtual ~nsPluginThreadRunnable();
   1.600 +
   1.601 +  NS_IMETHOD Run();
   1.602 +
   1.603 +  bool IsForInstance(NPP instance)
   1.604 +  {
   1.605 +    return (mInstance == instance);
   1.606 +  }
   1.607 +
   1.608 +  void Invalidate()
   1.609 +  {
   1.610 +    mFunc = nullptr;
   1.611 +  }
   1.612 +
   1.613 +  bool IsValid()
   1.614 +  {
   1.615 +    return (mFunc != nullptr);
   1.616 +  }
   1.617 +
   1.618 +private:
   1.619 +  NPP mInstance;
   1.620 +  PluginThreadCallback mFunc;
   1.621 +  void *mUserData;
   1.622 +};
   1.623 +
   1.624 +static nsIDocument *
   1.625 +GetDocumentFromNPP(NPP npp)
   1.626 +{
   1.627 +  NS_ENSURE_TRUE(npp, nullptr);
   1.628 +
   1.629 +  nsNPAPIPluginInstance *inst = (nsNPAPIPluginInstance *)npp->ndata;
   1.630 +  NS_ENSURE_TRUE(inst, nullptr);
   1.631 +
   1.632 +  PluginDestructionGuard guard(inst);
   1.633 +
   1.634 +  nsRefPtr<nsPluginInstanceOwner> owner = inst->GetOwner();
   1.635 +  NS_ENSURE_TRUE(owner, nullptr);
   1.636 +
   1.637 +  nsCOMPtr<nsIDocument> doc;
   1.638 +  owner->GetDocument(getter_AddRefs(doc));
   1.639 +
   1.640 +  return doc;
   1.641 +}
   1.642 +
   1.643 +static JSContext *
   1.644 +GetJSContextFromDoc(nsIDocument *doc)
   1.645 +{
   1.646 +  nsCOMPtr<nsIScriptGlobalObject> sgo = do_QueryInterface(doc->GetWindow());
   1.647 +  NS_ENSURE_TRUE(sgo, nullptr);
   1.648 +
   1.649 +  nsIScriptContext *scx = sgo->GetContext();
   1.650 +  NS_ENSURE_TRUE(scx, nullptr);
   1.651 +
   1.652 +  return scx->GetNativeContext();
   1.653 +}
   1.654 +
   1.655 +static JSContext *
   1.656 +GetJSContextFromNPP(NPP npp)
   1.657 +{
   1.658 +  nsIDocument *doc = GetDocumentFromNPP(npp);
   1.659 +  NS_ENSURE_TRUE(doc, nullptr);
   1.660 +
   1.661 +  return GetJSContextFromDoc(doc);
   1.662 +}
   1.663 +
   1.664 +static already_AddRefed<nsIChannel>
   1.665 +GetChannelFromNPP(NPP npp)
   1.666 +{
   1.667 +  nsCOMPtr<nsIDocument> doc = GetDocumentFromNPP(npp);
   1.668 +  if (!doc)
   1.669 +    return nullptr;
   1.670 +  nsCOMPtr<nsPIDOMWindow> domwindow = doc->GetWindow();
   1.671 +  nsCOMPtr<nsIChannel> channel;
   1.672 +  if (domwindow) {
   1.673 +    nsCOMPtr<nsIDocShell> docShell = domwindow->GetDocShell();
   1.674 +    if (docShell) {
   1.675 +      docShell->GetCurrentDocumentChannel(getter_AddRefs(channel));
   1.676 +    }
   1.677 +  }
   1.678 +  return channel.forget();
   1.679 +}
   1.680 +
   1.681 +static NPIdentifier
   1.682 +doGetIdentifier(JSContext *cx, const NPUTF8* name)
   1.683 +{
   1.684 +  NS_ConvertUTF8toUTF16 utf16name(name);
   1.685 +
   1.686 +  JSString *str = ::JS_InternUCStringN(cx, utf16name.get(), utf16name.Length());
   1.687 +
   1.688 +  if (!str)
   1.689 +    return nullptr;
   1.690 +
   1.691 +  return StringToNPIdentifier(cx, str);
   1.692 +}
   1.693 +
   1.694 +#if defined(MOZ_MEMORY_WINDOWS)
   1.695 +BOOL
   1.696 +InHeap(HANDLE hHeap, LPVOID lpMem)
   1.697 +{
   1.698 +  BOOL success = FALSE;
   1.699 +  PROCESS_HEAP_ENTRY he;
   1.700 +  he.lpData = nullptr;
   1.701 +  while (HeapWalk(hHeap, &he) != 0) {
   1.702 +    if (he.lpData == lpMem) {
   1.703 +      success = TRUE;
   1.704 +      break;
   1.705 +    }
   1.706 +  }
   1.707 +  HeapUnlock(hHeap);
   1.708 +  return success;
   1.709 +}
   1.710 +#endif
   1.711 +
   1.712 +} /* anonymous namespace */
   1.713 +
   1.714 +NPPExceptionAutoHolder::NPPExceptionAutoHolder()
   1.715 +  : mOldException(gNPPException)
   1.716 +{
   1.717 +  gNPPException = nullptr;
   1.718 +}
   1.719 +
   1.720 +NPPExceptionAutoHolder::~NPPExceptionAutoHolder()
   1.721 +{
   1.722 +  NS_ASSERTION(!gNPPException, "NPP exception not properly cleared!");
   1.723 +
   1.724 +  gNPPException = mOldException;
   1.725 +}
   1.726 +
   1.727 +nsPluginThreadRunnable::nsPluginThreadRunnable(NPP instance,
   1.728 +                                               PluginThreadCallback func,
   1.729 +                                               void *userData)
   1.730 +  : mInstance(instance), mFunc(func), mUserData(userData)
   1.731 +{
   1.732 +  if (!sPluginThreadAsyncCallLock) {
   1.733 +    // Failed to create lock, not much we can do here then...
   1.734 +    mFunc = nullptr;
   1.735 +
   1.736 +    return;
   1.737 +  }
   1.738 +
   1.739 +  PR_INIT_CLIST(this);
   1.740 +
   1.741 +  {
   1.742 +    MutexAutoLock lock(*sPluginThreadAsyncCallLock);
   1.743 +
   1.744 +    nsNPAPIPluginInstance *inst = (nsNPAPIPluginInstance *)instance->ndata;
   1.745 +    if (!inst || !inst->IsRunning()) {
   1.746 +      // The plugin was stopped, ignore this async call.
   1.747 +      mFunc = nullptr;
   1.748 +
   1.749 +      return;
   1.750 +    }
   1.751 +
   1.752 +    PR_APPEND_LINK(this, &sPendingAsyncCalls);
   1.753 +  }
   1.754 +}
   1.755 +
   1.756 +nsPluginThreadRunnable::~nsPluginThreadRunnable()
   1.757 +{
   1.758 +  if (!sPluginThreadAsyncCallLock) {
   1.759 +    return;
   1.760 +  }
   1.761 +
   1.762 +  {
   1.763 +    MutexAutoLock lock(*sPluginThreadAsyncCallLock);
   1.764 +
   1.765 +    PR_REMOVE_LINK(this);
   1.766 +  }
   1.767 +}
   1.768 +
   1.769 +NS_IMETHODIMP
   1.770 +nsPluginThreadRunnable::Run()
   1.771 +{
   1.772 +  if (mFunc) {
   1.773 +    PluginDestructionGuard guard(mInstance);
   1.774 +
   1.775 +    NS_TRY_SAFE_CALL_VOID(mFunc(mUserData), nullptr,
   1.776 +                          NS_PLUGIN_CALL_SAFE_TO_REENTER_GECKO);
   1.777 +  }
   1.778 +
   1.779 +  return NS_OK;
   1.780 +}
   1.781 +
   1.782 +void
   1.783 +OnPluginDestroy(NPP instance)
   1.784 +{
   1.785 +  if (!sPluginThreadAsyncCallLock) {
   1.786 +    return;
   1.787 +  }
   1.788 +
   1.789 +  {
   1.790 +    MutexAutoLock lock(*sPluginThreadAsyncCallLock);
   1.791 +
   1.792 +    if (PR_CLIST_IS_EMPTY(&sPendingAsyncCalls)) {
   1.793 +      return;
   1.794 +    }
   1.795 +
   1.796 +    nsPluginThreadRunnable *r =
   1.797 +      (nsPluginThreadRunnable *)PR_LIST_HEAD(&sPendingAsyncCalls);
   1.798 +
   1.799 +    do {
   1.800 +      if (r->IsForInstance(instance)) {
   1.801 +        r->Invalidate();
   1.802 +      }
   1.803 +
   1.804 +      r = (nsPluginThreadRunnable *)PR_NEXT_LINK(r);
   1.805 +    } while (r != &sPendingAsyncCalls);
   1.806 +  }
   1.807 +}
   1.808 +
   1.809 +void
   1.810 +OnShutdown()
   1.811 +{
   1.812 +  NS_ASSERTION(PR_CLIST_IS_EMPTY(&sPendingAsyncCalls),
   1.813 +               "Pending async plugin call list not cleaned up!");
   1.814 +
   1.815 +  if (sPluginThreadAsyncCallLock) {
   1.816 +    delete sPluginThreadAsyncCallLock;
   1.817 +
   1.818 +    sPluginThreadAsyncCallLock = nullptr;
   1.819 +  }
   1.820 +}
   1.821 +
   1.822 +AsyncCallbackAutoLock::AsyncCallbackAutoLock()
   1.823 +{
   1.824 +  if (sPluginThreadAsyncCallLock) {
   1.825 +    sPluginThreadAsyncCallLock->Lock();
   1.826 +  }
   1.827 +}
   1.828 +
   1.829 +AsyncCallbackAutoLock::~AsyncCallbackAutoLock()
   1.830 +{
   1.831 +  if (sPluginThreadAsyncCallLock) {
   1.832 +    sPluginThreadAsyncCallLock->Unlock();
   1.833 +  }
   1.834 +}
   1.835 +
   1.836 +
   1.837 +NPP NPPStack::sCurrentNPP = nullptr;
   1.838 +
   1.839 +const char *
   1.840 +PeekException()
   1.841 +{
   1.842 +  return gNPPException;
   1.843 +}
   1.844 +
   1.845 +void
   1.846 +PopException()
   1.847 +{
   1.848 +  NS_ASSERTION(gNPPException, "Uh, no NPP exception to pop!");
   1.849 +
   1.850 +  if (gNPPException) {
   1.851 +    free(gNPPException);
   1.852 +
   1.853 +    gNPPException = nullptr;
   1.854 +  }
   1.855 +}
   1.856 +
   1.857 +//
   1.858 +// Static callbacks that get routed back through the new C++ API
   1.859 +//
   1.860 +
   1.861 +namespace mozilla {
   1.862 +namespace plugins {
   1.863 +namespace parent {
   1.864 +
   1.865 +NPError
   1.866 +_geturl(NPP npp, const char* relativeURL, const char* target)
   1.867 +{
   1.868 +  if (!NS_IsMainThread()) {
   1.869 +    NPN_PLUGIN_LOG(PLUGIN_LOG_ALWAYS,("NPN_geturl called from the wrong thread\n"));
   1.870 +    return NPERR_INVALID_PARAM;
   1.871 +  }
   1.872 +
   1.873 +  NPN_PLUGIN_LOG(PLUGIN_LOG_NORMAL,
   1.874 +  ("NPN_GetURL: npp=%p, target=%s, url=%s\n", (void *)npp, target,
   1.875 +   relativeURL));
   1.876 +
   1.877 +  PluginDestructionGuard guard(npp);
   1.878 +
   1.879 +  // Block Adobe Acrobat from loading URLs that are not http:, https:,
   1.880 +  // or ftp: URLs if the given target is null.
   1.881 +  if (!target && relativeURL &&
   1.882 +      (strncmp(relativeURL, "http:", 5) != 0) &&
   1.883 +      (strncmp(relativeURL, "https:", 6) != 0) &&
   1.884 +      (strncmp(relativeURL, "ftp:", 4) != 0)) {
   1.885 +    nsNPAPIPluginInstance *inst = (nsNPAPIPluginInstance *) npp->ndata;
   1.886 +
   1.887 +    
   1.888 +    const char *name = nullptr;
   1.889 +    nsRefPtr<nsPluginHost> host = nsPluginHost::GetInst();
   1.890 +    host->GetPluginName(inst, &name);
   1.891 +
   1.892 +    if (name && strstr(name, "Adobe") && strstr(name, "Acrobat")) {
   1.893 +      return NPERR_NO_ERROR;
   1.894 +    }
   1.895 +  }
   1.896 +
   1.897 +  return MakeNewNPAPIStreamInternal(npp, relativeURL, target,
   1.898 +                                    eNPPStreamTypeInternal_Get);
   1.899 +}
   1.900 +
   1.901 +NPError
   1.902 +_geturlnotify(NPP npp, const char* relativeURL, const char* target,
   1.903 +              void* notifyData)
   1.904 +{
   1.905 +  if (!NS_IsMainThread()) {
   1.906 +    NPN_PLUGIN_LOG(PLUGIN_LOG_ALWAYS,("NPN_geturlnotify called from the wrong thread\n"));
   1.907 +    return NPERR_INVALID_PARAM;
   1.908 +  }
   1.909 +
   1.910 +  NPN_PLUGIN_LOG(PLUGIN_LOG_NORMAL,
   1.911 +    ("NPN_GetURLNotify: npp=%p, target=%s, notify=%p, url=%s\n", (void*)npp,
   1.912 +     target, notifyData, relativeURL));
   1.913 +
   1.914 +  PluginDestructionGuard guard(npp);
   1.915 +
   1.916 +  return MakeNewNPAPIStreamInternal(npp, relativeURL, target,
   1.917 +                                    eNPPStreamTypeInternal_Get, true,
   1.918 +                                    notifyData);
   1.919 +}
   1.920 +
   1.921 +NPError
   1.922 +_posturlnotify(NPP npp, const char *relativeURL, const char *target,
   1.923 +               uint32_t len, const char *buf, NPBool file, void *notifyData)
   1.924 +{
   1.925 +  if (!NS_IsMainThread()) {
   1.926 +    NPN_PLUGIN_LOG(PLUGIN_LOG_ALWAYS,("NPN_posturlnotify called from the wrong thread\n"));
   1.927 +    return NPERR_INVALID_PARAM;
   1.928 +  }
   1.929 +  if (!buf)
   1.930 +    return NPERR_INVALID_PARAM;
   1.931 +
   1.932 +  NPN_PLUGIN_LOG(PLUGIN_LOG_NORMAL,
   1.933 +                 ("NPN_PostURLNotify: npp=%p, target=%s, len=%d, file=%d, "
   1.934 +                  "notify=%p, url=%s, buf=%s\n",
   1.935 +                  (void*)npp, target, len, file, notifyData, relativeURL,
   1.936 +                  buf));
   1.937 +
   1.938 +  PluginDestructionGuard guard(npp);
   1.939 +
   1.940 +  return MakeNewNPAPIStreamInternal(npp, relativeURL, target,
   1.941 +                                    eNPPStreamTypeInternal_Post, true,
   1.942 +                                    notifyData, len, buf, file);
   1.943 +}
   1.944 +
   1.945 +NPError
   1.946 +_posturl(NPP npp, const char *relativeURL, const char *target,
   1.947 +         uint32_t len, const char *buf, NPBool file)
   1.948 +{
   1.949 +  if (!NS_IsMainThread()) {
   1.950 +    NPN_PLUGIN_LOG(PLUGIN_LOG_ALWAYS,("NPN_posturl called from the wrong thread\n"));
   1.951 +    return NPERR_INVALID_PARAM;
   1.952 +  }
   1.953 +  NPN_PLUGIN_LOG(PLUGIN_LOG_NORMAL,
   1.954 +                 ("NPN_PostURL: npp=%p, target=%s, file=%d, len=%d, url=%s, "
   1.955 +                  "buf=%s\n",
   1.956 +                  (void*)npp, target, file, len, relativeURL, buf));
   1.957 +
   1.958 +  PluginDestructionGuard guard(npp);
   1.959 +
   1.960 +  return MakeNewNPAPIStreamInternal(npp, relativeURL, target,
   1.961 +                                    eNPPStreamTypeInternal_Post, false, nullptr,
   1.962 +                                    len, buf, file);
   1.963 +}
   1.964 +
   1.965 +NPError
   1.966 +_newstream(NPP npp, NPMIMEType type, const char* target, NPStream* *result)
   1.967 +{
   1.968 +  if (!NS_IsMainThread()) {
   1.969 +    NPN_PLUGIN_LOG(PLUGIN_LOG_ALWAYS,("NPN_newstream called from the wrong thread\n"));
   1.970 +    return NPERR_INVALID_PARAM;
   1.971 +  }
   1.972 +  NPN_PLUGIN_LOG(PLUGIN_LOG_NORMAL,
   1.973 +  ("NPN_NewStream: npp=%p, type=%s, target=%s\n", (void*)npp,
   1.974 +   (const char *)type, target));
   1.975 +
   1.976 +  NPError err = NPERR_INVALID_INSTANCE_ERROR;
   1.977 +  if (npp && npp->ndata) {
   1.978 +    nsNPAPIPluginInstance *inst = (nsNPAPIPluginInstance*)npp->ndata;
   1.979 +
   1.980 +    PluginDestructionGuard guard(inst);
   1.981 +
   1.982 +    nsCOMPtr<nsIOutputStream> stream;
   1.983 +    if (NS_SUCCEEDED(inst->NewStreamFromPlugin((const char*) type, target,
   1.984 +                                               getter_AddRefs(stream)))) {
   1.985 +      nsNPAPIStreamWrapper* wrapper = new nsNPAPIStreamWrapper(stream, nullptr);
   1.986 +      if (wrapper) {
   1.987 +        (*result) = &wrapper->mNPStream;
   1.988 +        err = NPERR_NO_ERROR;
   1.989 +      } else {
   1.990 +        err = NPERR_OUT_OF_MEMORY_ERROR;
   1.991 +      }
   1.992 +    } else {
   1.993 +      err = NPERR_GENERIC_ERROR;
   1.994 +    }
   1.995 +  }
   1.996 +  return err;
   1.997 +}
   1.998 +
   1.999 +int32_t
  1.1000 +_write(NPP npp, NPStream *pstream, int32_t len, void *buffer)
  1.1001 +{
  1.1002 +  if (!NS_IsMainThread()) {
  1.1003 +    NPN_PLUGIN_LOG(PLUGIN_LOG_ALWAYS,("NPN_write called from the wrong thread\n"));
  1.1004 +    return 0;
  1.1005 +  }
  1.1006 +  NPN_PLUGIN_LOG(PLUGIN_LOG_NORMAL,
  1.1007 +                 ("NPN_Write: npp=%p, url=%s, len=%d, buffer=%s\n", (void*)npp,
  1.1008 +                  pstream->url, len, (char*)buffer));
  1.1009 +
  1.1010 +  // negative return indicates failure to the plugin
  1.1011 +  if (!npp)
  1.1012 +    return -1;
  1.1013 +
  1.1014 +  PluginDestructionGuard guard(npp);
  1.1015 +
  1.1016 +  nsNPAPIStreamWrapper* wrapper = static_cast<nsNPAPIStreamWrapper*>(pstream->ndata);
  1.1017 +  if (!wrapper) {
  1.1018 +    return -1;
  1.1019 +  }
  1.1020 +
  1.1021 +  nsIOutputStream* stream = wrapper->GetOutputStream();
  1.1022 +  if (!stream) {
  1.1023 +    return -1;
  1.1024 +  }
  1.1025 +
  1.1026 +  uint32_t count = 0;
  1.1027 +  nsresult rv = stream->Write((char *)buffer, len, &count);
  1.1028 +
  1.1029 +  if (NS_FAILED(rv)) {
  1.1030 +    return -1;
  1.1031 +  }
  1.1032 +
  1.1033 +  return (int32_t)count;
  1.1034 +}
  1.1035 +
  1.1036 +NPError
  1.1037 +_destroystream(NPP npp, NPStream *pstream, NPError reason)
  1.1038 +{
  1.1039 +  if (!NS_IsMainThread()) {
  1.1040 +    NPN_PLUGIN_LOG(PLUGIN_LOG_ALWAYS,("NPN_write called from the wrong thread\n"));
  1.1041 +    return NPERR_INVALID_PARAM;
  1.1042 +  }
  1.1043 +  NPN_PLUGIN_LOG(PLUGIN_LOG_NORMAL,
  1.1044 +                 ("NPN_DestroyStream: npp=%p, url=%s, reason=%d\n", (void*)npp,
  1.1045 +                  pstream->url, (int)reason));
  1.1046 +
  1.1047 +  if (!npp)
  1.1048 +    return NPERR_INVALID_INSTANCE_ERROR;
  1.1049 +
  1.1050 +  PluginDestructionGuard guard(npp);
  1.1051 +
  1.1052 +  nsNPAPIStreamWrapper *streamWrapper = static_cast<nsNPAPIStreamWrapper*>(pstream->ndata);
  1.1053 +  if (!streamWrapper) {
  1.1054 +    return NPERR_INVALID_PARAM;
  1.1055 +  }
  1.1056 +
  1.1057 +  nsNPAPIPluginStreamListener *listener = streamWrapper->GetStreamListener();
  1.1058 +  if (listener) {
  1.1059 +    // This type of stream is going from the browser to the plugin. It's either the
  1.1060 +    // initial src/data stream or another stream resulting from NPN_GetURL* or
  1.1061 +    // NPN_PostURL*.
  1.1062 +    //
  1.1063 +    // Calling OnStopBinding on the listener may cause it to be deleted due to the
  1.1064 +    // releasing of its last references.
  1.1065 +    listener->OnStopBinding(nullptr, NS_BINDING_ABORTED);
  1.1066 +  } else {
  1.1067 +    // This type of stream (NPStream) was created via NPN_NewStream. The plugin holds
  1.1068 +    // the reference until it is to be deleted here. Deleting the wrapper will
  1.1069 +    // release the wrapped nsIOutputStream.
  1.1070 +    //
  1.1071 +    // The NPStream the plugin references should always be a sub-object of it's own
  1.1072 +    // 'ndata', which is our nsNPAPIStramWrapper. See bug 548441.
  1.1073 +    NS_ASSERTION((char*)streamWrapper <= (char*)pstream &&
  1.1074 +                 ((char*)pstream) + sizeof(*pstream)
  1.1075 +                     <= ((char*)streamWrapper) + sizeof(*streamWrapper),
  1.1076 +                 "pstream is not a subobject of wrapper");
  1.1077 +    delete streamWrapper;
  1.1078 +  }
  1.1079 +
  1.1080 +  // 'listener' and/or 'streamWrapper' may be invalid (deleted) at this point. Don't
  1.1081 +  // touch them again!
  1.1082 +
  1.1083 +  return NPERR_NO_ERROR;
  1.1084 +}
  1.1085 +
  1.1086 +void
  1.1087 +_status(NPP npp, const char *message)
  1.1088 +{
  1.1089 +  if (!NS_IsMainThread()) {
  1.1090 +    NPN_PLUGIN_LOG(PLUGIN_LOG_ALWAYS,("NPN_status called from the wrong thread\n"));
  1.1091 +    return;
  1.1092 +  }
  1.1093 +  NPN_PLUGIN_LOG(PLUGIN_LOG_NORMAL, ("NPN_Status: npp=%p, message=%s\n",
  1.1094 +                                     (void*)npp, message));
  1.1095 +
  1.1096 +  if (!npp || !npp->ndata) {
  1.1097 +    NS_WARNING("_status: npp or npp->ndata == 0");
  1.1098 +    return;
  1.1099 +  }
  1.1100 +
  1.1101 +  nsNPAPIPluginInstance *inst = (nsNPAPIPluginInstance*)npp->ndata;
  1.1102 +
  1.1103 +  PluginDestructionGuard guard(inst);
  1.1104 +
  1.1105 +  inst->ShowStatus(message);
  1.1106 +}
  1.1107 +
  1.1108 +void
  1.1109 +_memfree (void *ptr)
  1.1110 +{
  1.1111 +  if (!NS_IsMainThread()) {
  1.1112 +    NPN_PLUGIN_LOG(PLUGIN_LOG_ALWAYS,("NPN_memfree called from the wrong thread\n"));
  1.1113 +  }
  1.1114 +  NPN_PLUGIN_LOG(PLUGIN_LOG_NOISY, ("NPN_MemFree: ptr=%p\n", ptr));
  1.1115 +
  1.1116 +  if (ptr)
  1.1117 +    nsMemory::Free(ptr);
  1.1118 +}
  1.1119 +
  1.1120 +uint32_t
  1.1121 +_memflush(uint32_t size)
  1.1122 +{
  1.1123 +  if (!NS_IsMainThread()) {
  1.1124 +    NPN_PLUGIN_LOG(PLUGIN_LOG_ALWAYS,("NPN_memflush called from the wrong thread\n"));
  1.1125 +  }
  1.1126 +  NPN_PLUGIN_LOG(PLUGIN_LOG_NOISY, ("NPN_MemFlush: size=%d\n", size));
  1.1127 +
  1.1128 +  nsMemory::HeapMinimize(true);
  1.1129 +  return 0;
  1.1130 +}
  1.1131 +
  1.1132 +void
  1.1133 +_reloadplugins(NPBool reloadPages)
  1.1134 +{
  1.1135 +  if (!NS_IsMainThread()) {
  1.1136 +    NPN_PLUGIN_LOG(PLUGIN_LOG_ALWAYS,("NPN_reloadplugins called from the wrong thread\n"));
  1.1137 +    return;
  1.1138 +  }
  1.1139 +  NPN_PLUGIN_LOG(PLUGIN_LOG_NORMAL,
  1.1140 +                 ("NPN_ReloadPlugins: reloadPages=%d\n", reloadPages));
  1.1141 +
  1.1142 +  nsCOMPtr<nsIPluginHost> pluginHost(do_GetService(MOZ_PLUGIN_HOST_CONTRACTID));
  1.1143 +  if (!pluginHost)
  1.1144 +    return;
  1.1145 +
  1.1146 +  pluginHost->ReloadPlugins();
  1.1147 +}
  1.1148 +
  1.1149 +void
  1.1150 +_invalidaterect(NPP npp, NPRect *invalidRect)
  1.1151 +{
  1.1152 +  if (!NS_IsMainThread()) {
  1.1153 +    NPN_PLUGIN_LOG(PLUGIN_LOG_ALWAYS,("NPN_invalidaterect called from the wrong thread\n"));
  1.1154 +    return;
  1.1155 +  }
  1.1156 +  NPN_PLUGIN_LOG(PLUGIN_LOG_NORMAL,
  1.1157 +                 ("NPN_InvalidateRect: npp=%p, top=%d, left=%d, bottom=%d, "
  1.1158 +                  "right=%d\n", (void *)npp, invalidRect->top,
  1.1159 +                  invalidRect->left, invalidRect->bottom, invalidRect->right));
  1.1160 +
  1.1161 +  if (!npp || !npp->ndata) {
  1.1162 +    NS_WARNING("_invalidaterect: npp or npp->ndata == 0");
  1.1163 +    return;
  1.1164 +  }
  1.1165 +
  1.1166 +  nsNPAPIPluginInstance *inst = (nsNPAPIPluginInstance*)npp->ndata;
  1.1167 +
  1.1168 +  PluginDestructionGuard guard(inst);
  1.1169 +
  1.1170 +  inst->InvalidateRect((NPRect *)invalidRect);
  1.1171 +}
  1.1172 +
  1.1173 +void
  1.1174 +_invalidateregion(NPP npp, NPRegion invalidRegion)
  1.1175 +{
  1.1176 +  if (!NS_IsMainThread()) {
  1.1177 +    NPN_PLUGIN_LOG(PLUGIN_LOG_ALWAYS,("NPN_invalidateregion called from the wrong thread\n"));
  1.1178 +    return;
  1.1179 +  }
  1.1180 +  NPN_PLUGIN_LOG(PLUGIN_LOG_NORMAL,
  1.1181 +                 ("NPN_InvalidateRegion: npp=%p, region=%p\n", (void*)npp,
  1.1182 +                  (void*)invalidRegion));
  1.1183 +
  1.1184 +  if (!npp || !npp->ndata) {
  1.1185 +    NS_WARNING("_invalidateregion: npp or npp->ndata == 0");
  1.1186 +    return;
  1.1187 +  }
  1.1188 +
  1.1189 +  nsNPAPIPluginInstance *inst = (nsNPAPIPluginInstance*)npp->ndata;
  1.1190 +
  1.1191 +  PluginDestructionGuard guard(inst);
  1.1192 +
  1.1193 +  inst->InvalidateRegion((NPRegion)invalidRegion);
  1.1194 +}
  1.1195 +
  1.1196 +void
  1.1197 +_forceredraw(NPP npp)
  1.1198 +{
  1.1199 +}
  1.1200 +
  1.1201 +NPObject*
  1.1202 +_getwindowobject(NPP npp)
  1.1203 +{
  1.1204 +  if (!NS_IsMainThread()) {
  1.1205 +    NPN_PLUGIN_LOG(PLUGIN_LOG_ALWAYS,("NPN_getwindowobject called from the wrong thread\n"));
  1.1206 +    return nullptr;
  1.1207 +  }
  1.1208 +
  1.1209 +  // The window want to return here is the outer window, *not* the inner (since
  1.1210 +  // we don't know what the plugin will do with it).
  1.1211 +  nsIDocument* doc = GetDocumentFromNPP(npp);
  1.1212 +  NS_ENSURE_TRUE(doc, nullptr);
  1.1213 +  nsCOMPtr<nsPIDOMWindow> outer = do_QueryInterface(doc->GetWindow());
  1.1214 +  NS_ENSURE_TRUE(outer, nullptr);
  1.1215 +
  1.1216 +  AutoJSContext cx;
  1.1217 +  JS::Rooted<JSObject*> global(cx, static_cast<nsGlobalWindow*>(outer.get())->GetGlobalJSObject());
  1.1218 +  return nsJSObjWrapper::GetNewOrUsed(npp, cx, global);
  1.1219 +}
  1.1220 +
  1.1221 +NPObject*
  1.1222 +_getpluginelement(NPP npp)
  1.1223 +{
  1.1224 +  if (!NS_IsMainThread()) {
  1.1225 +    NPN_PLUGIN_LOG(PLUGIN_LOG_ALWAYS,("NPN_getpluginelement called from the wrong thread\n"));
  1.1226 +    return nullptr;
  1.1227 +  }
  1.1228 +
  1.1229 +  nsNPAPIPluginInstance* inst = static_cast<nsNPAPIPluginInstance*>(npp->ndata);
  1.1230 +  if (!inst)
  1.1231 +    return nullptr;
  1.1232 +
  1.1233 +  nsCOMPtr<nsIDOMElement> element;
  1.1234 +  inst->GetDOMElement(getter_AddRefs(element));
  1.1235 +
  1.1236 +  if (!element)
  1.1237 +    return nullptr;
  1.1238 +
  1.1239 +  AutoPushJSContext cx(GetJSContextFromNPP(npp));
  1.1240 +  NS_ENSURE_TRUE(cx, nullptr);
  1.1241 +  JSAutoRequest ar(cx); // Unnecessary once bug 868130 lands.
  1.1242 +
  1.1243 +  nsCOMPtr<nsIXPConnect> xpc(do_GetService(nsIXPConnect::GetCID()));
  1.1244 +  NS_ENSURE_TRUE(xpc, nullptr);
  1.1245 +
  1.1246 +  nsCOMPtr<nsIXPConnectJSObjectHolder> holder;
  1.1247 +  xpc->WrapNative(cx, ::JS::CurrentGlobalOrNull(cx), element,
  1.1248 +                  NS_GET_IID(nsIDOMElement),
  1.1249 +                  getter_AddRefs(holder));
  1.1250 +  NS_ENSURE_TRUE(holder, nullptr);
  1.1251 +
  1.1252 +  JS::Rooted<JSObject*> obj(cx, holder->GetJSObject());
  1.1253 +  NS_ENSURE_TRUE(obj, nullptr);
  1.1254 +
  1.1255 +  return nsJSObjWrapper::GetNewOrUsed(npp, cx, obj);
  1.1256 +}
  1.1257 +
  1.1258 +NPIdentifier
  1.1259 +_getstringidentifier(const NPUTF8* name)
  1.1260 +{
  1.1261 +  if (!name) {
  1.1262 +    NPN_PLUGIN_LOG(PLUGIN_LOG_ALWAYS, ("NPN_getstringidentifier: passed null name"));
  1.1263 +    return nullptr;
  1.1264 +  }
  1.1265 +  if (!NS_IsMainThread()) {
  1.1266 +    NPN_PLUGIN_LOG(PLUGIN_LOG_ALWAYS,("NPN_getstringidentifier called from the wrong thread\n"));
  1.1267 +  }
  1.1268 +
  1.1269 +  AutoSafeJSContext cx;
  1.1270 +  return doGetIdentifier(cx, name);
  1.1271 +}
  1.1272 +
  1.1273 +void
  1.1274 +_getstringidentifiers(const NPUTF8** names, int32_t nameCount,
  1.1275 +                      NPIdentifier *identifiers)
  1.1276 +{
  1.1277 +  if (!NS_IsMainThread()) {
  1.1278 +    NPN_PLUGIN_LOG(PLUGIN_LOG_ALWAYS,("NPN_getstringidentifiers called from the wrong thread\n"));
  1.1279 +  }
  1.1280 +
  1.1281 +  AutoSafeJSContext cx;
  1.1282 +
  1.1283 +  for (int32_t i = 0; i < nameCount; ++i) {
  1.1284 +    if (names[i]) {
  1.1285 +      identifiers[i] = doGetIdentifier(cx, names[i]);
  1.1286 +    } else {
  1.1287 +      NPN_PLUGIN_LOG(PLUGIN_LOG_ALWAYS, ("NPN_getstringidentifiers: passed null name"));
  1.1288 +      identifiers[i] = nullptr;
  1.1289 +    }
  1.1290 +  }
  1.1291 +}
  1.1292 +
  1.1293 +NPIdentifier
  1.1294 +_getintidentifier(int32_t intid)
  1.1295 +{
  1.1296 +  if (!NS_IsMainThread()) {
  1.1297 +    NPN_PLUGIN_LOG(PLUGIN_LOG_ALWAYS,("NPN_getstringidentifier called from the wrong thread\n"));
  1.1298 +  }
  1.1299 +  return IntToNPIdentifier(intid);
  1.1300 +}
  1.1301 +
  1.1302 +NPUTF8*
  1.1303 +_utf8fromidentifier(NPIdentifier id)
  1.1304 +{
  1.1305 +  if (!NS_IsMainThread()) {
  1.1306 +    NPN_PLUGIN_LOG(PLUGIN_LOG_ALWAYS,("NPN_utf8fromidentifier called from the wrong thread\n"));
  1.1307 +  }
  1.1308 +  if (!id)
  1.1309 +    return nullptr;
  1.1310 +
  1.1311 +  if (!NPIdentifierIsString(id)) {
  1.1312 +    return nullptr;
  1.1313 +  }
  1.1314 +
  1.1315 +  JSString *str = NPIdentifierToString(id);
  1.1316 +
  1.1317 +  return
  1.1318 +    ToNewUTF8String(nsDependentString(::JS_GetInternedStringChars(str),
  1.1319 +                                      ::JS_GetStringLength(str)));
  1.1320 +}
  1.1321 +
  1.1322 +int32_t
  1.1323 +_intfromidentifier(NPIdentifier id)
  1.1324 +{
  1.1325 +  if (!NS_IsMainThread()) {
  1.1326 +    NPN_PLUGIN_LOG(PLUGIN_LOG_ALWAYS,("NPN_intfromidentifier called from the wrong thread\n"));
  1.1327 +  }
  1.1328 +
  1.1329 +  if (!NPIdentifierIsInt(id)) {
  1.1330 +    return INT32_MIN;
  1.1331 +  }
  1.1332 +
  1.1333 +  return NPIdentifierToInt(id);
  1.1334 +}
  1.1335 +
  1.1336 +bool
  1.1337 +_identifierisstring(NPIdentifier id)
  1.1338 +{
  1.1339 +  if (!NS_IsMainThread()) {
  1.1340 +    NPN_PLUGIN_LOG(PLUGIN_LOG_ALWAYS,("NPN_identifierisstring called from the wrong thread\n"));
  1.1341 +  }
  1.1342 +
  1.1343 +  return NPIdentifierIsString(id);
  1.1344 +}
  1.1345 +
  1.1346 +NPObject*
  1.1347 +_createobject(NPP npp, NPClass* aClass)
  1.1348 +{
  1.1349 +  if (!NS_IsMainThread()) {
  1.1350 +    NPN_PLUGIN_LOG(PLUGIN_LOG_ALWAYS,("NPN_createobject called from the wrong thread\n"));
  1.1351 +    return nullptr;
  1.1352 +  }
  1.1353 +  if (!npp) {
  1.1354 +    NS_ERROR("Null npp passed to _createobject()!");
  1.1355 +
  1.1356 +    return nullptr;
  1.1357 +  }
  1.1358 +
  1.1359 +  PluginDestructionGuard guard(npp);
  1.1360 +
  1.1361 +  if (!aClass) {
  1.1362 +    NS_ERROR("Null class passed to _createobject()!");
  1.1363 +
  1.1364 +    return nullptr;
  1.1365 +  }
  1.1366 +
  1.1367 +  NPPAutoPusher nppPusher(npp);
  1.1368 +
  1.1369 +  NPObject *npobj;
  1.1370 +
  1.1371 +  if (aClass->allocate) {
  1.1372 +    npobj = aClass->allocate(npp, aClass);
  1.1373 +  } else {
  1.1374 +    npobj = (NPObject *)PR_Malloc(sizeof(NPObject));
  1.1375 +  }
  1.1376 +
  1.1377 +  if (npobj) {
  1.1378 +    npobj->_class = aClass;
  1.1379 +    npobj->referenceCount = 1;
  1.1380 +    NS_LOG_ADDREF(npobj, 1, "BrowserNPObject", sizeof(NPObject));
  1.1381 +  }
  1.1382 +
  1.1383 +  NPN_PLUGIN_LOG(PLUGIN_LOG_NOISY,
  1.1384 +                 ("Created NPObject %p, NPClass %p\n", npobj, aClass));
  1.1385 +
  1.1386 +  return npobj;
  1.1387 +}
  1.1388 +
  1.1389 +NPObject*
  1.1390 +_retainobject(NPObject* npobj)
  1.1391 +{
  1.1392 +  if (!NS_IsMainThread()) {
  1.1393 +    NPN_PLUGIN_LOG(PLUGIN_LOG_ALWAYS,("NPN_retainobject called from the wrong thread\n"));
  1.1394 +  }
  1.1395 +  if (npobj) {
  1.1396 +#ifdef NS_BUILD_REFCNT_LOGGING
  1.1397 +    int32_t refCnt =
  1.1398 +#endif
  1.1399 +      PR_ATOMIC_INCREMENT((int32_t*)&npobj->referenceCount);
  1.1400 +    NS_LOG_ADDREF(npobj, refCnt, "BrowserNPObject", sizeof(NPObject));
  1.1401 +  }
  1.1402 +
  1.1403 +  return npobj;
  1.1404 +}
  1.1405 +
  1.1406 +void
  1.1407 +_releaseobject(NPObject* npobj)
  1.1408 +{
  1.1409 +  if (!NS_IsMainThread()) {
  1.1410 +    NPN_PLUGIN_LOG(PLUGIN_LOG_ALWAYS,("NPN_releaseobject called from the wrong thread\n"));
  1.1411 +  }
  1.1412 +  if (!npobj)
  1.1413 +    return;
  1.1414 +
  1.1415 +  int32_t refCnt = PR_ATOMIC_DECREMENT((int32_t*)&npobj->referenceCount);
  1.1416 +  NS_LOG_RELEASE(npobj, refCnt, "BrowserNPObject");
  1.1417 +
  1.1418 +  if (refCnt == 0) {
  1.1419 +    nsNPObjWrapper::OnDestroy(npobj);
  1.1420 +
  1.1421 +    NPN_PLUGIN_LOG(PLUGIN_LOG_NOISY,
  1.1422 +                   ("Deleting NPObject %p, refcount hit 0\n", npobj));
  1.1423 +
  1.1424 +    if (npobj->_class && npobj->_class->deallocate) {
  1.1425 +      npobj->_class->deallocate(npobj);
  1.1426 +    } else {
  1.1427 +      PR_Free(npobj);
  1.1428 +    }
  1.1429 +  }
  1.1430 +}
  1.1431 +
  1.1432 +bool
  1.1433 +_invoke(NPP npp, NPObject* npobj, NPIdentifier method, const NPVariant *args,
  1.1434 +        uint32_t argCount, NPVariant *result)
  1.1435 +{
  1.1436 +  if (!NS_IsMainThread()) {
  1.1437 +    NPN_PLUGIN_LOG(PLUGIN_LOG_ALWAYS,("NPN_invoke called from the wrong thread\n"));
  1.1438 +    return false;
  1.1439 +  }
  1.1440 +  if (!npp || !npobj || !npobj->_class || !npobj->_class->invoke)
  1.1441 +    return false;
  1.1442 +
  1.1443 +  PluginDestructionGuard guard(npp);
  1.1444 +
  1.1445 +  NPPExceptionAutoHolder nppExceptionHolder;
  1.1446 +  NPPAutoPusher nppPusher(npp);
  1.1447 +
  1.1448 +  NPN_PLUGIN_LOG(PLUGIN_LOG_NOISY,
  1.1449 +                 ("NPN_Invoke(npp %p, npobj %p, method %p, args %d\n", npp,
  1.1450 +                  npobj, method, argCount));
  1.1451 +
  1.1452 +  return npobj->_class->invoke(npobj, method, args, argCount, result);
  1.1453 +}
  1.1454 +
  1.1455 +bool
  1.1456 +_invokeDefault(NPP npp, NPObject* npobj, const NPVariant *args,
  1.1457 +               uint32_t argCount, NPVariant *result)
  1.1458 +{
  1.1459 +  if (!NS_IsMainThread()) {
  1.1460 +    NPN_PLUGIN_LOG(PLUGIN_LOG_ALWAYS,("NPN_invokedefault called from the wrong thread\n"));
  1.1461 +    return false;
  1.1462 +  }
  1.1463 +  if (!npp || !npobj || !npobj->_class || !npobj->_class->invokeDefault)
  1.1464 +    return false;
  1.1465 +
  1.1466 +  NPPExceptionAutoHolder nppExceptionHolder;
  1.1467 +  NPPAutoPusher nppPusher(npp);
  1.1468 +
  1.1469 +  NPN_PLUGIN_LOG(PLUGIN_LOG_NOISY,
  1.1470 +                 ("NPN_InvokeDefault(npp %p, npobj %p, args %d\n", npp,
  1.1471 +                  npobj, argCount));
  1.1472 +
  1.1473 +  return npobj->_class->invokeDefault(npobj, args, argCount, result);
  1.1474 +}
  1.1475 +
  1.1476 +bool
  1.1477 +_evaluate(NPP npp, NPObject* npobj, NPString *script, NPVariant *result)
  1.1478 +{
  1.1479 +  if (!NS_IsMainThread()) {
  1.1480 +    NPN_PLUGIN_LOG(PLUGIN_LOG_ALWAYS,("NPN_evaluate called from the wrong thread\n"));
  1.1481 +    return false;
  1.1482 +  }
  1.1483 +  if (!npp)
  1.1484 +    return false;
  1.1485 +
  1.1486 +  NPPAutoPusher nppPusher(npp);
  1.1487 +
  1.1488 +  nsIDocument *doc = GetDocumentFromNPP(npp);
  1.1489 +  NS_ENSURE_TRUE(doc, false);
  1.1490 +
  1.1491 +  nsGlobalWindow* win = static_cast<nsGlobalWindow*>(doc->GetInnerWindow());
  1.1492 +  if (NS_WARN_IF(!win || !win->FastGetGlobalJSObject())) {
  1.1493 +    return false;
  1.1494 +  }
  1.1495 +
  1.1496 +  AutoSafeJSContext cx;
  1.1497 +  JSAutoCompartment ac(cx, win->FastGetGlobalJSObject());
  1.1498 +
  1.1499 +  JS::Rooted<JSObject*> obj(cx, nsNPObjWrapper::GetNewOrUsed(npp, cx, npobj));
  1.1500 +
  1.1501 +  if (!obj) {
  1.1502 +    return false;
  1.1503 +  }
  1.1504 +
  1.1505 +  obj = JS_ObjectToInnerObject(cx, obj);
  1.1506 +  NS_ABORT_IF_FALSE(obj,
  1.1507 +    "JS_ObjectToInnerObject should never return null with non-null input.");
  1.1508 +
  1.1509 +  if (result) {
  1.1510 +    // Initialize the out param to void
  1.1511 +    VOID_TO_NPVARIANT(*result);
  1.1512 +  }
  1.1513 +
  1.1514 +  if (!script || !script->UTF8Length || !script->UTF8Characters) {
  1.1515 +    // Nothing to evaluate.
  1.1516 +
  1.1517 +    return true;
  1.1518 +  }
  1.1519 +
  1.1520 +  NS_ConvertUTF8toUTF16 utf16script(script->UTF8Characters,
  1.1521 +                                    script->UTF8Length);
  1.1522 +
  1.1523 +  nsIPrincipal *principal = doc->NodePrincipal();
  1.1524 +
  1.1525 +  nsAutoCString specStr;
  1.1526 +  const char *spec;
  1.1527 +
  1.1528 +  nsCOMPtr<nsIURI> uri;
  1.1529 +  principal->GetURI(getter_AddRefs(uri));
  1.1530 +
  1.1531 +  if (uri) {
  1.1532 +    uri->GetSpec(specStr);
  1.1533 +    spec = specStr.get();
  1.1534 +  } else {
  1.1535 +    // No URI in a principal means it's the system principal. If the
  1.1536 +    // document URI is a chrome:// URI, pass that in as the URI of the
  1.1537 +    // script, else pass in null for the filename as there's no way to
  1.1538 +    // know where this document really came from. Passing in null here
  1.1539 +    // also means that the script gets treated by XPConnect as if it
  1.1540 +    // needs additional protection, which is what we want for unknown
  1.1541 +    // chrome code anyways.
  1.1542 +
  1.1543 +    uri = doc->GetDocumentURI();
  1.1544 +    bool isChrome = false;
  1.1545 +
  1.1546 +    if (uri && NS_SUCCEEDED(uri->SchemeIs("chrome", &isChrome)) && isChrome) {
  1.1547 +      uri->GetSpec(specStr);
  1.1548 +      spec = specStr.get();
  1.1549 +    } else {
  1.1550 +      spec = nullptr;
  1.1551 +    }
  1.1552 +  }
  1.1553 +
  1.1554 +  NPN_PLUGIN_LOG(PLUGIN_LOG_NOISY,
  1.1555 +                 ("NPN_Evaluate(npp %p, npobj %p, script <<<%s>>>) called\n",
  1.1556 +                  npp, npobj, script->UTF8Characters));
  1.1557 +
  1.1558 +  JS::CompileOptions options(cx);
  1.1559 +  options.setFileAndLine(spec, 0)
  1.1560 +         .setVersion(JSVERSION_DEFAULT);
  1.1561 +  JS::Rooted<JS::Value> rval(cx);
  1.1562 +  nsJSUtils::EvaluateOptions evalOptions;
  1.1563 +  nsresult rv = nsJSUtils::EvaluateString(cx, utf16script, obj, options,
  1.1564 +                                          evalOptions, &rval);
  1.1565 +
  1.1566 +  return NS_SUCCEEDED(rv) &&
  1.1567 +         (!result || JSValToNPVariant(npp, cx, rval, result));
  1.1568 +}
  1.1569 +
  1.1570 +bool
  1.1571 +_getproperty(NPP npp, NPObject* npobj, NPIdentifier property,
  1.1572 +             NPVariant *result)
  1.1573 +{
  1.1574 +  if (!NS_IsMainThread()) {
  1.1575 +    NPN_PLUGIN_LOG(PLUGIN_LOG_ALWAYS,("NPN_getproperty called from the wrong thread\n"));
  1.1576 +    return false;
  1.1577 +  }
  1.1578 +  if (!npp || !npobj || !npobj->_class || !npobj->_class->getProperty)
  1.1579 +    return false;
  1.1580 +
  1.1581 +  NPPExceptionAutoHolder nppExceptionHolder;
  1.1582 +  NPPAutoPusher nppPusher(npp);
  1.1583 +
  1.1584 +  NPN_PLUGIN_LOG(PLUGIN_LOG_NOISY,
  1.1585 +                 ("NPN_GetProperty(npp %p, npobj %p, property %p) called\n",
  1.1586 +                  npp, npobj, property));
  1.1587 +
  1.1588 +  if (!npobj->_class->getProperty(npobj, property, result))
  1.1589 +    return false;
  1.1590 +
  1.1591 +  // If a Java plugin tries to get the document.URL or document.documentURI
  1.1592 +  // property from us, don't pass back a value that Java won't be able to
  1.1593 +  // understand -- one that will make the URL(String) constructor throw a
  1.1594 +  // MalformedURL exception.  Passing such a value causes Java Plugin2 to
  1.1595 +  // crash (to throw a RuntimeException in Plugin2Manager.getDocumentBase()).
  1.1596 +  // Also don't pass back a value that Java is likely to mishandle.
  1.1597 +
  1.1598 +  nsNPAPIPluginInstance* inst = (nsNPAPIPluginInstance*) npp->ndata;
  1.1599 +  if (!inst)
  1.1600 +    return false;
  1.1601 +  nsNPAPIPlugin* plugin = inst->GetPlugin();
  1.1602 +  if (!plugin)
  1.1603 +    return false;
  1.1604 +  nsRefPtr<nsPluginHost> host = nsPluginHost::GetInst();
  1.1605 +  nsPluginTag* pluginTag = host->TagForPlugin(plugin);
  1.1606 +  if (!pluginTag->mIsJavaPlugin)
  1.1607 +    return true;
  1.1608 +
  1.1609 +  if (!NPVARIANT_IS_STRING(*result))
  1.1610 +    return true;
  1.1611 +
  1.1612 +  NPUTF8* propertyName = _utf8fromidentifier(property);
  1.1613 +  if (!propertyName)
  1.1614 +    return true;
  1.1615 +  bool notURL =
  1.1616 +    (PL_strcasecmp(propertyName, "URL") &&
  1.1617 +     PL_strcasecmp(propertyName, "documentURI"));
  1.1618 +  _memfree(propertyName);
  1.1619 +  if (notURL)
  1.1620 +    return true;
  1.1621 +
  1.1622 +  NPObject* window_obj = _getwindowobject(npp);
  1.1623 +  if (!window_obj)
  1.1624 +    return true;
  1.1625 +
  1.1626 +  NPVariant doc_v;
  1.1627 +  NPObject* document_obj = nullptr;
  1.1628 +  NPIdentifier doc_id = _getstringidentifier("document");
  1.1629 +  bool ok = npobj->_class->getProperty(window_obj, doc_id, &doc_v);
  1.1630 +  _releaseobject(window_obj);
  1.1631 +  if (ok) {
  1.1632 +    if (NPVARIANT_IS_OBJECT(doc_v)) {
  1.1633 +      document_obj = NPVARIANT_TO_OBJECT(doc_v);
  1.1634 +    } else {
  1.1635 +      _releasevariantvalue(&doc_v);
  1.1636 +      return true;
  1.1637 +    }
  1.1638 +  } else {
  1.1639 +    return true;
  1.1640 +  }
  1.1641 +  _releaseobject(document_obj);
  1.1642 +  if (document_obj != npobj)
  1.1643 +    return true;
  1.1644 +
  1.1645 +  NPString urlnp = NPVARIANT_TO_STRING(*result);
  1.1646 +  nsXPIDLCString url;
  1.1647 +  url.Assign(urlnp.UTF8Characters, urlnp.UTF8Length);
  1.1648 +
  1.1649 +  bool javaCompatible = false;
  1.1650 +  if (NS_FAILED(NS_CheckIsJavaCompatibleURLString(url, &javaCompatible)))
  1.1651 +    javaCompatible = false;
  1.1652 +  if (javaCompatible)
  1.1653 +    return true;
  1.1654 +
  1.1655 +  // If Java won't be able to interpret the original value of document.URL or
  1.1656 +  // document.documentURI, or is likely to mishandle it, pass back something
  1.1657 +  // that Java will understand but won't be able to use to access the network,
  1.1658 +  // and for which same-origin checks will always fail.
  1.1659 +
  1.1660 +  if (inst->mFakeURL.IsVoid()) {
  1.1661 +    // Abort (do an error return) if NS_MakeRandomInvalidURLString() fails.
  1.1662 +    if (NS_FAILED(NS_MakeRandomInvalidURLString(inst->mFakeURL))) {
  1.1663 +      _releasevariantvalue(result);
  1.1664 +      return false;
  1.1665 +    }
  1.1666 +  }
  1.1667 +
  1.1668 +  _releasevariantvalue(result);
  1.1669 +  char* fakeurl = (char *) _memalloc(inst->mFakeURL.Length() + 1);
  1.1670 +  strcpy(fakeurl, inst->mFakeURL);
  1.1671 +  STRINGZ_TO_NPVARIANT(fakeurl, *result);
  1.1672 +
  1.1673 +  return true;
  1.1674 +}
  1.1675 +
  1.1676 +bool
  1.1677 +_setproperty(NPP npp, NPObject* npobj, NPIdentifier property,
  1.1678 +             const NPVariant *value)
  1.1679 +{
  1.1680 +  if (!NS_IsMainThread()) {
  1.1681 +    NPN_PLUGIN_LOG(PLUGIN_LOG_ALWAYS,("NPN_setproperty called from the wrong thread\n"));
  1.1682 +    return false;
  1.1683 +  }
  1.1684 +  if (!npp || !npobj || !npobj->_class || !npobj->_class->setProperty)
  1.1685 +    return false;
  1.1686 +
  1.1687 +  NPPExceptionAutoHolder nppExceptionHolder;
  1.1688 +  NPPAutoPusher nppPusher(npp);
  1.1689 +
  1.1690 +  NPN_PLUGIN_LOG(PLUGIN_LOG_NOISY,
  1.1691 +                 ("NPN_SetProperty(npp %p, npobj %p, property %p) called\n",
  1.1692 +                  npp, npobj, property));
  1.1693 +
  1.1694 +  return npobj->_class->setProperty(npobj, property, value);
  1.1695 +}
  1.1696 +
  1.1697 +bool
  1.1698 +_removeproperty(NPP npp, NPObject* npobj, NPIdentifier property)
  1.1699 +{
  1.1700 +  if (!NS_IsMainThread()) {
  1.1701 +    NPN_PLUGIN_LOG(PLUGIN_LOG_ALWAYS,("NPN_removeproperty called from the wrong thread\n"));
  1.1702 +    return false;
  1.1703 +  }
  1.1704 +  if (!npp || !npobj || !npobj->_class || !npobj->_class->removeProperty)
  1.1705 +    return false;
  1.1706 +
  1.1707 +  NPPExceptionAutoHolder nppExceptionHolder;
  1.1708 +  NPPAutoPusher nppPusher(npp);
  1.1709 +
  1.1710 +  NPN_PLUGIN_LOG(PLUGIN_LOG_NOISY,
  1.1711 +                 ("NPN_RemoveProperty(npp %p, npobj %p, property %p) called\n",
  1.1712 +                  npp, npobj, property));
  1.1713 +
  1.1714 +  return npobj->_class->removeProperty(npobj, property);
  1.1715 +}
  1.1716 +
  1.1717 +bool
  1.1718 +_hasproperty(NPP npp, NPObject* npobj, NPIdentifier propertyName)
  1.1719 +{
  1.1720 +  if (!NS_IsMainThread()) {
  1.1721 +    NPN_PLUGIN_LOG(PLUGIN_LOG_ALWAYS,("NPN_hasproperty called from the wrong thread\n"));
  1.1722 +    return false;
  1.1723 +  }
  1.1724 +  if (!npp || !npobj || !npobj->_class || !npobj->_class->hasProperty)
  1.1725 +    return false;
  1.1726 +
  1.1727 +  NPPExceptionAutoHolder nppExceptionHolder;
  1.1728 +  NPPAutoPusher nppPusher(npp);
  1.1729 +
  1.1730 +  NPN_PLUGIN_LOG(PLUGIN_LOG_NOISY,
  1.1731 +                 ("NPN_HasProperty(npp %p, npobj %p, property %p) called\n",
  1.1732 +                  npp, npobj, propertyName));
  1.1733 +
  1.1734 +  return npobj->_class->hasProperty(npobj, propertyName);
  1.1735 +}
  1.1736 +
  1.1737 +bool
  1.1738 +_hasmethod(NPP npp, NPObject* npobj, NPIdentifier methodName)
  1.1739 +{
  1.1740 +  if (!NS_IsMainThread()) {
  1.1741 +    NPN_PLUGIN_LOG(PLUGIN_LOG_ALWAYS,("NPN_hasmethod called from the wrong thread\n"));
  1.1742 +    return false;
  1.1743 +  }
  1.1744 +  if (!npp || !npobj || !npobj->_class || !npobj->_class->hasMethod)
  1.1745 +    return false;
  1.1746 +
  1.1747 +  NPPExceptionAutoHolder nppExceptionHolder;
  1.1748 +  NPPAutoPusher nppPusher(npp);
  1.1749 +
  1.1750 +  NPN_PLUGIN_LOG(PLUGIN_LOG_NOISY,
  1.1751 +                 ("NPN_HasMethod(npp %p, npobj %p, property %p) called\n",
  1.1752 +                  npp, npobj, methodName));
  1.1753 +
  1.1754 +  return npobj->_class->hasMethod(npobj, methodName);
  1.1755 +}
  1.1756 +
  1.1757 +bool
  1.1758 +_enumerate(NPP npp, NPObject *npobj, NPIdentifier **identifier,
  1.1759 +           uint32_t *count)
  1.1760 +{
  1.1761 +  if (!NS_IsMainThread()) {
  1.1762 +    NPN_PLUGIN_LOG(PLUGIN_LOG_ALWAYS,("NPN_enumerate called from the wrong thread\n"));
  1.1763 +    return false;
  1.1764 +  }
  1.1765 +  if (!npp || !npobj || !npobj->_class)
  1.1766 +    return false;
  1.1767 +
  1.1768 +  NPN_PLUGIN_LOG(PLUGIN_LOG_NOISY,
  1.1769 +                 ("NPN_Enumerate(npp %p, npobj %p) called\n", npp, npobj));
  1.1770 +
  1.1771 +  if (!NP_CLASS_STRUCT_VERSION_HAS_ENUM(npobj->_class) ||
  1.1772 +      !npobj->_class->enumerate) {
  1.1773 +    *identifier = 0;
  1.1774 +    *count = 0;
  1.1775 +    return true;
  1.1776 +  }
  1.1777 +
  1.1778 +  NPPExceptionAutoHolder nppExceptionHolder;
  1.1779 +  NPPAutoPusher nppPusher(npp);
  1.1780 +
  1.1781 +  return npobj->_class->enumerate(npobj, identifier, count);
  1.1782 +}
  1.1783 +
  1.1784 +bool
  1.1785 +_construct(NPP npp, NPObject* npobj, const NPVariant *args,
  1.1786 +               uint32_t argCount, NPVariant *result)
  1.1787 +{
  1.1788 +  if (!NS_IsMainThread()) {
  1.1789 +    NPN_PLUGIN_LOG(PLUGIN_LOG_ALWAYS,("NPN_construct called from the wrong thread\n"));
  1.1790 +    return false;
  1.1791 +  }
  1.1792 +  if (!npp || !npobj || !npobj->_class ||
  1.1793 +      !NP_CLASS_STRUCT_VERSION_HAS_CTOR(npobj->_class) ||
  1.1794 +      !npobj->_class->construct) {
  1.1795 +    return false;
  1.1796 +  }
  1.1797 +
  1.1798 +  NPPExceptionAutoHolder nppExceptionHolder;
  1.1799 +  NPPAutoPusher nppPusher(npp);
  1.1800 +
  1.1801 +  return npobj->_class->construct(npobj, args, argCount, result);
  1.1802 +}
  1.1803 +
  1.1804 +void
  1.1805 +_releasevariantvalue(NPVariant* variant)
  1.1806 +{
  1.1807 +  if (!NS_IsMainThread()) {
  1.1808 +    NPN_PLUGIN_LOG(PLUGIN_LOG_ALWAYS,("NPN_releasevariantvalue called from the wrong thread\n"));
  1.1809 +  }
  1.1810 +  switch (variant->type) {
  1.1811 +  case NPVariantType_Void :
  1.1812 +  case NPVariantType_Null :
  1.1813 +  case NPVariantType_Bool :
  1.1814 +  case NPVariantType_Int32 :
  1.1815 +  case NPVariantType_Double :
  1.1816 +    break;
  1.1817 +  case NPVariantType_String :
  1.1818 +    {
  1.1819 +      const NPString *s = &NPVARIANT_TO_STRING(*variant);
  1.1820 +
  1.1821 +      if (s->UTF8Characters) {
  1.1822 +#if defined(MOZ_MEMORY_WINDOWS)
  1.1823 +        if (malloc_usable_size((void *)s->UTF8Characters) != 0) {
  1.1824 +          PR_Free((void *)s->UTF8Characters);
  1.1825 +        } else {
  1.1826 +          void *p = (void *)s->UTF8Characters;
  1.1827 +          DWORD nheaps = 0;
  1.1828 +          nsAutoTArray<HANDLE, 50> heaps;
  1.1829 +          nheaps = GetProcessHeaps(0, heaps.Elements());
  1.1830 +          heaps.AppendElements(nheaps);
  1.1831 +          GetProcessHeaps(nheaps, heaps.Elements());
  1.1832 +          for (DWORD i = 0; i < nheaps; i++) {
  1.1833 +            if (InHeap(heaps[i], p)) {
  1.1834 +              HeapFree(heaps[i], 0, p);
  1.1835 +              break;
  1.1836 +            }
  1.1837 +          }
  1.1838 +        }
  1.1839 +#else
  1.1840 +        NS_Free((void *)s->UTF8Characters);
  1.1841 +#endif
  1.1842 +      }
  1.1843 +      break;
  1.1844 +    }
  1.1845 +  case NPVariantType_Object:
  1.1846 +    {
  1.1847 +      NPObject *npobj = NPVARIANT_TO_OBJECT(*variant);
  1.1848 +
  1.1849 +      if (npobj)
  1.1850 +        _releaseobject(npobj);
  1.1851 +
  1.1852 +      break;
  1.1853 +    }
  1.1854 +  default:
  1.1855 +    NS_ERROR("Unknown NPVariant type!");
  1.1856 +  }
  1.1857 +
  1.1858 +  VOID_TO_NPVARIANT(*variant);
  1.1859 +}
  1.1860 +
  1.1861 +void
  1.1862 +_setexception(NPObject* npobj, const NPUTF8 *message)
  1.1863 +{
  1.1864 +  if (!NS_IsMainThread()) {
  1.1865 +    NPN_PLUGIN_LOG(PLUGIN_LOG_ALWAYS,("NPN_setexception called from the wrong thread\n"));
  1.1866 +    return;
  1.1867 +  }
  1.1868 +
  1.1869 +  if (!message) return;
  1.1870 +
  1.1871 +  if (gNPPException) {
  1.1872 +    // If a plugin throws multiple exceptions, we'll only report the
  1.1873 +    // last one for now.
  1.1874 +    free(gNPPException);
  1.1875 +  }
  1.1876 +
  1.1877 +  gNPPException = strdup(message);
  1.1878 +}
  1.1879 +
  1.1880 +NPError
  1.1881 +_getvalue(NPP npp, NPNVariable variable, void *result)
  1.1882 +{
  1.1883 +  if (!NS_IsMainThread()) {
  1.1884 +    NPN_PLUGIN_LOG(PLUGIN_LOG_ALWAYS,("NPN_getvalue called from the wrong thread\n"));
  1.1885 +    return NPERR_INVALID_PARAM;
  1.1886 +  }
  1.1887 +  NPN_PLUGIN_LOG(PLUGIN_LOG_NORMAL, ("NPN_GetValue: npp=%p, var=%d\n",
  1.1888 +                                     (void*)npp, (int)variable));
  1.1889 +
  1.1890 +  nsresult res;
  1.1891 +
  1.1892 +  PluginDestructionGuard guard(npp);
  1.1893 +
  1.1894 +  switch(variable) {
  1.1895 +#if defined(XP_UNIX) && !defined(XP_MACOSX)
  1.1896 +  case NPNVxDisplay : {
  1.1897 +#if defined(MOZ_X11)
  1.1898 +    if (npp) {
  1.1899 +      nsNPAPIPluginInstance *inst = (nsNPAPIPluginInstance *) npp->ndata;
  1.1900 +      bool windowless = false;
  1.1901 +      inst->IsWindowless(&windowless);
  1.1902 +      // The documentation on the types for many variables in NP(N|P)_GetValue
  1.1903 +      // is vague.  Often boolean values are NPBool (1 byte), but
  1.1904 +      // https://developer.mozilla.org/en/XEmbed_Extension_for_Mozilla_Plugins
  1.1905 +      // treats NPPVpluginNeedsXEmbed as PRBool (int), and
  1.1906 +      // on x86/32-bit, flash stores to this using |movl 0x1,&needsXEmbed|.
  1.1907 +      // thus we can't use NPBool for needsXEmbed, or the three bytes above
  1.1908 +      // it on the stack would get clobbered. so protect with the larger bool.
  1.1909 +      int needsXEmbed = 0;
  1.1910 +      if (!windowless) {
  1.1911 +        res = inst->GetValueFromPlugin(NPPVpluginNeedsXEmbed, &needsXEmbed);
  1.1912 +        // If the call returned an error code make sure we still use our default value.
  1.1913 +        if (NS_FAILED(res)) {
  1.1914 +          needsXEmbed = 0;
  1.1915 +        }
  1.1916 +      }
  1.1917 +      if (windowless || needsXEmbed) {
  1.1918 +        (*(Display **)result) = mozilla::DefaultXDisplay();
  1.1919 +        return NPERR_NO_ERROR;
  1.1920 +      }
  1.1921 +    }
  1.1922 +#if (MOZ_WIDGET_GTK == 2)
  1.1923 +    // adobe nppdf calls XtGetApplicationNameAndClass(display,
  1.1924 +    // &instance, &class) we have to init Xt toolkit before get
  1.1925 +    // XtDisplay just call gtk_xtbin_new(w,0) once
  1.1926 +    static GtkWidget *gtkXtBinHolder = 0;
  1.1927 +    if (!gtkXtBinHolder) {
  1.1928 +      gtkXtBinHolder = gtk_xtbin_new(gdk_get_default_root_window(),0);
  1.1929 +      // it crashes on destroy, let it leak
  1.1930 +      // gtk_widget_destroy(gtkXtBinHolder);
  1.1931 +    }
  1.1932 +    (*(Display **)result) =  GTK_XTBIN(gtkXtBinHolder)->xtdisplay;
  1.1933 +    return NPERR_NO_ERROR;
  1.1934 +#endif
  1.1935 +#endif
  1.1936 +    return NPERR_GENERIC_ERROR;
  1.1937 +  }
  1.1938 +
  1.1939 +  case NPNVxtAppContext:
  1.1940 +    return NPERR_GENERIC_ERROR;
  1.1941 +#endif
  1.1942 +
  1.1943 +#if defined(XP_WIN) || (MOZ_WIDGET_GTK == 2) || defined(MOZ_WIDGET_QT)
  1.1944 +  case NPNVnetscapeWindow: {
  1.1945 +    if (!npp || !npp->ndata)
  1.1946 +      return NPERR_INVALID_INSTANCE_ERROR;
  1.1947 +
  1.1948 +    nsNPAPIPluginInstance *inst = (nsNPAPIPluginInstance *) npp->ndata;
  1.1949 +
  1.1950 +    nsRefPtr<nsPluginInstanceOwner> owner = inst->GetOwner();
  1.1951 +    NS_ENSURE_TRUE(owner, NPERR_NO_ERROR);
  1.1952 +
  1.1953 +    if (NS_SUCCEEDED(owner->GetNetscapeWindow(result))) {
  1.1954 +      return NPERR_NO_ERROR;
  1.1955 +    }
  1.1956 +    return NPERR_GENERIC_ERROR;
  1.1957 +  }
  1.1958 +#endif
  1.1959 +
  1.1960 +  case NPNVjavascriptEnabledBool: {
  1.1961 +    *(NPBool*)result = false;
  1.1962 +    bool js = false;
  1.1963 +    res = Preferences::GetBool("javascript.enabled", &js);
  1.1964 +    if (NS_SUCCEEDED(res)) {
  1.1965 +      *(NPBool*)result = js;
  1.1966 +    }
  1.1967 +    return NPERR_NO_ERROR;
  1.1968 +  }
  1.1969 +
  1.1970 +  case NPNVasdEnabledBool:
  1.1971 +    *(NPBool*)result = false;
  1.1972 +    return NPERR_NO_ERROR;
  1.1973 +
  1.1974 +  case NPNVisOfflineBool: {
  1.1975 +    bool offline = false;
  1.1976 +    nsCOMPtr<nsIIOService> ioservice =
  1.1977 +      do_GetService(NS_IOSERVICE_CONTRACTID, &res);
  1.1978 +    if (NS_SUCCEEDED(res))
  1.1979 +      res = ioservice->GetOffline(&offline);
  1.1980 +    if (NS_FAILED(res))
  1.1981 +      return NPERR_GENERIC_ERROR;
  1.1982 +
  1.1983 +    *(NPBool*)result = offline;
  1.1984 +    return NPERR_NO_ERROR;
  1.1985 +  }
  1.1986 +
  1.1987 +  case NPNVToolkit: {
  1.1988 +#ifdef MOZ_WIDGET_GTK
  1.1989 +    *((NPNToolkitType*)result) = NPNVGtk2;
  1.1990 +#endif
  1.1991 +
  1.1992 +#ifdef MOZ_WIDGET_QT
  1.1993 +    /* Fake toolkit so flash plugin works */
  1.1994 +    *((NPNToolkitType*)result) = NPNVGtk2;
  1.1995 +#endif
  1.1996 +    if (*(NPNToolkitType*)result)
  1.1997 +        return NPERR_NO_ERROR;
  1.1998 +
  1.1999 +    return NPERR_GENERIC_ERROR;
  1.2000 +  }
  1.2001 +
  1.2002 +  case NPNVSupportsXEmbedBool: {
  1.2003 +#ifdef MOZ_WIDGET_GTK
  1.2004 +    *(NPBool*)result = true;
  1.2005 +#elif defined(MOZ_WIDGET_QT)
  1.2006 +    // Desktop Flash fail to initialize if browser does not support NPNVSupportsXEmbedBool
  1.2007 +    // even when wmode!=windowed, lets return fake support
  1.2008 +    fprintf(stderr, "Fake support for XEmbed plugins in Qt port\n");
  1.2009 +    *(NPBool*)result = true;
  1.2010 +#else
  1.2011 +    *(NPBool*)result = false;
  1.2012 +#endif
  1.2013 +    return NPERR_NO_ERROR;
  1.2014 +  }
  1.2015 +
  1.2016 +  case NPNVWindowNPObject: {
  1.2017 +    *(NPObject **)result = _getwindowobject(npp);
  1.2018 +
  1.2019 +    return *(NPObject **)result ? NPERR_NO_ERROR : NPERR_GENERIC_ERROR;
  1.2020 +  }
  1.2021 +
  1.2022 +  case NPNVPluginElementNPObject: {
  1.2023 +    *(NPObject **)result = _getpluginelement(npp);
  1.2024 +
  1.2025 +    return *(NPObject **)result ? NPERR_NO_ERROR : NPERR_GENERIC_ERROR;
  1.2026 +  }
  1.2027 +
  1.2028 +  case NPNVSupportsWindowless: {
  1.2029 +#if defined(XP_WIN) || defined(XP_MACOSX) || \
  1.2030 +    (defined(MOZ_X11) && (defined(MOZ_WIDGET_GTK) || defined(MOZ_WIDGET_QT)))
  1.2031 +    *(NPBool*)result = true;
  1.2032 +#else
  1.2033 +    *(NPBool*)result = false;
  1.2034 +#endif
  1.2035 +    return NPERR_NO_ERROR;
  1.2036 +  }
  1.2037 +
  1.2038 +  case NPNVprivateModeBool: {
  1.2039 +    bool privacy;
  1.2040 +    nsNPAPIPluginInstance *inst = static_cast<nsNPAPIPluginInstance*>(npp->ndata);
  1.2041 +    if (!inst)
  1.2042 +      return NPERR_GENERIC_ERROR;
  1.2043 +
  1.2044 +    nsresult rv = inst->IsPrivateBrowsing(&privacy);
  1.2045 +    if (NS_FAILED(rv))
  1.2046 +      return NPERR_GENERIC_ERROR;
  1.2047 +    *(NPBool*)result = (NPBool)privacy;
  1.2048 +    return NPERR_NO_ERROR;
  1.2049 +  }
  1.2050 +
  1.2051 +  case NPNVdocumentOrigin: {
  1.2052 +    nsNPAPIPluginInstance *inst = (nsNPAPIPluginInstance *)npp->ndata;
  1.2053 +    if (!inst) {
  1.2054 +      return NPERR_GENERIC_ERROR;
  1.2055 +    }
  1.2056 +
  1.2057 +    nsCOMPtr<nsIDOMElement> element;
  1.2058 +    inst->GetDOMElement(getter_AddRefs(element));
  1.2059 +    if (!element) {
  1.2060 +      return NPERR_GENERIC_ERROR;
  1.2061 +    }
  1.2062 +
  1.2063 +    nsCOMPtr<nsIContent> content(do_QueryInterface(element));
  1.2064 +    if (!content) {
  1.2065 +      return NPERR_GENERIC_ERROR;
  1.2066 +    }
  1.2067 +
  1.2068 +    nsIPrincipal* principal = content->NodePrincipal();
  1.2069 +
  1.2070 +    nsAutoString utf16Origin;
  1.2071 +    res = nsContentUtils::GetUTFOrigin(principal, utf16Origin);
  1.2072 +    if (NS_FAILED(res)) {
  1.2073 +      return NPERR_GENERIC_ERROR;
  1.2074 +    }
  1.2075 +
  1.2076 +    nsCOMPtr<nsIUnicodeNormalizer> normalizer = do_GetService(NS_UNICODE_NORMALIZER_CONTRACTID);
  1.2077 +    if (!normalizer) {
  1.2078 +      return NPERR_GENERIC_ERROR;
  1.2079 +    }
  1.2080 +
  1.2081 +    nsAutoString normalizedUTF16Origin;
  1.2082 +    res = normalizer->NormalizeUnicodeNFKC(utf16Origin, normalizedUTF16Origin);
  1.2083 +    if (NS_FAILED(res)) {
  1.2084 +      return NPERR_GENERIC_ERROR;
  1.2085 +    }
  1.2086 +
  1.2087 +    *(char**)result = ToNewUTF8String(normalizedUTF16Origin);
  1.2088 +    return *(char**)result ? NPERR_NO_ERROR : NPERR_GENERIC_ERROR;
  1.2089 +  }
  1.2090 +
  1.2091 +#ifdef XP_MACOSX
  1.2092 +  case NPNVpluginDrawingModel: {
  1.2093 +    if (npp) {
  1.2094 +      nsNPAPIPluginInstance *inst = (nsNPAPIPluginInstance*)npp->ndata;
  1.2095 +      if (inst) {
  1.2096 +        NPDrawingModel drawingModel;
  1.2097 +        inst->GetDrawingModel((int32_t*)&drawingModel);
  1.2098 +        *(NPDrawingModel*)result = drawingModel;
  1.2099 +        return NPERR_NO_ERROR;
  1.2100 +      }
  1.2101 +    }
  1.2102 +    else {
  1.2103 +      return NPERR_GENERIC_ERROR;
  1.2104 +    }
  1.2105 +  }
  1.2106 +
  1.2107 +#ifndef NP_NO_QUICKDRAW
  1.2108 +  case NPNVsupportsQuickDrawBool: {
  1.2109 +    *(NPBool*)result = false;
  1.2110 +    
  1.2111 +    return NPERR_NO_ERROR;
  1.2112 +  }
  1.2113 +#endif
  1.2114 +
  1.2115 +  case NPNVsupportsCoreGraphicsBool: {
  1.2116 +    *(NPBool*)result = true;
  1.2117 +    
  1.2118 +    return NPERR_NO_ERROR;
  1.2119 +  }
  1.2120 +
  1.2121 +  case NPNVsupportsCoreAnimationBool: {
  1.2122 +    *(NPBool*)result = nsCocoaFeatures::SupportCoreAnimationPlugins();
  1.2123 +
  1.2124 +    return NPERR_NO_ERROR;
  1.2125 +  }
  1.2126 +
  1.2127 +  case NPNVsupportsInvalidatingCoreAnimationBool: {
  1.2128 +    *(NPBool*)result = nsCocoaFeatures::SupportCoreAnimationPlugins();
  1.2129 +
  1.2130 +    return NPERR_NO_ERROR;
  1.2131 +  }
  1.2132 +
  1.2133 +  case NPNVsupportsCompositingCoreAnimationPluginsBool: {
  1.2134 +    *(NPBool*)result = PR_TRUE;
  1.2135 +
  1.2136 +    return NPERR_NO_ERROR;
  1.2137 +  }
  1.2138 +
  1.2139 +#ifndef NP_NO_CARBON
  1.2140 +  case NPNVsupportsCarbonBool: {
  1.2141 +    *(NPBool*)result = false;
  1.2142 +
  1.2143 +    return NPERR_NO_ERROR;
  1.2144 +  }
  1.2145 +#endif
  1.2146 +  case NPNVsupportsCocoaBool: {
  1.2147 +    *(NPBool*)result = true;
  1.2148 +
  1.2149 +    return NPERR_NO_ERROR;
  1.2150 +  }
  1.2151 +
  1.2152 +  case NPNVsupportsUpdatedCocoaTextInputBool: {
  1.2153 +    *(NPBool*)result = true;
  1.2154 +    return NPERR_NO_ERROR;
  1.2155 +  }
  1.2156 +
  1.2157 +  case NPNVcontentsScaleFactor: {
  1.2158 +    nsNPAPIPluginInstance *inst =
  1.2159 +      (nsNPAPIPluginInstance *) (npp ? npp->ndata : nullptr);
  1.2160 +    double scaleFactor = inst ? inst->GetContentsScaleFactor() : 1.0;
  1.2161 +    *(double*)result = scaleFactor;
  1.2162 +    return NPERR_NO_ERROR;
  1.2163 +  }
  1.2164 +#endif
  1.2165 +
  1.2166 +#ifdef MOZ_WIDGET_ANDROID
  1.2167 +    case kLogInterfaceV0_ANPGetValue: {
  1.2168 +      LOG("get log interface");
  1.2169 +      ANPLogInterfaceV0 *i = (ANPLogInterfaceV0 *) result;
  1.2170 +      InitLogInterface(i);
  1.2171 +      return NPERR_NO_ERROR;
  1.2172 +    }
  1.2173 +
  1.2174 +    case kBitmapInterfaceV0_ANPGetValue: {
  1.2175 +      LOG("get bitmap interface");
  1.2176 +      ANPBitmapInterfaceV0 *i = (ANPBitmapInterfaceV0 *) result;
  1.2177 +      InitBitmapInterface(i);
  1.2178 +      return NPERR_NO_ERROR;
  1.2179 +    }
  1.2180 +
  1.2181 +    case kMatrixInterfaceV0_ANPGetValue: {
  1.2182 +      LOG("get matrix interface");
  1.2183 +      ANPMatrixInterfaceV0 *i = (ANPMatrixInterfaceV0 *) result;
  1.2184 +      InitMatrixInterface(i);
  1.2185 +      return NPERR_NO_ERROR;
  1.2186 +    }
  1.2187 +      
  1.2188 +    case kPathInterfaceV0_ANPGetValue: {
  1.2189 +      LOG("get path interface");
  1.2190 +      ANPPathInterfaceV0 *i = (ANPPathInterfaceV0 *) result;
  1.2191 +      InitPathInterface(i);
  1.2192 +      return NPERR_NO_ERROR;
  1.2193 +    }
  1.2194 +      
  1.2195 +    case kTypefaceInterfaceV0_ANPGetValue: {
  1.2196 +      LOG("get typeface interface");
  1.2197 +      ANPTypefaceInterfaceV0 *i = (ANPTypefaceInterfaceV0 *) result;
  1.2198 +      InitTypeFaceInterface(i);
  1.2199 +      return NPERR_NO_ERROR;
  1.2200 +    }
  1.2201 +
  1.2202 +    case kPaintInterfaceV0_ANPGetValue: {
  1.2203 +      LOG("get paint interface");
  1.2204 +      ANPPaintInterfaceV0 *i = (ANPPaintInterfaceV0 *) result;
  1.2205 +      InitPaintInterface(i);
  1.2206 +      return NPERR_NO_ERROR;
  1.2207 +    }
  1.2208 +
  1.2209 +    case kCanvasInterfaceV0_ANPGetValue: {
  1.2210 +      LOG("get canvas interface");
  1.2211 +      ANPCanvasInterfaceV0 *i = (ANPCanvasInterfaceV0 *) result;
  1.2212 +      InitCanvasInterface(i);
  1.2213 +      return NPERR_NO_ERROR;
  1.2214 +    }
  1.2215 +
  1.2216 +    case kWindowInterfaceV0_ANPGetValue: {
  1.2217 +      LOG("get window interface");
  1.2218 +      ANPWindowInterfaceV0 *i = (ANPWindowInterfaceV0 *) result;
  1.2219 +      InitWindowInterface(i);
  1.2220 +      return NPERR_NO_ERROR;
  1.2221 +    }
  1.2222 +
  1.2223 +    case kAudioTrackInterfaceV0_ANPGetValue: {
  1.2224 +      LOG("get audio interface");
  1.2225 +      ANPAudioTrackInterfaceV0 *i = (ANPAudioTrackInterfaceV0 *) result;
  1.2226 +      InitAudioTrackInterfaceV0(i);
  1.2227 +      return NPERR_NO_ERROR;
  1.2228 +    }
  1.2229 +
  1.2230 +    case kEventInterfaceV0_ANPGetValue: {
  1.2231 +      LOG("get event interface");
  1.2232 +      ANPEventInterfaceV0 *i = (ANPEventInterfaceV0 *) result;
  1.2233 +      InitEventInterface(i);
  1.2234 +      return NPERR_NO_ERROR;
  1.2235 +    }
  1.2236 +
  1.2237 +    case kSystemInterfaceV0_ANPGetValue: {
  1.2238 +      LOG("get system interface");
  1.2239 +      ANPSystemInterfaceV0* i = reinterpret_cast<ANPSystemInterfaceV0*>(result);
  1.2240 +      InitSystemInterface(i);
  1.2241 +      return NPERR_NO_ERROR;
  1.2242 +    }
  1.2243 +
  1.2244 +    case kSurfaceInterfaceV0_ANPGetValue: {
  1.2245 +      LOG("get surface interface");
  1.2246 +      ANPSurfaceInterfaceV0 *i = (ANPSurfaceInterfaceV0 *) result;
  1.2247 +      InitSurfaceInterface(i);
  1.2248 +      return NPERR_NO_ERROR;
  1.2249 +    }
  1.2250 +      
  1.2251 +    case kSupportedDrawingModel_ANPGetValue: {
  1.2252 +      LOG("get supported drawing model");
  1.2253 +      uint32_t* bits = reinterpret_cast<uint32_t*>(result);
  1.2254 +      *bits = kBitmap_ANPDrawingModel && kSurface_ANPDrawingModel;
  1.2255 +      return NPERR_NO_ERROR;
  1.2256 +    }
  1.2257 +
  1.2258 +    case kJavaContext_ANPGetValue: {
  1.2259 +      jobject ret = mozilla::widget::android::GeckoAppShell::GetContext();
  1.2260 +      if (!ret)
  1.2261 +        return NPERR_GENERIC_ERROR;
  1.2262 +
  1.2263 +      int32_t* i  = reinterpret_cast<int32_t*>(result);
  1.2264 +      *i = reinterpret_cast<int32_t>(ret);
  1.2265 +      return NPERR_NO_ERROR;
  1.2266 +    }
  1.2267 +
  1.2268 +    case kAudioTrackInterfaceV1_ANPGetValue: {
  1.2269 +      LOG("get audio interface v1");
  1.2270 +      ANPAudioTrackInterfaceV1 *i = (ANPAudioTrackInterfaceV1 *) result;
  1.2271 +      InitAudioTrackInterfaceV1(i);
  1.2272 +      return NPERR_NO_ERROR;
  1.2273 +    }
  1.2274 +
  1.2275 +    case kNativeWindowInterfaceV0_ANPGetValue: {
  1.2276 +      LOG("get native window interface v0");
  1.2277 +      ANPNativeWindowInterfaceV0* i = (ANPNativeWindowInterfaceV0 *) result;
  1.2278 +      InitNativeWindowInterface(i);
  1.2279 +      return NPERR_NO_ERROR;
  1.2280 +    }
  1.2281 +
  1.2282 +    case kOpenGLInterfaceV0_ANPGetValue: {
  1.2283 +      LOG("get openGL interface");
  1.2284 +      ANPOpenGLInterfaceV0 *i = (ANPOpenGLInterfaceV0*) result;
  1.2285 +      InitOpenGLInterface(i);
  1.2286 +      return NPERR_NO_ERROR;
  1.2287 +    }
  1.2288 +
  1.2289 +    case kWindowInterfaceV1_ANPGetValue: {
  1.2290 +      LOG("get Window interface V1");
  1.2291 +      ANPWindowInterfaceV1 *i = (ANPWindowInterfaceV1 *) result;
  1.2292 +      InitWindowInterfaceV1(i);
  1.2293 +      return NPERR_NO_ERROR;
  1.2294 +    }
  1.2295 +
  1.2296 +    case kWindowInterfaceV2_ANPGetValue: {
  1.2297 +      LOG("get Window interface V2");
  1.2298 +      ANPWindowInterfaceV2 *i = (ANPWindowInterfaceV2 *) result;
  1.2299 +      InitWindowInterfaceV2(i);
  1.2300 +      return NPERR_NO_ERROR;
  1.2301 +    }
  1.2302 +
  1.2303 +    case kVideoInterfaceV0_ANPGetValue: {
  1.2304 +      LOG("get video interface");
  1.2305 +      ANPVideoInterfaceV0 *i = (ANPVideoInterfaceV0*) result;
  1.2306 +      InitVideoInterfaceV0(i);
  1.2307 +      return NPERR_NO_ERROR;
  1.2308 +    }
  1.2309 +
  1.2310 +    case kVideoInterfaceV1_ANPGetValue: {
  1.2311 +      LOG("get video interface");
  1.2312 +      ANPVideoInterfaceV1 *i = (ANPVideoInterfaceV1*) result;
  1.2313 +      InitVideoInterfaceV1(i);
  1.2314 +      return NPERR_NO_ERROR;
  1.2315 +    }
  1.2316 +
  1.2317 +
  1.2318 +    case kSystemInterfaceV1_ANPGetValue: {
  1.2319 +      LOG("get system interface v1");
  1.2320 +      ANPSystemInterfaceV1* i = reinterpret_cast<ANPSystemInterfaceV1*>(result);
  1.2321 +      InitSystemInterfaceV1(i);
  1.2322 +      return NPERR_NO_ERROR;
  1.2323 +    }
  1.2324 +
  1.2325 +    case kSystemInterfaceV2_ANPGetValue: {
  1.2326 +      LOG("get system interface v2");
  1.2327 +      ANPSystemInterfaceV2* i = reinterpret_cast<ANPSystemInterfaceV2*>(result);
  1.2328 +      InitSystemInterfaceV2(i);
  1.2329 +      return NPERR_NO_ERROR;
  1.2330 +    }
  1.2331 +
  1.2332 +#endif
  1.2333 +
  1.2334 +  // we no longer hand out any XPCOM objects
  1.2335 +  case NPNVDOMElement:
  1.2336 +    // fall through
  1.2337 +  case NPNVDOMWindow:
  1.2338 +    // fall through
  1.2339 +  case NPNVserviceManager:
  1.2340 +    // old XPCOM objects, no longer supported, but null out the out
  1.2341 +    // param to avoid crashing plugins that still try to use this.
  1.2342 +    *(nsISupports**)result = nullptr;
  1.2343 +    // fall through
  1.2344 +  default:
  1.2345 +    NPN_PLUGIN_LOG(PLUGIN_LOG_NORMAL, ("NPN_getvalue unhandled get value: %d\n", variable));
  1.2346 +    return NPERR_GENERIC_ERROR;
  1.2347 +  }
  1.2348 +}
  1.2349 +
  1.2350 +NPError
  1.2351 +_setvalue(NPP npp, NPPVariable variable, void *result)
  1.2352 +{
  1.2353 +  if (!NS_IsMainThread()) {
  1.2354 +    NPN_PLUGIN_LOG(PLUGIN_LOG_ALWAYS,("NPN_setvalue called from the wrong thread\n"));
  1.2355 +    return NPERR_INVALID_PARAM;
  1.2356 +  }
  1.2357 +  NPN_PLUGIN_LOG(PLUGIN_LOG_NORMAL, ("NPN_SetValue: npp=%p, var=%d\n",
  1.2358 +                                     (void*)npp, (int)variable));
  1.2359 +
  1.2360 +  if (!npp)
  1.2361 +    return NPERR_INVALID_INSTANCE_ERROR;
  1.2362 +
  1.2363 +  nsNPAPIPluginInstance *inst = (nsNPAPIPluginInstance *) npp->ndata;
  1.2364 +
  1.2365 +  NS_ASSERTION(inst, "null instance");
  1.2366 +
  1.2367 +  if (!inst)
  1.2368 +    return NPERR_INVALID_INSTANCE_ERROR;
  1.2369 +
  1.2370 +  PluginDestructionGuard guard(inst);
  1.2371 +
  1.2372 +  switch (variable) {
  1.2373 +
  1.2374 +    // we should keep backward compatibility with NPAPI where the
  1.2375 +    // actual pointer value is checked rather than its content
  1.2376 +    // when passing booleans
  1.2377 +    case NPPVpluginWindowBool: {
  1.2378 +#ifdef XP_MACOSX
  1.2379 +      // This setting doesn't apply to OS X (only to Windows and Unix/Linux).
  1.2380 +      // See https://developer.mozilla.org/En/NPN_SetValue#section_5.  Return
  1.2381 +      // NPERR_NO_ERROR here to conform to other browsers' behavior on OS X
  1.2382 +      // (e.g. Safari and Opera).
  1.2383 +      return NPERR_NO_ERROR;
  1.2384 +#else
  1.2385 +      NPBool bWindowless = (result == nullptr);
  1.2386 +      return inst->SetWindowless(bWindowless);
  1.2387 +#endif
  1.2388 +    }
  1.2389 +    case NPPVpluginTransparentBool: {
  1.2390 +      NPBool bTransparent = (result != nullptr);
  1.2391 +      return inst->SetTransparent(bTransparent);
  1.2392 +    }
  1.2393 +
  1.2394 +    case NPPVjavascriptPushCallerBool: {
  1.2395 +      return NPERR_NO_ERROR;
  1.2396 +    }
  1.2397 +
  1.2398 +    case NPPVpluginKeepLibraryInMemory: {
  1.2399 +      NPBool bCached = (result != nullptr);
  1.2400 +      inst->SetCached(bCached);
  1.2401 +      return NPERR_NO_ERROR;
  1.2402 +    }
  1.2403 +
  1.2404 +    case NPPVpluginUsesDOMForCursorBool: {
  1.2405 +      bool useDOMForCursor = (result != nullptr);
  1.2406 +      return inst->SetUsesDOMForCursor(useDOMForCursor);
  1.2407 +    }
  1.2408 +
  1.2409 +#ifndef MOZ_WIDGET_ANDROID
  1.2410 +    // On android, their 'drawing model' uses the same constant!
  1.2411 +    case NPPVpluginDrawingModel: {
  1.2412 +      if (inst) {
  1.2413 +        inst->SetDrawingModel((NPDrawingModel)NS_PTR_TO_INT32(result));
  1.2414 +        return NPERR_NO_ERROR;
  1.2415 +      }
  1.2416 +      else {
  1.2417 +        return NPERR_GENERIC_ERROR;
  1.2418 +      }
  1.2419 +    }
  1.2420 +#endif
  1.2421 +
  1.2422 +#ifdef XP_MACOSX
  1.2423 +    case NPPVpluginEventModel: {
  1.2424 +      if (inst) {
  1.2425 +        inst->SetEventModel((NPEventModel)NS_PTR_TO_INT32(result));
  1.2426 +        return NPERR_NO_ERROR;
  1.2427 +      }
  1.2428 +      else {
  1.2429 +        return NPERR_GENERIC_ERROR;
  1.2430 +      }
  1.2431 +    }
  1.2432 +#endif
  1.2433 +#ifdef MOZ_WIDGET_ANDROID
  1.2434 +  case kRequestDrawingModel_ANPSetValue:
  1.2435 +    if (inst)
  1.2436 +      inst->SetANPDrawingModel(NS_PTR_TO_INT32(result));
  1.2437 +    return NPERR_NO_ERROR;
  1.2438 +  case kAcceptEvents_ANPSetValue:
  1.2439 +    return NPERR_NO_ERROR;
  1.2440 +#endif
  1.2441 +    default:
  1.2442 +      return NPERR_GENERIC_ERROR;
  1.2443 +  }
  1.2444 +}
  1.2445 +
  1.2446 +NPError
  1.2447 +_requestread(NPStream *pstream, NPByteRange *rangeList)
  1.2448 +{
  1.2449 +  if (!NS_IsMainThread()) {
  1.2450 +    NPN_PLUGIN_LOG(PLUGIN_LOG_ALWAYS,("NPN_requestread called from the wrong thread\n"));
  1.2451 +    return NPERR_INVALID_PARAM;
  1.2452 +  }
  1.2453 +  NPN_PLUGIN_LOG(PLUGIN_LOG_NORMAL, ("NPN_RequestRead: stream=%p\n",
  1.2454 +                                     (void*)pstream));
  1.2455 +
  1.2456 +#ifdef PLUGIN_LOGGING
  1.2457 +  for(NPByteRange * range = rangeList; range != nullptr; range = range->next)
  1.2458 +    PR_LOG(nsPluginLogging::gNPNLog,PLUGIN_LOG_NOISY,
  1.2459 +    ("%i-%i", range->offset, range->offset + range->length - 1));
  1.2460 +
  1.2461 +  PR_LOG(nsPluginLogging::gNPNLog,PLUGIN_LOG_NOISY, ("\n\n"));
  1.2462 +  PR_LogFlush();
  1.2463 +#endif
  1.2464 +
  1.2465 +  if (!pstream || !rangeList || !pstream->ndata)
  1.2466 +    return NPERR_INVALID_PARAM;
  1.2467 +
  1.2468 +  nsNPAPIStreamWrapper* streamWrapper = static_cast<nsNPAPIStreamWrapper*>(pstream->ndata);
  1.2469 +  nsNPAPIPluginStreamListener* streamlistener = streamWrapper->GetStreamListener();
  1.2470 +  if (!streamlistener) {
  1.2471 +    return NPERR_GENERIC_ERROR;
  1.2472 +  }
  1.2473 +
  1.2474 +  int32_t streamtype = NP_NORMAL;
  1.2475 +
  1.2476 +  streamlistener->GetStreamType(&streamtype);
  1.2477 +
  1.2478 +  if (streamtype != NP_SEEK)
  1.2479 +    return NPERR_STREAM_NOT_SEEKABLE;
  1.2480 +
  1.2481 +  if (!streamlistener->mStreamListenerPeer)
  1.2482 +    return NPERR_GENERIC_ERROR;
  1.2483 +
  1.2484 +  nsresult rv = streamlistener->mStreamListenerPeer->RequestRead((NPByteRange *)rangeList);
  1.2485 +  if (NS_FAILED(rv))
  1.2486 +    return NPERR_GENERIC_ERROR;
  1.2487 +
  1.2488 +  return NPERR_NO_ERROR;
  1.2489 +}
  1.2490 +
  1.2491 +// Deprecated, only stubbed out
  1.2492 +void* /* OJI type: JRIEnv* */
  1.2493 +_getJavaEnv()
  1.2494 +{
  1.2495 +  NPN_PLUGIN_LOG(PLUGIN_LOG_NORMAL, ("NPN_GetJavaEnv\n"));
  1.2496 +  return nullptr;
  1.2497 +}
  1.2498 +
  1.2499 +const char *
  1.2500 +_useragent(NPP npp)
  1.2501 +{
  1.2502 +  if (!NS_IsMainThread()) {
  1.2503 +    NPN_PLUGIN_LOG(PLUGIN_LOG_ALWAYS,("NPN_useragent called from the wrong thread\n"));
  1.2504 +    return nullptr;
  1.2505 +  }
  1.2506 +  NPN_PLUGIN_LOG(PLUGIN_LOG_NORMAL, ("NPN_UserAgent: npp=%p\n", (void*)npp));
  1.2507 +
  1.2508 +  nsCOMPtr<nsIPluginHost> pluginHostCOM(do_GetService(MOZ_PLUGIN_HOST_CONTRACTID));
  1.2509 +  nsPluginHost *pluginHost = static_cast<nsPluginHost*>(pluginHostCOM.get());
  1.2510 +  if (!pluginHost) {
  1.2511 +    return nullptr;
  1.2512 +  }
  1.2513 +
  1.2514 +  const char *retstr;
  1.2515 +  nsresult rv = pluginHost->UserAgent(&retstr);
  1.2516 +  if (NS_FAILED(rv))
  1.2517 +    return nullptr;
  1.2518 +
  1.2519 +  return retstr;
  1.2520 +}
  1.2521 +
  1.2522 +void *
  1.2523 +_memalloc (uint32_t size)
  1.2524 +{
  1.2525 +  if (!NS_IsMainThread()) {
  1.2526 +    NPN_PLUGIN_LOG(PLUGIN_LOG_NORMAL,("NPN_memalloc called from the wrong thread\n"));
  1.2527 +  }
  1.2528 +  NPN_PLUGIN_LOG(PLUGIN_LOG_NOISY, ("NPN_MemAlloc: size=%d\n", size));
  1.2529 +  return nsMemory::Alloc(size);
  1.2530 +}
  1.2531 +
  1.2532 +// Deprecated, only stubbed out
  1.2533 +void* /* OJI type: jref */
  1.2534 +_getJavaPeer(NPP npp)
  1.2535 +{
  1.2536 +  NPN_PLUGIN_LOG(PLUGIN_LOG_NORMAL, ("NPN_GetJavaPeer: npp=%p\n", (void*)npp));
  1.2537 +  return nullptr;
  1.2538 +}
  1.2539 +
  1.2540 +void
  1.2541 +_pushpopupsenabledstate(NPP npp, NPBool enabled)
  1.2542 +{
  1.2543 +  if (!NS_IsMainThread()) {
  1.2544 +    NPN_PLUGIN_LOG(PLUGIN_LOG_ALWAYS,("NPN_pushpopupsenabledstate called from the wrong thread\n"));
  1.2545 +    return;
  1.2546 +  }
  1.2547 +  nsNPAPIPluginInstance *inst = npp ? (nsNPAPIPluginInstance *)npp->ndata : nullptr;
  1.2548 +  if (!inst)
  1.2549 +    return;
  1.2550 +
  1.2551 +  inst->PushPopupsEnabledState(enabled);
  1.2552 +}
  1.2553 +
  1.2554 +void
  1.2555 +_poppopupsenabledstate(NPP npp)
  1.2556 +{
  1.2557 +  if (!NS_IsMainThread()) {
  1.2558 +    NPN_PLUGIN_LOG(PLUGIN_LOG_ALWAYS,("NPN_poppopupsenabledstate called from the wrong thread\n"));
  1.2559 +    return;
  1.2560 +  }
  1.2561 +  nsNPAPIPluginInstance *inst = npp ? (nsNPAPIPluginInstance *)npp->ndata : nullptr;
  1.2562 +  if (!inst)
  1.2563 +    return;
  1.2564 +
  1.2565 +  inst->PopPopupsEnabledState();
  1.2566 +}
  1.2567 +
  1.2568 +void
  1.2569 +_pluginthreadasynccall(NPP instance, PluginThreadCallback func, void *userData)
  1.2570 +{
  1.2571 +  if (NS_IsMainThread()) {
  1.2572 +    NPN_PLUGIN_LOG(PLUGIN_LOG_NOISY,("NPN_pluginthreadasynccall called from the main thread\n"));
  1.2573 +  } else {
  1.2574 +    NPN_PLUGIN_LOG(PLUGIN_LOG_NOISY,("NPN_pluginthreadasynccall called from a non main thread\n"));
  1.2575 +  }
  1.2576 +  nsRefPtr<nsPluginThreadRunnable> evt =
  1.2577 +    new nsPluginThreadRunnable(instance, func, userData);
  1.2578 +
  1.2579 +  if (evt && evt->IsValid()) {
  1.2580 +    NS_DispatchToMainThread(evt);
  1.2581 +  }
  1.2582 +}
  1.2583 +
  1.2584 +NPError
  1.2585 +_getvalueforurl(NPP instance, NPNURLVariable variable, const char *url,
  1.2586 +                char **value, uint32_t *len)
  1.2587 +{
  1.2588 +  if (!instance) {
  1.2589 +    return NPERR_INVALID_PARAM;
  1.2590 +  }
  1.2591 +
  1.2592 +  if (!url || !*url || !len) {
  1.2593 +    return NPERR_INVALID_URL;
  1.2594 +  }
  1.2595 +
  1.2596 +  *len = 0;
  1.2597 +
  1.2598 +  switch (variable) {
  1.2599 +  case NPNURLVProxy:
  1.2600 +    {
  1.2601 +      nsCOMPtr<nsIPluginHost> pluginHostCOM(do_GetService(MOZ_PLUGIN_HOST_CONTRACTID));
  1.2602 +      nsPluginHost *pluginHost = static_cast<nsPluginHost*>(pluginHostCOM.get());
  1.2603 +      if (pluginHost && NS_SUCCEEDED(pluginHost->FindProxyForURL(url, value))) {
  1.2604 +        *len = *value ? strlen(*value) : 0;
  1.2605 +        return NPERR_NO_ERROR;
  1.2606 +      }
  1.2607 +      break;
  1.2608 +    }
  1.2609 +  case NPNURLVCookie:
  1.2610 +    {
  1.2611 +      nsCOMPtr<nsICookieService> cookieService =
  1.2612 +        do_GetService(NS_COOKIESERVICE_CONTRACTID);
  1.2613 +
  1.2614 +      if (!cookieService)
  1.2615 +        return NPERR_GENERIC_ERROR;
  1.2616 +
  1.2617 +      // Make an nsURI from the url argument
  1.2618 +      nsCOMPtr<nsIURI> uri;
  1.2619 +      if (NS_FAILED(NS_NewURI(getter_AddRefs(uri), nsDependentCString(url)))) {
  1.2620 +        return NPERR_GENERIC_ERROR;
  1.2621 +      }
  1.2622 +
  1.2623 +      nsCOMPtr<nsIChannel> channel = GetChannelFromNPP(instance);
  1.2624 +
  1.2625 +      if (NS_FAILED(cookieService->GetCookieString(uri, channel, value)) ||
  1.2626 +          !*value) {
  1.2627 +        return NPERR_GENERIC_ERROR;
  1.2628 +      }
  1.2629 +
  1.2630 +      *len = strlen(*value);
  1.2631 +      return NPERR_NO_ERROR;
  1.2632 +    }
  1.2633 +
  1.2634 +    break;
  1.2635 +  default:
  1.2636 +    // Fall through and return an error...
  1.2637 +    ;
  1.2638 +  }
  1.2639 +
  1.2640 +  return NPERR_GENERIC_ERROR;
  1.2641 +}
  1.2642 +
  1.2643 +NPError
  1.2644 +_setvalueforurl(NPP instance, NPNURLVariable variable, const char *url,
  1.2645 +                const char *value, uint32_t len)
  1.2646 +{
  1.2647 +  if (!instance) {
  1.2648 +    return NPERR_INVALID_PARAM;
  1.2649 +  }
  1.2650 +
  1.2651 +  if (!url || !*url) {
  1.2652 +    return NPERR_INVALID_URL;
  1.2653 +  }
  1.2654 +
  1.2655 +  switch (variable) {
  1.2656 +  case NPNURLVCookie:
  1.2657 +    {
  1.2658 +      if (!url || !value || (0 >= len))
  1.2659 +        return NPERR_INVALID_PARAM;
  1.2660 +
  1.2661 +      nsresult rv = NS_ERROR_FAILURE;
  1.2662 +      nsCOMPtr<nsIIOService> ioService(do_GetService(NS_IOSERVICE_CONTRACTID, &rv));
  1.2663 +      if (NS_FAILED(rv))
  1.2664 +        return NPERR_GENERIC_ERROR;
  1.2665 +
  1.2666 +      nsCOMPtr<nsICookieService> cookieService = do_GetService(NS_COOKIESERVICE_CONTRACTID, &rv);
  1.2667 +      if (NS_FAILED(rv))
  1.2668 +        return NPERR_GENERIC_ERROR;
  1.2669 +
  1.2670 +      nsCOMPtr<nsIURI> uriIn;
  1.2671 +      rv = ioService->NewURI(nsDependentCString(url), nullptr, nullptr, getter_AddRefs(uriIn));
  1.2672 +      if (NS_FAILED(rv))
  1.2673 +        return NPERR_GENERIC_ERROR;
  1.2674 +
  1.2675 +      nsCOMPtr<nsIChannel> channel = GetChannelFromNPP(instance);
  1.2676 +
  1.2677 +      char *cookie = (char*)value;
  1.2678 +      char c = cookie[len];
  1.2679 +      cookie[len] = '\0';
  1.2680 +      rv = cookieService->SetCookieString(uriIn, nullptr, cookie, channel);
  1.2681 +      cookie[len] = c;
  1.2682 +      if (NS_SUCCEEDED(rv))
  1.2683 +        return NPERR_NO_ERROR;
  1.2684 +    }
  1.2685 +
  1.2686 +    break;
  1.2687 +  case NPNURLVProxy:
  1.2688 +    // We don't support setting proxy values, fall through...
  1.2689 +  default:
  1.2690 +    // Fall through and return an error...
  1.2691 +    ;
  1.2692 +  }
  1.2693 +
  1.2694 +  return NPERR_GENERIC_ERROR;
  1.2695 +}
  1.2696 +
  1.2697 +NPError
  1.2698 +_getauthenticationinfo(NPP instance, const char *protocol, const char *host,
  1.2699 +                       int32_t port, const char *scheme, const char *realm,
  1.2700 +                       char **username, uint32_t *ulen, char **password,
  1.2701 +                       uint32_t *plen)
  1.2702 +{
  1.2703 +  if (!instance || !protocol || !host || !scheme || !realm || !username ||
  1.2704 +      !ulen || !password || !plen)
  1.2705 +    return NPERR_INVALID_PARAM;
  1.2706 +
  1.2707 +  *username = nullptr;
  1.2708 +  *password = nullptr;
  1.2709 +  *ulen = 0;
  1.2710 +  *plen = 0;
  1.2711 +
  1.2712 +  nsDependentCString proto(protocol);
  1.2713 +
  1.2714 +  if (!proto.LowerCaseEqualsLiteral("http") &&
  1.2715 +      !proto.LowerCaseEqualsLiteral("https"))
  1.2716 +    return NPERR_GENERIC_ERROR;
  1.2717 +
  1.2718 +  nsCOMPtr<nsIHttpAuthManager> authManager =
  1.2719 +    do_GetService("@mozilla.org/network/http-auth-manager;1");
  1.2720 +  if (!authManager)
  1.2721 +    return NPERR_GENERIC_ERROR;
  1.2722 +
  1.2723 +  nsNPAPIPluginInstance *inst = static_cast<nsNPAPIPluginInstance*>(instance->ndata);
  1.2724 +  if (!inst)
  1.2725 +    return NPERR_GENERIC_ERROR;
  1.2726 +
  1.2727 +  bool authPrivate = false;
  1.2728 +  if (NS_FAILED(inst->IsPrivateBrowsing(&authPrivate)))
  1.2729 +    return NPERR_GENERIC_ERROR;
  1.2730 +
  1.2731 +  nsIDocument *doc = GetDocumentFromNPP(instance);
  1.2732 +  NS_ENSURE_TRUE(doc, NPERR_GENERIC_ERROR);
  1.2733 +  nsIPrincipal *principal = doc->NodePrincipal();
  1.2734 +
  1.2735 +  nsAutoString unused, uname16, pwd16;
  1.2736 +  if (NS_FAILED(authManager->GetAuthIdentity(proto, nsDependentCString(host),
  1.2737 +                                             port, nsDependentCString(scheme),
  1.2738 +                                             nsDependentCString(realm),
  1.2739 +                                             EmptyCString(), unused, uname16,
  1.2740 +                                             pwd16, authPrivate, principal))) {
  1.2741 +    return NPERR_GENERIC_ERROR;
  1.2742 +  }
  1.2743 +
  1.2744 +  NS_ConvertUTF16toUTF8 uname8(uname16);
  1.2745 +  NS_ConvertUTF16toUTF8 pwd8(pwd16);
  1.2746 +
  1.2747 +  *username = ToNewCString(uname8);
  1.2748 +  *ulen = *username ? uname8.Length() : 0;
  1.2749 +
  1.2750 +  *password = ToNewCString(pwd8);
  1.2751 +  *plen = *password ? pwd8.Length() : 0;
  1.2752 +
  1.2753 +  return NPERR_NO_ERROR;
  1.2754 +}
  1.2755 +
  1.2756 +uint32_t
  1.2757 +_scheduletimer(NPP instance, uint32_t interval, NPBool repeat, PluginTimerFunc timerFunc)
  1.2758 +{
  1.2759 +  nsNPAPIPluginInstance *inst = (nsNPAPIPluginInstance *)instance->ndata;
  1.2760 +  if (!inst)
  1.2761 +    return 0;
  1.2762 +
  1.2763 +  return inst->ScheduleTimer(interval, repeat, timerFunc);
  1.2764 +}
  1.2765 +
  1.2766 +void
  1.2767 +_unscheduletimer(NPP instance, uint32_t timerID)
  1.2768 +{
  1.2769 +#ifdef MOZ_WIDGET_ANDROID
  1.2770 +  // Sometimes Flash calls this with a dead NPP instance. Ensure the one we have
  1.2771 +  // here is valid and maps to a nsNPAPIPluginInstance.
  1.2772 +  nsNPAPIPluginInstance *inst = nsNPAPIPluginInstance::GetFromNPP(instance);
  1.2773 +#else
  1.2774 +  nsNPAPIPluginInstance *inst = (nsNPAPIPluginInstance *)instance->ndata;
  1.2775 +#endif
  1.2776 +  if (!inst)
  1.2777 +    return;
  1.2778 +
  1.2779 +  inst->UnscheduleTimer(timerID);
  1.2780 +}
  1.2781 +
  1.2782 +NPError
  1.2783 +_popupcontextmenu(NPP instance, NPMenu* menu)
  1.2784 +{
  1.2785 +  nsNPAPIPluginInstance *inst = (nsNPAPIPluginInstance *)instance->ndata;
  1.2786 +  if (!inst)
  1.2787 +    return NPERR_GENERIC_ERROR;
  1.2788 +
  1.2789 +  return inst->PopUpContextMenu(menu);
  1.2790 +}
  1.2791 +
  1.2792 +NPError
  1.2793 +_initasyncsurface(NPP instance, NPSize *size, NPImageFormat format, void *initData, NPAsyncSurface *surface)
  1.2794 +{
  1.2795 +  nsNPAPIPluginInstance *inst = (nsNPAPIPluginInstance *)instance->ndata;
  1.2796 +  if (!inst)
  1.2797 +    return NPERR_GENERIC_ERROR;
  1.2798 +
  1.2799 +  return inst->InitAsyncSurface(size, format, initData, surface);
  1.2800 +}
  1.2801 +
  1.2802 +NPError
  1.2803 +_finalizeasyncsurface(NPP instance, NPAsyncSurface *surface)
  1.2804 +{
  1.2805 +  nsNPAPIPluginInstance *inst = (nsNPAPIPluginInstance *)instance->ndata;
  1.2806 +  if (!inst)
  1.2807 +    return NPERR_GENERIC_ERROR;
  1.2808 +
  1.2809 +  return inst->FinalizeAsyncSurface(surface);
  1.2810 +}
  1.2811 +
  1.2812 +void
  1.2813 +_setcurrentasyncsurface(NPP instance, NPAsyncSurface *surface, NPRect *changed)
  1.2814 +{
  1.2815 +  nsNPAPIPluginInstance *inst = (nsNPAPIPluginInstance *)instance->ndata;
  1.2816 +  if (!inst)
  1.2817 +    return;
  1.2818 +
  1.2819 +  inst->SetCurrentAsyncSurface(surface, changed);
  1.2820 +}
  1.2821 +
  1.2822 +NPBool
  1.2823 +_convertpoint(NPP instance, double sourceX, double sourceY, NPCoordinateSpace sourceSpace, double *destX, double *destY, NPCoordinateSpace destSpace)
  1.2824 +{
  1.2825 +  nsNPAPIPluginInstance *inst = (nsNPAPIPluginInstance *)instance->ndata;
  1.2826 +  if (!inst)
  1.2827 +    return false;
  1.2828 +
  1.2829 +  return inst->ConvertPoint(sourceX, sourceY, sourceSpace, destX, destY, destSpace);
  1.2830 +}
  1.2831 +
  1.2832 +void
  1.2833 +_urlredirectresponse(NPP instance, void* notifyData, NPBool allow)
  1.2834 +{
  1.2835 +  nsNPAPIPluginInstance *inst = (nsNPAPIPluginInstance *)instance->ndata;
  1.2836 +  if (!inst) {
  1.2837 +    return;
  1.2838 +  }
  1.2839 +
  1.2840 +  inst->URLRedirectResponse(notifyData, allow);
  1.2841 +}
  1.2842 +
  1.2843 +} /* namespace parent */
  1.2844 +} /* namespace plugins */
  1.2845 +} /* namespace mozilla */

mercurial