LCOV - code coverage report
Current view: top level - js/xpconnect/src - XPCComponents.cpp (source / functions) Hit Total Coverage
Test: output.info Lines: 429 1540 27.9 %
Date: 2017-07-14 16:53:18 Functions: 90 282 31.9 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
       2             : /* vim: set ts=8 sts=4 et sw=4 tw=99: */
       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/. */
       6             : 
       7             : /* The "Components" xpcom objects for JavaScript. */
       8             : 
       9             : #include "xpcprivate.h"
      10             : #include "xpc_make_class.h"
      11             : #include "xpcIJSModuleLoader.h"
      12             : #include "XPCJSWeakReference.h"
      13             : #include "WrapperFactory.h"
      14             : #include "nsJSUtils.h"
      15             : #include "mozJSComponentLoader.h"
      16             : #include "nsContentUtils.h"
      17             : #include "nsCycleCollector.h"
      18             : #include "jsfriendapi.h"
      19             : #include "js/StructuredClone.h"
      20             : #include "mozilla/Attributes.h"
      21             : #include "mozilla/jsipc/CrossProcessObjectWrappers.h"
      22             : #include "mozilla/Preferences.h"
      23             : #include "nsJSEnvironment.h"
      24             : #include "mozilla/TimeStamp.h"
      25             : #include "mozilla/XPTInterfaceInfoManager.h"
      26             : #include "mozilla/dom/DOMException.h"
      27             : #include "mozilla/dom/DOMExceptionBinding.h"
      28             : #include "mozilla/dom/BindingUtils.h"
      29             : #include "mozilla/dom/StructuredCloneTags.h"
      30             : #include "mozilla/dom/WindowBinding.h"
      31             : #include "nsZipArchive.h"
      32             : #include "nsIDOMFileList.h"
      33             : #include "nsWindowMemoryReporter.h"
      34             : #include "nsDOMClassInfo.h"
      35             : #include "ShimInterfaceInfo.h"
      36             : #include "nsIAddonInterposition.h"
      37             : #include "nsIScriptError.h"
      38             : #include "nsISimpleEnumerator.h"
      39             : #include "nsPIDOMWindow.h"
      40             : #include "nsGlobalWindow.h"
      41             : #include "nsScriptError.h"
      42             : #include "GeckoProfiler.h"
      43             : 
      44             : using namespace mozilla;
      45             : using namespace JS;
      46             : using namespace js;
      47             : using namespace xpc;
      48             : using mozilla::dom::Exception;
      49             : 
      50             : /***************************************************************************/
      51             : // stuff used by all
      52             : 
      53             : nsresult
      54           0 : xpc::ThrowAndFail(nsresult errNum, JSContext* cx, bool* retval)
      55             : {
      56           0 :     XPCThrower::Throw(errNum, cx);
      57           0 :     *retval = false;
      58           0 :     return NS_OK;
      59             : }
      60             : 
      61             : static bool
      62          57 : JSValIsInterfaceOfType(JSContext* cx, HandleValue v, REFNSIID iid)
      63             : {
      64             : 
      65         114 :     nsCOMPtr<nsIXPConnectWrappedNative> wn;
      66         114 :     nsCOMPtr<nsISupports> iface;
      67             : 
      68          57 :     if (v.isPrimitive())
      69           0 :         return false;
      70             : 
      71          57 :     nsXPConnect* xpc = nsXPConnect::XPConnect();
      72         114 :     RootedObject obj(cx, &v.toObject());
      73         399 :     return NS_SUCCEEDED(xpc->GetWrappedNativeOfJSObject(cx, obj, getter_AddRefs(wn))) && wn &&
      74         342 :         NS_SUCCEEDED(wn->Native()->QueryInterface(iid, getter_AddRefs(iface))) && iface;
      75             : }
      76             : 
      77             : char*
      78           0 : xpc::CloneAllAccess()
      79             : {
      80             :     static const char allAccess[] = "AllAccess";
      81           0 :     return (char*)nsMemory::Clone(allAccess, sizeof(allAccess));
      82             : }
      83             : 
      84             : char*
      85           0 : xpc::CheckAccessList(const char16_t* wideName, const char* const list[])
      86             : {
      87           0 :     nsAutoCString asciiName;
      88           0 :     CopyUTF16toUTF8(nsDependentString(wideName), asciiName);
      89             : 
      90           0 :     for (const char* const* p = list; *p; p++)
      91           0 :         if (!strcmp(*p, asciiName.get()))
      92           0 :             return CloneAllAccess();
      93             : 
      94           0 :     return nullptr;
      95             : }
      96             : 
      97             : /***************************************************************************/
      98             : /***************************************************************************/
      99             : /***************************************************************************/
     100             : 
     101             : 
     102             : class nsXPCComponents_Interfaces final :
     103             :             public nsIXPCComponents_Interfaces,
     104             :             public nsIXPCScriptable,
     105             :             public nsIClassInfo
     106             : {
     107             : public:
     108             :     // all the interface method declarations...
     109             :     NS_DECL_ISUPPORTS
     110             :     NS_DECL_NSIXPCCOMPONENTS_INTERFACES
     111             :     NS_DECL_NSIXPCSCRIPTABLE
     112             :     NS_DECL_NSICLASSINFO
     113             : 
     114             : public:
     115             :     nsXPCComponents_Interfaces();
     116             : 
     117             : private:
     118             :     virtual ~nsXPCComponents_Interfaces();
     119             : 
     120             :     nsCOMArray<nsIInterfaceInfo> mInterfaces;
     121             : };
     122             : 
     123             : NS_IMETHODIMP
     124         237 : nsXPCComponents_Interfaces::GetInterfaces(uint32_t* aCount, nsIID * **aArray)
     125             : {
     126         237 :     const uint32_t count = 2;
     127         237 :     *aCount = count;
     128             :     nsIID** array;
     129         237 :     *aArray = array = static_cast<nsIID**>(moz_xmalloc(count * sizeof(nsIID*)));
     130         237 :     if (!array)
     131           0 :         return NS_ERROR_OUT_OF_MEMORY;
     132             : 
     133         237 :     uint32_t index = 0;
     134             :     nsIID* clone;
     135             : #define PUSH_IID(id)                                                          \
     136             :     clone = static_cast<nsIID*>(nsMemory::Clone(&NS_GET_IID( id ),           \
     137             :                                                  sizeof(nsIID)));             \
     138             :     if (!clone)                                                               \
     139             :         goto oom;                                                             \
     140             :     array[index++] = clone;
     141             : 
     142         237 :     PUSH_IID(nsIXPCComponents_Interfaces)
     143         237 :     PUSH_IID(nsIXPCScriptable)
     144             : #undef PUSH_IID
     145             : 
     146         237 :     return NS_OK;
     147             : oom:
     148           0 :     while (index)
     149           0 :         free(array[--index]);
     150           0 :     free(array);
     151           0 :     *aArray = nullptr;
     152           0 :     return NS_ERROR_OUT_OF_MEMORY;
     153             : }
     154             : 
     155             : NS_IMETHODIMP
     156         238 : nsXPCComponents_Interfaces::GetScriptableHelper(nsIXPCScriptable** retval)
     157             : {
     158         238 :     *retval = nullptr;
     159         238 :     return NS_OK;
     160             : }
     161             : 
     162             : NS_IMETHODIMP
     163           0 : nsXPCComponents_Interfaces::GetContractID(char * *aContractID)
     164             : {
     165           0 :     *aContractID = nullptr;
     166           0 :     return NS_ERROR_NOT_AVAILABLE;
     167             : }
     168             : 
     169             : NS_IMETHODIMP
     170           0 : nsXPCComponents_Interfaces::GetClassDescription(char * *aClassDescription)
     171             : {
     172             :     static const char classDescription[] = "XPCComponents_Interfaces";
     173           0 :     *aClassDescription = (char*)nsMemory::Clone(classDescription, sizeof(classDescription));
     174           0 :     return *aClassDescription ? NS_OK : NS_ERROR_OUT_OF_MEMORY;
     175             : }
     176             : 
     177             : NS_IMETHODIMP
     178           0 : nsXPCComponents_Interfaces::GetClassID(nsCID * *aClassID)
     179             : {
     180           0 :     *aClassID = nullptr;
     181           0 :     return NS_OK;
     182             : }
     183             : 
     184             : NS_IMETHODIMP
     185         238 : nsXPCComponents_Interfaces::GetFlags(uint32_t* aFlags)
     186             : {
     187             :     // Mark ourselves as a DOM object so that instances may be created in
     188             :     // unprivileged scopes.
     189         238 :     *aFlags = nsIClassInfo::DOM_OBJECT;
     190         238 :     return NS_OK;
     191             : }
     192             : 
     193             : NS_IMETHODIMP
     194           0 : nsXPCComponents_Interfaces::GetClassIDNoAlloc(nsCID* aClassIDNoAlloc)
     195             : {
     196           0 :     return NS_ERROR_NOT_AVAILABLE;
     197             : }
     198             : 
     199         237 : nsXPCComponents_Interfaces::nsXPCComponents_Interfaces()
     200             : {
     201         237 : }
     202             : 
     203           0 : nsXPCComponents_Interfaces::~nsXPCComponents_Interfaces()
     204             : {
     205             :     // empty
     206           0 : }
     207             : 
     208             : 
     209        5585 : NS_INTERFACE_MAP_BEGIN(nsXPCComponents_Interfaces)
     210        5585 :   NS_INTERFACE_MAP_ENTRY(nsIXPCComponents_Interfaces)
     211        5338 :   NS_INTERFACE_MAP_ENTRY(nsIXPCScriptable)
     212        2361 :   NS_INTERFACE_MAP_ENTRY(nsIClassInfo)
     213        1885 :   NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIXPCComponents_Interfaces)
     214        1416 : NS_INTERFACE_MAP_END
     215             : 
     216        7847 : NS_IMPL_ADDREF(nsXPCComponents_Interfaces)
     217        6658 : NS_IMPL_RELEASE(nsXPCComponents_Interfaces)
     218             : 
     219             : // The nsIXPCScriptable map declaration that will generate stubs for us...
     220             : #define XPC_MAP_CLASSNAME         nsXPCComponents_Interfaces
     221             : #define XPC_MAP_QUOTED_CLASSNAME "nsXPCComponents_Interfaces"
     222             : #define XPC_MAP_FLAGS (XPC_SCRIPTABLE_WANT_RESOLVE | \
     223             :                        XPC_SCRIPTABLE_WANT_NEWENUMERATE | \
     224             :                        XPC_SCRIPTABLE_ALLOW_PROP_MODS_DURING_RESOLVE)
     225             : #include "xpc_map_end.h" /* This will #undef the above */
     226             : 
     227             : 
     228             : NS_IMETHODIMP
     229           0 : nsXPCComponents_Interfaces::NewEnumerate(nsIXPConnectWrappedNative* wrapper,
     230             :                                          JSContext* cx, JSObject* obj,
     231             :                                          JS::AutoIdVector& properties,
     232             :                                          bool* _retval)
     233             : {
     234             : 
     235             :     // Lazily init the list of interfaces when someone tries to
     236             :     // enumerate them.
     237           0 :     if (mInterfaces.IsEmpty()) {
     238             :         XPTInterfaceInfoManager::GetSingleton()->
     239           0 :             GetScriptableInterfaces(mInterfaces);
     240             :     }
     241             : 
     242           0 :     if (!properties.reserve(mInterfaces.Length())) {
     243           0 :         *_retval = false;
     244           0 :         return NS_OK;
     245             :     }
     246             : 
     247           0 :     for (uint32_t index = 0; index < mInterfaces.Length(); index++) {
     248           0 :         nsIInterfaceInfo* interface = mInterfaces.SafeElementAt(index);
     249           0 :         if (!interface)
     250           0 :             continue;
     251             : 
     252             :         const char* name;
     253           0 :         if (NS_SUCCEEDED(interface->GetNameShared(&name)) && name) {
     254           0 :             RootedString idstr(cx, JS_NewStringCopyZ(cx, name));
     255           0 :             if (!idstr) {
     256           0 :                 *_retval = false;
     257           0 :                 return NS_OK;
     258             :             }
     259             : 
     260           0 :             RootedId id(cx);
     261           0 :             if (!JS_StringToId(cx, idstr, &id)) {
     262           0 :                 *_retval = false;
     263           0 :                 return NS_OK;
     264             :             }
     265             : 
     266           0 :             properties.infallibleAppend(id);
     267             :         }
     268             :     }
     269             : 
     270           0 :     return NS_OK;
     271             : }
     272             : 
     273             : NS_IMETHODIMP
     274         754 : nsXPCComponents_Interfaces::Resolve(nsIXPConnectWrappedNative* wrapper,
     275             :                                     JSContext* cx, JSObject* objArg,
     276             :                                     jsid idArg, bool* resolvedp,
     277             :                                     bool* _retval)
     278             : {
     279        1508 :     RootedObject obj(cx, objArg);
     280        1508 :     RootedId id(cx, idArg);
     281             : 
     282         754 :     if (!JSID_IS_STRING(id))
     283           0 :         return NS_OK;
     284             : 
     285        1508 :     JSAutoByteString name;
     286        1508 :     RootedString str(cx, JSID_TO_STRING(id));
     287             : 
     288             :     // we only allow interfaces by name here
     289         754 :     if (name.encodeLatin1(cx, str) && name.ptr()[0] != '{') {
     290             :         nsCOMPtr<nsIInterfaceInfo> info =
     291        1505 :             ShimInterfaceInfo::MaybeConstruct(name.ptr(), cx);
     292         754 :         if (!info) {
     293             :             XPTInterfaceInfoManager::GetSingleton()->
     294         744 :                 GetInfoForName(name.ptr(), getter_AddRefs(info));
     295             :         }
     296         754 :         if (!info)
     297           3 :             return NS_OK;
     298             : 
     299        1502 :         nsCOMPtr<nsIJSIID> nsid = nsJSIID::NewID(info);
     300             : 
     301         751 :         if (nsid) {
     302         751 :             nsXPConnect* xpc = nsXPConnect::XPConnect();
     303        1502 :             RootedObject idobj(cx);
     304         751 :             if (NS_SUCCEEDED(xpc->WrapNative(cx, obj,
     305             :                                              static_cast<nsIJSIID*>(nsid),
     306             :                                              NS_GET_IID(nsIJSIID),
     307             :                                              idobj.address()))) {
     308         751 :                 if (idobj) {
     309         751 :                     *resolvedp = true;
     310         751 :                     *_retval = JS_DefinePropertyById(cx, obj, id, idobj,
     311             :                                                      JSPROP_ENUMERATE |
     312             :                                                      JSPROP_READONLY |
     313             :                                                      JSPROP_PERMANENT |
     314             :                                                      JSPROP_RESOLVING);
     315             :                 }
     316             :             }
     317             :         }
     318             :     }
     319         751 :     return NS_OK;
     320             : }
     321             : 
     322             : /***************************************************************************/
     323             : /***************************************************************************/
     324             : /***************************************************************************/
     325             : 
     326             : class nsXPCComponents_InterfacesByID final :
     327             :             public nsIXPCComponents_InterfacesByID,
     328             :             public nsIXPCScriptable,
     329             :             public nsIClassInfo
     330             : {
     331             : public:
     332             :     // all the interface method declarations...
     333             :     NS_DECL_ISUPPORTS
     334             :     NS_DECL_NSIXPCCOMPONENTS_INTERFACESBYID
     335             :     NS_DECL_NSIXPCSCRIPTABLE
     336             :     NS_DECL_NSICLASSINFO
     337             : 
     338             : public:
     339             :     nsXPCComponents_InterfacesByID();
     340             : 
     341             : private:
     342             :     virtual ~nsXPCComponents_InterfacesByID();
     343             : 
     344             :     nsCOMArray<nsIInterfaceInfo> mInterfaces;
     345             : };
     346             : 
     347             : /***************************************************************************/
     348             : NS_IMETHODIMP
     349           0 : nsXPCComponents_InterfacesByID::GetInterfaces(uint32_t* aCount, nsIID * **aArray)
     350             : {
     351           0 :     const uint32_t count = 2;
     352           0 :     *aCount = count;
     353             :     nsIID** array;
     354           0 :     *aArray = array = static_cast<nsIID**>(moz_xmalloc(count * sizeof(nsIID*)));
     355           0 :     if (!array)
     356           0 :         return NS_ERROR_OUT_OF_MEMORY;
     357             : 
     358           0 :     uint32_t index = 0;
     359             :     nsIID* clone;
     360             : #define PUSH_IID(id)                                                          \
     361             :     clone = static_cast<nsIID*>(nsMemory::Clone(&NS_GET_IID( id ),           \
     362             :                                                  sizeof(nsIID)));             \
     363             :     if (!clone)                                                               \
     364             :         goto oom;                                                             \
     365             :     array[index++] = clone;
     366             : 
     367           0 :     PUSH_IID(nsIXPCComponents_InterfacesByID)
     368           0 :     PUSH_IID(nsIXPCScriptable)
     369             : #undef PUSH_IID
     370             : 
     371           0 :     return NS_OK;
     372             : oom:
     373           0 :     while (index)
     374           0 :         free(array[--index]);
     375           0 :     free(array);
     376           0 :     *aArray = nullptr;
     377           0 :     return NS_ERROR_OUT_OF_MEMORY;
     378             : }
     379             : 
     380             : NS_IMETHODIMP
     381           0 : nsXPCComponents_InterfacesByID::GetScriptableHelper(nsIXPCScriptable** retval)
     382             : {
     383           0 :     *retval = nullptr;
     384           0 :     return NS_OK;
     385             : }
     386             : 
     387             : NS_IMETHODIMP
     388           0 : nsXPCComponents_InterfacesByID::GetContractID(char * *aContractID)
     389             : {
     390           0 :     *aContractID = nullptr;
     391           0 :     return NS_ERROR_NOT_AVAILABLE;
     392             : }
     393             : 
     394             : NS_IMETHODIMP
     395           0 : nsXPCComponents_InterfacesByID::GetClassDescription(char * *aClassDescription)
     396             : {
     397             :     static const char classDescription[] = "XPCComponents_InterfacesByID";
     398           0 :     *aClassDescription = (char*)nsMemory::Clone(classDescription, sizeof(classDescription));
     399           0 :     return *aClassDescription ? NS_OK : NS_ERROR_OUT_OF_MEMORY;
     400             : }
     401             : 
     402             : NS_IMETHODIMP
     403           0 : nsXPCComponents_InterfacesByID::GetClassID(nsCID * *aClassID)
     404             : {
     405           0 :     *aClassID = nullptr;
     406           0 :     return NS_OK;
     407             : }
     408             : 
     409             : NS_IMETHODIMP
     410           0 : nsXPCComponents_InterfacesByID::GetFlags(uint32_t* aFlags)
     411             : {
     412             :     // Mark ourselves as a DOM object so that instances may be created in
     413             :     // unprivileged scopes.
     414           0 :     *aFlags = nsIClassInfo::DOM_OBJECT;
     415           0 :     return NS_OK;
     416             : }
     417             : 
     418             : NS_IMETHODIMP
     419           0 : nsXPCComponents_InterfacesByID::GetClassIDNoAlloc(nsCID* aClassIDNoAlloc)
     420             : {
     421           0 :     return NS_ERROR_NOT_AVAILABLE;
     422             : }
     423             : 
     424           0 : nsXPCComponents_InterfacesByID::nsXPCComponents_InterfacesByID()
     425             : {
     426           0 : }
     427             : 
     428           0 : nsXPCComponents_InterfacesByID::~nsXPCComponents_InterfacesByID()
     429             : {
     430             :     // empty
     431           0 : }
     432             : 
     433           0 : NS_INTERFACE_MAP_BEGIN(nsXPCComponents_InterfacesByID)
     434           0 :   NS_INTERFACE_MAP_ENTRY(nsIXPCComponents_InterfacesByID)
     435           0 :   NS_INTERFACE_MAP_ENTRY(nsIXPCScriptable)
     436           0 :   NS_INTERFACE_MAP_ENTRY(nsIClassInfo)
     437           0 :   NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIXPCComponents_InterfacesByID)
     438           0 : NS_INTERFACE_MAP_END
     439             : 
     440           0 : NS_IMPL_ADDREF(nsXPCComponents_InterfacesByID)
     441           0 : NS_IMPL_RELEASE(nsXPCComponents_InterfacesByID)
     442             : 
     443             : // The nsIXPCScriptable map declaration that will generate stubs for us...
     444             : #define XPC_MAP_CLASSNAME         nsXPCComponents_InterfacesByID
     445             : #define XPC_MAP_QUOTED_CLASSNAME "nsXPCComponents_InterfacesByID"
     446             : #define XPC_MAP_FLAGS (XPC_SCRIPTABLE_WANT_RESOLVE | \
     447             :                        XPC_SCRIPTABLE_WANT_NEWENUMERATE | \
     448             :                        XPC_SCRIPTABLE_ALLOW_PROP_MODS_DURING_RESOLVE)
     449             : #include "xpc_map_end.h" /* This will #undef the above */
     450             : 
     451             : NS_IMETHODIMP
     452           0 : nsXPCComponents_InterfacesByID::NewEnumerate(nsIXPConnectWrappedNative* wrapper,
     453             :                                              JSContext* cx, JSObject* obj,
     454             :                                              JS::AutoIdVector& properties,
     455             :                                              bool* _retval)
     456             : {
     457             : 
     458           0 :     if (mInterfaces.IsEmpty()) {
     459             :         XPTInterfaceInfoManager::GetSingleton()->
     460           0 :             GetScriptableInterfaces(mInterfaces);
     461             :     }
     462             : 
     463           0 :     if (!properties.reserve(mInterfaces.Length())) {
     464           0 :         *_retval = false;
     465           0 :         return NS_OK;
     466             :     }
     467             : 
     468           0 :     for (uint32_t index = 0; index < mInterfaces.Length(); index++) {
     469           0 :         nsIInterfaceInfo* interface = mInterfaces.SafeElementAt(index);
     470           0 :         if (!interface)
     471           0 :             continue;
     472             : 
     473             :         nsIID const* iid;
     474           0 :         if (NS_SUCCEEDED(interface->GetIIDShared(&iid))) {
     475             :             char idstr[NSID_LENGTH];
     476           0 :             iid->ToProvidedString(idstr);
     477           0 :             RootedString jsstr(cx, JS_NewStringCopyZ(cx, idstr));
     478           0 :             if (!jsstr) {
     479           0 :                 *_retval = false;
     480           0 :                 return NS_OK;
     481             :             }
     482             : 
     483           0 :             RootedId id(cx);
     484           0 :             if (!JS_StringToId(cx, jsstr, &id)) {
     485           0 :                 *_retval = false;
     486           0 :                 return NS_OK;
     487             :             }
     488             : 
     489           0 :             properties.infallibleAppend(id);
     490             :         }
     491             :     }
     492             : 
     493           0 :     return NS_OK;
     494             : }
     495             : 
     496             : NS_IMETHODIMP
     497           0 : nsXPCComponents_InterfacesByID::Resolve(nsIXPConnectWrappedNative* wrapper,
     498             :                                         JSContext* cx, JSObject* objArg,
     499             :                                         jsid idArg, bool* resolvedp,
     500             :                                         bool* _retval)
     501             : {
     502           0 :     RootedObject obj(cx, objArg);
     503           0 :     RootedId id(cx, idArg);
     504             : 
     505           0 :     if (!JSID_IS_STRING(id))
     506           0 :         return NS_OK;
     507             : 
     508           0 :     RootedString str(cx, JSID_TO_STRING(id));
     509           0 :     if (38 != JS_GetStringLength(str))
     510           0 :         return NS_OK;
     511             : 
     512           0 :     JSAutoByteString utf8str;
     513           0 :     if (utf8str.encodeUtf8(cx, str)) {
     514             :         nsID iid;
     515           0 :         if (!iid.Parse(utf8str.ptr()))
     516           0 :             return NS_OK;
     517             : 
     518           0 :         nsCOMPtr<nsIInterfaceInfo> info;
     519             :         XPTInterfaceInfoManager::GetSingleton()->
     520           0 :             GetInfoForIID(&iid, getter_AddRefs(info));
     521           0 :         if (!info)
     522           0 :             return NS_OK;
     523             : 
     524           0 :         nsCOMPtr<nsIJSIID> nsid = nsJSIID::NewID(info);
     525             : 
     526           0 :         if (!nsid)
     527           0 :             return NS_ERROR_OUT_OF_MEMORY;
     528             : 
     529           0 :         nsXPConnect* xpc = nsXPConnect::XPConnect();
     530           0 :         RootedObject idobj(cx);
     531           0 :         if (NS_SUCCEEDED(xpc->WrapNative(cx, obj,
     532             :                                          static_cast<nsIJSIID*>(nsid),
     533             :                                          NS_GET_IID(nsIJSIID),
     534             :                                          idobj.address()))) {
     535           0 :             if (idobj) {
     536           0 :                 *resolvedp = true;
     537           0 :                 *_retval =
     538           0 :                     JS_DefinePropertyById(cx, obj, id, idobj,
     539             :                                           JSPROP_ENUMERATE |
     540             :                                           JSPROP_READONLY |
     541             :                                           JSPROP_PERMANENT |
     542             :                                           JSPROP_RESOLVING);
     543             :             }
     544             :         }
     545             :     }
     546           0 :     return NS_OK;
     547             : }
     548             : 
     549             : /***************************************************************************/
     550             : /***************************************************************************/
     551             : /***************************************************************************/
     552             : 
     553             : 
     554             : 
     555             : class nsXPCComponents_Classes final :
     556             :   public nsIXPCComponents_Classes,
     557             :   public nsIXPCScriptable,
     558             :   public nsIClassInfo
     559             : {
     560             : public:
     561             :     // all the interface method declarations...
     562             :     NS_DECL_ISUPPORTS
     563             :     NS_DECL_NSIXPCCOMPONENTS_CLASSES
     564             :     NS_DECL_NSIXPCSCRIPTABLE
     565             :     NS_DECL_NSICLASSINFO
     566             : 
     567             : public:
     568             :     nsXPCComponents_Classes();
     569             : 
     570             : private:
     571             :     virtual ~nsXPCComponents_Classes();
     572             : };
     573             : 
     574             : /***************************************************************************/
     575             : NS_IMETHODIMP
     576         214 : nsXPCComponents_Classes::GetInterfaces(uint32_t* aCount, nsIID * **aArray)
     577             : {
     578         214 :     const uint32_t count = 2;
     579         214 :     *aCount = count;
     580             :     nsIID** array;
     581         214 :     *aArray = array = static_cast<nsIID**>(moz_xmalloc(count * sizeof(nsIID*)));
     582         214 :     if (!array)
     583           0 :         return NS_ERROR_OUT_OF_MEMORY;
     584             : 
     585         214 :     uint32_t index = 0;
     586             :     nsIID* clone;
     587             : #define PUSH_IID(id)                                                          \
     588             :     clone = static_cast<nsIID*>(nsMemory::Clone(&NS_GET_IID( id ),           \
     589             :                                                  sizeof(nsIID)));             \
     590             :     if (!clone)                                                               \
     591             :         goto oom;                                                             \
     592             :     array[index++] = clone;
     593             : 
     594         214 :     PUSH_IID(nsIXPCComponents_Classes)
     595         214 :     PUSH_IID(nsIXPCScriptable)
     596             : #undef PUSH_IID
     597             : 
     598         214 :     return NS_OK;
     599             : oom:
     600           0 :     while (index)
     601           0 :         free(array[--index]);
     602           0 :     free(array);
     603           0 :     *aArray = nullptr;
     604           0 :     return NS_ERROR_OUT_OF_MEMORY;
     605             : }
     606             : 
     607             : NS_IMETHODIMP
     608         215 : nsXPCComponents_Classes::GetScriptableHelper(nsIXPCScriptable** retval)
     609             : {
     610         215 :     *retval = nullptr;
     611         215 :     return NS_OK;
     612             : }
     613             : 
     614             : NS_IMETHODIMP
     615           0 : nsXPCComponents_Classes::GetContractID(char * *aContractID)
     616             : {
     617           0 :     *aContractID = nullptr;
     618           0 :     return NS_ERROR_NOT_AVAILABLE;
     619             : }
     620             : 
     621             : NS_IMETHODIMP
     622           0 : nsXPCComponents_Classes::GetClassDescription(char * *aClassDescription)
     623             : {
     624             :     static const char classDescription[] = "XPCComponents_Classes";
     625           0 :     *aClassDescription = (char*)nsMemory::Clone(classDescription, sizeof(classDescription));
     626           0 :     return *aClassDescription ? NS_OK : NS_ERROR_OUT_OF_MEMORY;
     627             : }
     628             : 
     629             : NS_IMETHODIMP
     630           0 : nsXPCComponents_Classes::GetClassID(nsCID * *aClassID)
     631             : {
     632           0 :     *aClassID = nullptr;
     633           0 :     return NS_OK;
     634             : }
     635             : 
     636             : NS_IMETHODIMP
     637         215 : nsXPCComponents_Classes::GetFlags(uint32_t* aFlags)
     638             : {
     639         215 :     *aFlags = 0;
     640         215 :     return NS_OK;
     641             : }
     642             : 
     643             : NS_IMETHODIMP
     644           0 : nsXPCComponents_Classes::GetClassIDNoAlloc(nsCID* aClassIDNoAlloc)
     645             : {
     646           0 :     return NS_ERROR_NOT_AVAILABLE;
     647             : }
     648             : 
     649         214 : nsXPCComponents_Classes::nsXPCComponents_Classes()
     650             : {
     651         214 : }
     652             : 
     653           0 : nsXPCComponents_Classes::~nsXPCComponents_Classes()
     654             : {
     655             :     // empty
     656           0 : }
     657             : 
     658        3189 : NS_INTERFACE_MAP_BEGIN(nsXPCComponents_Classes)
     659        3189 :   NS_INTERFACE_MAP_ENTRY(nsIXPCComponents_Classes)
     660        2965 :   NS_INTERFACE_MAP_ENTRY(nsIXPCScriptable)
     661        1712 :   NS_INTERFACE_MAP_ENTRY(nsIClassInfo)
     662        1282 :   NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIXPCComponents_Classes)
     663         998 : NS_INTERFACE_MAP_END
     664             : 
     665        3939 : NS_IMPL_ADDREF(nsXPCComponents_Classes)
     666        2865 : NS_IMPL_RELEASE(nsXPCComponents_Classes)
     667             : 
     668             : // The nsIXPCScriptable map declaration that will generate stubs for us...
     669             : #define XPC_MAP_CLASSNAME         nsXPCComponents_Classes
     670             : #define XPC_MAP_QUOTED_CLASSNAME "nsXPCComponents_Classes"
     671             : #define XPC_MAP_FLAGS (XPC_SCRIPTABLE_WANT_RESOLVE | \
     672             :                        XPC_SCRIPTABLE_WANT_NEWENUMERATE | \
     673             :                        XPC_SCRIPTABLE_ALLOW_PROP_MODS_DURING_RESOLVE)
     674             : #include "xpc_map_end.h" /* This will #undef the above */
     675             : 
     676             : NS_IMETHODIMP
     677           3 : nsXPCComponents_Classes::NewEnumerate(nsIXPConnectWrappedNative* wrapper,
     678             :                                       JSContext* cx, JSObject* obj,
     679             :                                       JS::AutoIdVector& properties,
     680             :                                       bool* _retval)
     681             : {
     682           6 :     nsCOMPtr<nsIComponentRegistrar> compMgr;
     683           3 :     if (NS_FAILED(NS_GetComponentRegistrar(getter_AddRefs(compMgr))) || !compMgr)
     684           0 :         return NS_ERROR_UNEXPECTED;
     685             : 
     686           6 :     nsCOMPtr<nsISimpleEnumerator> e;
     687           3 :     if (NS_FAILED(compMgr->EnumerateContractIDs(getter_AddRefs(e))) || !e)
     688           0 :         return NS_ERROR_UNEXPECTED;
     689             : 
     690             :     bool hasMore;
     691           6 :     nsCOMPtr<nsISupports> isup;
     692       16185 :     while(NS_SUCCEEDED(e->HasMoreElements(&hasMore)) && hasMore &&
     693       16179 :           NS_SUCCEEDED(e->GetNext(getter_AddRefs(isup))) && isup) {
     694        4620 :         nsCOMPtr<nsISupportsCString> holder(do_QueryInterface(isup));
     695        2310 :         if (!holder)
     696           0 :             continue;
     697             : 
     698        4620 :         nsAutoCString name;
     699        2310 :         if (NS_SUCCEEDED(holder->GetData(name))) {
     700        4620 :             RootedString idstr(cx, JS_NewStringCopyN(cx, name.get(), name.Length()));
     701        2310 :             if (!idstr) {
     702           0 :                 *_retval = false;
     703           0 :                 return NS_OK;
     704             :             }
     705             : 
     706        4620 :             RootedId id(cx);
     707        2310 :             if (!JS_StringToId(cx, idstr, &id)) {
     708           0 :                 *_retval = false;
     709           0 :                 return NS_OK;
     710             :             }
     711             : 
     712        2310 :             if (!properties.append(id)) {
     713           0 :                 *_retval = false;
     714           0 :                 return NS_OK;
     715             :             }
     716             :         }
     717             :     }
     718             : 
     719           3 :     return NS_OK;
     720             : }
     721             : 
     722             : NS_IMETHODIMP
     723         200 : nsXPCComponents_Classes::Resolve(nsIXPConnectWrappedNative* wrapper,
     724             :                                  JSContext* cx, JSObject* objArg,
     725             :                                  jsid idArg, bool* resolvedp,
     726             :                                  bool* _retval)
     727             : 
     728             : {
     729         400 :     RootedId id(cx, idArg);
     730         400 :     RootedObject obj(cx, objArg);
     731             : 
     732         400 :     JSAutoByteString name;
     733         600 :     if (JSID_IS_STRING(id) &&
     734         400 :         name.encodeLatin1(cx, JSID_TO_STRING(id)) &&
     735         200 :         name.ptr()[0] != '{') { // we only allow contractids here
     736         400 :         nsCOMPtr<nsIJSCID> nsid = nsJSCID::NewID(name.ptr());
     737         200 :         if (nsid) {
     738         197 :             nsXPConnect* xpc = nsXPConnect::XPConnect();
     739         394 :             RootedObject idobj(cx);
     740         197 :             if (NS_SUCCEEDED(xpc->WrapNative(cx, obj,
     741             :                                              static_cast<nsIJSCID*>(nsid),
     742             :                                              NS_GET_IID(nsIJSCID),
     743             :                                              idobj.address()))) {
     744         197 :                 if (idobj) {
     745         197 :                     *resolvedp = true;
     746         197 :                     *_retval = JS_DefinePropertyById(cx, obj, id, idobj,
     747             :                                                      JSPROP_ENUMERATE |
     748             :                                                      JSPROP_READONLY |
     749             :                                                      JSPROP_PERMANENT |
     750             :                                                      JSPROP_RESOLVING);
     751             :                 }
     752             :             }
     753             :         }
     754             :     }
     755         400 :     return NS_OK;
     756             : }
     757             : 
     758             : /***************************************************************************/
     759             : /***************************************************************************/
     760             : /***************************************************************************/
     761             : 
     762             : class nsXPCComponents_ClassesByID final :
     763             :   public nsIXPCComponents_ClassesByID,
     764             :   public nsIXPCScriptable,
     765             :   public nsIClassInfo
     766             : {
     767             : public:
     768             :     // all the interface method declarations...
     769             :     NS_DECL_ISUPPORTS
     770             :     NS_DECL_NSIXPCCOMPONENTS_CLASSESBYID
     771             :     NS_DECL_NSIXPCSCRIPTABLE
     772             :     NS_DECL_NSICLASSINFO
     773             : 
     774             : public:
     775             :     nsXPCComponents_ClassesByID();
     776             : 
     777             : private:
     778             :     virtual ~nsXPCComponents_ClassesByID();
     779             : };
     780             : 
     781             : /***************************************************************************/
     782             : NS_IMETHODIMP
     783           0 : nsXPCComponents_ClassesByID::GetInterfaces(uint32_t* aCount, nsIID * **aArray)
     784             : {
     785           0 :     const uint32_t count = 2;
     786           0 :     *aCount = count;
     787             :     nsIID** array;
     788           0 :     *aArray = array = static_cast<nsIID**>(moz_xmalloc(count * sizeof(nsIID*)));
     789           0 :     if (!array)
     790           0 :         return NS_ERROR_OUT_OF_MEMORY;
     791             : 
     792           0 :     uint32_t index = 0;
     793             :     nsIID* clone;
     794             : #define PUSH_IID(id)                                                          \
     795             :     clone = static_cast<nsIID*>(nsMemory::Clone(&NS_GET_IID( id ),           \
     796             :                                                  sizeof(nsIID)));             \
     797             :     if (!clone)                                                               \
     798             :         goto oom;                                                             \
     799             :     array[index++] = clone;
     800             : 
     801           0 :     PUSH_IID(nsIXPCComponents_ClassesByID)
     802           0 :     PUSH_IID(nsIXPCScriptable)
     803             : #undef PUSH_IID
     804             : 
     805           0 :     return NS_OK;
     806             : oom:
     807           0 :     while (index)
     808           0 :         free(array[--index]);
     809           0 :     free(array);
     810           0 :     *aArray = nullptr;
     811           0 :     return NS_ERROR_OUT_OF_MEMORY;
     812             : }
     813             : 
     814             : NS_IMETHODIMP
     815           0 : nsXPCComponents_ClassesByID::GetScriptableHelper(nsIXPCScriptable** retval)
     816             : {
     817           0 :     *retval = nullptr;
     818           0 :     return NS_OK;
     819             : }
     820             : 
     821             : NS_IMETHODIMP
     822           0 : nsXPCComponents_ClassesByID::GetContractID(char * *aContractID)
     823             : {
     824           0 :     *aContractID = nullptr;
     825           0 :     return NS_ERROR_NOT_AVAILABLE;
     826             : }
     827             : 
     828             : NS_IMETHODIMP
     829           0 : nsXPCComponents_ClassesByID::GetClassDescription(char * *aClassDescription)
     830             : {
     831             :     static const char classDescription[] = "XPCComponents_ClassesByID";
     832           0 :     *aClassDescription = (char*)nsMemory::Clone(classDescription, sizeof(classDescription));
     833           0 :     return *aClassDescription ? NS_OK : NS_ERROR_OUT_OF_MEMORY;
     834             : }
     835             : 
     836             : NS_IMETHODIMP
     837           0 : nsXPCComponents_ClassesByID::GetClassID(nsCID * *aClassID)
     838             : {
     839           0 :     *aClassID = nullptr;
     840           0 :     return NS_OK;
     841             : }
     842             : 
     843             : NS_IMETHODIMP
     844           0 : nsXPCComponents_ClassesByID::GetFlags(uint32_t* aFlags)
     845             : {
     846           0 :     *aFlags = 0;
     847           0 :     return NS_OK;
     848             : }
     849             : 
     850             : NS_IMETHODIMP
     851           0 : nsXPCComponents_ClassesByID::GetClassIDNoAlloc(nsCID* aClassIDNoAlloc)
     852             : {
     853           0 :     return NS_ERROR_NOT_AVAILABLE;
     854             : }
     855             : 
     856           0 : nsXPCComponents_ClassesByID::nsXPCComponents_ClassesByID()
     857             : {
     858           0 : }
     859             : 
     860           0 : nsXPCComponents_ClassesByID::~nsXPCComponents_ClassesByID()
     861             : {
     862             :     // empty
     863           0 : }
     864             : 
     865           0 : NS_INTERFACE_MAP_BEGIN(nsXPCComponents_ClassesByID)
     866           0 :   NS_INTERFACE_MAP_ENTRY(nsIXPCComponents_ClassesByID)
     867           0 :   NS_INTERFACE_MAP_ENTRY(nsIXPCScriptable)
     868           0 :   NS_INTERFACE_MAP_ENTRY(nsIClassInfo)
     869           0 :   NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIXPCComponents_ClassesByID)
     870           0 : NS_INTERFACE_MAP_END
     871             : 
     872           0 : NS_IMPL_ADDREF(nsXPCComponents_ClassesByID)
     873           0 : NS_IMPL_RELEASE(nsXPCComponents_ClassesByID)
     874             : 
     875             : // The nsIXPCScriptable map declaration that will generate stubs for us...
     876             : #define XPC_MAP_CLASSNAME         nsXPCComponents_ClassesByID
     877             : #define XPC_MAP_QUOTED_CLASSNAME "nsXPCComponents_ClassesByID"
     878             : #define XPC_MAP_FLAGS (XPC_SCRIPTABLE_WANT_RESOLVE | \
     879             :                        XPC_SCRIPTABLE_WANT_NEWENUMERATE | \
     880             :                        XPC_SCRIPTABLE_ALLOW_PROP_MODS_DURING_RESOLVE)
     881             : #include "xpc_map_end.h" /* This will #undef the above */
     882             : 
     883             : NS_IMETHODIMP
     884           0 : nsXPCComponents_ClassesByID::NewEnumerate(nsIXPConnectWrappedNative* wrapper,
     885             :                                           JSContext* cx, JSObject* obj,
     886             :                                           JS::AutoIdVector& properties,
     887             :                                           bool* _retval)
     888             : {
     889             : 
     890           0 :     nsCOMPtr<nsIComponentRegistrar> compMgr;
     891           0 :     if (NS_FAILED(NS_GetComponentRegistrar(getter_AddRefs(compMgr))) || !compMgr)
     892           0 :         return NS_ERROR_UNEXPECTED;
     893             : 
     894             :     nsISimpleEnumerator* e;
     895           0 :     if (NS_FAILED(compMgr->EnumerateCIDs(&e)) || !e)
     896           0 :         return NS_ERROR_UNEXPECTED;
     897             : 
     898             :     bool hasMore;
     899           0 :     nsCOMPtr<nsISupports> isup;
     900           0 :     while(NS_SUCCEEDED(e->HasMoreElements(&hasMore)) && hasMore &&
     901           0 :           NS_SUCCEEDED(e->GetNext(getter_AddRefs(isup))) && isup) {
     902           0 :         nsCOMPtr<nsISupportsID> holder(do_QueryInterface(isup));
     903           0 :         if (!holder)
     904           0 :             continue;
     905             : 
     906             :         char* name;
     907           0 :         if (NS_SUCCEEDED(holder->ToString(&name)) && name) {
     908           0 :             RootedString idstr(cx, JS_NewStringCopyZ(cx, name));
     909           0 :             if (!idstr) {
     910           0 :                 *_retval = false;
     911           0 :                 return NS_OK;
     912             :             }
     913             : 
     914           0 :             RootedId id(cx);
     915           0 :             if (!JS_StringToId(cx, idstr, &id)) {
     916           0 :                 *_retval = false;
     917           0 :                 return NS_OK;
     918             :             }
     919             : 
     920           0 :             if (!properties.append(id)) {
     921           0 :                 *_retval = false;
     922           0 :                 return NS_OK;
     923             :             }
     924             :         }
     925             :     }
     926             : 
     927           0 :     return NS_OK;
     928             : }
     929             : 
     930             : static bool
     931           0 : IsRegisteredCLSID(const char* str)
     932             : {
     933             :     bool registered;
     934             :     nsID id;
     935             : 
     936           0 :     if (!id.Parse(str))
     937           0 :         return false;
     938             : 
     939           0 :     nsCOMPtr<nsIComponentRegistrar> compMgr;
     940           0 :     if (NS_FAILED(NS_GetComponentRegistrar(getter_AddRefs(compMgr))) || !compMgr ||
     941           0 :         NS_FAILED(compMgr->IsCIDRegistered(id, &registered)))
     942           0 :         return false;
     943             : 
     944           0 :     return registered;
     945             : }
     946             : 
     947             : NS_IMETHODIMP
     948           0 : nsXPCComponents_ClassesByID::Resolve(nsIXPConnectWrappedNative* wrapper,
     949             :                                      JSContext* cx, JSObject* objArg,
     950             :                                      jsid idArg, bool* resolvedp,
     951             :                                      bool* _retval)
     952             : {
     953           0 :     RootedObject obj(cx, objArg);
     954           0 :     RootedId id(cx, idArg);
     955             : 
     956           0 :     if (!JSID_IS_STRING(id))
     957           0 :         return NS_OK;
     958             : 
     959           0 :     JSAutoByteString name;
     960           0 :     RootedString str(cx, JSID_TO_STRING(id));
     961           0 :     if (name.encodeLatin1(cx, str) && name.ptr()[0] == '{' &&
     962           0 :         IsRegisteredCLSID(name.ptr())) // we only allow canonical CLSIDs here
     963             :     {
     964           0 :         nsCOMPtr<nsIJSCID> nsid = nsJSCID::NewID(name.ptr());
     965           0 :         if (nsid) {
     966           0 :             nsXPConnect* xpc = nsXPConnect::XPConnect();
     967           0 :             RootedObject idobj(cx);
     968           0 :             if (NS_SUCCEEDED(xpc->WrapNative(cx, obj,
     969             :                                              static_cast<nsIJSCID*>(nsid),
     970             :                                              NS_GET_IID(nsIJSCID),
     971             :                                              idobj.address()))) {
     972           0 :                 if (idobj) {
     973           0 :                     *resolvedp = true;
     974           0 :                     *_retval = JS_DefinePropertyById(cx, obj, id, idobj,
     975             :                                                      JSPROP_ENUMERATE |
     976             :                                                      JSPROP_READONLY |
     977             :                                                      JSPROP_PERMANENT |
     978             :                                                      JSPROP_RESOLVING);
     979             :                 }
     980             :             }
     981             :         }
     982             :     }
     983           0 :     return NS_OK;
     984             : }
     985             : 
     986             : 
     987             : /***************************************************************************/
     988             : 
     989             : // Currently the possible results do not change at runtime, so they are only
     990             : // cached once (unlike ContractIDs, CLSIDs, and IIDs)
     991             : 
     992             : class nsXPCComponents_Results final :
     993             :   public nsIXPCComponents_Results,
     994             :   public nsIXPCScriptable,
     995             :   public nsIClassInfo
     996             : {
     997             : public:
     998             :     // all the interface method declarations...
     999             :     NS_DECL_ISUPPORTS
    1000             :     NS_DECL_NSIXPCCOMPONENTS_RESULTS
    1001             :     NS_DECL_NSIXPCSCRIPTABLE
    1002             :     NS_DECL_NSICLASSINFO
    1003             : 
    1004             : public:
    1005             :     nsXPCComponents_Results();
    1006             : 
    1007             : private:
    1008             :     virtual ~nsXPCComponents_Results();
    1009             : };
    1010             : 
    1011             : /***************************************************************************/
    1012             : NS_IMETHODIMP
    1013         128 : nsXPCComponents_Results::GetInterfaces(uint32_t* aCount, nsIID * **aArray)
    1014             : {
    1015         128 :     const uint32_t count = 2;
    1016         128 :     *aCount = count;
    1017             :     nsIID** array;
    1018         128 :     *aArray = array = static_cast<nsIID**>(moz_xmalloc(count * sizeof(nsIID*)));
    1019         128 :     if (!array)
    1020           0 :         return NS_ERROR_OUT_OF_MEMORY;
    1021             : 
    1022         128 :     uint32_t index = 0;
    1023             :     nsIID* clone;
    1024             : #define PUSH_IID(id)                                                          \
    1025             :     clone = static_cast<nsIID*>(nsMemory::Clone(&NS_GET_IID( id ),           \
    1026             :                                                  sizeof(nsIID)));             \
    1027             :     if (!clone)                                                               \
    1028             :         goto oom;                                                             \
    1029             :     array[index++] = clone;
    1030             : 
    1031         128 :     PUSH_IID(nsIXPCComponents_Results)
    1032         128 :     PUSH_IID(nsIXPCScriptable)
    1033             : #undef PUSH_IID
    1034             : 
    1035         128 :     return NS_OK;
    1036             : oom:
    1037           0 :     while (index)
    1038           0 :         free(array[--index]);
    1039           0 :     free(array);
    1040           0 :     *aArray = nullptr;
    1041           0 :     return NS_ERROR_OUT_OF_MEMORY;
    1042             : }
    1043             : 
    1044             : NS_IMETHODIMP
    1045         128 : nsXPCComponents_Results::GetScriptableHelper(nsIXPCScriptable** retval)
    1046             : {
    1047         128 :     *retval = nullptr;
    1048         128 :     return NS_OK;
    1049             : }
    1050             : 
    1051             : NS_IMETHODIMP
    1052           0 : nsXPCComponents_Results::GetContractID(char * *aContractID)
    1053             : {
    1054           0 :     *aContractID = nullptr;
    1055           0 :     return NS_ERROR_NOT_AVAILABLE;
    1056             : }
    1057             : 
    1058             : NS_IMETHODIMP
    1059           0 : nsXPCComponents_Results::GetClassDescription(char * *aClassDescription)
    1060             : {
    1061             :     static const char classDescription[] = "XPCComponents_Results";
    1062           0 :     *aClassDescription = (char*)nsMemory::Clone(classDescription, sizeof(classDescription));
    1063           0 :     return *aClassDescription ? NS_OK : NS_ERROR_OUT_OF_MEMORY;
    1064             : }
    1065             : 
    1066             : NS_IMETHODIMP
    1067           0 : nsXPCComponents_Results::GetClassID(nsCID * *aClassID)
    1068             : {
    1069           0 :     *aClassID = nullptr;
    1070           0 :     return NS_OK;
    1071             : }
    1072             : 
    1073             : NS_IMETHODIMP
    1074         128 : nsXPCComponents_Results::GetFlags(uint32_t* aFlags)
    1075             : {
    1076             :     // Mark ourselves as a DOM object so that instances may be created in
    1077             :     // unprivileged scopes.
    1078         128 :     *aFlags = nsIClassInfo::DOM_OBJECT;
    1079         128 :     return NS_OK;
    1080             : }
    1081             : 
    1082             : NS_IMETHODIMP
    1083           0 : nsXPCComponents_Results::GetClassIDNoAlloc(nsCID* aClassIDNoAlloc)
    1084             : {
    1085           0 :     return NS_ERROR_NOT_AVAILABLE;
    1086             : }
    1087             : 
    1088         128 : nsXPCComponents_Results::nsXPCComponents_Results()
    1089             : {
    1090         128 : }
    1091             : 
    1092           0 : nsXPCComponents_Results::~nsXPCComponents_Results()
    1093             : {
    1094             :     // empty
    1095           0 : }
    1096             : 
    1097        1498 : NS_INTERFACE_MAP_BEGIN(nsXPCComponents_Results)
    1098        1498 :   NS_INTERFACE_MAP_ENTRY(nsIXPCComponents_Results)
    1099        1370 :   NS_INTERFACE_MAP_ENTRY(nsIXPCScriptable)
    1100         953 :   NS_INTERFACE_MAP_ENTRY(nsIClassInfo)
    1101         697 :   NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIXPCComponents_Results)
    1102         550 : NS_INTERFACE_MAP_END
    1103             : 
    1104        1640 : NS_IMPL_ADDREF(nsXPCComponents_Results)
    1105        1000 : NS_IMPL_RELEASE(nsXPCComponents_Results)
    1106             : 
    1107             : // The nsIXPCScriptable map declaration that will generate stubs for us...
    1108             : #define XPC_MAP_CLASSNAME         nsXPCComponents_Results
    1109             : #define XPC_MAP_QUOTED_CLASSNAME "nsXPCComponents_Results"
    1110             : #define XPC_MAP_FLAGS (XPC_SCRIPTABLE_WANT_RESOLVE | \
    1111             :                        XPC_SCRIPTABLE_WANT_NEWENUMERATE | \
    1112             :                        XPC_SCRIPTABLE_ALLOW_PROP_MODS_DURING_RESOLVE)
    1113             : #include "xpc_map_end.h" /* This will #undef the above */
    1114             : 
    1115             : NS_IMETHODIMP
    1116           0 : nsXPCComponents_Results::NewEnumerate(nsIXPConnectWrappedNative* wrapper,
    1117             :                                       JSContext* cx, JSObject* obj,
    1118             :                                       JS::AutoIdVector& properties,
    1119             :                                       bool* _retval)
    1120             : {
    1121             :     const char* name;
    1122           0 :     const void* iter = nullptr;
    1123           0 :     while (nsXPCException::IterateNSResults(nullptr, &name, nullptr, &iter)) {
    1124           0 :         RootedString idstr(cx, JS_NewStringCopyZ(cx, name));
    1125           0 :         if (!idstr) {
    1126           0 :             *_retval = false;
    1127           0 :             return NS_OK;
    1128             :         }
    1129             : 
    1130           0 :         RootedId id(cx);
    1131           0 :         if (!JS_StringToId(cx, idstr, &id)) {
    1132           0 :             *_retval = false;
    1133           0 :             return NS_OK;
    1134             :         }
    1135             : 
    1136           0 :         if (!properties.append(id)) {
    1137           0 :             *_retval = false;
    1138           0 :             return NS_OK;
    1139             :         }
    1140             :     }
    1141             : 
    1142           0 :     return NS_OK;
    1143             : }
    1144             : 
    1145             : NS_IMETHODIMP
    1146          11 : nsXPCComponents_Results::Resolve(nsIXPConnectWrappedNative* wrapper,
    1147             :                                  JSContext* cx, JSObject* objArg,
    1148             :                                  jsid idArg, bool* resolvedp,
    1149             :                                  bool* _retval)
    1150             : {
    1151          22 :     RootedObject obj(cx, objArg);
    1152          22 :     RootedId id(cx, idArg);
    1153          22 :     JSAutoByteString name;
    1154             : 
    1155          11 :     if (JSID_IS_STRING(id) && name.encodeLatin1(cx, JSID_TO_STRING(id))) {
    1156             :         const char* rv_name;
    1157          11 :         const void* iter = nullptr;
    1158             :         nsresult rv;
    1159        4169 :         while (nsXPCException::IterateNSResults(&rv, &rv_name, nullptr, &iter)) {
    1160        2079 :             if (!strcmp(name.ptr(), rv_name)) {
    1161          11 :                 *resolvedp = true;
    1162          11 :                 if (!JS_DefinePropertyById(cx, obj, id, (uint32_t)rv,
    1163             :                                            JSPROP_ENUMERATE |
    1164             :                                            JSPROP_READONLY |
    1165             :                                            JSPROP_PERMANENT |
    1166             :                                            JSPROP_RESOLVING)) {
    1167           0 :                     return NS_ERROR_UNEXPECTED;
    1168             :                 }
    1169             :             }
    1170             :         }
    1171             :     }
    1172          11 :     return NS_OK;
    1173             : }
    1174             : 
    1175             : /***************************************************************************/
    1176             : // JavaScript Constructor for nsIJSID objects (Components.ID)
    1177             : 
    1178             : class nsXPCComponents_ID final :
    1179             :   public nsIXPCComponents_ID,
    1180             :   public nsIXPCScriptable,
    1181             :   public nsIClassInfo
    1182             : {
    1183             : public:
    1184             :     // all the interface method declarations...
    1185             :     NS_DECL_ISUPPORTS
    1186             :     NS_DECL_NSIXPCCOMPONENTS_ID
    1187             :     NS_DECL_NSIXPCSCRIPTABLE
    1188             :     NS_DECL_NSICLASSINFO
    1189             : 
    1190             : 
    1191             : public:
    1192             :     nsXPCComponents_ID();
    1193             : 
    1194             : private:
    1195             :     virtual ~nsXPCComponents_ID();
    1196             :     static nsresult CallOrConstruct(nsIXPConnectWrappedNative* wrapper,
    1197             :                                     JSContext* cx, HandleObject obj,
    1198             :                                     const CallArgs& args, bool* _retval);
    1199             : };
    1200             : 
    1201             : /***************************************************************************/
    1202             : NS_IMETHODIMP
    1203          66 : nsXPCComponents_ID::GetInterfaces(uint32_t* aCount, nsIID * **aArray)
    1204             : {
    1205          66 :     const uint32_t count = 2;
    1206          66 :     *aCount = count;
    1207             :     nsIID** array;
    1208          66 :     *aArray = array = static_cast<nsIID**>(moz_xmalloc(count * sizeof(nsIID*)));
    1209          66 :     if (!array)
    1210           0 :         return NS_ERROR_OUT_OF_MEMORY;
    1211             : 
    1212          66 :     uint32_t index = 0;
    1213             :     nsIID* clone;
    1214             : #define PUSH_IID(id)                                                          \
    1215             :     clone = static_cast<nsIID*>(nsMemory::Clone(&NS_GET_IID( id ),           \
    1216             :                                                  sizeof(nsIID)));             \
    1217             :     if (!clone)                                                               \
    1218             :         goto oom;                                                             \
    1219             :     array[index++] = clone;
    1220             : 
    1221          66 :     PUSH_IID(nsIXPCComponents_ID)
    1222          66 :     PUSH_IID(nsIXPCScriptable)
    1223             : #undef PUSH_IID
    1224             : 
    1225          66 :     return NS_OK;
    1226             : oom:
    1227           0 :     while (index)
    1228           0 :         free(array[--index]);
    1229           0 :     free(array);
    1230           0 :     *aArray = nullptr;
    1231           0 :     return NS_ERROR_OUT_OF_MEMORY;
    1232             : }
    1233             : 
    1234             : NS_IMETHODIMP
    1235          67 : nsXPCComponents_ID::GetScriptableHelper(nsIXPCScriptable** retval)
    1236             : {
    1237          67 :     *retval = nullptr;
    1238          67 :     return NS_OK;
    1239             : }
    1240             : 
    1241             : NS_IMETHODIMP
    1242           0 : nsXPCComponents_ID::GetContractID(char * *aContractID)
    1243             : {
    1244           0 :     *aContractID = nullptr;
    1245           0 :     return NS_ERROR_NOT_AVAILABLE;
    1246             : }
    1247             : 
    1248             : NS_IMETHODIMP
    1249           0 : nsXPCComponents_ID::GetClassDescription(char * *aClassDescription)
    1250             : {
    1251             :     static const char classDescription[] = "XPCComponents_ID";
    1252           0 :     *aClassDescription = (char*)nsMemory::Clone(classDescription, sizeof(classDescription));
    1253           0 :     return *aClassDescription ? NS_OK : NS_ERROR_OUT_OF_MEMORY;
    1254             : }
    1255             : 
    1256             : NS_IMETHODIMP
    1257           0 : nsXPCComponents_ID::GetClassID(nsCID * *aClassID)
    1258             : {
    1259           0 :     *aClassID = nullptr;
    1260           0 :     return NS_OK;
    1261             : }
    1262             : 
    1263             : NS_IMETHODIMP
    1264          67 : nsXPCComponents_ID::GetFlags(uint32_t* aFlags)
    1265             : {
    1266          67 :     *aFlags = 0;
    1267          67 :     return NS_OK;
    1268             : }
    1269             : 
    1270             : NS_IMETHODIMP
    1271           0 : nsXPCComponents_ID::GetClassIDNoAlloc(nsCID* aClassIDNoAlloc)
    1272             : {
    1273           0 :     return NS_ERROR_NOT_AVAILABLE;
    1274             : }
    1275             : 
    1276          66 : nsXPCComponents_ID::nsXPCComponents_ID()
    1277             : {
    1278          66 : }
    1279             : 
    1280           0 : nsXPCComponents_ID::~nsXPCComponents_ID()
    1281             : {
    1282             :     // empty
    1283           0 : }
    1284             : 
    1285        1024 : NS_INTERFACE_MAP_BEGIN(nsXPCComponents_ID)
    1286        1024 :   NS_INTERFACE_MAP_ENTRY(nsIXPCComponents_ID)
    1287         958 :   NS_INTERFACE_MAP_ENTRY(nsIXPCScriptable)
    1288         678 :   NS_INTERFACE_MAP_ENTRY(nsIClassInfo)
    1289         544 :   NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIXPCComponents_ID)
    1290         407 : NS_INTERFACE_MAP_END
    1291             : 
    1292        1098 : NS_IMPL_ADDREF(nsXPCComponents_ID)
    1293         764 : NS_IMPL_RELEASE(nsXPCComponents_ID)
    1294             : 
    1295             : // The nsIXPCScriptable map declaration that will generate stubs for us...
    1296             : #define XPC_MAP_CLASSNAME         nsXPCComponents_ID
    1297             : #define XPC_MAP_QUOTED_CLASSNAME "nsXPCComponents_ID"
    1298             : #define XPC_MAP_FLAGS (XPC_SCRIPTABLE_WANT_CALL | \
    1299             :                        XPC_SCRIPTABLE_WANT_CONSTRUCT | \
    1300             :                        XPC_SCRIPTABLE_WANT_HASINSTANCE | \
    1301             :                        XPC_SCRIPTABLE_ALLOW_PROP_MODS_DURING_RESOLVE)
    1302             : #include "xpc_map_end.h" /* This will #undef the above */
    1303             : 
    1304             : 
    1305             : NS_IMETHODIMP
    1306          78 : nsXPCComponents_ID::Call(nsIXPConnectWrappedNative* wrapper, JSContext* cx, JSObject* objArg,
    1307             :                          const CallArgs& args, bool* _retval)
    1308             : {
    1309         156 :     RootedObject obj(cx, objArg);
    1310         156 :     return CallOrConstruct(wrapper, cx, obj, args, _retval);
    1311             : }
    1312             : 
    1313             : NS_IMETHODIMP
    1314           0 : nsXPCComponents_ID::Construct(nsIXPConnectWrappedNative* wrapper, JSContext* cx, JSObject* objArg,
    1315             :                               const CallArgs& args, bool* _retval)
    1316             : {
    1317           0 :     RootedObject obj(cx, objArg);
    1318           0 :     return CallOrConstruct(wrapper, cx, obj, args, _retval);
    1319             : }
    1320             : 
    1321             : // static
    1322             : nsresult
    1323          78 : nsXPCComponents_ID::CallOrConstruct(nsIXPConnectWrappedNative* wrapper,
    1324             :                                     JSContext* cx, HandleObject obj,
    1325             :                                     const CallArgs& args, bool* _retval)
    1326             : {
    1327             :     // make sure we have at least one arg
    1328             : 
    1329          78 :     if (args.length() < 1)
    1330           0 :         return ThrowAndFail(NS_ERROR_XPC_NOT_ENOUGH_ARGS, cx, _retval);
    1331             : 
    1332             :     // Do the security check if necessary
    1333             : 
    1334          78 :     if (NS_FAILED(nsXPConnect::SecurityManager()->CanCreateInstance(cx, nsJSID::GetCID()))) {
    1335             :         // the security manager vetoed. It should have set an exception.
    1336           0 :         *_retval = false;
    1337           0 :         return NS_OK;
    1338             :     }
    1339             : 
    1340             :     // convert the first argument into a string and see if it looks like an id
    1341             : 
    1342             :     JSString* jsstr;
    1343         156 :     JSAutoByteString bytes;
    1344             :     nsID id;
    1345             : 
    1346         234 :     if (!(jsstr = ToString(cx, args[0])) ||
    1347         234 :         !bytes.encodeLatin1(cx, jsstr) ||
    1348          78 :         !id.Parse(bytes.ptr())) {
    1349           0 :         return ThrowAndFail(NS_ERROR_XPC_BAD_ID_STRING, cx, _retval);
    1350             :     }
    1351             : 
    1352             :     // make the new object and return it.
    1353             : 
    1354          78 :     JSObject* newobj = xpc_NewIDObject(cx, obj, id);
    1355          78 :     if (!newobj)
    1356           0 :         return NS_ERROR_UNEXPECTED;
    1357             : 
    1358          78 :     args.rval().setObject(*newobj);
    1359          78 :     return NS_OK;
    1360             : }
    1361             : 
    1362             : NS_IMETHODIMP
    1363          57 : nsXPCComponents_ID::HasInstance(nsIXPConnectWrappedNative* wrapper,
    1364             :                                 JSContext* cx, JSObject* obj,
    1365             :                                 HandleValue val, bool* bp, bool* _retval)
    1366             : {
    1367          57 :     if (bp)
    1368          57 :         *bp = JSValIsInterfaceOfType(cx, val, NS_GET_IID(nsIJSID));
    1369          57 :     return NS_OK;
    1370             : }
    1371             : 
    1372             : /***************************************************************************/
    1373             : // JavaScript Constructor for nsIXPCException objects (Components.Exception)
    1374             : 
    1375             : class nsXPCComponents_Exception final :
    1376             :   public nsIXPCComponents_Exception,
    1377             :   public nsIXPCScriptable,
    1378             :   public nsIClassInfo
    1379             : {
    1380             : public:
    1381             :     // all the interface method declarations...
    1382             :     NS_DECL_ISUPPORTS
    1383             :     NS_DECL_NSIXPCCOMPONENTS_EXCEPTION
    1384             :     NS_DECL_NSIXPCSCRIPTABLE
    1385             :     NS_DECL_NSICLASSINFO
    1386             : 
    1387             : 
    1388             : public:
    1389             :     nsXPCComponents_Exception();
    1390             : 
    1391             : private:
    1392             :     virtual ~nsXPCComponents_Exception();
    1393             :     static nsresult CallOrConstruct(nsIXPConnectWrappedNative* wrapper,
    1394             :                                     JSContext* cx, HandleObject obj,
    1395             :                                     const CallArgs& args, bool* _retval);
    1396             : };
    1397             : 
    1398             : /***************************************************************************/
    1399             : NS_IMETHODIMP
    1400           0 : nsXPCComponents_Exception::GetInterfaces(uint32_t* aCount, nsIID * **aArray)
    1401             : {
    1402           0 :     const uint32_t count = 2;
    1403           0 :     *aCount = count;
    1404             :     nsIID** array;
    1405           0 :     *aArray = array = static_cast<nsIID**>(moz_xmalloc(count * sizeof(nsIID*)));
    1406           0 :     if (!array)
    1407           0 :         return NS_ERROR_OUT_OF_MEMORY;
    1408             : 
    1409           0 :     uint32_t index = 0;
    1410             :     nsIID* clone;
    1411             : #define PUSH_IID(id)                                                          \
    1412             :     clone = static_cast<nsIID*>(nsMemory::Clone(&NS_GET_IID( id ),           \
    1413             :                                                  sizeof(nsIID)));             \
    1414             :     if (!clone)                                                               \
    1415             :         goto oom;                                                             \
    1416             :     array[index++] = clone;
    1417             : 
    1418           0 :     PUSH_IID(nsIXPCComponents_Exception)
    1419           0 :     PUSH_IID(nsIXPCScriptable)
    1420             : #undef PUSH_IID
    1421             : 
    1422           0 :     return NS_OK;
    1423             : oom:
    1424           0 :     while (index)
    1425           0 :         free(array[--index]);
    1426           0 :     free(array);
    1427           0 :     *aArray = nullptr;
    1428           0 :     return NS_ERROR_OUT_OF_MEMORY;
    1429             : }
    1430             : 
    1431             : NS_IMETHODIMP
    1432           0 : nsXPCComponents_Exception::GetScriptableHelper(nsIXPCScriptable** retval)
    1433             : {
    1434           0 :     *retval = nullptr;
    1435           0 :     return NS_OK;
    1436             : }
    1437             : 
    1438             : NS_IMETHODIMP
    1439           0 : nsXPCComponents_Exception::GetContractID(char * *aContractID)
    1440             : {
    1441           0 :     *aContractID = nullptr;
    1442           0 :     return NS_ERROR_NOT_AVAILABLE;
    1443             : }
    1444             : 
    1445             : NS_IMETHODIMP
    1446           0 : nsXPCComponents_Exception::GetClassDescription(char * *aClassDescription)
    1447             : {
    1448             :     static const char classDescription[] = "XPCComponents_Exception";
    1449           0 :     *aClassDescription = (char*)nsMemory::Clone(classDescription, sizeof(classDescription));
    1450           0 :     return *aClassDescription ? NS_OK : NS_ERROR_OUT_OF_MEMORY;
    1451             : }
    1452             : 
    1453             : NS_IMETHODIMP
    1454           0 : nsXPCComponents_Exception::GetClassID(nsCID * *aClassID)
    1455             : {
    1456           0 :     *aClassID = nullptr;
    1457           0 :     return NS_OK;
    1458             : }
    1459             : 
    1460             : NS_IMETHODIMP
    1461           0 : nsXPCComponents_Exception::GetFlags(uint32_t* aFlags)
    1462             : {
    1463           0 :     *aFlags = 0;
    1464           0 :     return NS_OK;
    1465             : }
    1466             : 
    1467             : NS_IMETHODIMP
    1468           0 : nsXPCComponents_Exception::GetClassIDNoAlloc(nsCID* aClassIDNoAlloc)
    1469             : {
    1470           0 :     return NS_ERROR_NOT_AVAILABLE;
    1471             : }
    1472             : 
    1473           0 : nsXPCComponents_Exception::nsXPCComponents_Exception()
    1474             : {
    1475           0 : }
    1476             : 
    1477           0 : nsXPCComponents_Exception::~nsXPCComponents_Exception()
    1478             : {
    1479             :     // empty
    1480           0 : }
    1481             : 
    1482           0 : NS_INTERFACE_MAP_BEGIN(nsXPCComponents_Exception)
    1483           0 :   NS_INTERFACE_MAP_ENTRY(nsIXPCComponents_Exception)
    1484           0 :   NS_INTERFACE_MAP_ENTRY(nsIXPCScriptable)
    1485           0 :   NS_INTERFACE_MAP_ENTRY(nsIClassInfo)
    1486           0 :   NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIXPCComponents_Exception)
    1487           0 : NS_INTERFACE_MAP_END
    1488             : 
    1489           0 : NS_IMPL_ADDREF(nsXPCComponents_Exception)
    1490           0 : NS_IMPL_RELEASE(nsXPCComponents_Exception)
    1491             : 
    1492             : // The nsIXPCScriptable map declaration that will generate stubs for us...
    1493             : #define XPC_MAP_CLASSNAME         nsXPCComponents_Exception
    1494             : #define XPC_MAP_QUOTED_CLASSNAME "nsXPCComponents_Exception"
    1495             : #define XPC_MAP_FLAGS (XPC_SCRIPTABLE_WANT_CALL | \
    1496             :                        XPC_SCRIPTABLE_WANT_CONSTRUCT | \
    1497             :                        XPC_SCRIPTABLE_WANT_HASINSTANCE | \
    1498             :                        XPC_SCRIPTABLE_ALLOW_PROP_MODS_DURING_RESOLVE)
    1499             : #include "xpc_map_end.h" /* This will #undef the above */
    1500             : 
    1501             : 
    1502             : NS_IMETHODIMP
    1503           0 : nsXPCComponents_Exception::Call(nsIXPConnectWrappedNative* wrapper, JSContext* cx, JSObject* objArg,
    1504             :                                 const CallArgs& args, bool* _retval)
    1505             : {
    1506           0 :     RootedObject obj(cx, objArg);
    1507           0 :     return CallOrConstruct(wrapper, cx, obj, args, _retval);
    1508             : }
    1509             : 
    1510             : NS_IMETHODIMP
    1511           0 : nsXPCComponents_Exception::Construct(nsIXPConnectWrappedNative* wrapper, JSContext* cx,
    1512             :                                      JSObject* objArg, const CallArgs& args, bool* _retval)
    1513             : {
    1514           0 :     RootedObject obj(cx, objArg);
    1515           0 :     return CallOrConstruct(wrapper, cx, obj, args, _retval);
    1516             : }
    1517             : 
    1518           0 : struct MOZ_STACK_CLASS ExceptionArgParser
    1519             : {
    1520           0 :     ExceptionArgParser(JSContext* context,
    1521             :                        nsXPConnect* xpconnect)
    1522           0 :         : eMsg("exception")
    1523             :         , eResult(NS_ERROR_FAILURE)
    1524             :         , cx(context)
    1525           0 :         , xpc(xpconnect)
    1526           0 :     {}
    1527             : 
    1528             :     // Public exception parameter values. During construction, these are
    1529             :     // initialized to the appropriate defaults.
    1530             :     const char*             eMsg;
    1531             :     nsresult                eResult;
    1532             :     nsCOMPtr<nsIStackFrame> eStack;
    1533             :     nsCOMPtr<nsISupports>   eData;
    1534             : 
    1535             :     // Parse the constructor arguments into the above |eFoo| parameter values.
    1536           0 :     bool parse(const CallArgs& args) {
    1537             :         /*
    1538             :          * The Components.Exception takes a series of arguments, all of them
    1539             :          * optional:
    1540             :          *
    1541             :          * Argument 0: Exception message (defaults to 'exception').
    1542             :          * Argument 1: Result code (defaults to NS_ERROR_FAILURE) _or_ options
    1543             :          *             object (see below).
    1544             :          * Argument 2: Stack (defaults to the current stack, which we trigger
    1545             :          *                    by leaving this nullptr in the parser).
    1546             :          * Argument 3: Optional user data (defaults to nullptr).
    1547             :          *
    1548             :          * To dig our way out of this clunky API, we now support passing an
    1549             :          * options object as the second parameter (as opposed to a result code).
    1550             :          * If this is the case, all subsequent arguments are ignored, and the
    1551             :          * following properties are parsed out of the object (using the
    1552             :          * associated default if the property does not exist):
    1553             :          *
    1554             :          *   result:    Result code (see argument 1).
    1555             :          *   stack:     Call stack (see argument 2).
    1556             :          *   data:      User data (see argument 3).
    1557             :          */
    1558           0 :         if (args.length() > 0 && !parseMessage(args[0]))
    1559           0 :             return false;
    1560           0 :         if (args.length() > 1) {
    1561           0 :             if (args[1].isObject()) {
    1562           0 :                 RootedObject obj(cx, &args[1].toObject());
    1563           0 :                 return parseOptionsObject(obj);
    1564             :             }
    1565           0 :             if (!parseResult(args[1]))
    1566           0 :                 return false;
    1567             :         }
    1568           0 :         if (args.length() > 2) {
    1569           0 :             if (!parseStack(args[2]))
    1570           0 :                 return false;
    1571             :         }
    1572           0 :         if (args.length() > 3) {
    1573           0 :             if (!parseData(args[3]))
    1574           0 :                 return false;
    1575             :         }
    1576           0 :         return true;
    1577             :     }
    1578             : 
    1579             :   protected:
    1580             : 
    1581             :     /*
    1582             :      * Parsing helpers.
    1583             :      */
    1584             : 
    1585           0 :     bool parseMessage(HandleValue v) {
    1586           0 :         JSString* str = ToString(cx, v);
    1587           0 :         if (!str)
    1588           0 :            return false;
    1589           0 :         eMsg = messageBytes.encodeLatin1(cx, str);
    1590           0 :         return !!eMsg;
    1591             :     }
    1592             : 
    1593           0 :     bool parseResult(HandleValue v) {
    1594           0 :         return JS::ToUint32(cx, v, (uint32_t*) &eResult);
    1595             :     }
    1596             : 
    1597           0 :     bool parseStack(HandleValue v) {
    1598           0 :         if (!v.isObject()) {
    1599             :             // eStack has already been initialized to null, which is what we want
    1600             :             // for any non-object values (including null).
    1601           0 :             return true;
    1602             :         }
    1603             : 
    1604           0 :         return NS_SUCCEEDED(xpc->WrapJS(cx, &v.toObject(),
    1605             :                                         NS_GET_IID(nsIStackFrame),
    1606             :                                         getter_AddRefs(eStack)));
    1607             :     }
    1608             : 
    1609           0 :     bool parseData(HandleValue v) {
    1610           0 :         if (!v.isObject()) {
    1611             :             // eData has already been initialized to null, which is what we want
    1612             :             // for any non-object values (including null).
    1613           0 :             return true;
    1614             :         }
    1615             : 
    1616           0 :         return NS_SUCCEEDED(xpc->WrapJS(cx, &v.toObject(),
    1617             :                                         NS_GET_IID(nsISupports),
    1618             :                                         getter_AddRefs(eData)));
    1619             :     }
    1620             : 
    1621           0 :     bool parseOptionsObject(HandleObject obj) {
    1622           0 :         RootedValue v(cx);
    1623             : 
    1624           0 :         if (!getOption(obj, "result", &v) ||
    1625           0 :             (!v.isUndefined() && !parseResult(v)))
    1626           0 :             return false;
    1627             : 
    1628           0 :         if (!getOption(obj, "stack", &v) ||
    1629           0 :             (!v.isUndefined() && !parseStack(v)))
    1630           0 :             return false;
    1631             : 
    1632           0 :         if (!getOption(obj, "data", &v) ||
    1633           0 :             (!v.isUndefined() && !parseData(v)))
    1634           0 :             return false;
    1635             : 
    1636           0 :         return true;
    1637             :     }
    1638             : 
    1639           0 :     bool getOption(HandleObject obj, const char* name, MutableHandleValue rv) {
    1640             :         // Look for the property.
    1641             :         bool found;
    1642           0 :         if (!JS_HasProperty(cx, obj, name, &found))
    1643           0 :             return false;
    1644             : 
    1645             :         // If it wasn't found, indicate with undefined.
    1646           0 :         if (!found) {
    1647           0 :             rv.setUndefined();
    1648           0 :             return true;
    1649             :         }
    1650             : 
    1651             :         // Get the property.
    1652           0 :         return JS_GetProperty(cx, obj, name, rv);
    1653             :     }
    1654             : 
    1655             :     /*
    1656             :      * Internal data members.
    1657             :      */
    1658             : 
    1659             :     // If there's a non-default exception string, hold onto the allocated bytes.
    1660             :     JSAutoByteString messageBytes;
    1661             : 
    1662             :     // Various bits and pieces that are helpful to have around.
    1663             :     JSContext* cx;
    1664             :     nsXPConnect* xpc;
    1665             : };
    1666             : 
    1667             : // static
    1668             : nsresult
    1669           0 : nsXPCComponents_Exception::CallOrConstruct(nsIXPConnectWrappedNative* wrapper,
    1670             :                                            JSContext* cx, HandleObject obj,
    1671             :                                            const CallArgs& args, bool* _retval)
    1672             : {
    1673           0 :     nsXPConnect* xpc = nsXPConnect::XPConnect();
    1674             : 
    1675             :     // Do the security check if necessary
    1676             : 
    1677           0 :     if (NS_FAILED(nsXPConnect::SecurityManager()->CanCreateInstance(cx, Exception::GetCID()))) {
    1678             :         // the security manager vetoed. It should have set an exception.
    1679           0 :         *_retval = false;
    1680           0 :         return NS_OK;
    1681             :     }
    1682             : 
    1683             :     // Parse the arguments to the Exception constructor.
    1684           0 :     ExceptionArgParser parser(cx, xpc);
    1685           0 :     if (!parser.parse(args))
    1686           0 :         return ThrowAndFail(NS_ERROR_XPC_BAD_CONVERT_JS, cx, _retval);
    1687             : 
    1688           0 :     nsCOMPtr<nsIException> e = new Exception(nsCString(parser.eMsg),
    1689             :                                              parser.eResult,
    1690           0 :                                              EmptyCString(),
    1691             :                                              parser.eStack,
    1692           0 :                                              parser.eData);
    1693             : 
    1694           0 :     RootedObject newObj(cx);
    1695           0 :     if (NS_FAILED(xpc->WrapNative(cx, obj, e, NS_GET_IID(nsIXPCException), newObj.address())) || !newObj) {
    1696           0 :         return ThrowAndFail(NS_ERROR_XPC_CANT_CREATE_WN, cx, _retval);
    1697             :     }
    1698             : 
    1699           0 :     args.rval().setObject(*newObj);
    1700           0 :     return NS_OK;
    1701             : }
    1702             : 
    1703             : NS_IMETHODIMP
    1704           0 : nsXPCComponents_Exception::HasInstance(nsIXPConnectWrappedNative* wrapper,
    1705             :                                        JSContext * cx, JSObject * obj,
    1706             :                                        HandleValue val, bool* bp,
    1707             :                                        bool* _retval)
    1708             : {
    1709             :     using namespace mozilla::dom;
    1710             : 
    1711           0 :     if (bp) {
    1712           0 :         *bp = (val.isObject() &&
    1713           0 :                IS_INSTANCE_OF(Exception, &val.toObject())) ||
    1714           0 :               JSValIsInterfaceOfType(cx, val, NS_GET_IID(nsIException));
    1715             :     }
    1716           0 :     return NS_OK;
    1717             : }
    1718             : 
    1719             : /***************************************************************************/
    1720             : // This class is for the thing returned by "new Component.Constructor".
    1721             : 
    1722             : // XXXjband we use this CID for security check, but security system can't see
    1723             : // it since it has no registed factory. Security really kicks in when we try
    1724             : // to build a wrapper around an instance.
    1725             : 
    1726             : // {B4A95150-E25A-11d3-8F61-0010A4E73D9A}
    1727             : #define NS_XPCCONSTRUCTOR_CID                                                 \
    1728             : { 0xb4a95150, 0xe25a, 0x11d3,                                                 \
    1729             :     { 0x8f, 0x61, 0x0, 0x10, 0xa4, 0xe7, 0x3d, 0x9a } }
    1730             : 
    1731             : class nsXPCConstructor :
    1732             :   public nsIXPCConstructor,
    1733             :   public nsIXPCScriptable,
    1734             :   public nsIClassInfo
    1735             : {
    1736             : public:
    1737          10 :     NS_DEFINE_STATIC_CID_ACCESSOR(NS_XPCCONSTRUCTOR_CID)
    1738             : public:
    1739             :     // all the interface method declarations...
    1740             :     NS_DECL_ISUPPORTS
    1741             :     NS_DECL_NSIXPCCONSTRUCTOR
    1742             :     NS_DECL_NSIXPCSCRIPTABLE
    1743             :     NS_DECL_NSICLASSINFO
    1744             : 
    1745             : public:
    1746             :     nsXPCConstructor() = delete;
    1747             :     nsXPCConstructor(nsIJSCID* aClassID,
    1748             :                      nsIJSIID* aInterfaceID,
    1749             :                      const char* aInitializer);
    1750             : 
    1751             : private:
    1752             :     virtual ~nsXPCConstructor();
    1753             :     nsresult CallOrConstruct(nsIXPConnectWrappedNative* wrapper,
    1754             :                              JSContext* cx, HandleObject obj,
    1755             :                              const CallArgs& args, bool* _retval);
    1756             : private:
    1757             :     RefPtr<nsIJSCID> mClassID;
    1758             :     RefPtr<nsIJSIID> mInterfaceID;
    1759             :     char*              mInitializer;
    1760             : };
    1761             : 
    1762             : /***************************************************************************/
    1763             : NS_IMETHODIMP
    1764          10 : nsXPCConstructor::GetInterfaces(uint32_t* aCount, nsIID * **aArray)
    1765             : {
    1766          10 :     const uint32_t count = 2;
    1767          10 :     *aCount = count;
    1768             :     nsIID** array;
    1769          10 :     *aArray = array = static_cast<nsIID**>(moz_xmalloc(count * sizeof(nsIID*)));
    1770          10 :     if (!array)
    1771           0 :         return NS_ERROR_OUT_OF_MEMORY;
    1772             : 
    1773          10 :     uint32_t index = 0;
    1774             :     nsIID* clone;
    1775             : #define PUSH_IID(id)                                                          \
    1776             :     clone = static_cast<nsIID*>(nsMemory::Clone(&NS_GET_IID( id ),           \
    1777             :                                                  sizeof(nsIID)));             \
    1778             :     if (!clone)                                                               \
    1779             :         goto oom;                                                             \
    1780             :     array[index++] = clone;
    1781             : 
    1782          10 :     PUSH_IID(nsIXPCConstructor)
    1783          10 :     PUSH_IID(nsIXPCScriptable)
    1784             : #undef PUSH_IID
    1785             : 
    1786          10 :     return NS_OK;
    1787             : oom:
    1788           0 :     while (index)
    1789           0 :         free(array[--index]);
    1790           0 :     free(array);
    1791           0 :     *aArray = nullptr;
    1792           0 :     return NS_ERROR_OUT_OF_MEMORY;
    1793             : }
    1794             : 
    1795             : NS_IMETHODIMP
    1796          12 : nsXPCConstructor::GetScriptableHelper(nsIXPCScriptable** retval)
    1797             : {
    1798          12 :     *retval = nullptr;
    1799          12 :     return NS_OK;
    1800             : }
    1801             : 
    1802             : NS_IMETHODIMP
    1803           0 : nsXPCConstructor::GetContractID(char * *aContractID)
    1804             : {
    1805           0 :     *aContractID = nullptr;
    1806           0 :     return NS_ERROR_NOT_AVAILABLE;
    1807             : }
    1808             : 
    1809             : NS_IMETHODIMP
    1810           0 : nsXPCConstructor::GetClassDescription(char * *aClassDescription)
    1811             : {
    1812             :     static const char classDescription[] = "XPCConstructor";
    1813           0 :     *aClassDescription = (char*)nsMemory::Clone(classDescription, sizeof(classDescription));
    1814           0 :     return *aClassDescription ? NS_OK : NS_ERROR_OUT_OF_MEMORY;
    1815             : }
    1816             : 
    1817             : NS_IMETHODIMP
    1818           0 : nsXPCConstructor::GetClassID(nsCID * *aClassID)
    1819             : {
    1820           0 :     *aClassID = nullptr;
    1821           0 :     return NS_OK;
    1822             : }
    1823             : 
    1824             : NS_IMETHODIMP
    1825          12 : nsXPCConstructor::GetFlags(uint32_t* aFlags)
    1826             : {
    1827          12 :     *aFlags = 0;
    1828          12 :     return NS_OK;
    1829             : }
    1830             : 
    1831             : NS_IMETHODIMP
    1832           0 : nsXPCConstructor::GetClassIDNoAlloc(nsCID* aClassIDNoAlloc)
    1833             : {
    1834           0 :     return NS_ERROR_NOT_AVAILABLE;
    1835             : }
    1836             : 
    1837          10 : nsXPCConstructor::nsXPCConstructor(nsIJSCID* aClassID,
    1838             :                                    nsIJSIID* aInterfaceID,
    1839          10 :                                    const char* aInitializer)
    1840             :     : mClassID(aClassID),
    1841          10 :       mInterfaceID(aInterfaceID)
    1842             : {
    1843          18 :     mInitializer = aInitializer ?
    1844           8 :         (char*) nsMemory::Clone(aInitializer, strlen(aInitializer)+1) :
    1845             :         nullptr;
    1846          10 : }
    1847             : 
    1848           0 : nsXPCConstructor::~nsXPCConstructor()
    1849             : {
    1850           0 :     if (mInitializer)
    1851           0 :         free(mInitializer);
    1852           0 : }
    1853             : 
    1854             : NS_IMETHODIMP
    1855           0 : nsXPCConstructor::GetClassID(nsIJSCID * *aClassID)
    1856             : {
    1857           0 :     RefPtr<nsIJSCID> rval = mClassID;
    1858           0 :     rval.forget(aClassID);
    1859           0 :     return NS_OK;
    1860             : }
    1861             : 
    1862             : NS_IMETHODIMP
    1863           0 : nsXPCConstructor::GetInterfaceID(nsIJSIID * *aInterfaceID)
    1864             : {
    1865           0 :     RefPtr<nsIJSIID> rval = mInterfaceID;
    1866           0 :     rval.forget(aInterfaceID);
    1867           0 :     return NS_OK;
    1868             : }
    1869             : 
    1870             : NS_IMETHODIMP
    1871           0 : nsXPCConstructor::GetInitializer(char * *aInitializer)
    1872             : {
    1873           0 :     XPC_STRING_GETTER_BODY(aInitializer, mInitializer);
    1874             : }
    1875             : 
    1876         175 : NS_INTERFACE_MAP_BEGIN(nsXPCConstructor)
    1877         175 :   NS_INTERFACE_MAP_ENTRY(nsIXPCConstructor)
    1878         155 :   NS_INTERFACE_MAP_ENTRY(nsIXPCScriptable)
    1879          88 :   NS_INTERFACE_MAP_ENTRY(nsIClassInfo)
    1880          64 :   NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIXPCConstructor)
    1881          50 : NS_INTERFACE_MAP_END
    1882             : 
    1883         202 : NS_IMPL_ADDREF(nsXPCConstructor)
    1884         154 : NS_IMPL_RELEASE(nsXPCConstructor)
    1885             : 
    1886             : // The nsIXPCScriptable map declaration that will generate stubs for us...
    1887             : #define XPC_MAP_CLASSNAME         nsXPCConstructor
    1888             : #define XPC_MAP_QUOTED_CLASSNAME "nsXPCConstructor"
    1889             : #define XPC_MAP_FLAGS (XPC_SCRIPTABLE_WANT_CALL | \
    1890             :                        XPC_SCRIPTABLE_WANT_CONSTRUCT)
    1891             : #include "xpc_map_end.h" /* This will #undef the above */
    1892             : 
    1893             : 
    1894             : NS_IMETHODIMP
    1895           2 : nsXPCConstructor::Call(nsIXPConnectWrappedNative* wrapper, JSContext* cx, JSObject* objArg,
    1896             :                        const CallArgs& args, bool* _retval)
    1897             : {
    1898           4 :     RootedObject obj(cx, objArg);
    1899           4 :     return CallOrConstruct(wrapper, cx, obj, args, _retval);
    1900             : 
    1901             : }
    1902             : 
    1903             : NS_IMETHODIMP
    1904          27 : nsXPCConstructor::Construct(nsIXPConnectWrappedNative* wrapper, JSContext* cx, JSObject* objArg,
    1905             :                             const CallArgs& args, bool* _retval)
    1906             : {
    1907          54 :     RootedObject obj(cx, objArg);
    1908          54 :     return CallOrConstruct(wrapper, cx, obj, args, _retval);
    1909             : }
    1910             : 
    1911             : // static
    1912             : nsresult
    1913          29 : nsXPCConstructor::CallOrConstruct(nsIXPConnectWrappedNative* wrapper,JSContext* cx,
    1914             :                                   HandleObject obj, const CallArgs& args, bool* _retval)
    1915             : {
    1916          29 :     nsXPConnect* xpc = nsXPConnect::XPConnect();
    1917             : 
    1918             :     // security check not required because we are going to call through the
    1919             :     // code which is reflected into JS which will do that for us later.
    1920             : 
    1921          58 :     RootedObject cidObj(cx);
    1922          58 :     RootedObject iidObj(cx);
    1923             : 
    1924         116 :     if (NS_FAILED(xpc->WrapNative(cx, obj, mClassID, NS_GET_IID(nsIJSCID), cidObj.address())) || !cidObj ||
    1925          87 :         NS_FAILED(xpc->WrapNative(cx, obj, mInterfaceID, NS_GET_IID(nsIJSIID), iidObj.address())) || !iidObj) {
    1926           0 :         return ThrowAndFail(NS_ERROR_XPC_CANT_CREATE_WN, cx, _retval);
    1927             :     }
    1928             : 
    1929          58 :     JS::Rooted<JS::Value> arg(cx, ObjectValue(*iidObj));
    1930          58 :     RootedValue rval(cx);
    1931          58 :     if (!JS_CallFunctionName(cx, cidObj, "createInstance", JS::HandleValueArray(arg), &rval) ||
    1932          29 :         rval.isPrimitive()) {
    1933             :         // createInstance will have thrown an exception
    1934           0 :         *_retval = false;
    1935           0 :         return NS_OK;
    1936             :     }
    1937             : 
    1938          29 :     args.rval().set(rval);
    1939             : 
    1940             :     // call initializer method if supplied
    1941          29 :     if (mInitializer) {
    1942          36 :         RootedObject newObj(cx, &rval.toObject());
    1943             :         // first check existence of function property for better error reporting
    1944          36 :         RootedValue fun(cx);
    1945          54 :         if (!JS_GetProperty(cx, newObj, mInitializer, &fun) ||
    1946          27 :             fun.isPrimitive()) {
    1947           0 :             return ThrowAndFail(NS_ERROR_XPC_BAD_INITIALIZER_NAME, cx, _retval);
    1948             :         }
    1949             : 
    1950          36 :         RootedValue dummy(cx);
    1951          27 :         if (!JS_CallFunctionValue(cx, newObj, fun, args, &dummy)) {
    1952             :             // function should have thrown an exception
    1953          18 :             *_retval = false;
    1954          18 :             return NS_OK;
    1955             :         }
    1956             :     }
    1957             : 
    1958          11 :     return NS_OK;
    1959             : }
    1960             : 
    1961             : /*******************************************************/
    1962             : // JavaScript Constructor for nsIXPCConstructor objects (Components.Constructor)
    1963             : 
    1964             : class nsXPCComponents_Constructor final :
    1965             :   public nsIXPCComponents_Constructor,
    1966             :   public nsIXPCScriptable,
    1967             :   public nsIClassInfo
    1968             : {
    1969             : public:
    1970             :     // all the interface method declarations...
    1971             :     NS_DECL_ISUPPORTS
    1972             :     NS_DECL_NSIXPCCOMPONENTS_CONSTRUCTOR
    1973             :     NS_DECL_NSIXPCSCRIPTABLE
    1974             :     NS_DECL_NSICLASSINFO
    1975             : 
    1976             : public:
    1977             :     nsXPCComponents_Constructor();
    1978             : 
    1979             : private:
    1980             :     virtual ~nsXPCComponents_Constructor();
    1981             :     static nsresult CallOrConstruct(nsIXPConnectWrappedNative* wrapper,
    1982             :                                     JSContext* cx, HandleObject obj,
    1983             :                                     const CallArgs& args, bool* _retval);
    1984             : };
    1985             : 
    1986             : /***************************************************************************/
    1987             : NS_IMETHODIMP
    1988           9 : nsXPCComponents_Constructor::GetInterfaces(uint32_t* aCount, nsIID * **aArray)
    1989             : {
    1990           9 :     const uint32_t count = 2;
    1991           9 :     *aCount = count;
    1992             :     nsIID** array;
    1993           9 :     *aArray = array = static_cast<nsIID**>(moz_xmalloc(count * sizeof(nsIID*)));
    1994           9 :     if (!array)
    1995           0 :         return NS_ERROR_OUT_OF_MEMORY;
    1996             : 
    1997           9 :     uint32_t index = 0;
    1998             :     nsIID* clone;
    1999             : #define PUSH_IID(id)                                                          \
    2000             :     clone = static_cast<nsIID*>(nsMemory::Clone(&NS_GET_IID( id ),           \
    2001             :                                                  sizeof(nsIID)));             \
    2002             :     if (!clone)                                                               \
    2003             :         goto oom;                                                             \
    2004             :     array[index++] = clone;
    2005             : 
    2006           9 :     PUSH_IID(nsIXPCComponents_Constructor)
    2007           9 :     PUSH_IID(nsIXPCScriptable)
    2008             : #undef PUSH_IID
    2009             : 
    2010           9 :     return NS_OK;
    2011             : oom:
    2012           0 :     while (index)
    2013           0 :         free(array[--index]);
    2014           0 :     free(array);
    2015           0 :     *aArray = nullptr;
    2016           0 :     return NS_ERROR_OUT_OF_MEMORY;
    2017             : }
    2018             : 
    2019             : NS_IMETHODIMP
    2020           9 : nsXPCComponents_Constructor::GetScriptableHelper(nsIXPCScriptable** retval)
    2021             : {
    2022           9 :     *retval = nullptr;
    2023           9 :     return NS_OK;
    2024             : }
    2025             : 
    2026             : NS_IMETHODIMP
    2027           0 : nsXPCComponents_Constructor::GetContractID(char * *aContractID)
    2028             : {
    2029           0 :     *aContractID = nullptr;
    2030           0 :     return NS_ERROR_NOT_AVAILABLE;
    2031             : }
    2032             : 
    2033             : NS_IMETHODIMP
    2034           0 : nsXPCComponents_Constructor::GetClassDescription(char * *aClassDescription)
    2035             : {
    2036             :     static const char classDescription[] = "XPCComponents_Constructor";
    2037           0 :     *aClassDescription = (char*)nsMemory::Clone(classDescription, sizeof(classDescription));
    2038           0 :     return *aClassDescription ? NS_OK : NS_ERROR_OUT_OF_MEMORY;
    2039             : }
    2040             : 
    2041             : NS_IMETHODIMP
    2042           0 : nsXPCComponents_Constructor::GetClassID(nsCID * *aClassID)
    2043             : {
    2044           0 :     *aClassID = nullptr;
    2045           0 :     return NS_OK;
    2046             : }
    2047             : 
    2048             : NS_IMETHODIMP
    2049           9 : nsXPCComponents_Constructor::GetFlags(uint32_t* aFlags)
    2050             : {
    2051           9 :     *aFlags = 0;
    2052           9 :     return NS_OK;
    2053             : }
    2054             : 
    2055             : NS_IMETHODIMP
    2056           0 : nsXPCComponents_Constructor::GetClassIDNoAlloc(nsCID* aClassIDNoAlloc)
    2057             : {
    2058           0 :     return NS_ERROR_NOT_AVAILABLE;
    2059             : }
    2060             : 
    2061           9 : nsXPCComponents_Constructor::nsXPCComponents_Constructor()
    2062             : {
    2063           9 : }
    2064             : 
    2065           0 : nsXPCComponents_Constructor::~nsXPCComponents_Constructor()
    2066             : {
    2067             :     // empty
    2068           0 : }
    2069             : 
    2070         113 : NS_INTERFACE_MAP_BEGIN(nsXPCComponents_Constructor)
    2071         113 :   NS_INTERFACE_MAP_ENTRY(nsIXPCComponents_Constructor)
    2072         104 :   NS_INTERFACE_MAP_ENTRY(nsIXPCScriptable)
    2073          63 :   NS_INTERFACE_MAP_ENTRY(nsIClassInfo)
    2074          45 :   NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIXPCComponents_Constructor)
    2075          36 : NS_INTERFACE_MAP_END
    2076             : 
    2077         136 : NS_IMPL_ADDREF(nsXPCComponents_Constructor)
    2078          91 : NS_IMPL_RELEASE(nsXPCComponents_Constructor)
    2079             : 
    2080             : // The nsIXPCScriptable map declaration that will generate stubs for us...
    2081             : #define XPC_MAP_CLASSNAME         nsXPCComponents_Constructor
    2082             : #define XPC_MAP_QUOTED_CLASSNAME "nsXPCComponents_Constructor"
    2083             : #define XPC_MAP_FLAGS (XPC_SCRIPTABLE_WANT_CALL | \
    2084             :                        XPC_SCRIPTABLE_WANT_CONSTRUCT | \
    2085             :                        XPC_SCRIPTABLE_WANT_HASINSTANCE | \
    2086             :                        XPC_SCRIPTABLE_ALLOW_PROP_MODS_DURING_RESOLVE)
    2087             : #include "xpc_map_end.h" /* This will #undef the above */
    2088             : 
    2089             : 
    2090             : NS_IMETHODIMP
    2091          10 : nsXPCComponents_Constructor::Call(nsIXPConnectWrappedNative* wrapper, JSContext* cx,
    2092             :                                   JSObject* objArg, const CallArgs& args, bool* _retval)
    2093             : {
    2094          20 :     RootedObject obj(cx, objArg);
    2095          20 :     return CallOrConstruct(wrapper, cx, obj, args, _retval);
    2096             : }
    2097             : 
    2098             : NS_IMETHODIMP
    2099           0 : nsXPCComponents_Constructor::Construct(nsIXPConnectWrappedNative* wrapper, JSContext* cx,
    2100             :                                        JSObject* objArg, const CallArgs& args, bool* _retval)
    2101             : {
    2102           0 :     RootedObject obj(cx, objArg);
    2103           0 :     return CallOrConstruct(wrapper, cx, obj, args, _retval);
    2104             : }
    2105             : 
    2106             : // static
    2107             : nsresult
    2108          10 : nsXPCComponents_Constructor::CallOrConstruct(nsIXPConnectWrappedNative* wrapper,
    2109             :                                              JSContext* cx, HandleObject obj,
    2110             :                                              const CallArgs& args, bool* _retval)
    2111             : {
    2112             :     // make sure we have at least one arg
    2113             : 
    2114          10 :     if (args.length() < 1)
    2115           0 :         return ThrowAndFail(NS_ERROR_XPC_NOT_ENOUGH_ARGS, cx, _retval);
    2116             : 
    2117             :     // get the various other object pointers we need
    2118             : 
    2119          10 :     nsXPConnect* xpc = nsXPConnect::XPConnect();
    2120          10 :     XPCWrappedNativeScope* scope = ObjectScope(obj);
    2121          20 :     nsCOMPtr<nsIXPCComponents> comp;
    2122             : 
    2123          10 :     if (!xpc || !scope || !(comp = do_QueryInterface(scope->GetComponents())))
    2124           0 :         return ThrowAndFail(NS_ERROR_XPC_UNEXPECTED, cx, _retval);
    2125             : 
    2126             :     // Do the security check if necessary
    2127             : 
    2128          10 :     if (NS_FAILED(nsXPConnect::SecurityManager()->CanCreateInstance(cx, nsXPCConstructor::GetCID()))) {
    2129             :         // the security manager vetoed. It should have set an exception.
    2130           0 :         *_retval = false;
    2131           0 :         return NS_OK;
    2132             :     }
    2133             : 
    2134             :     // initialization params for the Constructor object we will create
    2135          20 :     nsCOMPtr<nsIJSCID> cClassID;
    2136          20 :     nsCOMPtr<nsIJSIID> cInterfaceID;
    2137          10 :     const char*        cInitializer = nullptr;
    2138          20 :     JSAutoByteString  cInitializerBytes;
    2139             : 
    2140          10 :     if (args.length() >= 3) {
    2141             :         // args[2] is an initializer function or property name
    2142          16 :         RootedString str(cx, ToString(cx, args[2]));
    2143           8 :         if (!str || !(cInitializer = cInitializerBytes.encodeLatin1(cx, str)))
    2144           0 :             return ThrowAndFail(NS_ERROR_XPC_BAD_CONVERT_JS, cx, _retval);
    2145             :     }
    2146             : 
    2147          10 :     if (args.length() >= 2) {
    2148             :         // args[1] is an iid name string
    2149             :         // XXXjband support passing "Components.interfaces.foo"?
    2150             : 
    2151          20 :         nsCOMPtr<nsIXPCComponents_Interfaces> ifaces;
    2152          20 :         RootedObject ifacesObj(cx);
    2153             : 
    2154             :         // we do the lookup by asking the Components.interfaces object
    2155             :         // for the property with this name - i.e. we let its caching of these
    2156             :         // nsIJSIID objects work for us.
    2157             : 
    2158          40 :         if (NS_FAILED(comp->GetInterfaces(getter_AddRefs(ifaces))) ||
    2159          10 :             NS_FAILED(xpc->WrapNative(cx, obj, ifaces,
    2160             :                                       NS_GET_IID(nsIXPCComponents_Interfaces),
    2161          40 :                                       ifacesObj.address())) || !ifacesObj) {
    2162           0 :             return ThrowAndFail(NS_ERROR_XPC_UNEXPECTED, cx, _retval);
    2163             :         }
    2164             : 
    2165          20 :         RootedString str(cx, ToString(cx, args[1]));
    2166          20 :         RootedId id(cx);
    2167          10 :         if (!str || !JS_StringToId(cx, str, &id))
    2168           0 :             return ThrowAndFail(NS_ERROR_XPC_BAD_CONVERT_JS, cx, _retval);
    2169             : 
    2170          20 :         RootedValue val(cx);
    2171          10 :         if (!JS_GetPropertyById(cx, ifacesObj, id, &val) || val.isPrimitive())
    2172           0 :             return ThrowAndFail(NS_ERROR_XPC_BAD_IID, cx, _retval);
    2173             : 
    2174          20 :         nsCOMPtr<nsIXPConnectWrappedNative> wn;
    2175          30 :         if (NS_FAILED(xpc->GetWrappedNativeOfJSObject(cx, &val.toObject(),
    2176          40 :                                                       getter_AddRefs(wn))) || !wn ||
    2177          10 :             !(cInterfaceID = do_QueryWrappedNative(wn))) {
    2178           0 :             return ThrowAndFail(NS_ERROR_XPC_UNEXPECTED, cx, _retval);
    2179             :         }
    2180             :     } else {
    2181           0 :         nsCOMPtr<nsIInterfaceInfo> info;
    2182           0 :         xpc->GetInfoForIID(&NS_GET_IID(nsISupports), getter_AddRefs(info));
    2183             : 
    2184           0 :         if (info) {
    2185           0 :             cInterfaceID = nsJSIID::NewID(info);
    2186             :         }
    2187           0 :         if (!cInterfaceID)
    2188           0 :             return ThrowAndFail(NS_ERROR_XPC_UNEXPECTED, cx, _retval);
    2189             :     }
    2190             : 
    2191             :     // a new scope to avoid warnings about shadowed names
    2192             :     {
    2193             :         // argv[0] is a contractid name string
    2194             :         // XXXjband support passing "Components.classes.foo"?
    2195             : 
    2196             :         // we do the lookup by asking the Components.classes object
    2197             :         // for the property with this name - i.e. we let its caching of these
    2198             :         // nsIJSCID objects work for us.
    2199             : 
    2200          20 :         nsCOMPtr<nsIXPCComponents_Classes> classes;
    2201          20 :         RootedObject classesObj(cx);
    2202             : 
    2203          40 :         if (NS_FAILED(comp->GetClasses(getter_AddRefs(classes))) ||
    2204          10 :             NS_FAILED(xpc->WrapNative(cx, obj, classes,
    2205             :                                       NS_GET_IID(nsIXPCComponents_Classes),
    2206          40 :                                       classesObj.address())) || !classesObj) {
    2207           0 :             return ThrowAndFail(NS_ERROR_XPC_UNEXPECTED, cx, _retval);
    2208             :         }
    2209             : 
    2210          20 :         RootedString str(cx, ToString(cx, args[0]));
    2211          20 :         RootedId id(cx);
    2212          10 :         if (!str || !JS_StringToId(cx, str, &id))
    2213           0 :             return ThrowAndFail(NS_ERROR_XPC_BAD_CONVERT_JS, cx, _retval);
    2214             : 
    2215          20 :         RootedValue val(cx);
    2216          10 :         if (!JS_GetPropertyById(cx, classesObj, id, &val) || val.isPrimitive())
    2217           0 :             return ThrowAndFail(NS_ERROR_XPC_BAD_CID, cx, _retval);
    2218             : 
    2219          20 :         nsCOMPtr<nsIXPConnectWrappedNative> wn;
    2220          30 :         if (NS_FAILED(xpc->GetWrappedNativeOfJSObject(cx, val.toObjectOrNull(),
    2221          40 :                                                       getter_AddRefs(wn))) || !wn ||
    2222          10 :             !(cClassID = do_QueryWrappedNative(wn))) {
    2223           0 :             return ThrowAndFail(NS_ERROR_XPC_UNEXPECTED, cx, _retval);
    2224             :         }
    2225             :     }
    2226             : 
    2227          30 :     nsCOMPtr<nsIXPCConstructor> ctor = new nsXPCConstructor(cClassID, cInterfaceID, cInitializer);
    2228          20 :     RootedObject newObj(cx);
    2229             : 
    2230          10 :     if (NS_FAILED(xpc->WrapNative(cx, obj, ctor, NS_GET_IID(nsIXPCConstructor), newObj.address())) || !newObj) {
    2231           0 :         return ThrowAndFail(NS_ERROR_XPC_CANT_CREATE_WN, cx, _retval);
    2232             :     }
    2233             : 
    2234          10 :     args.rval().setObject(*newObj);
    2235          10 :     return NS_OK;
    2236             : }
    2237             : 
    2238             : NS_IMETHODIMP
    2239           0 : nsXPCComponents_Constructor::HasInstance(nsIXPConnectWrappedNative* wrapper,
    2240             :                                          JSContext * cx, JSObject * obj,
    2241             :                                          HandleValue val, bool* bp,
    2242             :                                          bool* _retval)
    2243             : {
    2244           0 :     if (bp)
    2245           0 :         *bp = JSValIsInterfaceOfType(cx, val, NS_GET_IID(nsIXPCConstructor));
    2246           0 :     return NS_OK;
    2247             : }
    2248             : 
    2249             : class nsXPCComponents_Utils final :
    2250             :             public nsIXPCComponents_Utils,
    2251             :             public nsIXPCScriptable
    2252             : {
    2253             : public:
    2254             :     // all the interface method declarations...
    2255             :     NS_DECL_ISUPPORTS
    2256             :     NS_DECL_NSIXPCSCRIPTABLE
    2257             :     NS_DECL_NSIXPCCOMPONENTS_UTILS
    2258             : 
    2259             : public:
    2260         266 :     nsXPCComponents_Utils() { }
    2261             : 
    2262             : private:
    2263           0 :     virtual ~nsXPCComponents_Utils() { }
    2264             :     nsCOMPtr<nsIXPCComponents_utils_Sandbox> mSandbox;
    2265             : };
    2266             : 
    2267        5000 : NS_INTERFACE_MAP_BEGIN(nsXPCComponents_Utils)
    2268        5000 :   NS_INTERFACE_MAP_ENTRY(nsIXPCComponents_Utils)
    2269        4733 :   NS_INTERFACE_MAP_ENTRY(nsIXPCScriptable)
    2270        1978 :   NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIXPCComponents_Utils)
    2271        1587 : NS_INTERFACE_MAP_END
    2272             : 
    2273        6553 : NS_IMPL_ADDREF(nsXPCComponents_Utils)
    2274        5485 : NS_IMPL_RELEASE(nsXPCComponents_Utils)
    2275             : 
    2276             : // The nsIXPCScriptable map declaration that will generate stubs for us...
    2277             : #define XPC_MAP_CLASSNAME         nsXPCComponents_Utils
    2278             : #define XPC_MAP_QUOTED_CLASSNAME "nsXPCComponents_Utils"
    2279             : #define XPC_MAP_FLAGS XPC_SCRIPTABLE_ALLOW_PROP_MODS_DURING_RESOLVE
    2280             : #include "xpc_map_end.h" /* This will #undef the above */
    2281             : 
    2282             : NS_IMETHODIMP
    2283          16 : nsXPCComponents_Utils::GetSandbox(nsIXPCComponents_utils_Sandbox** aSandbox)
    2284             : {
    2285          16 :     NS_ENSURE_ARG_POINTER(aSandbox);
    2286          16 :     if (!mSandbox)
    2287           2 :         mSandbox = NewSandboxConstructor();
    2288             : 
    2289          32 :     nsCOMPtr<nsIXPCComponents_utils_Sandbox> rval = mSandbox;
    2290          16 :     rval.forget(aSandbox);
    2291          16 :     return NS_OK;
    2292             : }
    2293             : 
    2294             : NS_IMETHODIMP
    2295           0 : nsXPCComponents_Utils::ReportError(HandleValue error, JSContext* cx)
    2296             : {
    2297             :     // This function shall never fail! Silently eat any failure conditions.
    2298             : 
    2299           0 :     nsCOMPtr<nsIConsoleService> console(do_GetService(NS_CONSOLESERVICE_CONTRACTID));
    2300           0 :     if (!console)
    2301           0 :         return NS_OK;
    2302             : 
    2303           0 :     nsGlobalWindow* globalWin = CurrentWindowOrNull(cx);
    2304           0 :     nsPIDOMWindowInner* win = globalWin ? globalWin->AsInner() : nullptr;
    2305           0 :     const uint64_t innerWindowID = win ? win->WindowID() : 0;
    2306             : 
    2307           0 :     RootedObject errorObj(cx, error.isObject() ? &error.toObject() : nullptr);
    2308           0 :     JSErrorReport* err = errorObj ? JS_ErrorFromException(cx, errorObj) : nullptr;
    2309             : 
    2310           0 :     nsCOMPtr<nsIScriptError> scripterr;
    2311             : 
    2312           0 :     if (errorObj) {
    2313             :         JS::RootedObject stackVal(cx,
    2314           0 :           FindExceptionStackForConsoleReport(win, error));
    2315           0 :         if (stackVal) {
    2316           0 :             scripterr = new nsScriptErrorWithStack(stackVal);
    2317             :         }
    2318             :     }
    2319             : 
    2320           0 :     nsString fileName;
    2321           0 :     int32_t lineNo = 0;
    2322             : 
    2323           0 :     if (!scripterr) {
    2324           0 :         nsCOMPtr<nsIStackFrame> frame = dom::GetCurrentJSStack();
    2325           0 :         if (frame) {
    2326           0 :             frame->GetFilename(cx, fileName);
    2327           0 :             frame->GetLineNumber(cx, &lineNo);
    2328           0 :             JS::Rooted<JS::Value> stack(cx);
    2329           0 :             nsresult rv = frame->GetNativeSavedFrame(&stack);
    2330           0 :             if (NS_SUCCEEDED(rv) && stack.isObject()) {
    2331           0 :               JS::Rooted<JSObject*> stackObj(cx, &stack.toObject());
    2332           0 :               scripterr = new nsScriptErrorWithStack(stackObj);
    2333             :             }
    2334             :         }
    2335             :     }
    2336             : 
    2337           0 :     if (!scripterr) {
    2338           0 :         scripterr = new nsScriptError();
    2339             :     }
    2340             : 
    2341           0 :     if (err) {
    2342             :         // It's a proper JS Error
    2343           0 :         nsAutoString fileUni;
    2344           0 :         CopyUTF8toUTF16(err->filename, fileUni);
    2345             : 
    2346           0 :         uint32_t column = err->tokenOffset();
    2347             : 
    2348           0 :         const char16_t* linebuf = err->linebuf();
    2349             : 
    2350           0 :         nsresult rv = scripterr->InitWithWindowID(
    2351           0 :                 err->message() ? NS_ConvertUTF8toUTF16(err->message().c_str())
    2352           0 :                 : EmptyString(),
    2353             :                 fileUni,
    2354           0 :                 linebuf ? nsDependentString(linebuf, err->linebufLength()) : EmptyString(),
    2355             :                 err->lineno,
    2356           0 :                 column, err->flags, "XPConnect JavaScript", innerWindowID);
    2357           0 :         NS_ENSURE_SUCCESS(rv, NS_OK);
    2358             : 
    2359           0 :         console->LogMessage(scripterr);
    2360           0 :         return NS_OK;
    2361             :     }
    2362             : 
    2363             :     // It's not a JS Error object, so we synthesize as best we're able.
    2364           0 :     RootedString msgstr(cx, ToString(cx, error));
    2365           0 :     if (!msgstr)
    2366           0 :         return NS_OK;
    2367             : 
    2368           0 :     nsAutoJSString msg;
    2369           0 :     if (!msg.init(cx, msgstr))
    2370           0 :         return NS_OK;
    2371             : 
    2372           0 :     nsresult rv = scripterr->InitWithWindowID(
    2373           0 :             msg, fileName, EmptyString(), lineNo, 0, 0,
    2374           0 :             "XPConnect JavaScript", innerWindowID);
    2375           0 :     NS_ENSURE_SUCCESS(rv, NS_OK);
    2376             : 
    2377           0 :     console->LogMessage(scripterr);
    2378           0 :     return NS_OK;
    2379             : }
    2380             : 
    2381             : NS_IMETHODIMP
    2382           0 : nsXPCComponents_Utils::EvalInSandbox(const nsAString& source,
    2383             :                                      HandleValue sandboxVal,
    2384             :                                      HandleValue version,
    2385             :                                      const nsACString& filenameArg,
    2386             :                                      int32_t lineNumber,
    2387             :                                      JSContext* cx,
    2388             :                                      uint8_t optionalArgc,
    2389             :                                      MutableHandleValue retval)
    2390             : {
    2391           0 :     RootedObject sandbox(cx);
    2392           0 :     if (!JS_ValueToObject(cx, sandboxVal, &sandbox) || !sandbox)
    2393           0 :         return NS_ERROR_INVALID_ARG;
    2394             : 
    2395             :     // Optional third argument: JS version, as a string.
    2396           0 :     JSVersion jsVersion = JSVERSION_DEFAULT;
    2397           0 :     if (optionalArgc >= 1) {
    2398           0 :         JSString* jsVersionStr = ToString(cx, version);
    2399           0 :         if (!jsVersionStr)
    2400           0 :             return NS_ERROR_INVALID_ARG;
    2401             : 
    2402           0 :         JSAutoByteString bytes(cx, jsVersionStr);
    2403           0 :         if (!bytes)
    2404           0 :             return NS_ERROR_INVALID_ARG;
    2405             : 
    2406           0 :         jsVersion = JS_StringToVersion(bytes.ptr());
    2407             :         // Explicitly check for "latest", which we support for sandboxes but
    2408             :         // isn't in the set of web-exposed version strings.
    2409           0 :         if (jsVersion == JSVERSION_UNKNOWN &&
    2410           0 :             !strcmp(bytes.ptr(), "latest"))
    2411             :         {
    2412           0 :             jsVersion = JSVERSION_LATEST;
    2413             :         }
    2414           0 :         if (jsVersion == JSVERSION_UNKNOWN)
    2415           0 :             return NS_ERROR_INVALID_ARG;
    2416             :     }
    2417             : 
    2418             :     // Optional fourth and fifth arguments: filename and line number.
    2419           0 :     int32_t lineNo = (optionalArgc >= 3) ? lineNumber : 1;
    2420           0 :     nsCString filename;
    2421           0 :     if (!filenameArg.IsVoid()) {
    2422           0 :         filename.Assign(filenameArg);
    2423             :     } else {
    2424             :         // Get the current source info from xpc.
    2425             :         nsresult rv;
    2426           0 :         nsCOMPtr<nsIXPConnect> xpc = do_GetService(nsIXPConnect::GetCID(), &rv);
    2427           0 :         NS_ENSURE_SUCCESS(rv, rv);
    2428             : 
    2429           0 :         nsCOMPtr<nsIStackFrame> frame;
    2430           0 :         xpc->GetCurrentJSStack(getter_AddRefs(frame));
    2431           0 :         if (frame) {
    2432           0 :             nsString frameFile;
    2433           0 :             frame->GetFilename(cx, frameFile);
    2434           0 :             CopyUTF16toUTF8(frameFile, filename);
    2435           0 :             frame->GetLineNumber(cx, &lineNo);
    2436             :         }
    2437             :     }
    2438             : 
    2439           0 :     return xpc::EvalInSandbox(cx, sandbox, source, filename, lineNo,
    2440           0 :                               jsVersion, retval);
    2441             : }
    2442             : 
    2443             : NS_IMETHODIMP
    2444           0 : nsXPCComponents_Utils::GetSandboxAddonId(HandleValue sandboxVal,
    2445             :                                          JSContext* cx, MutableHandleValue rval)
    2446             : {
    2447           0 :     if (!sandboxVal.isObject())
    2448           0 :         return NS_ERROR_INVALID_ARG;
    2449             : 
    2450           0 :     RootedObject sandbox(cx, &sandboxVal.toObject());
    2451           0 :     sandbox = js::CheckedUnwrap(sandbox);
    2452           0 :     if (!sandbox || !xpc::IsSandbox(sandbox))
    2453           0 :         return NS_ERROR_INVALID_ARG;
    2454             : 
    2455           0 :     return xpc::GetSandboxAddonId(cx, sandbox, rval);
    2456             : }
    2457             : 
    2458             : NS_IMETHODIMP
    2459           0 : nsXPCComponents_Utils::GetSandboxMetadata(HandleValue sandboxVal,
    2460             :                                           JSContext* cx, MutableHandleValue rval)
    2461             : {
    2462           0 :     if (!sandboxVal.isObject())
    2463           0 :         return NS_ERROR_INVALID_ARG;
    2464             : 
    2465           0 :     RootedObject sandbox(cx, &sandboxVal.toObject());
    2466           0 :     sandbox = js::CheckedUnwrap(sandbox);
    2467           0 :     if (!sandbox || !xpc::IsSandbox(sandbox))
    2468           0 :         return NS_ERROR_INVALID_ARG;
    2469             : 
    2470           0 :     return xpc::GetSandboxMetadata(cx, sandbox, rval);
    2471             : }
    2472             : 
    2473             : NS_IMETHODIMP
    2474           0 : nsXPCComponents_Utils::SetSandboxMetadata(HandleValue sandboxVal,
    2475             :                                           HandleValue metadataVal,
    2476             :                                           JSContext* cx)
    2477             : {
    2478           0 :     if (!sandboxVal.isObject())
    2479           0 :         return NS_ERROR_INVALID_ARG;
    2480             : 
    2481           0 :     RootedObject sandbox(cx, &sandboxVal.toObject());
    2482           0 :     sandbox = js::CheckedUnwrap(sandbox);
    2483           0 :     if (!sandbox || !xpc::IsSandbox(sandbox))
    2484           0 :         return NS_ERROR_INVALID_ARG;
    2485             : 
    2486           0 :     nsresult rv = xpc::SetSandboxMetadata(cx, sandbox, metadataVal);
    2487           0 :     NS_ENSURE_SUCCESS(rv, rv);
    2488             : 
    2489           0 :     return NS_OK;
    2490             : }
    2491             : 
    2492             : NS_IMETHODIMP
    2493         998 : nsXPCComponents_Utils::Import(const nsACString& registryLocation,
    2494             :                               HandleValue targetObj,
    2495             :                               JSContext* cx,
    2496             :                               uint8_t optionalArgc,
    2497             :                               MutableHandleValue retval)
    2498             : {
    2499             :     nsCOMPtr<xpcIJSModuleLoader> moduleloader =
    2500        1996 :         do_GetService(MOZJSCOMPONENTLOADER_CONTRACTID);
    2501         998 :     if (!moduleloader)
    2502           0 :         return NS_ERROR_FAILURE;
    2503             : 
    2504        1996 :     const nsCString& flatLocation = PromiseFlatCString(registryLocation);
    2505        1996 :     AUTO_PROFILER_LABEL_DYNAMIC("nsXPCComponents_Utils::Import", OTHER,
    2506             :                                 flatLocation.get());
    2507             : 
    2508         998 :     return moduleloader->Import(registryLocation, targetObj, cx, optionalArgc, retval);
    2509             : }
    2510             : 
    2511             : NS_IMETHODIMP
    2512           0 : nsXPCComponents_Utils::IsModuleLoaded(const nsACString& registryLocation, bool* retval)
    2513             : {
    2514             :     nsCOMPtr<xpcIJSModuleLoader> moduleloader =
    2515           0 :         do_GetService(MOZJSCOMPONENTLOADER_CONTRACTID);
    2516           0 :     if (!moduleloader)
    2517           0 :         return NS_ERROR_FAILURE;
    2518           0 :     return moduleloader->IsModuleLoaded(registryLocation, retval);
    2519             : }
    2520             : 
    2521             : NS_IMETHODIMP
    2522           0 : nsXPCComponents_Utils::Unload(const nsACString & registryLocation)
    2523             : {
    2524             :     nsCOMPtr<xpcIJSModuleLoader> moduleloader =
    2525           0 :         do_GetService(MOZJSCOMPONENTLOADER_CONTRACTID);
    2526           0 :     if (!moduleloader)
    2527           0 :         return NS_ERROR_FAILURE;
    2528           0 :     return moduleloader->Unload(registryLocation);
    2529             : }
    2530             : 
    2531             : NS_IMETHODIMP
    2532          20 : nsXPCComponents_Utils::ImportGlobalProperties(HandleValue aPropertyList,
    2533             :                                               JSContext* cx)
    2534             : {
    2535          40 :     RootedObject global(cx, CurrentGlobalOrNull(cx));
    2536          20 :     MOZ_ASSERT(global);
    2537             : 
    2538             :     // Don't allow doing this if the global is a Window
    2539             :     nsGlobalWindow* win;
    2540          20 :     if (NS_SUCCEEDED(UNWRAP_OBJECT(Window, &global, win))) {
    2541           0 :         return NS_ERROR_NOT_AVAILABLE;
    2542             :     }
    2543             : 
    2544          20 :     GlobalProperties options;
    2545          20 :     NS_ENSURE_TRUE(aPropertyList.isObject(), NS_ERROR_INVALID_ARG);
    2546             : 
    2547          40 :     RootedObject propertyList(cx, &aPropertyList.toObject());
    2548             :     bool isArray;
    2549          20 :     if (NS_WARN_IF(!JS_IsArrayObject(cx, propertyList, &isArray))) {
    2550           0 :         return NS_ERROR_FAILURE;
    2551             :     }
    2552          20 :     if (NS_WARN_IF(!isArray)) {
    2553           0 :         return NS_ERROR_INVALID_ARG;
    2554             :     }
    2555             : 
    2556          80 :     if (!options.Parse(cx, propertyList) ||
    2557          60 :         !options.DefineInXPCComponents(cx, global))
    2558             :     {
    2559           0 :         return NS_ERROR_FAILURE;
    2560             :     }
    2561             : 
    2562          20 :     return NS_OK;
    2563             : }
    2564             : 
    2565             : NS_IMETHODIMP
    2566           0 : nsXPCComponents_Utils::GetWeakReference(HandleValue object, JSContext* cx,
    2567             :                                         xpcIJSWeakReference** _retval)
    2568             : {
    2569           0 :     RefPtr<xpcJSWeakReference> ref = new xpcJSWeakReference();
    2570           0 :     nsresult rv = ref->Init(cx, object);
    2571           0 :     NS_ENSURE_SUCCESS(rv, rv);
    2572           0 :     ref.forget(_retval);
    2573           0 :     return NS_OK;
    2574             : }
    2575             : 
    2576             : NS_IMETHODIMP
    2577           0 : nsXPCComponents_Utils::ForceGC()
    2578             : {
    2579           0 :     JSContext* cx = XPCJSContext::Get()->Context();
    2580           0 :     PrepareForFullGC(cx);
    2581           0 :     GCForReason(cx, GC_NORMAL, gcreason::COMPONENT_UTILS);
    2582           0 :     return NS_OK;
    2583             : }
    2584             : 
    2585             : NS_IMETHODIMP
    2586           0 : nsXPCComponents_Utils::ForceCC(nsICycleCollectorListener* listener)
    2587             : {
    2588           0 :     nsJSContext::CycleCollectNow(listener);
    2589           0 :     return NS_OK;
    2590             : }
    2591             : 
    2592             : NS_IMETHODIMP
    2593           0 : nsXPCComponents_Utils::FinishCC()
    2594             : {
    2595           0 :     nsCycleCollector_finishAnyCurrentCollection();
    2596           0 :     return NS_OK;
    2597             : }
    2598             : 
    2599             : NS_IMETHODIMP
    2600           0 : nsXPCComponents_Utils::CcSlice(int64_t budget)
    2601             : {
    2602           0 :     nsJSContext::RunCycleCollectorWorkSlice(budget);
    2603           0 :     return NS_OK;
    2604             : }
    2605             : 
    2606             : NS_IMETHODIMP
    2607           0 : nsXPCComponents_Utils::GetMaxCCSliceTimeSinceClear(int32_t* out)
    2608             : {
    2609           0 :     *out = nsJSContext::GetMaxCCSliceTimeSinceClear();
    2610           0 :     return NS_OK;
    2611             : }
    2612             : 
    2613             : NS_IMETHODIMP
    2614           0 : nsXPCComponents_Utils::ClearMaxCCTime()
    2615             : {
    2616           0 :     nsJSContext::ClearMaxCCSliceTime();
    2617           0 :     return NS_OK;
    2618             : }
    2619             : 
    2620             : NS_IMETHODIMP
    2621           0 : nsXPCComponents_Utils::ForceShrinkingGC()
    2622             : {
    2623           0 :     JSContext* cx = dom::danger::GetJSContext();
    2624           0 :     PrepareForFullGC(cx);
    2625           0 :     GCForReason(cx, GC_SHRINK, gcreason::COMPONENT_UTILS);
    2626           0 :     return NS_OK;
    2627             : }
    2628             : 
    2629           0 : class PreciseGCRunnable : public Runnable
    2630             : {
    2631             :   public:
    2632           0 :     PreciseGCRunnable(ScheduledGCCallback* aCallback, bool aShrinking)
    2633           0 :       : mozilla::Runnable("PreciseGCRunnable")
    2634             :       , mCallback(aCallback)
    2635           0 :       , mShrinking(aShrinking)
    2636             :     {
    2637           0 :     }
    2638             : 
    2639           0 :     NS_IMETHOD Run() override
    2640             :     {
    2641           0 :         nsJSContext::GarbageCollectNow(gcreason::COMPONENT_UTILS,
    2642             :                                        nsJSContext::NonIncrementalGC,
    2643           0 :                                        mShrinking ?
    2644             :                                          nsJSContext::ShrinkingGC :
    2645           0 :                                          nsJSContext::NonShrinkingGC);
    2646             : 
    2647           0 :         mCallback->Callback();
    2648           0 :         return NS_OK;
    2649             :     }
    2650             : 
    2651             :   private:
    2652             :     RefPtr<ScheduledGCCallback> mCallback;
    2653             :     bool mShrinking;
    2654             : };
    2655             : 
    2656             : NS_IMETHODIMP
    2657           0 : nsXPCComponents_Utils::SchedulePreciseGC(ScheduledGCCallback* aCallback)
    2658             : {
    2659           0 :     RefPtr<PreciseGCRunnable> event = new PreciseGCRunnable(aCallback, false);
    2660           0 :     return NS_DispatchToMainThread(event);
    2661             : }
    2662             : 
    2663             : NS_IMETHODIMP
    2664           0 : nsXPCComponents_Utils::SchedulePreciseShrinkingGC(ScheduledGCCallback* aCallback)
    2665             : {
    2666           0 :     RefPtr<PreciseGCRunnable> event = new PreciseGCRunnable(aCallback, true);
    2667           0 :     return NS_DispatchToMainThread(event);
    2668             : }
    2669             : 
    2670             : NS_IMETHODIMP
    2671           0 : nsXPCComponents_Utils::UnlinkGhostWindows()
    2672             : {
    2673             : #ifdef DEBUG
    2674           0 :     nsWindowMemoryReporter::UnlinkGhostWindows();
    2675           0 :     return NS_OK;
    2676             : #else
    2677             :     return NS_ERROR_NOT_IMPLEMENTED;
    2678             : #endif
    2679             : }
    2680             : 
    2681             : NS_IMETHODIMP
    2682           0 : nsXPCComponents_Utils::GetJSTestingFunctions(JSContext* cx,
    2683             :                                              MutableHandleValue retval)
    2684             : {
    2685           0 :     JSObject* obj = js::GetTestingFunctions(cx);
    2686           0 :     if (!obj)
    2687           0 :         return NS_ERROR_XPC_JAVASCRIPT_ERROR;
    2688           0 :     retval.setObject(*obj);
    2689           0 :     return NS_OK;
    2690             : }
    2691             : 
    2692             : NS_IMETHODIMP
    2693           0 : nsXPCComponents_Utils::CallFunctionWithAsyncStack(HandleValue function,
    2694             :                                                   nsIStackFrame* stack,
    2695             :                                                   const nsAString& asyncCause,
    2696             :                                                   JSContext* cx,
    2697             :                                                   MutableHandleValue retval)
    2698             : {
    2699             :     nsresult rv;
    2700             : 
    2701           0 :     if (!stack || asyncCause.IsEmpty()) {
    2702           0 :         return NS_ERROR_INVALID_ARG;
    2703             :     }
    2704             : 
    2705           0 :     JS::Rooted<JS::Value> asyncStack(cx);
    2706           0 :     rv = stack->GetNativeSavedFrame(&asyncStack);
    2707           0 :     if (NS_FAILED(rv))
    2708           0 :         return rv;
    2709           0 :     if (!asyncStack.isObject()) {
    2710           0 :         JS_ReportErrorASCII(cx, "Must use a native JavaScript stack frame");
    2711           0 :         return NS_ERROR_INVALID_ARG;
    2712             :     }
    2713             : 
    2714           0 :     JS::Rooted<JSObject*> asyncStackObj(cx, &asyncStack.toObject());
    2715             : 
    2716           0 :     NS_ConvertUTF16toUTF8 utf8Cause(asyncCause);
    2717             :     JS::AutoSetAsyncStackForNewCalls sas(cx, asyncStackObj, utf8Cause.get(),
    2718           0 :                                          JS::AutoSetAsyncStackForNewCalls::AsyncCallKind::EXPLICIT);
    2719             : 
    2720           0 :     if (!JS_CallFunctionValue(cx, nullptr, function,
    2721           0 :                               JS::HandleValueArray::empty(), retval))
    2722             :     {
    2723           0 :         return NS_ERROR_XPC_JAVASCRIPT_ERROR;
    2724             :     }
    2725             : 
    2726           0 :     return NS_OK;
    2727             : }
    2728             : 
    2729             : NS_IMETHODIMP
    2730           0 : nsXPCComponents_Utils::GetGlobalForObject(HandleValue object,
    2731             :                                           JSContext* cx,
    2732             :                                           MutableHandleValue retval)
    2733             : {
    2734             :     // First argument must be an object.
    2735           0 :     if (object.isPrimitive())
    2736           0 :         return NS_ERROR_XPC_BAD_CONVERT_JS;
    2737             : 
    2738             :     // Wrappers are parented to their the global in their home compartment. But
    2739             :     // when getting the global for a cross-compartment wrapper, we really want
    2740             :     // a wrapper for the foreign global. So we need to unwrap before getting the
    2741             :     // parent, enter the compartment for the duration of the call, and wrap the
    2742             :     // result.
    2743           0 :     Rooted<JSObject*> obj(cx, &object.toObject());
    2744           0 :     obj = js::UncheckedUnwrap(obj);
    2745             :     {
    2746           0 :         JSAutoCompartment ac(cx, obj);
    2747           0 :         obj = JS_GetGlobalForObject(cx, obj);
    2748             :     }
    2749             : 
    2750           0 :     if (!JS_WrapObject(cx, &obj))
    2751           0 :         return NS_ERROR_FAILURE;
    2752             : 
    2753             :     // Get the WindowProxy if necessary.
    2754           0 :     obj = js::ToWindowProxyIfWindow(obj);
    2755             : 
    2756           0 :     retval.setObject(*obj);
    2757           0 :     return NS_OK;
    2758             : }
    2759             : 
    2760             : NS_IMETHODIMP
    2761           0 : nsXPCComponents_Utils::IsProxy(HandleValue vobj, JSContext* cx, bool* rval)
    2762             : {
    2763           0 :     if (!vobj.isObject()) {
    2764           0 :         *rval = false;
    2765           0 :         return NS_OK;
    2766             :     }
    2767             : 
    2768           0 :     RootedObject obj(cx, &vobj.toObject());
    2769           0 :     obj = js::CheckedUnwrap(obj, /* stopAtWindowProxy = */ false);
    2770           0 :     NS_ENSURE_TRUE(obj, NS_ERROR_FAILURE);
    2771             : 
    2772           0 :     *rval = js::IsScriptedProxy(obj);
    2773           0 :     return NS_OK;
    2774             : }
    2775             : 
    2776             : NS_IMETHODIMP
    2777           0 : nsXPCComponents_Utils::ExportFunction(HandleValue vfunction, HandleValue vscope,
    2778             :                                       HandleValue voptions, JSContext* cx,
    2779             :                                       MutableHandleValue rval)
    2780             : {
    2781           0 :     if (!xpc::ExportFunction(cx, vfunction, vscope, voptions, rval))
    2782           0 :         return NS_ERROR_FAILURE;
    2783           0 :     return NS_OK;
    2784             : }
    2785             : 
    2786             : NS_IMETHODIMP
    2787           0 : nsXPCComponents_Utils::CreateObjectIn(HandleValue vobj, HandleValue voptions,
    2788             :                                       JSContext* cx, MutableHandleValue rval)
    2789             : {
    2790           0 :     RootedObject optionsObject(cx, voptions.isObject() ? &voptions.toObject()
    2791           0 :                                                        : nullptr);
    2792           0 :     CreateObjectInOptions options(cx, optionsObject);
    2793           0 :     if (voptions.isObject() &&
    2794           0 :         !options.Parse())
    2795             :     {
    2796           0 :         return NS_ERROR_FAILURE;
    2797             :     }
    2798             : 
    2799           0 :     if (!xpc::CreateObjectIn(cx, vobj, options, rval))
    2800           0 :         return NS_ERROR_FAILURE;
    2801           0 :     return NS_OK;
    2802             : }
    2803             : 
    2804             : NS_IMETHODIMP
    2805           0 : nsXPCComponents_Utils::MakeObjectPropsNormal(HandleValue vobj, JSContext* cx)
    2806             : {
    2807           0 :     if (!cx)
    2808           0 :         return NS_ERROR_FAILURE;
    2809             : 
    2810             :     // first argument must be an object
    2811           0 :     if (vobj.isPrimitive())
    2812           0 :         return NS_ERROR_XPC_BAD_CONVERT_JS;
    2813             : 
    2814           0 :     RootedObject obj(cx, js::UncheckedUnwrap(&vobj.toObject()));
    2815           0 :     JSAutoCompartment ac(cx, obj);
    2816           0 :     Rooted<IdVector> ida(cx, IdVector(cx));
    2817           0 :     if (!JS_Enumerate(cx, obj, &ida))
    2818           0 :         return NS_ERROR_FAILURE;
    2819             : 
    2820           0 :     RootedId id(cx);
    2821           0 :     RootedValue v(cx);
    2822           0 :     for (size_t i = 0; i < ida.length(); ++i) {
    2823           0 :         id = ida[i];
    2824             : 
    2825           0 :         if (!JS_GetPropertyById(cx, obj, id, &v))
    2826           0 :             return NS_ERROR_FAILURE;
    2827             : 
    2828           0 :         if (v.isPrimitive())
    2829           0 :             continue;
    2830             : 
    2831           0 :         RootedObject propobj(cx, &v.toObject());
    2832             :         // TODO Deal with non-functions.
    2833           0 :         if (!js::IsWrapper(propobj) || !JS::IsCallable(propobj))
    2834           0 :             continue;
    2835             : 
    2836           0 :         FunctionForwarderOptions forwarderOptions;
    2837           0 :         if (!NewFunctionForwarder(cx, id, propobj, forwarderOptions, &v) ||
    2838           0 :             !JS_SetPropertyById(cx, obj, id, v))
    2839           0 :             return NS_ERROR_FAILURE;
    2840             :     }
    2841             : 
    2842           0 :     return NS_OK;
    2843             : }
    2844             : 
    2845             : NS_IMETHODIMP
    2846           0 : nsXPCComponents_Utils::IsDeadWrapper(HandleValue obj, bool* out)
    2847             : {
    2848           0 :     *out = false;
    2849           0 :     if (obj.isPrimitive())
    2850           0 :         return NS_ERROR_INVALID_ARG;
    2851             : 
    2852             :     // We should never have cross-compartment wrappers for dead wrappers.
    2853           0 :     MOZ_ASSERT_IF(js::IsCrossCompartmentWrapper(&obj.toObject()),
    2854             :                   !JS_IsDeadWrapper(js::UncheckedUnwrap(&obj.toObject())));
    2855             : 
    2856           0 :     *out = JS_IsDeadWrapper(&obj.toObject());
    2857           0 :     return NS_OK;
    2858             : }
    2859             : 
    2860             : NS_IMETHODIMP
    2861           0 : nsXPCComponents_Utils::IsCrossProcessWrapper(HandleValue obj, bool* out)
    2862             : {
    2863           0 :     *out = false;
    2864           0 :     if (obj.isPrimitive())
    2865           0 :         return NS_ERROR_INVALID_ARG;
    2866             : 
    2867           0 :     *out = jsipc::IsWrappedCPOW(&obj.toObject());
    2868           0 :     return NS_OK;
    2869             : }
    2870             : 
    2871             : NS_IMETHODIMP
    2872           0 : nsXPCComponents_Utils::GetCrossProcessWrapperTag(HandleValue obj, nsACString& out)
    2873             : {
    2874           0 :     if (obj.isPrimitive() || !jsipc::IsWrappedCPOW(&obj.toObject()))
    2875           0 :         return NS_ERROR_INVALID_ARG;
    2876             : 
    2877           0 :     jsipc::GetWrappedCPOWTag(&obj.toObject(), out);
    2878           0 :     return NS_OK;
    2879             : }
    2880             : 
    2881             : NS_IMETHODIMP
    2882           1 : nsXPCComponents_Utils::PermitCPOWsInScope(HandleValue obj)
    2883             : {
    2884           1 :     if (!obj.isObject())
    2885           0 :         return NS_ERROR_INVALID_ARG;
    2886             : 
    2887           1 :     JSObject* scopeObj = js::UncheckedUnwrap(&obj.toObject());
    2888           1 :     CompartmentPrivate::Get(scopeObj)->allowCPOWs = true;
    2889           1 :     return NS_OK;
    2890             : }
    2891             : 
    2892             : NS_IMETHODIMP
    2893           0 : nsXPCComponents_Utils::RecomputeWrappers(HandleValue vobj, JSContext* cx)
    2894             : {
    2895             :     // Determine the compartment of the given object, if any.
    2896           0 :     JSCompartment* c = vobj.isObject()
    2897           0 :                        ? js::GetObjectCompartment(js::UncheckedUnwrap(&vobj.toObject()))
    2898           0 :                        : nullptr;
    2899             : 
    2900             :     // If no compartment was given, recompute all.
    2901           0 :     if (!c)
    2902           0 :         js::RecomputeWrappers(cx, js::AllCompartments(), js::AllCompartments());
    2903             :     // Otherwise, recompute wrappers for the given compartment.
    2904             :     else
    2905           0 :         js::RecomputeWrappers(cx, js::SingleCompartment(c), js::AllCompartments()) &&
    2906           0 :         js::RecomputeWrappers(cx, js::AllCompartments(), js::SingleCompartment(c));
    2907             : 
    2908           0 :     return NS_OK;
    2909             : }
    2910             : 
    2911             : NS_IMETHODIMP
    2912           0 : nsXPCComponents_Utils::SetWantXrays(HandleValue vscope, JSContext* cx)
    2913             : {
    2914           0 :     if (!vscope.isObject())
    2915           0 :         return NS_ERROR_INVALID_ARG;
    2916           0 :     JSObject* scopeObj = js::UncheckedUnwrap(&vscope.toObject());
    2917           0 :     JSCompartment* compartment = js::GetObjectCompartment(scopeObj);
    2918           0 :     CompartmentPrivate::Get(scopeObj)->wantXrays = true;
    2919           0 :     bool ok = js::RecomputeWrappers(cx, js::SingleCompartment(compartment),
    2920           0 :                                     js::AllCompartments());
    2921           0 :     NS_ENSURE_TRUE(ok, NS_ERROR_FAILURE);
    2922           0 :     return NS_OK;
    2923             : }
    2924             : 
    2925             : NS_IMETHODIMP
    2926           0 : nsXPCComponents_Utils::ForcePermissiveCOWs(JSContext* cx)
    2927             : {
    2928           0 :     xpc::CrashIfNotInAutomation();
    2929           0 :     CompartmentPrivate::Get(CurrentGlobalOrNull(cx))->forcePermissiveCOWs = true;
    2930           0 :     return NS_OK;
    2931             : }
    2932             : 
    2933             : NS_IMETHODIMP
    2934           0 : nsXPCComponents_Utils::ForcePrivilegedComponentsForScope(HandleValue vscope,
    2935             :                                                          JSContext* cx)
    2936             : {
    2937           0 :     if (!vscope.isObject())
    2938           0 :         return NS_ERROR_INVALID_ARG;
    2939           0 :     xpc::CrashIfNotInAutomation();
    2940           0 :     JSObject* scopeObj = js::UncheckedUnwrap(&vscope.toObject());
    2941           0 :     XPCWrappedNativeScope* scope = ObjectScope(scopeObj);
    2942           0 :     scope->ForcePrivilegedComponents();
    2943           0 :     return NS_OK;
    2944             : }
    2945             : 
    2946             : NS_IMETHODIMP
    2947           0 : nsXPCComponents_Utils::GetComponentsForScope(HandleValue vscope, JSContext* cx,
    2948             :                                              MutableHandleValue rval)
    2949             : {
    2950           0 :     if (!vscope.isObject())
    2951           0 :         return NS_ERROR_INVALID_ARG;
    2952           0 :     JSObject* scopeObj = js::UncheckedUnwrap(&vscope.toObject());
    2953           0 :     XPCWrappedNativeScope* scope = ObjectScope(scopeObj);
    2954           0 :     RootedObject components(cx);
    2955           0 :     if (!scope->GetComponentsJSObject(&components))
    2956           0 :         return NS_ERROR_FAILURE;
    2957           0 :     if (!JS_WrapObject(cx, &components))
    2958           0 :         return NS_ERROR_FAILURE;
    2959           0 :     rval.setObject(*components);
    2960           0 :     return NS_OK;
    2961             : }
    2962             : 
    2963             : NS_IMETHODIMP
    2964           0 : nsXPCComponents_Utils::Dispatch(HandleValue runnableArg, HandleValue scope,
    2965             :                                 JSContext* cx)
    2966             : {
    2967           0 :     RootedValue runnable(cx, runnableArg);
    2968             :     // Enter the given compartment, if any, and rewrap runnable.
    2969           0 :     Maybe<JSAutoCompartment> ac;
    2970           0 :     if (scope.isObject()) {
    2971           0 :         JSObject* scopeObj = js::UncheckedUnwrap(&scope.toObject());
    2972           0 :         if (!scopeObj)
    2973           0 :             return NS_ERROR_FAILURE;
    2974           0 :         ac.emplace(cx, scopeObj);
    2975           0 :         if (!JS_WrapValue(cx, &runnable))
    2976           0 :             return NS_ERROR_FAILURE;
    2977             :     }
    2978             : 
    2979             :     // Get an XPCWrappedJS for |runnable|.
    2980           0 :     if (!runnable.isObject())
    2981           0 :         return NS_ERROR_INVALID_ARG;
    2982             : 
    2983           0 :     nsCOMPtr<nsIRunnable> run;
    2984           0 :     nsresult rv = nsXPConnect::XPConnect()->WrapJS(cx, &runnable.toObject(),
    2985             :                                                    NS_GET_IID(nsIRunnable),
    2986           0 :                                                    getter_AddRefs(run));
    2987           0 :     NS_ENSURE_SUCCESS(rv, rv);
    2988           0 :     MOZ_ASSERT(run);
    2989             : 
    2990             :     // Dispatch.
    2991           0 :     return NS_DispatchToMainThread(run);
    2992             : }
    2993             : 
    2994             : #define GENERATE_JSCONTEXTOPTION_GETTER_SETTER(_attr, _getter, _setter) \
    2995             :     NS_IMETHODIMP                                                       \
    2996             :     nsXPCComponents_Utils::Get## _attr(JSContext* cx, bool* aValue)     \
    2997             :     {                                                                   \
    2998             :         *aValue = ContextOptionsRef(cx)._getter();                      \
    2999             :         return NS_OK;                                                   \
    3000             :     }                                                                   \
    3001             :     NS_IMETHODIMP                                                       \
    3002             :     nsXPCComponents_Utils::Set## _attr(JSContext* cx, bool aValue)      \
    3003             :     {                                                                   \
    3004             :         ContextOptionsRef(cx)._setter(aValue);                          \
    3005             :         return NS_OK;                                                   \
    3006             :     }
    3007             : 
    3008           0 : GENERATE_JSCONTEXTOPTION_GETTER_SETTER(Strict, extraWarnings, setExtraWarnings)
    3009           0 : GENERATE_JSCONTEXTOPTION_GETTER_SETTER(Werror, werror, setWerror)
    3010           0 : GENERATE_JSCONTEXTOPTION_GETTER_SETTER(Strict_mode, strictMode, setStrictMode)
    3011           0 : GENERATE_JSCONTEXTOPTION_GETTER_SETTER(Ion, ion, setIon)
    3012             : 
    3013             : #undef GENERATE_JSCONTEXTOPTION_GETTER_SETTER
    3014             : 
    3015             : NS_IMETHODIMP
    3016           0 : nsXPCComponents_Utils::SetGCZeal(int32_t aValue, JSContext* cx)
    3017             : {
    3018             : #ifdef JS_GC_ZEAL
    3019           0 :     JS_SetGCZeal(cx, uint8_t(aValue), JS_DEFAULT_ZEAL_FREQ);
    3020             : #endif
    3021           0 :     return NS_OK;
    3022             : }
    3023             : 
    3024             : NS_IMETHODIMP
    3025           0 : nsXPCComponents_Utils::GetIsInAutomation(bool* aResult)
    3026             : {
    3027           0 :     NS_ENSURE_ARG_POINTER(aResult);
    3028             : 
    3029           0 :     *aResult = xpc::IsInAutomation();
    3030           0 :     return NS_OK;
    3031             : }
    3032             : 
    3033             : NS_IMETHODIMP
    3034           0 : nsXPCComponents_Utils::CrashIfNotInAutomation()
    3035             : {
    3036           0 :     xpc::CrashIfNotInAutomation();
    3037           0 :     return NS_OK;
    3038             : }
    3039             : 
    3040             : NS_IMETHODIMP
    3041           0 : nsXPCComponents_Utils::NukeSandbox(HandleValue obj, JSContext* cx)
    3042             : {
    3043           0 :     AUTO_PROFILER_LABEL("nsXPCComponents_Utils::NukeSandbox", JS);
    3044           0 :     NS_ENSURE_TRUE(obj.isObject(), NS_ERROR_INVALID_ARG);
    3045           0 :     JSObject* wrapper = &obj.toObject();
    3046           0 :     NS_ENSURE_TRUE(IsWrapper(wrapper), NS_ERROR_INVALID_ARG);
    3047           0 :     RootedObject sb(cx, UncheckedUnwrap(wrapper));
    3048           0 :     NS_ENSURE_TRUE(IsSandbox(sb), NS_ERROR_INVALID_ARG);
    3049             : 
    3050           0 :     xpc::NukeAllWrappersForCompartment(cx, GetObjectCompartment(sb));
    3051             : 
    3052           0 :     return NS_OK;
    3053             : }
    3054             : 
    3055             : NS_IMETHODIMP
    3056           0 : nsXPCComponents_Utils::BlockScriptForGlobal(HandleValue globalArg,
    3057             :                                             JSContext* cx)
    3058             : {
    3059           0 :     NS_ENSURE_TRUE(globalArg.isObject(), NS_ERROR_INVALID_ARG);
    3060           0 :     RootedObject global(cx, UncheckedUnwrap(&globalArg.toObject(),
    3061           0 :                                             /* stopAtWindowProxy = */ false));
    3062           0 :     NS_ENSURE_TRUE(JS_IsGlobalObject(global), NS_ERROR_INVALID_ARG);
    3063           0 :     if (nsContentUtils::IsSystemPrincipal(xpc::GetObjectPrincipal(global))) {
    3064           0 :         JS_ReportErrorASCII(cx, "Script may not be disabled for system globals");
    3065           0 :         return NS_ERROR_FAILURE;
    3066             :     }
    3067           0 :     Scriptability::Get(global).Block();
    3068           0 :     return NS_OK;
    3069             : }
    3070             : 
    3071             : NS_IMETHODIMP
    3072           0 : nsXPCComponents_Utils::UnblockScriptForGlobal(HandleValue globalArg,
    3073             :                                               JSContext* cx)
    3074             : {
    3075           0 :     NS_ENSURE_TRUE(globalArg.isObject(), NS_ERROR_INVALID_ARG);
    3076           0 :     RootedObject global(cx, UncheckedUnwrap(&globalArg.toObject(),
    3077           0 :                                             /* stopAtWindowProxy = */ false));
    3078           0 :     NS_ENSURE_TRUE(JS_IsGlobalObject(global), NS_ERROR_INVALID_ARG);
    3079           0 :     if (nsContentUtils::IsSystemPrincipal(xpc::GetObjectPrincipal(global))) {
    3080           0 :         JS_ReportErrorASCII(cx, "Script may not be disabled for system globals");
    3081           0 :         return NS_ERROR_FAILURE;
    3082             :     }
    3083           0 :     Scriptability::Get(global).Unblock();
    3084           0 :     return NS_OK;
    3085             : }
    3086             : 
    3087             : NS_IMETHODIMP
    3088           0 : nsXPCComponents_Utils::IsXrayWrapper(HandleValue obj, bool* aRetval)
    3089             : {
    3090           0 :     *aRetval =
    3091           0 :         obj.isObject() && xpc::WrapperFactory::IsXrayWrapper(&obj.toObject());
    3092           0 :     return NS_OK;
    3093             : }
    3094             : 
    3095             : NS_IMETHODIMP
    3096           0 : nsXPCComponents_Utils::WaiveXrays(HandleValue aVal, JSContext* aCx, MutableHandleValue aRetval)
    3097             : {
    3098           0 :     RootedValue value(aCx, aVal);
    3099           0 :     if (!xpc::WrapperFactory::WaiveXrayAndWrap(aCx, &value))
    3100           0 :         return NS_ERROR_FAILURE;
    3101           0 :     aRetval.set(value);
    3102           0 :     return NS_OK;
    3103             : }
    3104             : 
    3105             : NS_IMETHODIMP
    3106           0 : nsXPCComponents_Utils::UnwaiveXrays(HandleValue aVal, JSContext* aCx, MutableHandleValue aRetval)
    3107             : {
    3108           0 :     if (!aVal.isObject()) {
    3109           0 :         aRetval.set(aVal);
    3110           0 :         return NS_OK;
    3111             :     }
    3112             : 
    3113           0 :     RootedObject obj(aCx, js::UncheckedUnwrap(&aVal.toObject()));
    3114           0 :     if (!JS_WrapObject(aCx, &obj))
    3115           0 :         return NS_ERROR_FAILURE;
    3116           0 :     aRetval.setObject(*obj);
    3117           0 :     return NS_OK;
    3118             : }
    3119             : 
    3120             : NS_IMETHODIMP
    3121           0 : nsXPCComponents_Utils::GetClassName(HandleValue aObj, bool aUnwrap, JSContext* aCx, char** aRv)
    3122             : {
    3123           0 :     if (!aObj.isObject())
    3124           0 :         return NS_ERROR_INVALID_ARG;
    3125           0 :     RootedObject obj(aCx, &aObj.toObject());
    3126           0 :     if (aUnwrap)
    3127           0 :         obj = js::UncheckedUnwrap(obj, /* stopAtWindowProxy = */ false);
    3128           0 :     *aRv = NS_strdup(js::GetObjectClass(obj)->name);
    3129           0 :     NS_ENSURE_TRUE(*aRv, NS_ERROR_OUT_OF_MEMORY);
    3130           0 :     return NS_OK;
    3131             : }
    3132             : 
    3133             : NS_IMETHODIMP
    3134           0 : nsXPCComponents_Utils::GetDOMClassInfo(const nsAString& aClassName,
    3135             :                                        nsIClassInfo** aClassInfo)
    3136             : {
    3137           0 :     *aClassInfo = nullptr;
    3138           0 :     return NS_ERROR_NOT_AVAILABLE;
    3139             : }
    3140             : 
    3141             : NS_IMETHODIMP
    3142           0 : nsXPCComponents_Utils::GetIncumbentGlobal(HandleValue aCallback,
    3143             :                                           JSContext* aCx, MutableHandleValue aOut)
    3144             : {
    3145           0 :     nsCOMPtr<nsIGlobalObject> global = mozilla::dom::GetIncumbentGlobal();
    3146           0 :     RootedValue globalVal(aCx);
    3147             : 
    3148           0 :     if (!global) {
    3149           0 :         globalVal = NullValue();
    3150             :     } else {
    3151             :         // Note: We rely on the wrap call for outerization.
    3152           0 :         globalVal = ObjectValue(*global->GetGlobalJSObject());
    3153           0 :         if (!JS_WrapValue(aCx, &globalVal))
    3154           0 :             return NS_ERROR_FAILURE;
    3155             :     }
    3156             : 
    3157             :     // Invoke the callback, if passed.
    3158           0 :     if (aCallback.isObject()) {
    3159           0 :         RootedValue ignored(aCx);
    3160           0 :         if (!JS_CallFunctionValue(aCx, nullptr, aCallback, JS::HandleValueArray(globalVal), &ignored))
    3161           0 :             return NS_ERROR_FAILURE;
    3162             :     }
    3163             : 
    3164           0 :     aOut.set(globalVal);
    3165           0 :     return NS_OK;
    3166             : }
    3167             : 
    3168             : /*
    3169             :  * Below is a bunch of awkward junk to allow JS test code to trigger the
    3170             :  * creation of an XPCWrappedJS, such that it ends up in the map. We need to
    3171             :  * hand the caller some sort of reference to hold onto (to prevent the
    3172             :  * refcount from dropping to zero as soon as the function returns), but trying
    3173             :  * to return a bonafide XPCWrappedJS to script causes all sorts of trouble. So
    3174             :  * we create a benign holder class instead, which acts as an opaque reference
    3175             :  * that script can use to keep the XPCWrappedJS alive and in the map.
    3176             :  */
    3177             : 
    3178             : class WrappedJSHolder : public nsISupports
    3179             : {
    3180             :     NS_DECL_ISUPPORTS
    3181           0 :     WrappedJSHolder() {}
    3182             : 
    3183             :     RefPtr<nsXPCWrappedJS> mWrappedJS;
    3184             : 
    3185             : private:
    3186           0 :     virtual ~WrappedJSHolder() {}
    3187             : };
    3188           0 : NS_IMPL_ISUPPORTS0(WrappedJSHolder);
    3189             : 
    3190             : NS_IMETHODIMP
    3191           0 : nsXPCComponents_Utils::GenerateXPCWrappedJS(HandleValue aObj, HandleValue aScope,
    3192             :                                             JSContext* aCx, nsISupports** aOut)
    3193             : {
    3194           0 :     if (!aObj.isObject())
    3195           0 :         return NS_ERROR_INVALID_ARG;
    3196           0 :     RootedObject obj(aCx, &aObj.toObject());
    3197           0 :     RootedObject scope(aCx, aScope.isObject() ? js::UncheckedUnwrap(&aScope.toObject())
    3198           0 :                                               : CurrentGlobalOrNull(aCx));
    3199           0 :     JSAutoCompartment ac(aCx, scope);
    3200           0 :     if (!JS_WrapObject(aCx, &obj))
    3201           0 :         return NS_ERROR_FAILURE;
    3202             : 
    3203           0 :     RefPtr<WrappedJSHolder> holder = new WrappedJSHolder();
    3204           0 :     nsresult rv = nsXPCWrappedJS::GetNewOrUsed(obj, NS_GET_IID(nsISupports),
    3205           0 :                                                getter_AddRefs(holder->mWrappedJS));
    3206           0 :     holder.forget(aOut);
    3207           0 :     return rv;
    3208             : }
    3209             : 
    3210             : NS_IMETHODIMP
    3211           0 : nsXPCComponents_Utils::GetWatchdogTimestamp(const nsAString& aCategory, PRTime* aOut)
    3212             : {
    3213             :     WatchdogTimestampCategory category;
    3214           0 :     if (aCategory.EqualsLiteral("ContextStateChange"))
    3215           0 :         category = TimestampContextStateChange;
    3216           0 :     else if (aCategory.EqualsLiteral("WatchdogWakeup"))
    3217           0 :         category = TimestampWatchdogWakeup;
    3218           0 :     else if (aCategory.EqualsLiteral("WatchdogHibernateStart"))
    3219           0 :         category = TimestampWatchdogHibernateStart;
    3220           0 :     else if (aCategory.EqualsLiteral("WatchdogHibernateStop"))
    3221           0 :         category = TimestampWatchdogHibernateStop;
    3222             :     else
    3223           0 :         return NS_ERROR_INVALID_ARG;
    3224           0 :     *aOut = XPCJSContext::Get()->GetWatchdogTimestamp(category);
    3225           0 :     return NS_OK;
    3226             : }
    3227             : 
    3228             : NS_IMETHODIMP
    3229           0 : nsXPCComponents_Utils::GetJSEngineTelemetryValue(JSContext* cx, MutableHandleValue rval)
    3230             : {
    3231           0 :     RootedObject obj(cx, JS_NewPlainObject(cx));
    3232           0 :     if (!obj)
    3233           0 :         return NS_ERROR_OUT_OF_MEMORY;
    3234             : 
    3235           0 :     unsigned attrs = JSPROP_ENUMERATE | JSPROP_READONLY | JSPROP_PERMANENT;
    3236             : 
    3237           0 :     size_t i = JS_SetProtoCalled(cx);
    3238           0 :     RootedValue v(cx, DoubleValue(i));
    3239           0 :     if (!JS_DefineProperty(cx, obj, "setProto", v, attrs))
    3240           0 :         return NS_ERROR_OUT_OF_MEMORY;
    3241             : 
    3242           0 :     i = JS_GetCustomIteratorCount(cx);
    3243           0 :     v.setDouble(i);
    3244           0 :     if (!JS_DefineProperty(cx, obj, "customIter", v, attrs))
    3245           0 :         return NS_ERROR_OUT_OF_MEMORY;
    3246             : 
    3247           0 :     rval.setObject(*obj);
    3248           0 :     return NS_OK;
    3249             : }
    3250             : 
    3251             : bool
    3252           4 : xpc::CloneInto(JSContext* aCx, HandleValue aValue, HandleValue aScope,
    3253             :                HandleValue aOptions, MutableHandleValue aCloned)
    3254             : {
    3255           4 :     if (!aScope.isObject())
    3256           0 :         return false;
    3257             : 
    3258           8 :     RootedObject scope(aCx, &aScope.toObject());
    3259           4 :     scope = js::CheckedUnwrap(scope);
    3260           4 :     if(!scope) {
    3261           0 :         JS_ReportErrorASCII(aCx, "Permission denied to clone object into scope");
    3262           0 :         return false;
    3263             :     }
    3264             : 
    3265           4 :     if (!aOptions.isUndefined() && !aOptions.isObject()) {
    3266           0 :         JS_ReportErrorASCII(aCx, "Invalid argument");
    3267           0 :         return false;
    3268             :     }
    3269             : 
    3270           8 :     RootedObject optionsObject(aCx, aOptions.isObject() ? &aOptions.toObject()
    3271           8 :                                                         : nullptr);
    3272           8 :     StackScopedCloneOptions options(aCx, optionsObject);
    3273           4 :     if (aOptions.isObject() && !options.Parse())
    3274           0 :         return false;
    3275             : 
    3276             :     {
    3277           8 :         JSAutoCompartment ac(aCx, scope);
    3278           4 :         aCloned.set(aValue);
    3279           4 :         if (!StackScopedClone(aCx, options, aCloned))
    3280           0 :             return false;
    3281             :     }
    3282             : 
    3283           4 :     return JS_WrapValue(aCx, aCloned);
    3284             : }
    3285             : 
    3286             : NS_IMETHODIMP
    3287           4 : nsXPCComponents_Utils::CloneInto(HandleValue aValue, HandleValue aScope,
    3288             :                                  HandleValue aOptions, JSContext* aCx,
    3289             :                                  MutableHandleValue aCloned)
    3290             : {
    3291           4 :     return xpc::CloneInto(aCx, aValue, aScope, aOptions, aCloned) ?
    3292           4 :            NS_OK : NS_ERROR_FAILURE;
    3293             : }
    3294             : 
    3295             : NS_IMETHODIMP
    3296           0 : nsXPCComponents_Utils::GetWebIDLCallerPrincipal(nsIPrincipal** aResult)
    3297             : {
    3298             :     // This API may only be when the Entry Settings Object corresponds to a
    3299             :     // JS-implemented WebIDL call. In all other cases, the value will be null,
    3300             :     // and we throw.
    3301           0 :     nsCOMPtr<nsIPrincipal> callerPrin = mozilla::dom::GetWebIDLCallerPrincipal();
    3302           0 :     if (!callerPrin)
    3303           0 :         return NS_ERROR_NOT_AVAILABLE;
    3304           0 :     callerPrin.forget(aResult);
    3305           0 :     return NS_OK;
    3306             : }
    3307             : 
    3308             : NS_IMETHODIMP
    3309           0 : nsXPCComponents_Utils::GetObjectPrincipal(HandleValue val, JSContext* cx,
    3310             :                                           nsIPrincipal** result)
    3311             : {
    3312           0 :     if (!val.isObject())
    3313           0 :         return NS_ERROR_INVALID_ARG;
    3314           0 :     RootedObject obj(cx, &val.toObject());
    3315           0 :     obj = js::CheckedUnwrap(obj);
    3316           0 :     MOZ_ASSERT(obj);
    3317             : 
    3318           0 :     nsCOMPtr<nsIPrincipal> prin = nsContentUtils::ObjectPrincipal(obj);
    3319           0 :     prin.forget(result);
    3320           0 :     return NS_OK;
    3321             : }
    3322             : 
    3323             : NS_IMETHODIMP
    3324           0 : nsXPCComponents_Utils::GetCompartmentLocation(HandleValue val,
    3325             :                                               JSContext* cx,
    3326             :                                               nsACString& result)
    3327             : {
    3328           0 :     if (!val.isObject())
    3329           0 :         return NS_ERROR_INVALID_ARG;
    3330           0 :     RootedObject obj(cx, &val.toObject());
    3331           0 :     obj = js::CheckedUnwrap(obj);
    3332           0 :     MOZ_ASSERT(obj);
    3333             : 
    3334           0 :     result = xpc::CompartmentPrivate::Get(obj)->GetLocation();
    3335           0 :     return NS_OK;
    3336             : }
    3337             : 
    3338             : NS_IMETHODIMP
    3339           0 : nsXPCComponents_Utils::SetAddonInterposition(const nsACString& addonIdStr,
    3340             :                                              nsIAddonInterposition* interposition,
    3341             :                                              JSContext* cx)
    3342             : {
    3343           0 :     JSAddonId* addonId = xpc::NewAddonId(cx, addonIdStr);
    3344           0 :     if (!addonId)
    3345           0 :         return NS_ERROR_FAILURE;
    3346           0 :     if (!XPCWrappedNativeScope::SetAddonInterposition(cx, addonId, interposition))
    3347           0 :         return NS_ERROR_FAILURE;
    3348             : 
    3349           0 :     return NS_OK;
    3350             : }
    3351             : 
    3352             : NS_IMETHODIMP
    3353           0 : nsXPCComponents_Utils::SetAddonCallInterposition(HandleValue target,
    3354             :                                                  JSContext* cx)
    3355             : {
    3356           0 :     NS_ENSURE_TRUE(target.isObject(), NS_ERROR_INVALID_ARG);
    3357           0 :     RootedObject targetObj(cx, &target.toObject());
    3358           0 :     targetObj = js::CheckedUnwrap(targetObj);
    3359           0 :     NS_ENSURE_TRUE(targetObj, NS_ERROR_INVALID_ARG);
    3360           0 :     XPCWrappedNativeScope* xpcScope = ObjectScope(targetObj);
    3361           0 :     NS_ENSURE_TRUE(xpcScope, NS_ERROR_INVALID_ARG);
    3362             : 
    3363           0 :     xpcScope->SetAddonCallInterposition();
    3364           0 :     return NS_OK;
    3365             : }
    3366             : 
    3367             : NS_IMETHODIMP
    3368           0 : nsXPCComponents_Utils::AllowCPOWsInAddon(const nsACString& addonIdStr,
    3369             :                                          bool allow,
    3370             :                                          JSContext* cx)
    3371             : {
    3372           0 :     JSAddonId* addonId = xpc::NewAddonId(cx, addonIdStr);
    3373           0 :     if (!addonId)
    3374           0 :         return NS_ERROR_FAILURE;
    3375           0 :     if (!XPCWrappedNativeScope::AllowCPOWsInAddon(cx, addonId, allow))
    3376           0 :         return NS_ERROR_FAILURE;
    3377             : 
    3378           0 :     return NS_OK;
    3379             : }
    3380             : 
    3381             : NS_IMETHODIMP
    3382          16 : nsXPCComponents_Utils::Now(double* aRetval)
    3383             : {
    3384          16 :     TimeStamp start = TimeStamp::ProcessCreation();
    3385          16 :     *aRetval = (TimeStamp::Now() - start).ToMilliseconds();
    3386          16 :     return NS_OK;
    3387             : }
    3388             : 
    3389             : /***************************************************************************/
    3390             : /***************************************************************************/
    3391             : /***************************************************************************/
    3392             : 
    3393             : 
    3394         279 : nsXPCComponentsBase::nsXPCComponentsBase(XPCWrappedNativeScope* aScope)
    3395         279 :     :   mScope(aScope)
    3396             : {
    3397         279 :     MOZ_ASSERT(aScope, "aScope must not be null");
    3398         279 : }
    3399             : 
    3400         279 : nsXPCComponents::nsXPCComponents(XPCWrappedNativeScope* aScope)
    3401         279 :     :   nsXPCComponentsBase(aScope)
    3402             : {
    3403         279 : }
    3404             : 
    3405           0 : nsXPCComponentsBase::~nsXPCComponentsBase()
    3406             : {
    3407           0 : }
    3408             : 
    3409           0 : nsXPCComponents::~nsXPCComponents()
    3410             : {
    3411           0 : }
    3412             : 
    3413             : void
    3414           0 : nsXPCComponentsBase::ClearMembers()
    3415             : {
    3416           0 :     mInterfaces = nullptr;
    3417           0 :     mInterfacesByID = nullptr;
    3418           0 :     mResults = nullptr;
    3419           0 : }
    3420             : 
    3421             : void
    3422           0 : nsXPCComponents::ClearMembers()
    3423             : {
    3424           0 :     mClasses = nullptr;
    3425           0 :     mClassesByID = nullptr;
    3426           0 :     mID = nullptr;
    3427           0 :     mException = nullptr;
    3428           0 :     mConstructor = nullptr;
    3429           0 :     mUtils = nullptr;
    3430             : 
    3431           0 :     nsXPCComponentsBase::ClearMembers();
    3432           0 : }
    3433             : 
    3434             : /*******************************************/
    3435             : #define XPC_IMPL_GET_OBJ_METHOD(_class, _n)                                   \
    3436             : NS_IMETHODIMP _class::Get##_n(nsIXPCComponents_##_n * *a##_n) {               \
    3437             :     NS_ENSURE_ARG_POINTER(a##_n);                                             \
    3438             :     if (!m##_n)                                                               \
    3439             :         m##_n = new nsXPCComponents_##_n();                                   \
    3440             :     RefPtr<nsXPCComponents_##_n> ret = m##_n;                               \
    3441             :     ret.forget(a##_n);                                                        \
    3442             :     return NS_OK;                                                             \
    3443             : }
    3444             : 
    3445         701 : XPC_IMPL_GET_OBJ_METHOD(nsXPCComponentsBase, Interfaces)
    3446           0 : XPC_IMPL_GET_OBJ_METHOD(nsXPCComponentsBase, InterfacesByID)
    3447         495 : XPC_IMPL_GET_OBJ_METHOD(nsXPCComponents, Classes)
    3448           0 : XPC_IMPL_GET_OBJ_METHOD(nsXPCComponents, ClassesByID)
    3449         275 : XPC_IMPL_GET_OBJ_METHOD(nsXPCComponentsBase, Results)
    3450         201 : XPC_IMPL_GET_OBJ_METHOD(nsXPCComponents, ID)
    3451           0 : XPC_IMPL_GET_OBJ_METHOD(nsXPCComponents, Exception)
    3452          18 : XPC_IMPL_GET_OBJ_METHOD(nsXPCComponents, Constructor)
    3453         651 : XPC_IMPL_GET_OBJ_METHOD(nsXPCComponents, Utils)
    3454             : 
    3455             : #undef XPC_IMPL_GET_OBJ_METHOD
    3456             : /*******************************************/
    3457             : 
    3458             : NS_IMETHODIMP
    3459           2 : nsXPCComponentsBase::IsSuccessCode(nsresult result, bool* out)
    3460             : {
    3461           2 :     *out = NS_SUCCEEDED(result);
    3462           2 :     return NS_OK;
    3463             : }
    3464             : 
    3465             : NS_IMETHODIMP
    3466          25 : nsXPCComponents::GetStack(nsIStackFrame * *aStack)
    3467             : {
    3468             :     nsresult rv;
    3469          25 :     nsXPConnect* xpc = nsXPConnect::XPConnect();
    3470          25 :     rv = xpc->GetCurrentJSStack(aStack);
    3471          25 :     return rv;
    3472             : }
    3473             : 
    3474             : NS_IMETHODIMP
    3475          31 : nsXPCComponents::GetManager(nsIComponentManager * *aManager)
    3476             : {
    3477          31 :     MOZ_ASSERT(aManager, "bad param");
    3478          31 :     return NS_GetComponentManager(aManager);
    3479             : }
    3480             : 
    3481             : NS_IMETHODIMP
    3482           0 : nsXPCComponents::GetReturnCode(JSContext* aCx, MutableHandleValue aOut)
    3483             : {
    3484           0 :     nsresult res = XPCJSContext::Get()->GetPendingResult();
    3485           0 :     aOut.setNumber(static_cast<uint32_t>(res));
    3486           0 :     return NS_OK;
    3487             : }
    3488             : 
    3489             : NS_IMETHODIMP
    3490           0 : nsXPCComponents::SetReturnCode(JSContext* aCx, HandleValue aCode)
    3491             : {
    3492             :     nsresult rv;
    3493           0 :     if (!ToUint32(aCx, aCode, (uint32_t*)&rv))
    3494           0 :         return NS_ERROR_FAILURE;
    3495           0 :     XPCJSContext::Get()->SetPendingResult(rv);
    3496           0 :     return NS_OK;
    3497             : }
    3498             : 
    3499             : // static
    3500           0 : NS_IMETHODIMP nsXPCComponents::ReportError(HandleValue error, JSContext* cx)
    3501             : {
    3502           0 :     NS_WARNING("Components.reportError deprecated, use Components.utils.reportError");
    3503             : 
    3504           0 :     nsCOMPtr<nsIXPCComponents_Utils> utils;
    3505           0 :     nsresult rv = GetUtils(getter_AddRefs(utils));
    3506           0 :     if (NS_FAILED(rv))
    3507           0 :         return rv;
    3508             : 
    3509           0 :     return utils->ReportError(error, cx);
    3510             : }
    3511             : 
    3512             : /**********************************************/
    3513             : 
    3514             : class ComponentsSH : public nsIXPCScriptable
    3515             : {
    3516             : public:
    3517             :     explicit constexpr ComponentsSH(unsigned dummy)
    3518             :     {
    3519             :     }
    3520             : 
    3521             :     // We don't actually inherit any ref counting infrastructure, but we don't
    3522             :     // need an nsAutoRefCnt member, so the _INHERITED macro is a hack to avoid
    3523             :     // having one.
    3524             :     NS_DECL_ISUPPORTS_INHERITED
    3525             :     NS_DECL_NSIXPCSCRIPTABLE
    3526         279 :     static nsresult Get(nsIXPCScriptable** helper)
    3527             :     {
    3528         279 :         *helper = &singleton;
    3529         279 :         return NS_OK;
    3530             :     }
    3531             : 
    3532             : private:
    3533             :     static ComponentsSH singleton;
    3534             : };
    3535             : 
    3536             : ComponentsSH ComponentsSH::singleton(0);
    3537             : 
    3538             : // Singleton refcounting.
    3539       13428 : NS_IMETHODIMP_(MozExternalRefCountType) ComponentsSH::AddRef(void) { return 1; }
    3540       13149 : NS_IMETHODIMP_(MozExternalRefCountType) ComponentsSH::Release(void) { return 1; }
    3541             : 
    3542        6993 : NS_INTERFACE_MAP_BEGIN(ComponentsSH)
    3543        6993 :   NS_INTERFACE_MAP_ENTRY(nsIXPCScriptable)
    3544           0 :   NS_INTERFACE_MAP_ENTRY(nsISupports)
    3545           0 : NS_INTERFACE_MAP_END
    3546             : 
    3547             : #define NSXPCCOMPONENTSBASE_CID \
    3548             : { 0xc62998e5, 0x95f1, 0x4058, \
    3549             :   { 0xa5, 0x09, 0xec, 0x21, 0x66, 0x18, 0x92, 0xb9 } }
    3550             : 
    3551             : #define NSXPCCOMPONENTS_CID \
    3552             : { 0x3649f405, 0xf0ec, 0x4c28, \
    3553             :     { 0xae, 0xb0, 0xaf, 0x9a, 0x51, 0xe4, 0x4c, 0x81 } }
    3554             : 
    3555           3 : NS_IMPL_CLASSINFO(nsXPCComponentsBase, &ComponentsSH::Get, nsIClassInfo::DOM_OBJECT, NSXPCCOMPONENTSBASE_CID)
    3556        5002 : NS_IMPL_ISUPPORTS_CI(nsXPCComponentsBase, nsIXPCComponentsBase)
    3557             : 
    3558           3 : NS_IMPL_CLASSINFO(nsXPCComponents, &ComponentsSH::Get, nsIClassInfo::DOM_OBJECT, NSXPCCOMPONENTS_CID)
    3559             : // Below is more or less what NS_IMPL_ISUPPORTS_CI_INHERITED1 would look like
    3560             : // if it existed.
    3561        1943 : NS_IMPL_ADDREF_INHERITED(nsXPCComponents, nsXPCComponentsBase)
    3562         837 : NS_IMPL_RELEASE_INHERITED(nsXPCComponents, nsXPCComponentsBase)
    3563        3059 : NS_INTERFACE_MAP_BEGIN(nsXPCComponents)
    3564        3059 :     NS_INTERFACE_MAP_ENTRY(nsIXPCComponents)
    3565        2501 :     NS_IMPL_QUERY_CLASSINFO(nsXPCComponents)
    3566        2222 : NS_INTERFACE_MAP_END_INHERITING(nsXPCComponentsBase)
    3567           3 : NS_IMPL_CI_INTERFACE_GETTER(nsXPCComponents, nsIXPCComponents)
    3568             : 
    3569             : // The nsIXPCScriptable map declaration that will generate stubs for us
    3570             : #define XPC_MAP_CLASSNAME ComponentsSH
    3571             : #define XPC_MAP_QUOTED_CLASSNAME "nsXPCComponents"
    3572             : #define XPC_MAP_FLAGS XPC_SCRIPTABLE_WANT_PRECREATE
    3573             : #include "xpc_map_end.h" /* This will #undef the above */
    3574             : 
    3575             : NS_IMETHODIMP
    3576         281 : ComponentsSH::PreCreate(nsISupports* nativeObj, JSContext* cx, JSObject* globalObj, JSObject** parentObj)
    3577             : {
    3578         281 :   nsXPCComponentsBase* self = static_cast<nsXPCComponentsBase*>(nativeObj);
    3579             :   // this should never happen
    3580         281 :   if (!self->GetScope()) {
    3581           0 :       NS_WARNING("mScope must not be null when nsXPCComponents::PreCreate is called");
    3582           0 :       return NS_ERROR_FAILURE;
    3583             :   }
    3584         281 :   *parentObj = self->GetScope()->GetGlobalJSObject();
    3585         281 :   return NS_OK;
    3586             : }

Generated by: LCOV version 1.13