dom/plugins/ipc/PluginScriptableObjectParent.cpp

Thu, 22 Jan 2015 13:21:57 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Thu, 22 Jan 2015 13:21:57 +0100
branch
TOR_BUG_9701
changeset 15
b8a032363ba2
permissions
-rw-r--r--

Incorporate requested changes from Mozilla in review:
https://bugzilla.mozilla.org/show_bug.cgi?id=1123480#c6

     1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*-
     2  * vim: sw=2 ts=2 et :
     3  * This Source Code Form is subject to the terms of the Mozilla Public
     4  * License, v. 2.0. If a copy of the MPL was not distributed with this
     5  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
     7 #include "PluginScriptableObjectParent.h"
     9 #include "mozilla/DebugOnly.h"
    10 #include "mozilla/plugins/PluginIdentifierParent.h"
    11 #include "mozilla/unused.h"
    12 #include "nsCxPusher.h"
    13 #include "nsNPAPIPlugin.h"
    14 #include "PluginScriptableObjectUtils.h"
    16 using namespace mozilla::plugins;
    17 using namespace mozilla::plugins::parent;
    19 namespace {
    21 inline void
    22 ReleaseVariant(NPVariant& aVariant,
    23                PluginInstanceParent* aInstance)
    24 {
    25   const NPNetscapeFuncs* npn = GetNetscapeFuncs(aInstance);
    26   if (npn) {
    27     npn->releasevariantvalue(&aVariant);
    28   }
    29 }
    31 } // anonymous namespace
    33 // static
    34 NPObject*
    35 PluginScriptableObjectParent::ScriptableAllocate(NPP aInstance,
    36                                                  NPClass* aClass)
    37 {
    38   if (aClass != GetClass()) {
    39     NS_ERROR("Huh?! Wrong class!");
    40     return nullptr;
    41   }
    43   return new ParentNPObject();
    44 }
    46 // static
    47 void
    48 PluginScriptableObjectParent::ScriptableInvalidate(NPObject* aObject)
    49 {
    50   if (aObject->_class != GetClass()) {
    51     NS_ERROR("Don't know what kind of object this is!");
    52     return;
    53   }
    55   ParentNPObject* object = reinterpret_cast<ParentNPObject*>(aObject);
    56   if (object->invalidated) {
    57     // This can happen more than once, and is just fine.
    58     return;
    59   }
    61   object->invalidated = true;
    63   // |object->parent| may be null already if the instance has gone away.
    64   if (object->parent && !object->parent->CallInvalidate()) {
    65     NS_ERROR("Failed to send message!");
    66   }
    67 }
    69 // static
    70 void
    71 PluginScriptableObjectParent::ScriptableDeallocate(NPObject* aObject)
    72 {
    73   if (aObject->_class != GetClass()) {
    74     NS_ERROR("Don't know what kind of object this is!");
    75     return;
    76   }
    78   ParentNPObject* object = reinterpret_cast<ParentNPObject*>(aObject);
    79   PluginScriptableObjectParent* actor = object->parent;
    80   if (actor) {
    81     NS_ASSERTION(actor->Type() == Proxy, "Bad type!");
    82     actor->DropNPObject();
    83   }
    85   delete object;
    86 }
    88 // static
    89 bool
    90 PluginScriptableObjectParent::ScriptableHasMethod(NPObject* aObject,
    91                                                   NPIdentifier aName)
    92 {
    93   if (aObject->_class != GetClass()) {
    94     NS_ERROR("Don't know what kind of object this is!");
    95     return false;
    96   }
    98   ParentNPObject* object = reinterpret_cast<ParentNPObject*>(aObject);
    99   if (object->invalidated) {
   100     NS_WARNING("Calling method on an invalidated object!");
   101     return false;
   102   }
   104   ProtectedActor<PluginScriptableObjectParent> actor(object->parent);
   105   if (!actor) {
   106     return false;
   107   }
   109   PluginIdentifierParent::StackIdentifier identifier(aObject, aName);
   110   if (!identifier) {
   111     return false;
   112   }
   114   NS_ASSERTION(actor->Type() == Proxy, "Bad type!");
   116   bool result;
   117   if (!actor->CallHasMethod(identifier, &result)) {
   118     NS_WARNING("Failed to send message!");
   119     return false;
   120   }
   122   return result;
   123 }
   125 // static
   126 bool
   127 PluginScriptableObjectParent::ScriptableInvoke(NPObject* aObject,
   128                                                NPIdentifier aName,
   129                                                const NPVariant* aArgs,
   130                                                uint32_t aArgCount,
   131                                                NPVariant* aResult)
   132 {
   133   if (aObject->_class != GetClass()) {
   134     NS_ERROR("Don't know what kind of object this is!");
   135     return false;
   136   }
   138   ParentNPObject* object = reinterpret_cast<ParentNPObject*>(aObject);
   139   if (object->invalidated) {
   140     NS_WARNING("Calling method on an invalidated object!");
   141     return false;
   142   }
   144   ProtectedActor<PluginScriptableObjectParent> actor(object->parent);
   145   if (!actor) {
   146     return false;
   147   }
   149   PluginIdentifierParent::StackIdentifier identifier(aObject, aName);
   150   if (!identifier) {
   151     return false;
   152   }
   154   NS_ASSERTION(actor->Type() == Proxy, "Bad type!");
   156   ProtectedVariantArray args(aArgs, aArgCount, actor->GetInstance());
   157   if (!args.IsOk()) {
   158     NS_ERROR("Failed to convert arguments!");
   159     return false;
   160   }
   162   Variant remoteResult;
   163   bool success;
   164   if (!actor->CallInvoke(identifier, args, &remoteResult,
   165                          &success)) {
   166     NS_WARNING("Failed to send message!");
   167     return false;
   168   }
   170   if (!success) {
   171     return false;
   172   }
   174   if (!ConvertToVariant(remoteResult, *aResult, actor->GetInstance())) {
   175     NS_WARNING("Failed to convert result!");
   176     return false;
   177   }
   178   return true;
   179 }
   181 // static
   182 bool
   183 PluginScriptableObjectParent::ScriptableInvokeDefault(NPObject* aObject,
   184                                                       const NPVariant* aArgs,
   185                                                       uint32_t aArgCount,
   186                                                       NPVariant* aResult)
   187 {
   188   if (aObject->_class != GetClass()) {
   189     NS_ERROR("Don't know what kind of object this is!");
   190     return false;
   191   }
   193   ParentNPObject* object = reinterpret_cast<ParentNPObject*>(aObject);
   194   if (object->invalidated) {
   195     NS_WARNING("Calling method on an invalidated object!");
   196     return false;
   197   }
   199   ProtectedActor<PluginScriptableObjectParent> actor(object->parent);
   200   if (!actor) {
   201     return false;
   202   }
   204   NS_ASSERTION(actor->Type() == Proxy, "Bad type!");
   206   ProtectedVariantArray args(aArgs, aArgCount, actor->GetInstance());
   207   if (!args.IsOk()) {
   208     NS_ERROR("Failed to convert arguments!");
   209     return false;
   210   }
   212   Variant remoteResult;
   213   bool success;
   214   if (!actor->CallInvokeDefault(args, &remoteResult, &success)) {
   215     NS_WARNING("Failed to send message!");
   216     return false;
   217   }
   219   if (!success) {
   220     return false;
   221   }
   223   if (!ConvertToVariant(remoteResult, *aResult, actor->GetInstance())) {
   224     NS_WARNING("Failed to convert result!");
   225     return false;
   226   }
   227   return true;
   228 }
   230 // static
   231 bool
   232 PluginScriptableObjectParent::ScriptableHasProperty(NPObject* aObject,
   233                                                     NPIdentifier aName)
   234 {
   235   if (aObject->_class != GetClass()) {
   236     NS_ERROR("Don't know what kind of object this is!");
   237     return false;
   238   }
   240   ParentNPObject* object = reinterpret_cast<ParentNPObject*>(aObject);
   241   if (object->invalidated) {
   242     NS_WARNING("Calling method on an invalidated object!");
   243     return false;
   244   }
   246   ProtectedActor<PluginScriptableObjectParent> actor(object->parent);
   247   if (!actor) {
   248     return false;
   249   }
   251   PluginIdentifierParent::StackIdentifier identifier(aObject, aName);
   252   if (!identifier) {
   253     return false;
   254   }
   256   NS_ASSERTION(actor->Type() == Proxy, "Bad type!");
   258   bool result;
   259   if (!actor->CallHasProperty(identifier, &result)) {
   260     NS_WARNING("Failed to send message!");
   261     return false;
   262   }
   264   return result;
   265 }
   267 // static
   268 bool
   269 PluginScriptableObjectParent::ScriptableGetProperty(NPObject* aObject,
   270                                                     NPIdentifier aName,
   271                                                     NPVariant* aResult)
   272 {
   273   // See GetPropertyHelper below.
   274   NS_NOTREACHED("Shouldn't ever call this directly!");
   275   return false;
   276 }
   278 // static
   279 bool
   280 PluginScriptableObjectParent::ScriptableSetProperty(NPObject* aObject,
   281                                                     NPIdentifier aName,
   282                                                     const NPVariant* aValue)
   283 {
   284   if (aObject->_class != GetClass()) {
   285     NS_ERROR("Don't know what kind of object this is!");
   286     return false;
   287   }
   289   ParentNPObject* object = reinterpret_cast<ParentNPObject*>(aObject);
   290   if (object->invalidated) {
   291     NS_WARNING("Calling method on an invalidated object!");
   292     return false;
   293   }
   295   ProtectedActor<PluginScriptableObjectParent> actor(object->parent);
   296   if (!actor) {
   297     return false;
   298   }
   300   PluginIdentifierParent::StackIdentifier identifier(aObject, aName);
   301   if (!identifier) {
   302     return false;
   303   }
   305   NS_ASSERTION(actor->Type() == Proxy, "Bad type!");
   307   ProtectedVariant value(*aValue, actor->GetInstance());
   308   if (!value.IsOk()) {
   309     NS_WARNING("Failed to convert variant!");
   310     return false;
   311   }
   313   bool success;
   314   if (!actor->CallSetProperty(identifier, value, &success)) {
   315     NS_WARNING("Failed to send message!");
   316     return false;
   317   }
   319   return success;
   320 }
   322 // static
   323 bool
   324 PluginScriptableObjectParent::ScriptableRemoveProperty(NPObject* aObject,
   325                                                        NPIdentifier aName)
   326 {
   327   if (aObject->_class != GetClass()) {
   328     NS_ERROR("Don't know what kind of object this is!");
   329     return false;
   330   }
   332   ParentNPObject* object = reinterpret_cast<ParentNPObject*>(aObject);
   333   if (object->invalidated) {
   334     NS_WARNING("Calling method on an invalidated object!");
   335     return false;
   336   }
   338   ProtectedActor<PluginScriptableObjectParent> actor(object->parent);
   339   if (!actor) {
   340     return false;
   341   }
   343   PluginIdentifierParent::StackIdentifier identifier(aObject, aName);
   344   if (!identifier) {
   345     return false;
   346   }
   348   NS_ASSERTION(actor->Type() == Proxy, "Bad type!");
   350   bool success;
   351   if (!actor->CallRemoveProperty(identifier, &success)) {
   352     NS_WARNING("Failed to send message!");
   353     return false;
   354   }
   356   return success;
   357 }
   359 // static
   360 bool
   361 PluginScriptableObjectParent::ScriptableEnumerate(NPObject* aObject,
   362                                                   NPIdentifier** aIdentifiers,
   363                                                   uint32_t* aCount)
   364 {
   365   if (aObject->_class != GetClass()) {
   366     NS_ERROR("Don't know what kind of object this is!");
   367     return false;
   368   }
   370   ParentNPObject* object = reinterpret_cast<ParentNPObject*>(aObject);
   371   if (object->invalidated) {
   372     NS_WARNING("Calling method on an invalidated object!");
   373     return false;
   374   }
   376   ProtectedActor<PluginScriptableObjectParent> actor(object->parent);
   377   if (!actor) {
   378     return false;
   379   }
   381   NS_ASSERTION(actor->Type() == Proxy, "Bad type!");
   383   const NPNetscapeFuncs* npn = GetNetscapeFuncs(aObject);
   384   if (!npn) {
   385     NS_ERROR("No netscape funcs!");
   386     return false;
   387   }
   389   AutoInfallibleTArray<PPluginIdentifierParent*, 10> identifiers;
   390   bool success;
   391   if (!actor->CallEnumerate(&identifiers, &success)) {
   392     NS_WARNING("Failed to send message!");
   393     return false;
   394   }
   396   if (!success) {
   397     return false;
   398   }
   400   *aCount = identifiers.Length();
   401   if (!*aCount) {
   402     *aIdentifiers = nullptr;
   403     return true;
   404   }
   406   *aIdentifiers = (NPIdentifier*)npn->memalloc(*aCount * sizeof(NPIdentifier));
   407   if (!*aIdentifiers) {
   408     NS_ERROR("Out of memory!");
   409     return false;
   410   }
   412   for (uint32_t index = 0; index < *aCount; index++) {
   413     PluginIdentifierParent* id =
   414       static_cast<PluginIdentifierParent*>(identifiers[index]);
   415     (*aIdentifiers)[index] = id->ToNPIdentifier();
   416   }
   417   return true;
   418 }
   420 // static
   421 bool
   422 PluginScriptableObjectParent::ScriptableConstruct(NPObject* aObject,
   423                                                   const NPVariant* aArgs,
   424                                                   uint32_t aArgCount,
   425                                                   NPVariant* aResult)
   426 {
   427   if (aObject->_class != GetClass()) {
   428     NS_ERROR("Don't know what kind of object this is!");
   429     return false;
   430   }
   432   ParentNPObject* object = reinterpret_cast<ParentNPObject*>(aObject);
   433   if (object->invalidated) {
   434     NS_WARNING("Calling method on an invalidated object!");
   435     return false;
   436   }
   438   ProtectedActor<PluginScriptableObjectParent> actor(object->parent);
   439   if (!actor) {
   440     return false;
   441   }
   443   NS_ASSERTION(actor->Type() == Proxy, "Bad type!");
   445   ProtectedVariantArray args(aArgs, aArgCount, actor->GetInstance());
   446   if (!args.IsOk()) {
   447     NS_ERROR("Failed to convert arguments!");
   448     return false;
   449   }
   451   Variant remoteResult;
   452   bool success;
   453   if (!actor->CallConstruct(args, &remoteResult, &success)) {
   454     NS_WARNING("Failed to send message!");
   455     return false;
   456   }
   458   if (!success) {
   459     return false;
   460   }
   462   if (!ConvertToVariant(remoteResult, *aResult, actor->GetInstance())) {
   463     NS_WARNING("Failed to convert result!");
   464     return false;
   465   }
   466   return true;
   467 }
   469 const NPClass PluginScriptableObjectParent::sNPClass = {
   470   NP_CLASS_STRUCT_VERSION,
   471   PluginScriptableObjectParent::ScriptableAllocate,
   472   PluginScriptableObjectParent::ScriptableDeallocate,
   473   PluginScriptableObjectParent::ScriptableInvalidate,
   474   PluginScriptableObjectParent::ScriptableHasMethod,
   475   PluginScriptableObjectParent::ScriptableInvoke,
   476   PluginScriptableObjectParent::ScriptableInvokeDefault,
   477   PluginScriptableObjectParent::ScriptableHasProperty,
   478   PluginScriptableObjectParent::ScriptableGetProperty,
   479   PluginScriptableObjectParent::ScriptableSetProperty,
   480   PluginScriptableObjectParent::ScriptableRemoveProperty,
   481   PluginScriptableObjectParent::ScriptableEnumerate,
   482   PluginScriptableObjectParent::ScriptableConstruct
   483 };
   485 PluginScriptableObjectParent::PluginScriptableObjectParent(
   486                                                      ScriptableObjectType aType)
   487 : mInstance(nullptr),
   488   mObject(nullptr),
   489   mProtectCount(0),
   490   mType(aType)
   491 {
   492 }
   494 PluginScriptableObjectParent::~PluginScriptableObjectParent()
   495 {
   496   if (mObject) {
   497     if (mObject->_class == GetClass()) {
   498       NS_ASSERTION(mType == Proxy, "Wrong type!");
   499       static_cast<ParentNPObject*>(mObject)->parent = nullptr;
   500     }
   501     else {
   502       NS_ASSERTION(mType == LocalObject, "Wrong type!");
   503       GetInstance()->GetNPNIface()->releaseobject(mObject);
   504     }
   505   }
   506 }
   508 void
   509 PluginScriptableObjectParent::InitializeProxy()
   510 {
   511   NS_ASSERTION(mType == Proxy, "Bad type!");
   512   NS_ASSERTION(!mObject, "Calling Initialize more than once!");
   514   mInstance = static_cast<PluginInstanceParent*>(Manager());
   515   NS_ASSERTION(mInstance, "Null manager?!");
   517   NPObject* object = CreateProxyObject();
   518   NS_ASSERTION(object, "Failed to create object!");
   520   if (!mInstance->RegisterNPObjectForActor(object, this)) {
   521     NS_ERROR("Out of memory?");
   522   }
   524   mObject = object;
   525 }
   527 void
   528 PluginScriptableObjectParent::InitializeLocal(NPObject* aObject)
   529 {
   530   NS_ASSERTION(mType == LocalObject, "Bad type!");
   531   NS_ASSERTION(!(mInstance && mObject), "Calling Initialize more than once!");
   533   mInstance = static_cast<PluginInstanceParent*>(Manager());
   534   NS_ASSERTION(mInstance, "Null manager?!");
   536   mInstance->GetNPNIface()->retainobject(aObject);
   538   NS_ASSERTION(!mProtectCount, "Should be zero!");
   539   mProtectCount++;
   541   if (!mInstance->RegisterNPObjectForActor(aObject, this)) {
   542     NS_ERROR("Out of memory?");
   543   }
   545   mObject = aObject;
   546 }
   548 NPObject*
   549 PluginScriptableObjectParent::CreateProxyObject()
   550 {
   551   NS_ASSERTION(mInstance, "Must have an instance!");
   552   NS_ASSERTION(mType == Proxy, "Shouldn't call this for non-proxy object!");
   554   const NPNetscapeFuncs* npn = GetNetscapeFuncs(mInstance);
   556   NPObject* npobject = npn->createobject(mInstance->GetNPP(),
   557                                          const_cast<NPClass*>(GetClass()));
   558   NS_ASSERTION(npobject, "Failed to create object?!");
   559   NS_ASSERTION(npobject->_class == GetClass(), "Wrong kind of object!");
   560   NS_ASSERTION(npobject->referenceCount == 1, "Some kind of live object!");
   562   ParentNPObject* object = static_cast<ParentNPObject*>(npobject);
   563   NS_ASSERTION(!object->invalidated, "Bad object!");
   564   NS_ASSERTION(!object->parent, "Bad object!");
   566   // We don't want to have the actor own this object but rather let the object
   567   // own this actor. Set the reference count to 0 here so that when the object
   568   // dies we will send the destructor message to the child.
   569   object->referenceCount = 0;
   570   NS_LOG_RELEASE(object, 0, "BrowserNPObject");
   572   object->parent = const_cast<PluginScriptableObjectParent*>(this);
   573   return object;
   574 }
   576 bool
   577 PluginScriptableObjectParent::ResurrectProxyObject()
   578 {
   579   NS_ASSERTION(mInstance, "Must have an instance already!");
   580   NS_ASSERTION(!mObject, "Should not have an object already!");
   581   NS_ASSERTION(mType == Proxy, "Shouldn't call this for non-proxy object!");
   583   InitializeProxy();
   584   NS_ASSERTION(mObject, "Initialize failed!");
   586   if (!SendProtect()) {
   587     NS_WARNING("Failed to send message!");
   588     return false;
   589   }
   591   return true;
   592 }
   594 NPObject*
   595 PluginScriptableObjectParent::GetObject(bool aCanResurrect)
   596 {
   597   if (!mObject && aCanResurrect && !ResurrectProxyObject()) {
   598     NS_ERROR("Null object!");
   599     return nullptr;
   600   }
   601   return mObject;
   602 }
   604 void
   605 PluginScriptableObjectParent::Protect()
   606 {
   607   NS_ASSERTION(mObject, "No object!");
   608   NS_ASSERTION(mProtectCount >= 0, "Negative protect count?!");
   610   if (mType == LocalObject) {
   611     ++mProtectCount;
   612   }
   613 }
   615 void
   616 PluginScriptableObjectParent::Unprotect()
   617 {
   618   NS_ASSERTION(mObject, "No object!");
   619   NS_ASSERTION(mProtectCount >= 0, "Negative protect count?!");
   621   if (mType == LocalObject) {
   622     if (--mProtectCount == 0) {
   623       unused << PluginScriptableObjectParent::Send__delete__(this);
   624     }
   625   }
   626 }
   628 void
   629 PluginScriptableObjectParent::DropNPObject()
   630 {
   631   NS_ASSERTION(mObject, "Invalidated object!");
   632   NS_ASSERTION(mObject->_class == GetClass(), "Wrong type of object!");
   633   NS_ASSERTION(mType == Proxy, "Shouldn't call this for non-proxy object!");
   635   // We think we're about to be deleted, but we could be racing with the other
   636   // process.
   637   PluginInstanceParent* instance = GetInstance();
   638   NS_ASSERTION(instance, "Must have an instance!");
   640   instance->UnregisterNPObject(mObject);
   641   mObject = nullptr;
   643   unused << SendUnprotect();
   644 }
   646 bool
   647 PluginScriptableObjectParent::AnswerHasMethod(PPluginIdentifierParent* aId,
   648                                               bool* aHasMethod)
   649 {
   650   if (!mObject) {
   651     NS_WARNING("Calling AnswerHasMethod with an invalidated object!");
   652     *aHasMethod = false;
   653     return true;
   654   }
   656   NS_ASSERTION(mObject->_class != GetClass(), "Bad object type!");
   657   NS_ASSERTION(mType == LocalObject, "Bad type!");
   659   PluginInstanceParent* instance = GetInstance();
   660   if (!instance) {
   661     NS_ERROR("No instance?!");
   662     *aHasMethod = false;
   663     return true;
   664   }
   666   const NPNetscapeFuncs* npn = GetNetscapeFuncs(instance);
   667   if (!npn) {
   668     NS_ERROR("No netscape funcs?!");
   669     *aHasMethod = false;
   670     return true;
   671   }
   673   PluginIdentifierParent* id = static_cast<PluginIdentifierParent*>(aId);
   674   *aHasMethod = npn->hasmethod(instance->GetNPP(), mObject, id->ToNPIdentifier());
   675   return true;
   676 }
   678 bool
   679 PluginScriptableObjectParent::AnswerInvoke(PPluginIdentifierParent* aId,
   680                                            const InfallibleTArray<Variant>& aArgs,
   681                                            Variant* aResult,
   682                                            bool* aSuccess)
   683 {
   684   if (!mObject) {
   685     NS_WARNING("Calling AnswerInvoke with an invalidated object!");
   686     *aResult = void_t();
   687     *aSuccess = false;
   688     return true;
   689   }
   691   NS_ASSERTION(mObject->_class != GetClass(), "Bad object type!");
   692   NS_ASSERTION(mType == LocalObject, "Bad type!");
   694   PluginInstanceParent* instance = GetInstance();
   695   if (!instance) {
   696     NS_ERROR("No instance?!");
   697     *aResult = void_t();
   698     *aSuccess = false;
   699     return true;
   700   }
   702   const NPNetscapeFuncs* npn = GetNetscapeFuncs(instance);
   703   if (!npn) {
   704     NS_ERROR("No netscape funcs?!");
   705     *aResult = void_t();
   706     *aSuccess = false;
   707     return true;
   708   }
   710   AutoFallibleTArray<NPVariant, 10> convertedArgs;
   711   uint32_t argCount = aArgs.Length();
   713   if (!convertedArgs.SetLength(argCount)) {
   714     *aResult = void_t();
   715     *aSuccess = false;
   716     return true;
   717   }
   719   for (uint32_t index = 0; index < argCount; index++) {
   720     if (!ConvertToVariant(aArgs[index], convertedArgs[index], instance)) {
   721       // Don't leak things we've already converted!
   722       while (index-- > 0) {
   723         ReleaseVariant(convertedArgs[index], instance);
   724       }
   725       *aResult = void_t();
   726       *aSuccess = false;
   727       return true;
   728     }
   729   }
   731   PluginIdentifierParent* id = static_cast<PluginIdentifierParent*>(aId);
   732   NPVariant result;
   733   bool success = npn->invoke(instance->GetNPP(), mObject, id->ToNPIdentifier(),
   734                              convertedArgs.Elements(), argCount, &result);
   736   for (uint32_t index = 0; index < argCount; index++) {
   737     ReleaseVariant(convertedArgs[index], instance);
   738   }
   740   if (!success) {
   741     *aResult = void_t();
   742     *aSuccess = false;
   743     return true;
   744   }
   746   Variant convertedResult;
   747   success = ConvertToRemoteVariant(result, convertedResult, GetInstance());
   749   DeferNPVariantLastRelease(npn, &result);
   751   if (!success) {
   752     *aResult = void_t();
   753     *aSuccess = false;
   754     return true;
   755   }
   757   *aResult = convertedResult;
   758   *aSuccess = true;
   759   return true;
   760 }
   762 bool
   763 PluginScriptableObjectParent::AnswerInvokeDefault(const InfallibleTArray<Variant>& aArgs,
   764                                                   Variant* aResult,
   765                                                   bool* aSuccess)
   766 {
   767   if (!mObject) {
   768     NS_WARNING("Calling AnswerInvoke with an invalidated object!");
   769     *aResult = void_t();
   770     *aSuccess = false;
   771     return true;
   772   }
   774   NS_ASSERTION(mObject->_class != GetClass(), "Bad object type!");
   775   NS_ASSERTION(mType == LocalObject, "Bad type!");
   777   PluginInstanceParent* instance = GetInstance();
   778   if (!instance) {
   779     NS_ERROR("No instance?!");
   780     *aResult = void_t();
   781     *aSuccess = false;
   782     return true;
   783   }
   785   const NPNetscapeFuncs* npn = GetNetscapeFuncs(instance);
   786   if (!npn) {
   787     NS_ERROR("No netscape funcs?!");
   788     *aResult = void_t();
   789     *aSuccess = false;
   790     return true;
   791   }
   793   AutoFallibleTArray<NPVariant, 10> convertedArgs;
   794   uint32_t argCount = aArgs.Length();
   796   if (!convertedArgs.SetLength(argCount)) {
   797     *aResult = void_t();
   798     *aSuccess = false;
   799     return true;
   800   }
   802   for (uint32_t index = 0; index < argCount; index++) {
   803     if (!ConvertToVariant(aArgs[index], convertedArgs[index], instance)) {
   804       // Don't leak things we've already converted!
   805       while (index-- > 0) {
   806         ReleaseVariant(convertedArgs[index], instance);
   807       }
   808       *aResult = void_t();
   809       *aSuccess = false;
   810       return true;
   811     }
   812   }
   814   NPVariant result;
   815   bool success = npn->invokeDefault(instance->GetNPP(), mObject,
   816                                     convertedArgs.Elements(), argCount,
   817                                     &result);
   819   for (uint32_t index = 0; index < argCount; index++) {
   820     ReleaseVariant(convertedArgs[index], instance);
   821   }
   823   if (!success) {
   824     *aResult = void_t();
   825     *aSuccess = false;
   826     return true;
   827   }
   829   Variant convertedResult;
   830   success = ConvertToRemoteVariant(result, convertedResult, GetInstance());
   832   DeferNPVariantLastRelease(npn, &result);
   834   if (!success) {
   835     *aResult = void_t();
   836     *aSuccess = false;
   837     return true;
   838   }
   840   *aResult = convertedResult;
   841   *aSuccess = true;
   842   return true;
   843 }
   845 bool
   846 PluginScriptableObjectParent::AnswerHasProperty(PPluginIdentifierParent* aId,
   847                                                 bool* aHasProperty)
   848 {
   849   if (!mObject) {
   850     NS_WARNING("Calling AnswerHasProperty with an invalidated object!");
   851     *aHasProperty = false;
   852     return true;
   853   }
   855   NS_ASSERTION(mObject->_class != GetClass(), "Bad object type!");
   856   NS_ASSERTION(mType == LocalObject, "Bad type!");
   858   PluginInstanceParent* instance = GetInstance();
   859   if (!instance) {
   860     NS_ERROR("No instance?!");
   861     *aHasProperty = false;
   862     return true;
   863   }
   865   const NPNetscapeFuncs* npn = GetNetscapeFuncs(instance);
   866   if (!npn) {
   867     NS_ERROR("No netscape funcs?!");
   868     *aHasProperty = false;
   869     return true;
   870   }
   872   PluginIdentifierParent* id = static_cast<PluginIdentifierParent*>(aId);
   873   *aHasProperty = npn->hasproperty(instance->GetNPP(), mObject,
   874                                    id->ToNPIdentifier());
   875   return true;
   876 }
   878 bool
   879 PluginScriptableObjectParent::AnswerGetParentProperty(
   880                                                    PPluginIdentifierParent* aId,
   881                                                    Variant* aResult,
   882                                                    bool* aSuccess)
   883 {
   884   if (!mObject) {
   885     NS_WARNING("Calling AnswerGetProperty with an invalidated object!");
   886     *aResult = void_t();
   887     *aSuccess = false;
   888     return true;
   889   }
   891   NS_ASSERTION(mObject->_class != GetClass(), "Bad object type!");
   892   NS_ASSERTION(mType == LocalObject, "Bad type!");
   894   PluginInstanceParent* instance = GetInstance();
   895   if (!instance) {
   896     NS_ERROR("No instance?!");
   897     *aResult = void_t();
   898     *aSuccess = false;
   899     return true;
   900   }
   902   const NPNetscapeFuncs* npn = GetNetscapeFuncs(instance);
   903   if (!npn) {
   904     NS_ERROR("No netscape funcs?!");
   905     *aResult = void_t();
   906     *aSuccess = false;
   907     return true;
   908   }
   910   PluginIdentifierParent* id = static_cast<PluginIdentifierParent*>(aId);
   911   NPVariant result;
   912   if (!npn->getproperty(instance->GetNPP(), mObject, id->ToNPIdentifier(),
   913                         &result)) {
   914     *aResult = void_t();
   915     *aSuccess = false;
   916     return true;
   917   }
   919   Variant converted;
   920   if ((*aSuccess = ConvertToRemoteVariant(result, converted, instance))) {
   921     DeferNPVariantLastRelease(npn, &result);
   922     *aResult = converted;
   923   }
   924   else {
   925     *aResult = void_t();
   926   }
   928   return true;
   929 }
   931 bool
   932 PluginScriptableObjectParent::AnswerSetProperty(PPluginIdentifierParent* aId,
   933                                                 const Variant& aValue,
   934                                                 bool* aSuccess)
   935 {
   936   if (!mObject) {
   937     NS_WARNING("Calling AnswerSetProperty with an invalidated object!");
   938     *aSuccess = false;
   939     return true;
   940   }
   942   NS_ASSERTION(mObject->_class != GetClass(), "Bad object type!");
   943   NS_ASSERTION(mType == LocalObject, "Bad type!");
   945   PluginInstanceParent* instance = GetInstance();
   946   if (!instance) {
   947     NS_ERROR("No instance?!");
   948     *aSuccess = false;
   949     return true;
   950   }
   952   const NPNetscapeFuncs* npn = GetNetscapeFuncs(instance);
   953   if (!npn) {
   954     NS_ERROR("No netscape funcs?!");
   955     *aSuccess = false;
   956     return true;
   957   }
   959   NPVariant converted;
   960   if (!ConvertToVariant(aValue, converted, instance)) {
   961     *aSuccess = false;
   962     return true;
   963   }
   965   PluginIdentifierParent* id = static_cast<PluginIdentifierParent*>(aId);
   966   if ((*aSuccess = npn->setproperty(instance->GetNPP(), mObject,
   967                                     id->ToNPIdentifier(), &converted))) {
   968     ReleaseVariant(converted, instance);
   969   }
   970   return true;
   971 }
   973 bool
   974 PluginScriptableObjectParent::AnswerRemoveProperty(PPluginIdentifierParent* aId,
   975                                                    bool* aSuccess)
   976 {
   977   if (!mObject) {
   978     NS_WARNING("Calling AnswerRemoveProperty with an invalidated object!");
   979     *aSuccess = false;
   980     return true;
   981   }
   983   NS_ASSERTION(mObject->_class != GetClass(), "Bad object type!");
   984   NS_ASSERTION(mType == LocalObject, "Bad type!");
   986   PluginInstanceParent* instance = GetInstance();
   987   if (!instance) {
   988     NS_ERROR("No instance?!");
   989     *aSuccess = false;
   990     return true;
   991   }
   993   const NPNetscapeFuncs* npn = GetNetscapeFuncs(instance);
   994   if (!npn) {
   995     NS_ERROR("No netscape funcs?!");
   996     *aSuccess = false;
   997     return true;
   998   }
  1000   PluginIdentifierParent* id = static_cast<PluginIdentifierParent*>(aId);
  1001   *aSuccess = npn->removeproperty(instance->GetNPP(), mObject,
  1002                                   id->ToNPIdentifier());
  1003   return true;
  1006 bool
  1007 PluginScriptableObjectParent::AnswerEnumerate(InfallibleTArray<PPluginIdentifierParent*>* aProperties,
  1008                                               bool* aSuccess)
  1010   if (!mObject) {
  1011     NS_WARNING("Calling AnswerEnumerate with an invalidated object!");
  1012     *aSuccess = false;
  1013     return true;
  1016   NS_ASSERTION(mObject->_class != GetClass(), "Bad object type!");
  1017   NS_ASSERTION(mType == LocalObject, "Bad type!");
  1019   PluginInstanceParent* instance = GetInstance();
  1020   if (!instance) {
  1021     NS_ERROR("No instance?!");
  1022     *aSuccess = false;
  1023     return true;
  1026   const NPNetscapeFuncs* npn = GetNetscapeFuncs(instance);
  1027   if (!npn) {
  1028     NS_WARNING("No netscape funcs?!");
  1029     *aSuccess = false;
  1030     return true;
  1033   NPIdentifier* ids;
  1034   uint32_t idCount;
  1035   if (!npn->enumerate(instance->GetNPP(), mObject, &ids, &idCount)) {
  1036     *aSuccess = false;
  1037     return true;
  1040   aProperties->SetCapacity(idCount);
  1042   mozilla::AutoSafeJSContext cx;
  1043   for (uint32_t index = 0; index < idCount; index++) {
  1044     // Because of GC hazards, all identifiers returned from enumerate
  1045     // must be made permanent.
  1046     if (_identifierisstring(ids[index])) {
  1047       JS::Rooted<JSString*> str(cx, NPIdentifierToString(ids[index]));
  1048       if (!JS_StringHasBeenInterned(cx, str)) {
  1049         DebugOnly<JSString*> str2 = JS_InternJSString(cx, str);
  1050         NS_ASSERTION(str2 == str, "Interning a JS string which is currently an ID should return itself.");
  1053     PluginIdentifierParent* id =
  1054       instance->Module()->GetIdentifierForNPIdentifier(instance->GetNPP(), ids[index]);
  1055     aProperties->AppendElement(id);
  1056     NS_ASSERTION(!id->IsTemporary(), "Should only have permanent identifiers!");
  1059   npn->memfree(ids);
  1060   *aSuccess = true;
  1061   return true;
  1064 bool
  1065 PluginScriptableObjectParent::AnswerConstruct(const InfallibleTArray<Variant>& aArgs,
  1066                                               Variant* aResult,
  1067                                               bool* aSuccess)
  1069   if (!mObject) {
  1070     NS_WARNING("Calling AnswerConstruct with an invalidated object!");
  1071     *aResult = void_t();
  1072     *aSuccess = false;
  1073     return true;
  1076   NS_ASSERTION(mObject->_class != GetClass(), "Bad object type!");
  1077   NS_ASSERTION(mType == LocalObject, "Bad type!");
  1079   PluginInstanceParent* instance = GetInstance();
  1080   if (!instance) {
  1081     NS_ERROR("No instance?!");
  1082     *aResult = void_t();
  1083     *aSuccess = false;
  1084     return true;
  1087   const NPNetscapeFuncs* npn = GetNetscapeFuncs(instance);
  1088   if (!npn) {
  1089     NS_ERROR("No netscape funcs?!");
  1090     *aResult = void_t();
  1091     *aSuccess = false;
  1092     return true;
  1095   AutoFallibleTArray<NPVariant, 10> convertedArgs;
  1096   uint32_t argCount = aArgs.Length();
  1098   if (!convertedArgs.SetLength(argCount)) {
  1099     *aResult = void_t();
  1100     *aSuccess = false;
  1101     return true;
  1104   for (uint32_t index = 0; index < argCount; index++) {
  1105     if (!ConvertToVariant(aArgs[index], convertedArgs[index], instance)) {
  1106       // Don't leak things we've already converted!
  1107       while (index-- > 0) {
  1108         ReleaseVariant(convertedArgs[index], instance);
  1110       *aResult = void_t();
  1111       *aSuccess = false;
  1112       return true;
  1116   NPVariant result;
  1117   bool success = npn->construct(instance->GetNPP(), mObject,
  1118                                 convertedArgs.Elements(), argCount, &result);
  1120   for (uint32_t index = 0; index < argCount; index++) {
  1121     ReleaseVariant(convertedArgs[index], instance);
  1124   if (!success) {
  1125     *aResult = void_t();
  1126     *aSuccess = false;
  1127     return true;
  1130   Variant convertedResult;
  1131   success = ConvertToRemoteVariant(result, convertedResult, instance);
  1133   DeferNPVariantLastRelease(npn, &result);
  1135   if (!success) {
  1136     *aResult = void_t();
  1137     *aSuccess = false;
  1138     return true;
  1141   *aSuccess = true;
  1142   *aResult = convertedResult;
  1143   return true;
  1146 bool
  1147 PluginScriptableObjectParent::RecvProtect()
  1149   NS_ASSERTION(mObject->_class != GetClass(), "Bad object type!");
  1150   NS_ASSERTION(mType == LocalObject, "Bad type!");
  1152   Protect();
  1153   return true;
  1156 bool
  1157 PluginScriptableObjectParent::RecvUnprotect()
  1159   NS_ASSERTION(mObject->_class != GetClass(), "Bad object type!");
  1160   NS_ASSERTION(mType == LocalObject, "Bad type!");
  1162   Unprotect();
  1163   return true;
  1166 bool
  1167 PluginScriptableObjectParent::AnswerNPN_Evaluate(const nsCString& aScript,
  1168                                                  Variant* aResult,
  1169                                                  bool* aSuccess)
  1171   PluginInstanceParent* instance = GetInstance();
  1172   if (!instance) {
  1173     NS_ERROR("No instance?!");
  1174     *aResult = void_t();
  1175     *aSuccess = false;
  1176     return true;
  1179   const NPNetscapeFuncs* npn = GetNetscapeFuncs(instance);
  1180   if (!npn) {
  1181     NS_ERROR("No netscape funcs?!");
  1182     *aResult = void_t();
  1183     *aSuccess = false;
  1184     return true;
  1187   NPString script = { aScript.get(), aScript.Length() };
  1189   NPVariant result;
  1190   bool success = npn->evaluate(instance->GetNPP(), mObject, &script, &result);
  1191   if (!success) {
  1192     *aResult = void_t();
  1193     *aSuccess = false;
  1194     return true;
  1197   Variant convertedResult;
  1198   success = ConvertToRemoteVariant(result, convertedResult, instance);
  1200   DeferNPVariantLastRelease(npn, &result);
  1202   if (!success) {
  1203     *aResult = void_t();
  1204     *aSuccess = false;
  1205     return true;
  1208   *aSuccess = true;
  1209   *aResult = convertedResult;
  1210   return true;
  1213 bool
  1214 PluginScriptableObjectParent::GetPropertyHelper(NPIdentifier aName,
  1215                                                 bool* aHasProperty,
  1216                                                 bool* aHasMethod,
  1217                                                 NPVariant* aResult)
  1219   NS_ASSERTION(Type() == Proxy, "Bad type!");
  1221   ParentNPObject* object = static_cast<ParentNPObject*>(mObject);
  1222   if (object->invalidated) {
  1223     NS_WARNING("Calling method on an invalidated object!");
  1224     return false;
  1227   PluginIdentifierParent::StackIdentifier identifier(GetInstance(), aName);
  1228   if (!identifier) {
  1229     return false;
  1232   bool hasProperty, hasMethod, success;
  1233   Variant result;
  1234   if (!CallGetChildProperty(identifier, &hasProperty, &hasMethod, &result,
  1235                             &success)) {
  1236     return false;
  1239   if (!success) {
  1240     return false;
  1243   if (!ConvertToVariant(result, *aResult, GetInstance())) {
  1244     NS_WARNING("Failed to convert result!");
  1245     return false;
  1248   *aHasProperty = hasProperty;
  1249   *aHasMethod = hasMethod;
  1250   return true;

mercurial