1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/js/xpconnect/src/XPCComponents.cpp Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,3849 @@ 1.4 +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ 1.5 +/* vim: set ts=8 sts=4 et sw=4 tw=99: */ 1.6 +/* This Source Code Form is subject to the terms of the Mozilla Public 1.7 + * License, v. 2.0. If a copy of the MPL was not distributed with this 1.8 + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 1.9 + 1.10 +/* The "Components" xpcom objects for JavaScript. */ 1.11 + 1.12 +#include "xpcprivate.h" 1.13 +#include "xpcIJSModuleLoader.h" 1.14 +#include "XPCJSWeakReference.h" 1.15 +#include "WrapperFactory.h" 1.16 +#include "nsJSUtils.h" 1.17 +#include "mozJSComponentLoader.h" 1.18 +#include "nsContentUtils.h" 1.19 +#include "jsfriendapi.h" 1.20 +#include "js/StructuredClone.h" 1.21 +#include "mozilla/Attributes.h" 1.22 +#include "nsJSEnvironment.h" 1.23 +#include "mozilla/XPTInterfaceInfoManager.h" 1.24 +#include "mozilla/dom/DOMException.h" 1.25 +#include "mozilla/dom/DOMExceptionBinding.h" 1.26 +#include "mozilla/dom/BindingUtils.h" 1.27 +#include "mozilla/dom/StructuredCloneTags.h" 1.28 +#include "nsZipArchive.h" 1.29 +#include "nsIDOMFile.h" 1.30 +#include "nsIDOMFileList.h" 1.31 +#include "nsWindowMemoryReporter.h" 1.32 + 1.33 +using namespace mozilla; 1.34 +using namespace JS; 1.35 +using namespace js; 1.36 +using namespace xpc; 1.37 +using mozilla::dom::Exception; 1.38 + 1.39 +/***************************************************************************/ 1.40 +// stuff used by all 1.41 + 1.42 +nsresult 1.43 +xpc::ThrowAndFail(nsresult errNum, JSContext *cx, bool *retval) 1.44 +{ 1.45 + XPCThrower::Throw(errNum, cx); 1.46 + *retval = false; 1.47 + return NS_OK; 1.48 +} 1.49 + 1.50 +static bool 1.51 +JSValIsInterfaceOfType(JSContext *cx, HandleValue v, REFNSIID iid) 1.52 +{ 1.53 + 1.54 + nsCOMPtr<nsIXPConnectWrappedNative> wn; 1.55 + nsCOMPtr<nsISupports> sup; 1.56 + nsISupports* iface; 1.57 + 1.58 + if (v.isPrimitive()) 1.59 + return false; 1.60 + 1.61 + nsXPConnect* xpc = nsXPConnect::XPConnect(); 1.62 + RootedObject obj(cx, &v.toObject()); 1.63 + if (NS_SUCCEEDED(xpc->GetWrappedNativeOfJSObject(cx, obj, getter_AddRefs(wn))) && wn && 1.64 + NS_SUCCEEDED(wn->Native()->QueryInterface(iid, (void**)&iface)) && iface) 1.65 + { 1.66 + NS_RELEASE(iface); 1.67 + return true; 1.68 + } 1.69 + return false; 1.70 +} 1.71 + 1.72 +char * 1.73 +xpc::CloneAllAccess() 1.74 +{ 1.75 + static const char allAccess[] = "AllAccess"; 1.76 + return (char*)nsMemory::Clone(allAccess, sizeof(allAccess)); 1.77 +} 1.78 + 1.79 +char * 1.80 +xpc::CheckAccessList(const char16_t *wideName, const char *const list[]) 1.81 +{ 1.82 + nsAutoCString asciiName; 1.83 + CopyUTF16toUTF8(nsDependentString(wideName), asciiName); 1.84 + 1.85 + for (const char* const* p = list; *p; p++) 1.86 + if (!strcmp(*p, asciiName.get())) 1.87 + return CloneAllAccess(); 1.88 + 1.89 + return nullptr; 1.90 +} 1.91 + 1.92 +/***************************************************************************/ 1.93 +/***************************************************************************/ 1.94 +/***************************************************************************/ 1.95 + 1.96 + 1.97 +class nsXPCComponents_Interfaces : 1.98 + public nsIXPCComponents_Interfaces, 1.99 + public nsIXPCScriptable, 1.100 + public nsIClassInfo 1.101 +{ 1.102 +public: 1.103 + // all the interface method declarations... 1.104 + NS_DECL_ISUPPORTS 1.105 + NS_DECL_NSIXPCCOMPONENTS_INTERFACES 1.106 + NS_DECL_NSIXPCSCRIPTABLE 1.107 + NS_DECL_NSICLASSINFO 1.108 + 1.109 +public: 1.110 + nsXPCComponents_Interfaces(); 1.111 + virtual ~nsXPCComponents_Interfaces(); 1.112 + 1.113 +private: 1.114 + nsCOMArray<nsIInterfaceInfo> mInterfaces; 1.115 +}; 1.116 + 1.117 +/* void getInterfaces (out uint32_t count, [array, size_is (count), retval] 1.118 + out nsIIDPtr array); */ 1.119 +NS_IMETHODIMP 1.120 +nsXPCComponents_Interfaces::GetInterfaces(uint32_t *aCount, nsIID * **aArray) 1.121 +{ 1.122 + const uint32_t count = 2; 1.123 + *aCount = count; 1.124 + nsIID **array; 1.125 + *aArray = array = static_cast<nsIID**>(nsMemory::Alloc(count * sizeof(nsIID*))); 1.126 + if (!array) 1.127 + return NS_ERROR_OUT_OF_MEMORY; 1.128 + 1.129 + uint32_t index = 0; 1.130 + nsIID* clone; 1.131 +#define PUSH_IID(id) \ 1.132 + clone = static_cast<nsIID *>(nsMemory::Clone(&NS_GET_IID( id ), \ 1.133 + sizeof(nsIID))); \ 1.134 + if (!clone) \ 1.135 + goto oom; \ 1.136 + array[index++] = clone; 1.137 + 1.138 + PUSH_IID(nsIXPCComponents_Interfaces) 1.139 + PUSH_IID(nsIXPCScriptable) 1.140 +#undef PUSH_IID 1.141 + 1.142 + return NS_OK; 1.143 +oom: 1.144 + while (index) 1.145 + nsMemory::Free(array[--index]); 1.146 + nsMemory::Free(array); 1.147 + *aArray = nullptr; 1.148 + return NS_ERROR_OUT_OF_MEMORY; 1.149 +} 1.150 + 1.151 +/* nsISupports getHelperForLanguage (in uint32_t language); */ 1.152 +NS_IMETHODIMP 1.153 +nsXPCComponents_Interfaces::GetHelperForLanguage(uint32_t language, 1.154 + nsISupports **retval) 1.155 +{ 1.156 + *retval = nullptr; 1.157 + return NS_OK; 1.158 +} 1.159 + 1.160 +/* readonly attribute string contractID; */ 1.161 +NS_IMETHODIMP 1.162 +nsXPCComponents_Interfaces::GetContractID(char * *aContractID) 1.163 +{ 1.164 + *aContractID = nullptr; 1.165 + return NS_ERROR_NOT_AVAILABLE; 1.166 +} 1.167 + 1.168 +/* readonly attribute string classDescription; */ 1.169 +NS_IMETHODIMP 1.170 +nsXPCComponents_Interfaces::GetClassDescription(char * *aClassDescription) 1.171 +{ 1.172 + static const char classDescription[] = "XPCComponents_Interfaces"; 1.173 + *aClassDescription = (char*)nsMemory::Clone(classDescription, sizeof(classDescription)); 1.174 + return *aClassDescription ? NS_OK : NS_ERROR_OUT_OF_MEMORY; 1.175 +} 1.176 + 1.177 +/* readonly attribute nsCIDPtr classID; */ 1.178 +NS_IMETHODIMP 1.179 +nsXPCComponents_Interfaces::GetClassID(nsCID * *aClassID) 1.180 +{ 1.181 + *aClassID = nullptr; 1.182 + return NS_OK; 1.183 +} 1.184 + 1.185 +/* readonly attribute uint32_t implementationLanguage; */ 1.186 +NS_IMETHODIMP 1.187 +nsXPCComponents_Interfaces::GetImplementationLanguage(uint32_t *aImplementationLanguage) 1.188 +{ 1.189 + *aImplementationLanguage = nsIProgrammingLanguage::CPLUSPLUS; 1.190 + return NS_OK; 1.191 +} 1.192 + 1.193 +/* readonly attribute uint32_t flags; */ 1.194 +NS_IMETHODIMP 1.195 +nsXPCComponents_Interfaces::GetFlags(uint32_t *aFlags) 1.196 +{ 1.197 + // Mark ourselves as a DOM object so that instances may be created in 1.198 + // unprivileged scopes. 1.199 + *aFlags = nsIClassInfo::DOM_OBJECT; 1.200 + return NS_OK; 1.201 +} 1.202 + 1.203 +/* [notxpcom] readonly attribute nsCID classIDNoAlloc; */ 1.204 +NS_IMETHODIMP 1.205 +nsXPCComponents_Interfaces::GetClassIDNoAlloc(nsCID *aClassIDNoAlloc) 1.206 +{ 1.207 + return NS_ERROR_NOT_AVAILABLE; 1.208 +} 1.209 + 1.210 +nsXPCComponents_Interfaces::nsXPCComponents_Interfaces() 1.211 +{ 1.212 +} 1.213 + 1.214 +nsXPCComponents_Interfaces::~nsXPCComponents_Interfaces() 1.215 +{ 1.216 + // empty 1.217 +} 1.218 + 1.219 + 1.220 +NS_INTERFACE_MAP_BEGIN(nsXPCComponents_Interfaces) 1.221 + NS_INTERFACE_MAP_ENTRY(nsIXPCComponents_Interfaces) 1.222 + NS_INTERFACE_MAP_ENTRY(nsIXPCScriptable) 1.223 + NS_INTERFACE_MAP_ENTRY(nsIClassInfo) 1.224 + NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIXPCComponents_Interfaces) 1.225 +NS_INTERFACE_MAP_END 1.226 + 1.227 +NS_IMPL_ADDREF(nsXPCComponents_Interfaces) 1.228 +NS_IMPL_RELEASE(nsXPCComponents_Interfaces) 1.229 + 1.230 +// The nsIXPCScriptable map declaration that will generate stubs for us... 1.231 +#define XPC_MAP_CLASSNAME nsXPCComponents_Interfaces 1.232 +#define XPC_MAP_QUOTED_CLASSNAME "nsXPCComponents_Interfaces" 1.233 +#define XPC_MAP_WANT_NEWRESOLVE 1.234 +#define XPC_MAP_WANT_NEWENUMERATE 1.235 +#define XPC_MAP_FLAGS nsIXPCScriptable::DONT_ENUM_STATIC_PROPS |\ 1.236 + nsIXPCScriptable::ALLOW_PROP_MODS_DURING_RESOLVE 1.237 +#include "xpc_map_end.h" /* This will #undef the above */ 1.238 + 1.239 + 1.240 +/* bool newEnumerate (in nsIXPConnectWrappedNative wrapper, in JSContextPtr cx, in JSObjectPtr obj, in uint32_t enum_op, in JSValPtr statep, out JSID idp); */ 1.241 +NS_IMETHODIMP 1.242 +nsXPCComponents_Interfaces::NewEnumerate(nsIXPConnectWrappedNative *wrapper, 1.243 + JSContext * cx, JSObject * obj, 1.244 + uint32_t enum_op, jsval * statep, 1.245 + jsid * idp, bool *_retval) 1.246 +{ 1.247 + switch (enum_op) { 1.248 + case JSENUMERATE_INIT: 1.249 + case JSENUMERATE_INIT_ALL: 1.250 + { 1.251 + // Lazily init the list of interfaces when someone tries to 1.252 + // enumerate them. 1.253 + if (mInterfaces.IsEmpty()) { 1.254 + XPTInterfaceInfoManager::GetSingleton()-> 1.255 + GetScriptableInterfaces(mInterfaces); 1.256 + } 1.257 + 1.258 + *statep = JSVAL_ZERO; 1.259 + if (idp) 1.260 + *idp = INT_TO_JSID(mInterfaces.Length()); 1.261 + return NS_OK; 1.262 + } 1.263 + case JSENUMERATE_NEXT: 1.264 + { 1.265 + uint32_t idx = JSVAL_TO_INT(*statep); 1.266 + nsIInterfaceInfo* interface = mInterfaces.SafeElementAt(idx); 1.267 + *statep = UINT_TO_JSVAL(idx + 1); 1.268 + 1.269 + if (interface) { 1.270 + const char* name; 1.271 + 1.272 + RootedId id(cx); 1.273 + if (NS_SUCCEEDED(interface->GetNameShared(&name)) && name) { 1.274 + RootedString idstr(cx, JS_NewStringCopyZ(cx, name)); 1.275 + if (idstr && JS_StringToId(cx, idstr, &id)) { 1.276 + *idp = id; 1.277 + return NS_OK; 1.278 + } 1.279 + } 1.280 + } 1.281 + // fall through 1.282 + } 1.283 + 1.284 + case JSENUMERATE_DESTROY: 1.285 + default: 1.286 + *statep = JSVAL_NULL; 1.287 + return NS_OK; 1.288 + } 1.289 +} 1.290 + 1.291 +/* bool newResolve (in nsIXPConnectWrappedNative wrapper, in JSContextPtr cx, in JSObjectPtr obj, in jsval id, out JSObjectPtr objp); */ 1.292 +NS_IMETHODIMP 1.293 +nsXPCComponents_Interfaces::NewResolve(nsIXPConnectWrappedNative *wrapper, 1.294 + JSContext *cx, JSObject *objArg, 1.295 + jsid idArg, JSObject **objp, 1.296 + bool *_retval) 1.297 +{ 1.298 + RootedObject obj(cx, objArg); 1.299 + RootedId id(cx, idArg); 1.300 + 1.301 + if (!JSID_IS_STRING(id)) 1.302 + return NS_OK; 1.303 + 1.304 + JSAutoByteString name; 1.305 + RootedString str(cx, JSID_TO_STRING(id)); 1.306 + 1.307 + // we only allow interfaces by name here 1.308 + if (name.encodeLatin1(cx, str) && name.ptr()[0] != '{') { 1.309 + nsCOMPtr<nsIInterfaceInfo> info; 1.310 + XPTInterfaceInfoManager::GetSingleton()-> 1.311 + GetInfoForName(name.ptr(), getter_AddRefs(info)); 1.312 + if (!info) 1.313 + return NS_OK; 1.314 + 1.315 + nsCOMPtr<nsIJSIID> nsid = nsJSIID::NewID(info); 1.316 + 1.317 + if (nsid) { 1.318 + nsXPConnect* xpc = nsXPConnect::XPConnect(); 1.319 + nsCOMPtr<nsIXPConnectJSObjectHolder> holder; 1.320 + if (NS_SUCCEEDED(xpc->WrapNative(cx, obj, 1.321 + static_cast<nsIJSIID*>(nsid), 1.322 + NS_GET_IID(nsIJSIID), 1.323 + getter_AddRefs(holder)))) { 1.324 + RootedObject idobj(cx); 1.325 + if (holder && 1.326 + // Assign, not compare 1.327 + (idobj = holder->GetJSObject())) { 1.328 + *objp = obj; 1.329 + *_retval = JS_DefinePropertyById(cx, obj, id, 1.330 + OBJECT_TO_JSVAL(idobj), 1.331 + nullptr, nullptr, 1.332 + JSPROP_ENUMERATE | 1.333 + JSPROP_READONLY | 1.334 + JSPROP_PERMANENT); 1.335 + } 1.336 + } 1.337 + } 1.338 + } 1.339 + return NS_OK; 1.340 +} 1.341 + 1.342 +/***************************************************************************/ 1.343 +/***************************************************************************/ 1.344 +/***************************************************************************/ 1.345 + 1.346 +class nsXPCComponents_InterfacesByID : 1.347 + public nsIXPCComponents_InterfacesByID, 1.348 + public nsIXPCScriptable, 1.349 + public nsIClassInfo 1.350 +{ 1.351 +public: 1.352 + // all the interface method declarations... 1.353 + NS_DECL_ISUPPORTS 1.354 + NS_DECL_NSIXPCCOMPONENTS_INTERFACESBYID 1.355 + NS_DECL_NSIXPCSCRIPTABLE 1.356 + NS_DECL_NSICLASSINFO 1.357 + 1.358 +public: 1.359 + nsXPCComponents_InterfacesByID(); 1.360 + virtual ~nsXPCComponents_InterfacesByID(); 1.361 + 1.362 +private: 1.363 + nsCOMArray<nsIInterfaceInfo> mInterfaces; 1.364 +}; 1.365 + 1.366 +/***************************************************************************/ 1.367 +/* void getInterfaces (out uint32_t count, [array, size_is (count), retval] 1.368 + out nsIIDPtr array); */ 1.369 +NS_IMETHODIMP 1.370 +nsXPCComponents_InterfacesByID::GetInterfaces(uint32_t *aCount, nsIID * **aArray) 1.371 +{ 1.372 + const uint32_t count = 2; 1.373 + *aCount = count; 1.374 + nsIID **array; 1.375 + *aArray = array = static_cast<nsIID**>(nsMemory::Alloc(count * sizeof(nsIID*))); 1.376 + if (!array) 1.377 + return NS_ERROR_OUT_OF_MEMORY; 1.378 + 1.379 + uint32_t index = 0; 1.380 + nsIID* clone; 1.381 +#define PUSH_IID(id) \ 1.382 + clone = static_cast<nsIID *>(nsMemory::Clone(&NS_GET_IID( id ), \ 1.383 + sizeof(nsIID))); \ 1.384 + if (!clone) \ 1.385 + goto oom; \ 1.386 + array[index++] = clone; 1.387 + 1.388 + PUSH_IID(nsIXPCComponents_InterfacesByID) 1.389 + PUSH_IID(nsIXPCScriptable) 1.390 +#undef PUSH_IID 1.391 + 1.392 + return NS_OK; 1.393 +oom: 1.394 + while (index) 1.395 + nsMemory::Free(array[--index]); 1.396 + nsMemory::Free(array); 1.397 + *aArray = nullptr; 1.398 + return NS_ERROR_OUT_OF_MEMORY; 1.399 +} 1.400 + 1.401 +/* nsISupports getHelperForLanguage (in uint32_t language); */ 1.402 +NS_IMETHODIMP 1.403 +nsXPCComponents_InterfacesByID::GetHelperForLanguage(uint32_t language, 1.404 + nsISupports **retval) 1.405 +{ 1.406 + *retval = nullptr; 1.407 + return NS_OK; 1.408 +} 1.409 + 1.410 +/* readonly attribute string contractID; */ 1.411 +NS_IMETHODIMP 1.412 +nsXPCComponents_InterfacesByID::GetContractID(char * *aContractID) 1.413 +{ 1.414 + *aContractID = nullptr; 1.415 + return NS_ERROR_NOT_AVAILABLE; 1.416 +} 1.417 + 1.418 +/* readonly attribute string classDescription; */ 1.419 +NS_IMETHODIMP 1.420 +nsXPCComponents_InterfacesByID::GetClassDescription(char * *aClassDescription) 1.421 +{ 1.422 + static const char classDescription[] = "XPCComponents_InterfacesByID"; 1.423 + *aClassDescription = (char*)nsMemory::Clone(classDescription, sizeof(classDescription)); 1.424 + return *aClassDescription ? NS_OK : NS_ERROR_OUT_OF_MEMORY; 1.425 +} 1.426 + 1.427 +/* readonly attribute nsCIDPtr classID; */ 1.428 +NS_IMETHODIMP 1.429 +nsXPCComponents_InterfacesByID::GetClassID(nsCID * *aClassID) 1.430 +{ 1.431 + *aClassID = nullptr; 1.432 + return NS_OK; 1.433 +} 1.434 + 1.435 +/* readonly attribute uint32_t implementationLanguage; */ 1.436 +NS_IMETHODIMP 1.437 +nsXPCComponents_InterfacesByID::GetImplementationLanguage(uint32_t *aImplementationLanguage) 1.438 +{ 1.439 + *aImplementationLanguage = nsIProgrammingLanguage::CPLUSPLUS; 1.440 + return NS_OK; 1.441 +} 1.442 + 1.443 +/* readonly attribute uint32_t flags; */ 1.444 +NS_IMETHODIMP 1.445 +nsXPCComponents_InterfacesByID::GetFlags(uint32_t *aFlags) 1.446 +{ 1.447 + // Mark ourselves as a DOM object so that instances may be created in 1.448 + // unprivileged scopes. 1.449 + *aFlags = nsIClassInfo::DOM_OBJECT; 1.450 + return NS_OK; 1.451 +} 1.452 + 1.453 +/* [notxpcom] readonly attribute nsCID classIDNoAlloc; */ 1.454 +NS_IMETHODIMP 1.455 +nsXPCComponents_InterfacesByID::GetClassIDNoAlloc(nsCID *aClassIDNoAlloc) 1.456 +{ 1.457 + return NS_ERROR_NOT_AVAILABLE; 1.458 +} 1.459 + 1.460 +nsXPCComponents_InterfacesByID::nsXPCComponents_InterfacesByID() 1.461 +{ 1.462 +} 1.463 + 1.464 +nsXPCComponents_InterfacesByID::~nsXPCComponents_InterfacesByID() 1.465 +{ 1.466 + // empty 1.467 +} 1.468 + 1.469 +NS_INTERFACE_MAP_BEGIN(nsXPCComponents_InterfacesByID) 1.470 + NS_INTERFACE_MAP_ENTRY(nsIXPCComponents_InterfacesByID) 1.471 + NS_INTERFACE_MAP_ENTRY(nsIXPCScriptable) 1.472 + NS_INTERFACE_MAP_ENTRY(nsIClassInfo) 1.473 + NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIXPCComponents_InterfacesByID) 1.474 +NS_INTERFACE_MAP_END 1.475 + 1.476 +NS_IMPL_ADDREF(nsXPCComponents_InterfacesByID) 1.477 +NS_IMPL_RELEASE(nsXPCComponents_InterfacesByID) 1.478 + 1.479 +// The nsIXPCScriptable map declaration that will generate stubs for us... 1.480 +#define XPC_MAP_CLASSNAME nsXPCComponents_InterfacesByID 1.481 +#define XPC_MAP_QUOTED_CLASSNAME "nsXPCComponents_InterfacesByID" 1.482 +#define XPC_MAP_WANT_NEWRESOLVE 1.483 +#define XPC_MAP_WANT_NEWENUMERATE 1.484 +#define XPC_MAP_FLAGS nsIXPCScriptable::DONT_ENUM_STATIC_PROPS |\ 1.485 + nsIXPCScriptable::ALLOW_PROP_MODS_DURING_RESOLVE 1.486 +#include "xpc_map_end.h" /* This will #undef the above */ 1.487 + 1.488 +/* bool newEnumerate (in nsIXPConnectWrappedNative wrapper, in JSContextPtr cx, in JSObjectPtr obj, in uint32_t enum_op, in JSValPtr statep, out JSID idp); */ 1.489 +NS_IMETHODIMP 1.490 +nsXPCComponents_InterfacesByID::NewEnumerate(nsIXPConnectWrappedNative *wrapper, 1.491 + JSContext * cx, JSObject * obj, 1.492 + uint32_t enum_op, jsval * statep, 1.493 + jsid * idp, bool *_retval) 1.494 +{ 1.495 + switch (enum_op) { 1.496 + case JSENUMERATE_INIT: 1.497 + case JSENUMERATE_INIT_ALL: 1.498 + { 1.499 + // Lazily init the list of interfaces when someone tries to 1.500 + // enumerate them. 1.501 + if (mInterfaces.IsEmpty()) { 1.502 + XPTInterfaceInfoManager::GetSingleton()-> 1.503 + GetScriptableInterfaces(mInterfaces); 1.504 + } 1.505 + 1.506 + *statep = JSVAL_ZERO; 1.507 + if (idp) 1.508 + *idp = INT_TO_JSID(mInterfaces.Length()); 1.509 + return NS_OK; 1.510 + } 1.511 + case JSENUMERATE_NEXT: 1.512 + { 1.513 + uint32_t idx = JSVAL_TO_INT(*statep); 1.514 + nsIInterfaceInfo* interface = mInterfaces.SafeElementAt(idx); 1.515 + *statep = UINT_TO_JSVAL(idx + 1); 1.516 + if (interface) { 1.517 + nsIID const *iid; 1.518 + char idstr[NSID_LENGTH]; 1.519 + 1.520 + if (NS_SUCCEEDED(interface->GetIIDShared(&iid))) { 1.521 + iid->ToProvidedString(idstr); 1.522 + RootedString jsstr(cx, JS_NewStringCopyZ(cx, idstr)); 1.523 + RootedId id(cx); 1.524 + if (jsstr && JS_StringToId(cx, jsstr, &id)) { 1.525 + *idp = id; 1.526 + return NS_OK; 1.527 + } 1.528 + } 1.529 + } 1.530 + // FALL THROUGH 1.531 + } 1.532 + 1.533 + case JSENUMERATE_DESTROY: 1.534 + default: 1.535 + *statep = JSVAL_NULL; 1.536 + return NS_OK; 1.537 + } 1.538 +} 1.539 + 1.540 +/* bool newResolve (in nsIXPConnectWrappedNative wrapper, in JSContextPtr cx, in JSObjectPtr obj, in jsval id, out JSObjectPtr objp); */ 1.541 +NS_IMETHODIMP 1.542 +nsXPCComponents_InterfacesByID::NewResolve(nsIXPConnectWrappedNative *wrapper, 1.543 + JSContext *cx, JSObject *objArg, 1.544 + jsid idArg, JSObject **objp, 1.545 + bool *_retval) 1.546 +{ 1.547 + RootedObject obj(cx, objArg); 1.548 + RootedId id(cx, idArg); 1.549 + 1.550 + if (!JSID_IS_STRING(id)) 1.551 + return NS_OK; 1.552 + 1.553 + RootedString str(cx, JSID_TO_STRING(id)); 1.554 + if (38 != JS_GetStringLength(str)) 1.555 + return NS_OK; 1.556 + 1.557 + if (const jschar *name = JS_GetInternedStringChars(str)) { 1.558 + nsID iid; 1.559 + if (!iid.Parse(NS_ConvertUTF16toUTF8(name).get())) 1.560 + return NS_OK; 1.561 + 1.562 + nsCOMPtr<nsIInterfaceInfo> info; 1.563 + XPTInterfaceInfoManager::GetSingleton()-> 1.564 + GetInfoForIID(&iid, getter_AddRefs(info)); 1.565 + if (!info) 1.566 + return NS_OK; 1.567 + 1.568 + nsCOMPtr<nsIJSIID> nsid = nsJSIID::NewID(info); 1.569 + 1.570 + if (!nsid) 1.571 + return NS_ERROR_OUT_OF_MEMORY; 1.572 + 1.573 + nsXPConnect* xpc = nsXPConnect::XPConnect(); 1.574 + nsCOMPtr<nsIXPConnectJSObjectHolder> holder; 1.575 + if (NS_SUCCEEDED(xpc->WrapNative(cx, obj, 1.576 + static_cast<nsIJSIID*>(nsid), 1.577 + NS_GET_IID(nsIJSIID), 1.578 + getter_AddRefs(holder)))) { 1.579 + RootedObject idobj(cx); 1.580 + if (holder && 1.581 + // Assign, not compare 1.582 + (idobj = holder->GetJSObject())) { 1.583 + *objp = obj; 1.584 + *_retval = 1.585 + JS_DefinePropertyById(cx, obj, id, 1.586 + OBJECT_TO_JSVAL(idobj), 1.587 + nullptr, nullptr, 1.588 + JSPROP_ENUMERATE | 1.589 + JSPROP_READONLY | 1.590 + JSPROP_PERMANENT); 1.591 + } 1.592 + } 1.593 + } 1.594 + return NS_OK; 1.595 +} 1.596 + 1.597 +/***************************************************************************/ 1.598 +/***************************************************************************/ 1.599 +/***************************************************************************/ 1.600 + 1.601 + 1.602 + 1.603 +class nsXPCComponents_Classes : 1.604 + public nsIXPCComponents_Classes, 1.605 + public nsIXPCScriptable, 1.606 + public nsIClassInfo 1.607 +{ 1.608 +public: 1.609 + // all the interface method declarations... 1.610 + NS_DECL_ISUPPORTS 1.611 + NS_DECL_NSIXPCCOMPONENTS_CLASSES 1.612 + NS_DECL_NSIXPCSCRIPTABLE 1.613 + NS_DECL_NSICLASSINFO 1.614 + 1.615 +public: 1.616 + nsXPCComponents_Classes(); 1.617 + virtual ~nsXPCComponents_Classes(); 1.618 +}; 1.619 + 1.620 +/***************************************************************************/ 1.621 +/* void getInterfaces (out uint32_t count, [array, size_is (count), retval] 1.622 + out nsIIDPtr array); */ 1.623 +NS_IMETHODIMP 1.624 +nsXPCComponents_Classes::GetInterfaces(uint32_t *aCount, nsIID * **aArray) 1.625 +{ 1.626 + const uint32_t count = 2; 1.627 + *aCount = count; 1.628 + nsIID **array; 1.629 + *aArray = array = static_cast<nsIID**>(nsMemory::Alloc(count * sizeof(nsIID*))); 1.630 + if (!array) 1.631 + return NS_ERROR_OUT_OF_MEMORY; 1.632 + 1.633 + uint32_t index = 0; 1.634 + nsIID* clone; 1.635 +#define PUSH_IID(id) \ 1.636 + clone = static_cast<nsIID *>(nsMemory::Clone(&NS_GET_IID( id ), \ 1.637 + sizeof(nsIID))); \ 1.638 + if (!clone) \ 1.639 + goto oom; \ 1.640 + array[index++] = clone; 1.641 + 1.642 + PUSH_IID(nsIXPCComponents_Classes) 1.643 + PUSH_IID(nsIXPCScriptable) 1.644 +#undef PUSH_IID 1.645 + 1.646 + return NS_OK; 1.647 +oom: 1.648 + while (index) 1.649 + nsMemory::Free(array[--index]); 1.650 + nsMemory::Free(array); 1.651 + *aArray = nullptr; 1.652 + return NS_ERROR_OUT_OF_MEMORY; 1.653 +} 1.654 + 1.655 +/* nsISupports getHelperForLanguage (in uint32_t language); */ 1.656 +NS_IMETHODIMP 1.657 +nsXPCComponents_Classes::GetHelperForLanguage(uint32_t language, 1.658 + nsISupports **retval) 1.659 +{ 1.660 + *retval = nullptr; 1.661 + return NS_OK; 1.662 +} 1.663 + 1.664 +/* readonly attribute string contractID; */ 1.665 +NS_IMETHODIMP 1.666 +nsXPCComponents_Classes::GetContractID(char * *aContractID) 1.667 +{ 1.668 + *aContractID = nullptr; 1.669 + return NS_ERROR_NOT_AVAILABLE; 1.670 +} 1.671 + 1.672 +/* readonly attribute string classDescription; */ 1.673 +NS_IMETHODIMP 1.674 +nsXPCComponents_Classes::GetClassDescription(char * *aClassDescription) 1.675 +{ 1.676 + static const char classDescription[] = "XPCComponents_Classes"; 1.677 + *aClassDescription = (char*)nsMemory::Clone(classDescription, sizeof(classDescription)); 1.678 + return *aClassDescription ? NS_OK : NS_ERROR_OUT_OF_MEMORY; 1.679 +} 1.680 + 1.681 +/* readonly attribute nsCIDPtr classID; */ 1.682 +NS_IMETHODIMP 1.683 +nsXPCComponents_Classes::GetClassID(nsCID * *aClassID) 1.684 +{ 1.685 + *aClassID = nullptr; 1.686 + return NS_OK; 1.687 +} 1.688 + 1.689 +/* readonly attribute uint32_t implementationLanguage; */ 1.690 +NS_IMETHODIMP 1.691 +nsXPCComponents_Classes::GetImplementationLanguage(uint32_t *aImplementationLanguage) 1.692 +{ 1.693 + *aImplementationLanguage = nsIProgrammingLanguage::CPLUSPLUS; 1.694 + return NS_OK; 1.695 +} 1.696 + 1.697 +/* readonly attribute uint32_t flags; */ 1.698 +NS_IMETHODIMP 1.699 +nsXPCComponents_Classes::GetFlags(uint32_t *aFlags) 1.700 +{ 1.701 + *aFlags = 0; 1.702 + return NS_OK; 1.703 +} 1.704 + 1.705 +/* [notxpcom] readonly attribute nsCID classIDNoAlloc; */ 1.706 +NS_IMETHODIMP 1.707 +nsXPCComponents_Classes::GetClassIDNoAlloc(nsCID *aClassIDNoAlloc) 1.708 +{ 1.709 + return NS_ERROR_NOT_AVAILABLE; 1.710 +} 1.711 + 1.712 +nsXPCComponents_Classes::nsXPCComponents_Classes() 1.713 +{ 1.714 +} 1.715 + 1.716 +nsXPCComponents_Classes::~nsXPCComponents_Classes() 1.717 +{ 1.718 + // empty 1.719 +} 1.720 + 1.721 +NS_INTERFACE_MAP_BEGIN(nsXPCComponents_Classes) 1.722 + NS_INTERFACE_MAP_ENTRY(nsIXPCComponents_Classes) 1.723 + NS_INTERFACE_MAP_ENTRY(nsIXPCScriptable) 1.724 + NS_INTERFACE_MAP_ENTRY(nsIClassInfo) 1.725 + NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIXPCComponents_Classes) 1.726 +NS_INTERFACE_MAP_END 1.727 + 1.728 +NS_IMPL_ADDREF(nsXPCComponents_Classes) 1.729 +NS_IMPL_RELEASE(nsXPCComponents_Classes) 1.730 + 1.731 +// The nsIXPCScriptable map declaration that will generate stubs for us... 1.732 +#define XPC_MAP_CLASSNAME nsXPCComponents_Classes 1.733 +#define XPC_MAP_QUOTED_CLASSNAME "nsXPCComponents_Classes" 1.734 +#define XPC_MAP_WANT_NEWRESOLVE 1.735 +#define XPC_MAP_WANT_NEWENUMERATE 1.736 +#define XPC_MAP_FLAGS nsIXPCScriptable::DONT_ENUM_STATIC_PROPS |\ 1.737 + nsIXPCScriptable::ALLOW_PROP_MODS_DURING_RESOLVE 1.738 +#include "xpc_map_end.h" /* This will #undef the above */ 1.739 + 1.740 + 1.741 +/* bool newEnumerate (in nsIXPConnectWrappedNative wrapper, in JSContextPtr cx, in JSObjectPtr obj, in uint32_t enum_op, in JSValPtr statep, out JSID idp); */ 1.742 +NS_IMETHODIMP 1.743 +nsXPCComponents_Classes::NewEnumerate(nsIXPConnectWrappedNative *wrapper, 1.744 + JSContext * cx, JSObject * obj, 1.745 + uint32_t enum_op, jsval * statep, 1.746 + jsid * idp, bool *_retval) 1.747 +{ 1.748 + nsISimpleEnumerator* e; 1.749 + 1.750 + switch (enum_op) { 1.751 + case JSENUMERATE_INIT: 1.752 + case JSENUMERATE_INIT_ALL: 1.753 + { 1.754 + nsCOMPtr<nsIComponentRegistrar> compMgr; 1.755 + if (NS_FAILED(NS_GetComponentRegistrar(getter_AddRefs(compMgr))) || !compMgr || 1.756 + NS_FAILED(compMgr->EnumerateContractIDs(&e)) || !e ) { 1.757 + *statep = JSVAL_NULL; 1.758 + return NS_ERROR_UNEXPECTED; 1.759 + } 1.760 + 1.761 + *statep = PRIVATE_TO_JSVAL(e); 1.762 + if (idp) 1.763 + *idp = INT_TO_JSID(0); // indicate that we don't know the count 1.764 + return NS_OK; 1.765 + } 1.766 + case JSENUMERATE_NEXT: 1.767 + { 1.768 + nsCOMPtr<nsISupports> isup; 1.769 + bool hasMore; 1.770 + e = (nsISimpleEnumerator*) JSVAL_TO_PRIVATE(*statep); 1.771 + 1.772 + if (NS_SUCCEEDED(e->HasMoreElements(&hasMore)) && hasMore && 1.773 + NS_SUCCEEDED(e->GetNext(getter_AddRefs(isup))) && isup) { 1.774 + nsCOMPtr<nsISupportsCString> holder(do_QueryInterface(isup)); 1.775 + if (holder) { 1.776 + nsAutoCString name; 1.777 + if (NS_SUCCEEDED(holder->GetData(name))) { 1.778 + RootedString idstr(cx, JS_NewStringCopyN(cx, name.get(), name.Length())); 1.779 + RootedId id(cx); 1.780 + if (idstr && JS_StringToId(cx, idstr, &id)) { 1.781 + *idp = id; 1.782 + return NS_OK; 1.783 + } 1.784 + } 1.785 + } 1.786 + } 1.787 + // else... FALL THROUGH 1.788 + } 1.789 + 1.790 + case JSENUMERATE_DESTROY: 1.791 + default: 1.792 + e = (nsISimpleEnumerator*) JSVAL_TO_PRIVATE(*statep); 1.793 + NS_IF_RELEASE(e); 1.794 + *statep = JSVAL_NULL; 1.795 + return NS_OK; 1.796 + } 1.797 +} 1.798 + 1.799 +/* bool newResolve (in nsIXPConnectWrappedNative wrapper, in JSContextPtr cx, in JSObjectPtr obj, in jsval id, out JSObjectPtr objp); */ 1.800 +NS_IMETHODIMP 1.801 +nsXPCComponents_Classes::NewResolve(nsIXPConnectWrappedNative *wrapper, 1.802 + JSContext *cx, JSObject *objArg, 1.803 + jsid idArg, JSObject **objp, 1.804 + bool *_retval) 1.805 + 1.806 +{ 1.807 + RootedId id(cx, idArg); 1.808 + RootedObject obj(cx, objArg); 1.809 + 1.810 + JSAutoByteString name; 1.811 + if (JSID_IS_STRING(id) && 1.812 + name.encodeLatin1(cx, JSID_TO_STRING(id)) && 1.813 + name.ptr()[0] != '{') { // we only allow contractids here 1.814 + nsCOMPtr<nsIJSCID> nsid = nsJSCID::NewID(name.ptr()); 1.815 + if (nsid) { 1.816 + nsXPConnect* xpc = nsXPConnect::XPConnect(); 1.817 + nsCOMPtr<nsIXPConnectJSObjectHolder> holder; 1.818 + if (NS_SUCCEEDED(xpc->WrapNative(cx, obj, 1.819 + static_cast<nsIJSCID*>(nsid), 1.820 + NS_GET_IID(nsIJSCID), 1.821 + getter_AddRefs(holder)))) { 1.822 + RootedObject idobj(cx); 1.823 + if (holder && 1.824 + // Assign, not compare 1.825 + (idobj = holder->GetJSObject())) { 1.826 + *objp = obj; 1.827 + *_retval = JS_DefinePropertyById(cx, obj, id, 1.828 + OBJECT_TO_JSVAL(idobj), 1.829 + nullptr, nullptr, 1.830 + JSPROP_ENUMERATE | 1.831 + JSPROP_READONLY | 1.832 + JSPROP_PERMANENT); 1.833 + } 1.834 + } 1.835 + } 1.836 + } 1.837 + return NS_OK; 1.838 +} 1.839 + 1.840 +/***************************************************************************/ 1.841 +/***************************************************************************/ 1.842 +/***************************************************************************/ 1.843 + 1.844 +class nsXPCComponents_ClassesByID : 1.845 + public nsIXPCComponents_ClassesByID, 1.846 + public nsIXPCScriptable, 1.847 + public nsIClassInfo 1.848 +{ 1.849 +public: 1.850 + // all the interface method declarations... 1.851 + NS_DECL_ISUPPORTS 1.852 + NS_DECL_NSIXPCCOMPONENTS_CLASSESBYID 1.853 + NS_DECL_NSIXPCSCRIPTABLE 1.854 + NS_DECL_NSICLASSINFO 1.855 + 1.856 +public: 1.857 + nsXPCComponents_ClassesByID(); 1.858 + virtual ~nsXPCComponents_ClassesByID(); 1.859 +}; 1.860 + 1.861 +/***************************************************************************/ 1.862 +/* void getInterfaces (out uint32_t count, [array, size_is (count), retval] 1.863 + out nsIIDPtr array); */ 1.864 +NS_IMETHODIMP 1.865 +nsXPCComponents_ClassesByID::GetInterfaces(uint32_t *aCount, nsIID * **aArray) 1.866 +{ 1.867 + const uint32_t count = 2; 1.868 + *aCount = count; 1.869 + nsIID **array; 1.870 + *aArray = array = static_cast<nsIID**>(nsMemory::Alloc(count * sizeof(nsIID*))); 1.871 + if (!array) 1.872 + return NS_ERROR_OUT_OF_MEMORY; 1.873 + 1.874 + uint32_t index = 0; 1.875 + nsIID* clone; 1.876 +#define PUSH_IID(id) \ 1.877 + clone = static_cast<nsIID *>(nsMemory::Clone(&NS_GET_IID( id ), \ 1.878 + sizeof(nsIID))); \ 1.879 + if (!clone) \ 1.880 + goto oom; \ 1.881 + array[index++] = clone; 1.882 + 1.883 + PUSH_IID(nsIXPCComponents_ClassesByID) 1.884 + PUSH_IID(nsIXPCScriptable) 1.885 +#undef PUSH_IID 1.886 + 1.887 + return NS_OK; 1.888 +oom: 1.889 + while (index) 1.890 + nsMemory::Free(array[--index]); 1.891 + nsMemory::Free(array); 1.892 + *aArray = nullptr; 1.893 + return NS_ERROR_OUT_OF_MEMORY; 1.894 +} 1.895 + 1.896 +/* nsISupports getHelperForLanguage (in uint32_t language); */ 1.897 +NS_IMETHODIMP 1.898 +nsXPCComponents_ClassesByID::GetHelperForLanguage(uint32_t language, 1.899 + nsISupports **retval) 1.900 +{ 1.901 + *retval = nullptr; 1.902 + return NS_OK; 1.903 +} 1.904 + 1.905 +/* readonly attribute string contractID; */ 1.906 +NS_IMETHODIMP 1.907 +nsXPCComponents_ClassesByID::GetContractID(char * *aContractID) 1.908 +{ 1.909 + *aContractID = nullptr; 1.910 + return NS_ERROR_NOT_AVAILABLE; 1.911 +} 1.912 + 1.913 +/* readonly attribute string classDescription; */ 1.914 +NS_IMETHODIMP 1.915 +nsXPCComponents_ClassesByID::GetClassDescription(char * *aClassDescription) 1.916 +{ 1.917 + static const char classDescription[] = "XPCComponents_ClassesByID"; 1.918 + *aClassDescription = (char*)nsMemory::Clone(classDescription, sizeof(classDescription)); 1.919 + return *aClassDescription ? NS_OK : NS_ERROR_OUT_OF_MEMORY; 1.920 +} 1.921 + 1.922 +/* readonly attribute nsCIDPtr classID; */ 1.923 +NS_IMETHODIMP 1.924 +nsXPCComponents_ClassesByID::GetClassID(nsCID * *aClassID) 1.925 +{ 1.926 + *aClassID = nullptr; 1.927 + return NS_OK; 1.928 +} 1.929 + 1.930 +/* readonly attribute uint32_t implementationLanguage; */ 1.931 +NS_IMETHODIMP 1.932 +nsXPCComponents_ClassesByID::GetImplementationLanguage(uint32_t *aImplementationLanguage) 1.933 +{ 1.934 + *aImplementationLanguage = nsIProgrammingLanguage::CPLUSPLUS; 1.935 + return NS_OK; 1.936 +} 1.937 + 1.938 +/* readonly attribute uint32_t flags; */ 1.939 +NS_IMETHODIMP 1.940 +nsXPCComponents_ClassesByID::GetFlags(uint32_t *aFlags) 1.941 +{ 1.942 + *aFlags = 0; 1.943 + return NS_OK; 1.944 +} 1.945 + 1.946 +/* [notxpcom] readonly attribute nsCID classIDNoAlloc; */ 1.947 +NS_IMETHODIMP 1.948 +nsXPCComponents_ClassesByID::GetClassIDNoAlloc(nsCID *aClassIDNoAlloc) 1.949 +{ 1.950 + return NS_ERROR_NOT_AVAILABLE; 1.951 +} 1.952 + 1.953 +nsXPCComponents_ClassesByID::nsXPCComponents_ClassesByID() 1.954 +{ 1.955 +} 1.956 + 1.957 +nsXPCComponents_ClassesByID::~nsXPCComponents_ClassesByID() 1.958 +{ 1.959 + // empty 1.960 +} 1.961 + 1.962 +NS_INTERFACE_MAP_BEGIN(nsXPCComponents_ClassesByID) 1.963 + NS_INTERFACE_MAP_ENTRY(nsIXPCComponents_ClassesByID) 1.964 + NS_INTERFACE_MAP_ENTRY(nsIXPCScriptable) 1.965 + NS_INTERFACE_MAP_ENTRY(nsIClassInfo) 1.966 + NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIXPCComponents_ClassesByID) 1.967 +NS_INTERFACE_MAP_END 1.968 + 1.969 +NS_IMPL_ADDREF(nsXPCComponents_ClassesByID) 1.970 +NS_IMPL_RELEASE(nsXPCComponents_ClassesByID) 1.971 + 1.972 +// The nsIXPCScriptable map declaration that will generate stubs for us... 1.973 +#define XPC_MAP_CLASSNAME nsXPCComponents_ClassesByID 1.974 +#define XPC_MAP_QUOTED_CLASSNAME "nsXPCComponents_ClassesByID" 1.975 +#define XPC_MAP_WANT_NEWRESOLVE 1.976 +#define XPC_MAP_WANT_NEWENUMERATE 1.977 +#define XPC_MAP_FLAGS nsIXPCScriptable::DONT_ENUM_STATIC_PROPS |\ 1.978 + nsIXPCScriptable::ALLOW_PROP_MODS_DURING_RESOLVE 1.979 +#include "xpc_map_end.h" /* This will #undef the above */ 1.980 + 1.981 +/* bool newEnumerate (in nsIXPConnectWrappedNative wrapper, in JSContextPtr cx, in JSObjectPtr obj, in uint32_t enum_op, in JSValPtr statep, out JSID idp); */ 1.982 +NS_IMETHODIMP 1.983 +nsXPCComponents_ClassesByID::NewEnumerate(nsIXPConnectWrappedNative *wrapper, 1.984 + JSContext * cx, JSObject * obj, 1.985 + uint32_t enum_op, jsval * statep, 1.986 + jsid * idp, bool *_retval) 1.987 +{ 1.988 + nsISimpleEnumerator* e; 1.989 + 1.990 + switch (enum_op) { 1.991 + case JSENUMERATE_INIT: 1.992 + case JSENUMERATE_INIT_ALL: 1.993 + { 1.994 + nsCOMPtr<nsIComponentRegistrar> compMgr; 1.995 + if (NS_FAILED(NS_GetComponentRegistrar(getter_AddRefs(compMgr))) || !compMgr || 1.996 + NS_FAILED(compMgr->EnumerateCIDs(&e)) || !e ) { 1.997 + *statep = JSVAL_NULL; 1.998 + return NS_ERROR_UNEXPECTED; 1.999 + } 1.1000 + 1.1001 + *statep = PRIVATE_TO_JSVAL(e); 1.1002 + if (idp) 1.1003 + *idp = INT_TO_JSID(0); // indicate that we don't know the count 1.1004 + return NS_OK; 1.1005 + } 1.1006 + case JSENUMERATE_NEXT: 1.1007 + { 1.1008 + nsCOMPtr<nsISupports> isup; 1.1009 + bool hasMore; 1.1010 + e = (nsISimpleEnumerator*) JSVAL_TO_PRIVATE(*statep); 1.1011 + 1.1012 + if (NS_SUCCEEDED(e->HasMoreElements(&hasMore)) && hasMore && 1.1013 + NS_SUCCEEDED(e->GetNext(getter_AddRefs(isup))) && isup) { 1.1014 + nsCOMPtr<nsISupportsID> holder(do_QueryInterface(isup)); 1.1015 + if (holder) { 1.1016 + char* name; 1.1017 + if (NS_SUCCEEDED(holder->ToString(&name)) && name) { 1.1018 + RootedString idstr(cx, JS_NewStringCopyZ(cx, name)); 1.1019 + nsMemory::Free(name); 1.1020 + RootedId id(cx); 1.1021 + if (idstr && JS_StringToId(cx, idstr, &id)) { 1.1022 + *idp = id; 1.1023 + return NS_OK; 1.1024 + } 1.1025 + } 1.1026 + } 1.1027 + } 1.1028 + // else... FALL THROUGH 1.1029 + } 1.1030 + 1.1031 + case JSENUMERATE_DESTROY: 1.1032 + default: 1.1033 + e = (nsISimpleEnumerator*) JSVAL_TO_PRIVATE(*statep); 1.1034 + NS_IF_RELEASE(e); 1.1035 + *statep = JSVAL_NULL; 1.1036 + return NS_OK; 1.1037 + } 1.1038 +} 1.1039 + 1.1040 +static bool 1.1041 +IsRegisteredCLSID(const char* str) 1.1042 +{ 1.1043 + bool registered; 1.1044 + nsID id; 1.1045 + 1.1046 + if (!id.Parse(str)) 1.1047 + return false; 1.1048 + 1.1049 + nsCOMPtr<nsIComponentRegistrar> compMgr; 1.1050 + if (NS_FAILED(NS_GetComponentRegistrar(getter_AddRefs(compMgr))) || !compMgr || 1.1051 + NS_FAILED(compMgr->IsCIDRegistered(id, ®istered))) 1.1052 + return false; 1.1053 + 1.1054 + return registered; 1.1055 +} 1.1056 + 1.1057 +/* bool newResolve (in nsIXPConnectWrappedNative wrapper, in JSContextPtr cx, in JSObjectPtr obj, in jsval id, out JSObjectPtr objp); */ 1.1058 +NS_IMETHODIMP 1.1059 +nsXPCComponents_ClassesByID::NewResolve(nsIXPConnectWrappedNative *wrapper, 1.1060 + JSContext *cx, JSObject *objArg, 1.1061 + jsid idArg, JSObject **objp, 1.1062 + bool *_retval) 1.1063 +{ 1.1064 + RootedObject obj(cx, objArg); 1.1065 + RootedId id(cx, idArg); 1.1066 + 1.1067 + if (!JSID_IS_STRING(id)) 1.1068 + return NS_OK; 1.1069 + 1.1070 + JSAutoByteString name; 1.1071 + RootedString str(cx, JSID_TO_STRING(id)); 1.1072 + if (name.encodeLatin1(cx, str) && name.ptr()[0] == '{' && 1.1073 + IsRegisteredCLSID(name.ptr())) // we only allow canonical CLSIDs here 1.1074 + { 1.1075 + nsCOMPtr<nsIJSCID> nsid = nsJSCID::NewID(name.ptr()); 1.1076 + if (nsid) { 1.1077 + nsXPConnect* xpc = nsXPConnect::XPConnect(); 1.1078 + nsCOMPtr<nsIXPConnectJSObjectHolder> holder; 1.1079 + if (NS_SUCCEEDED(xpc->WrapNative(cx, obj, 1.1080 + static_cast<nsIJSCID*>(nsid), 1.1081 + NS_GET_IID(nsIJSCID), 1.1082 + getter_AddRefs(holder)))) { 1.1083 + RootedObject idobj(cx); 1.1084 + if (holder && 1.1085 + // Assign, not compare 1.1086 + (idobj = holder->GetJSObject())) { 1.1087 + *objp = obj; 1.1088 + *_retval = JS_DefinePropertyById(cx, obj, id, 1.1089 + ObjectValue(*idobj), 1.1090 + nullptr, nullptr, 1.1091 + JSPROP_ENUMERATE | 1.1092 + JSPROP_READONLY | 1.1093 + JSPROP_PERMANENT); 1.1094 + } 1.1095 + } 1.1096 + } 1.1097 + } 1.1098 + return NS_OK; 1.1099 +} 1.1100 + 1.1101 + 1.1102 +/***************************************************************************/ 1.1103 + 1.1104 +// Currently the possible results do not change at runtime, so they are only 1.1105 +// cached once (unlike ContractIDs, CLSIDs, and IIDs) 1.1106 + 1.1107 +class nsXPCComponents_Results : 1.1108 + public nsIXPCComponents_Results, 1.1109 + public nsIXPCScriptable, 1.1110 + public nsIClassInfo 1.1111 +{ 1.1112 +public: 1.1113 + // all the interface method declarations... 1.1114 + NS_DECL_ISUPPORTS 1.1115 + NS_DECL_NSIXPCCOMPONENTS_RESULTS 1.1116 + NS_DECL_NSIXPCSCRIPTABLE 1.1117 + NS_DECL_NSICLASSINFO 1.1118 + 1.1119 +public: 1.1120 + nsXPCComponents_Results(); 1.1121 + virtual ~nsXPCComponents_Results(); 1.1122 +}; 1.1123 + 1.1124 +/***************************************************************************/ 1.1125 +/* void getInterfaces (out uint32_t count, [array, size_is (count), retval] 1.1126 + out nsIIDPtr array); */ 1.1127 +NS_IMETHODIMP 1.1128 +nsXPCComponents_Results::GetInterfaces(uint32_t *aCount, nsIID * **aArray) 1.1129 +{ 1.1130 + const uint32_t count = 2; 1.1131 + *aCount = count; 1.1132 + nsIID **array; 1.1133 + *aArray = array = static_cast<nsIID**>(nsMemory::Alloc(count * sizeof(nsIID*))); 1.1134 + if (!array) 1.1135 + return NS_ERROR_OUT_OF_MEMORY; 1.1136 + 1.1137 + uint32_t index = 0; 1.1138 + nsIID* clone; 1.1139 +#define PUSH_IID(id) \ 1.1140 + clone = static_cast<nsIID *>(nsMemory::Clone(&NS_GET_IID( id ), \ 1.1141 + sizeof(nsIID))); \ 1.1142 + if (!clone) \ 1.1143 + goto oom; \ 1.1144 + array[index++] = clone; 1.1145 + 1.1146 + PUSH_IID(nsIXPCComponents_Results) 1.1147 + PUSH_IID(nsIXPCScriptable) 1.1148 +#undef PUSH_IID 1.1149 + 1.1150 + return NS_OK; 1.1151 +oom: 1.1152 + while (index) 1.1153 + nsMemory::Free(array[--index]); 1.1154 + nsMemory::Free(array); 1.1155 + *aArray = nullptr; 1.1156 + return NS_ERROR_OUT_OF_MEMORY; 1.1157 +} 1.1158 + 1.1159 +/* nsISupports getHelperForLanguage (in uint32_t language); */ 1.1160 +NS_IMETHODIMP 1.1161 +nsXPCComponents_Results::GetHelperForLanguage(uint32_t language, 1.1162 + nsISupports **retval) 1.1163 +{ 1.1164 + *retval = nullptr; 1.1165 + return NS_OK; 1.1166 +} 1.1167 + 1.1168 +/* readonly attribute string contractID; */ 1.1169 +NS_IMETHODIMP 1.1170 +nsXPCComponents_Results::GetContractID(char * *aContractID) 1.1171 +{ 1.1172 + *aContractID = nullptr; 1.1173 + return NS_ERROR_NOT_AVAILABLE; 1.1174 +} 1.1175 + 1.1176 +/* readonly attribute string classDescription; */ 1.1177 +NS_IMETHODIMP 1.1178 +nsXPCComponents_Results::GetClassDescription(char * *aClassDescription) 1.1179 +{ 1.1180 + static const char classDescription[] = "XPCComponents_Results"; 1.1181 + *aClassDescription = (char*)nsMemory::Clone(classDescription, sizeof(classDescription)); 1.1182 + return *aClassDescription ? NS_OK : NS_ERROR_OUT_OF_MEMORY; 1.1183 +} 1.1184 + 1.1185 +/* readonly attribute nsCIDPtr classID; */ 1.1186 +NS_IMETHODIMP 1.1187 +nsXPCComponents_Results::GetClassID(nsCID * *aClassID) 1.1188 +{ 1.1189 + *aClassID = nullptr; 1.1190 + return NS_OK; 1.1191 +} 1.1192 + 1.1193 +/* readonly attribute uint32_t implementationLanguage; */ 1.1194 +NS_IMETHODIMP 1.1195 +nsXPCComponents_Results::GetImplementationLanguage(uint32_t *aImplementationLanguage) 1.1196 +{ 1.1197 + *aImplementationLanguage = nsIProgrammingLanguage::CPLUSPLUS; 1.1198 + return NS_OK; 1.1199 +} 1.1200 + 1.1201 +/* readonly attribute uint32_t flags; */ 1.1202 +NS_IMETHODIMP 1.1203 +nsXPCComponents_Results::GetFlags(uint32_t *aFlags) 1.1204 +{ 1.1205 + // Mark ourselves as a DOM object so that instances may be created in 1.1206 + // unprivileged scopes. 1.1207 + *aFlags = nsIClassInfo::DOM_OBJECT; 1.1208 + return NS_OK; 1.1209 +} 1.1210 + 1.1211 +/* [notxpcom] readonly attribute nsCID classIDNoAlloc; */ 1.1212 +NS_IMETHODIMP 1.1213 +nsXPCComponents_Results::GetClassIDNoAlloc(nsCID *aClassIDNoAlloc) 1.1214 +{ 1.1215 + return NS_ERROR_NOT_AVAILABLE; 1.1216 +} 1.1217 + 1.1218 +nsXPCComponents_Results::nsXPCComponents_Results() 1.1219 +{ 1.1220 +} 1.1221 + 1.1222 +nsXPCComponents_Results::~nsXPCComponents_Results() 1.1223 +{ 1.1224 + // empty 1.1225 +} 1.1226 + 1.1227 +NS_INTERFACE_MAP_BEGIN(nsXPCComponents_Results) 1.1228 + NS_INTERFACE_MAP_ENTRY(nsIXPCComponents_Results) 1.1229 + NS_INTERFACE_MAP_ENTRY(nsIXPCScriptable) 1.1230 + NS_INTERFACE_MAP_ENTRY(nsIClassInfo) 1.1231 + NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIXPCComponents_Results) 1.1232 +NS_INTERFACE_MAP_END 1.1233 + 1.1234 +NS_IMPL_ADDREF(nsXPCComponents_Results) 1.1235 +NS_IMPL_RELEASE(nsXPCComponents_Results) 1.1236 + 1.1237 +// The nsIXPCScriptable map declaration that will generate stubs for us... 1.1238 +#define XPC_MAP_CLASSNAME nsXPCComponents_Results 1.1239 +#define XPC_MAP_QUOTED_CLASSNAME "nsXPCComponents_Results" 1.1240 +#define XPC_MAP_WANT_NEWRESOLVE 1.1241 +#define XPC_MAP_WANT_NEWENUMERATE 1.1242 +#define XPC_MAP_FLAGS nsIXPCScriptable::DONT_ENUM_STATIC_PROPS |\ 1.1243 + nsIXPCScriptable::ALLOW_PROP_MODS_DURING_RESOLVE 1.1244 +#include "xpc_map_end.h" /* This will #undef the above */ 1.1245 + 1.1246 +/* bool newEnumerate (in nsIXPConnectWrappedNative wrapper, in JSContextPtr cx, in JSObjectPtr obj, in uint32_t enum_op, in JSValPtr statep, out JSID idp); */ 1.1247 +NS_IMETHODIMP 1.1248 +nsXPCComponents_Results::NewEnumerate(nsIXPConnectWrappedNative *wrapper, 1.1249 + JSContext * cx, JSObject * obj, 1.1250 + uint32_t enum_op, jsval * statep, 1.1251 + jsid * idp, bool *_retval) 1.1252 +{ 1.1253 + const void** iter; 1.1254 + 1.1255 + switch (enum_op) { 1.1256 + case JSENUMERATE_INIT: 1.1257 + case JSENUMERATE_INIT_ALL: 1.1258 + { 1.1259 + if (idp) 1.1260 + *idp = INT_TO_JSID(nsXPCException::GetNSResultCount()); 1.1261 + 1.1262 + void** space = (void**) new char[sizeof(void*)]; 1.1263 + *space = nullptr; 1.1264 + *statep = PRIVATE_TO_JSVAL(space); 1.1265 + return NS_OK; 1.1266 + } 1.1267 + case JSENUMERATE_NEXT: 1.1268 + { 1.1269 + const char* name; 1.1270 + iter = (const void**) JSVAL_TO_PRIVATE(*statep); 1.1271 + if (nsXPCException::IterateNSResults(nullptr, &name, nullptr, iter)) { 1.1272 + RootedString idstr(cx, JS_NewStringCopyZ(cx, name)); 1.1273 + JS::RootedId id(cx); 1.1274 + if (idstr && JS_StringToId(cx, idstr, &id)) { 1.1275 + *idp = id; 1.1276 + return NS_OK; 1.1277 + } 1.1278 + } 1.1279 + // else... FALL THROUGH 1.1280 + } 1.1281 + 1.1282 + case JSENUMERATE_DESTROY: 1.1283 + default: 1.1284 + iter = (const void**) JSVAL_TO_PRIVATE(*statep); 1.1285 + delete [] (char*) iter; 1.1286 + *statep = JSVAL_NULL; 1.1287 + return NS_OK; 1.1288 + } 1.1289 +} 1.1290 + 1.1291 + 1.1292 +/* bool newResolve (in nsIXPConnectWrappedNative wrapper, in JSContextPtr cx, in JSObjectPtr obj, in jsval id, out JSObjectPtr objp); */ 1.1293 +NS_IMETHODIMP 1.1294 +nsXPCComponents_Results::NewResolve(nsIXPConnectWrappedNative *wrapper, 1.1295 + JSContext *cx, JSObject *objArg, 1.1296 + jsid idArg, JSObject * *objp, 1.1297 + bool *_retval) 1.1298 +{ 1.1299 + RootedObject obj(cx, objArg); 1.1300 + RootedId id(cx, idArg); 1.1301 + JSAutoByteString name; 1.1302 + 1.1303 + if (JSID_IS_STRING(id) && name.encodeLatin1(cx, JSID_TO_STRING(id))) { 1.1304 + const char* rv_name; 1.1305 + const void* iter = nullptr; 1.1306 + nsresult rv; 1.1307 + while (nsXPCException::IterateNSResults(&rv, &rv_name, nullptr, &iter)) { 1.1308 + if (!strcmp(name.ptr(), rv_name)) { 1.1309 + jsval val = JS_NumberValue((double)rv); 1.1310 + 1.1311 + *objp = obj; 1.1312 + if (!JS_DefinePropertyById(cx, obj, id, val, 1.1313 + nullptr, nullptr, 1.1314 + JSPROP_ENUMERATE | 1.1315 + JSPROP_READONLY | 1.1316 + JSPROP_PERMANENT)) { 1.1317 + return NS_ERROR_UNEXPECTED; 1.1318 + } 1.1319 + } 1.1320 + } 1.1321 + } 1.1322 + return NS_OK; 1.1323 +} 1.1324 + 1.1325 +/***************************************************************************/ 1.1326 +// JavaScript Constructor for nsIJSID objects (Components.ID) 1.1327 + 1.1328 +class nsXPCComponents_ID : 1.1329 + public nsIXPCComponents_ID, 1.1330 + public nsIXPCScriptable, 1.1331 + public nsIClassInfo 1.1332 +{ 1.1333 +public: 1.1334 + // all the interface method declarations... 1.1335 + NS_DECL_ISUPPORTS 1.1336 + NS_DECL_NSIXPCCOMPONENTS_ID 1.1337 + NS_DECL_NSIXPCSCRIPTABLE 1.1338 + NS_DECL_NSICLASSINFO 1.1339 + 1.1340 + 1.1341 +public: 1.1342 + nsXPCComponents_ID(); 1.1343 + virtual ~nsXPCComponents_ID(); 1.1344 + 1.1345 +private: 1.1346 + static nsresult CallOrConstruct(nsIXPConnectWrappedNative *wrapper, 1.1347 + JSContext *cx, HandleObject obj, 1.1348 + const CallArgs &args, bool *_retval); 1.1349 +}; 1.1350 + 1.1351 +/***************************************************************************/ 1.1352 +/* void getInterfaces (out uint32_t count, [array, size_is (count), retval] 1.1353 + out nsIIDPtr array); */ 1.1354 +NS_IMETHODIMP 1.1355 +nsXPCComponents_ID::GetInterfaces(uint32_t *aCount, nsIID * **aArray) 1.1356 +{ 1.1357 + const uint32_t count = 2; 1.1358 + *aCount = count; 1.1359 + nsIID **array; 1.1360 + *aArray = array = static_cast<nsIID**>(nsMemory::Alloc(count * sizeof(nsIID*))); 1.1361 + if (!array) 1.1362 + return NS_ERROR_OUT_OF_MEMORY; 1.1363 + 1.1364 + uint32_t index = 0; 1.1365 + nsIID* clone; 1.1366 +#define PUSH_IID(id) \ 1.1367 + clone = static_cast<nsIID *>(nsMemory::Clone(&NS_GET_IID( id ), \ 1.1368 + sizeof(nsIID))); \ 1.1369 + if (!clone) \ 1.1370 + goto oom; \ 1.1371 + array[index++] = clone; 1.1372 + 1.1373 + PUSH_IID(nsIXPCComponents_ID) 1.1374 + PUSH_IID(nsIXPCScriptable) 1.1375 +#undef PUSH_IID 1.1376 + 1.1377 + return NS_OK; 1.1378 +oom: 1.1379 + while (index) 1.1380 + nsMemory::Free(array[--index]); 1.1381 + nsMemory::Free(array); 1.1382 + *aArray = nullptr; 1.1383 + return NS_ERROR_OUT_OF_MEMORY; 1.1384 +} 1.1385 + 1.1386 +/* nsISupports getHelperForLanguage (in uint32_t language); */ 1.1387 +NS_IMETHODIMP 1.1388 +nsXPCComponents_ID::GetHelperForLanguage(uint32_t language, 1.1389 + nsISupports **retval) 1.1390 +{ 1.1391 + *retval = nullptr; 1.1392 + return NS_OK; 1.1393 +} 1.1394 + 1.1395 +/* readonly attribute string contractID; */ 1.1396 +NS_IMETHODIMP 1.1397 +nsXPCComponents_ID::GetContractID(char * *aContractID) 1.1398 +{ 1.1399 + *aContractID = nullptr; 1.1400 + return NS_ERROR_NOT_AVAILABLE; 1.1401 +} 1.1402 + 1.1403 +/* readonly attribute string classDescription; */ 1.1404 +NS_IMETHODIMP 1.1405 +nsXPCComponents_ID::GetClassDescription(char * *aClassDescription) 1.1406 +{ 1.1407 + static const char classDescription[] = "XPCComponents_ID"; 1.1408 + *aClassDescription = (char*)nsMemory::Clone(classDescription, sizeof(classDescription)); 1.1409 + return *aClassDescription ? NS_OK : NS_ERROR_OUT_OF_MEMORY; 1.1410 +} 1.1411 + 1.1412 +/* readonly attribute nsCIDPtr classID; */ 1.1413 +NS_IMETHODIMP 1.1414 +nsXPCComponents_ID::GetClassID(nsCID * *aClassID) 1.1415 +{ 1.1416 + *aClassID = nullptr; 1.1417 + return NS_OK; 1.1418 +} 1.1419 + 1.1420 +/* readonly attribute uint32_t implementationLanguage; */ 1.1421 +NS_IMETHODIMP 1.1422 +nsXPCComponents_ID::GetImplementationLanguage(uint32_t *aImplementationLanguage) 1.1423 +{ 1.1424 + *aImplementationLanguage = nsIProgrammingLanguage::CPLUSPLUS; 1.1425 + return NS_OK; 1.1426 +} 1.1427 + 1.1428 +/* readonly attribute uint32_t flags; */ 1.1429 +NS_IMETHODIMP 1.1430 +nsXPCComponents_ID::GetFlags(uint32_t *aFlags) 1.1431 +{ 1.1432 + *aFlags = 0; 1.1433 + return NS_OK; 1.1434 +} 1.1435 + 1.1436 +/* [notxpcom] readonly attribute nsCID classIDNoAlloc; */ 1.1437 +NS_IMETHODIMP 1.1438 +nsXPCComponents_ID::GetClassIDNoAlloc(nsCID *aClassIDNoAlloc) 1.1439 +{ 1.1440 + return NS_ERROR_NOT_AVAILABLE; 1.1441 +} 1.1442 + 1.1443 +nsXPCComponents_ID::nsXPCComponents_ID() 1.1444 +{ 1.1445 +} 1.1446 + 1.1447 +nsXPCComponents_ID::~nsXPCComponents_ID() 1.1448 +{ 1.1449 + // empty 1.1450 +} 1.1451 + 1.1452 +NS_INTERFACE_MAP_BEGIN(nsXPCComponents_ID) 1.1453 + NS_INTERFACE_MAP_ENTRY(nsIXPCComponents_ID) 1.1454 + NS_INTERFACE_MAP_ENTRY(nsIXPCScriptable) 1.1455 + NS_INTERFACE_MAP_ENTRY(nsIClassInfo) 1.1456 + NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIXPCComponents_ID) 1.1457 +NS_INTERFACE_MAP_END 1.1458 + 1.1459 +NS_IMPL_ADDREF(nsXPCComponents_ID) 1.1460 +NS_IMPL_RELEASE(nsXPCComponents_ID) 1.1461 + 1.1462 +// The nsIXPCScriptable map declaration that will generate stubs for us... 1.1463 +#define XPC_MAP_CLASSNAME nsXPCComponents_ID 1.1464 +#define XPC_MAP_QUOTED_CLASSNAME "nsXPCComponents_ID" 1.1465 +#define XPC_MAP_WANT_CALL 1.1466 +#define XPC_MAP_WANT_CONSTRUCT 1.1467 +#define XPC_MAP_WANT_HASINSTANCE 1.1468 +#define XPC_MAP_FLAGS nsIXPCScriptable::ALLOW_PROP_MODS_DURING_RESOLVE 1.1469 +#include "xpc_map_end.h" /* This will #undef the above */ 1.1470 + 1.1471 + 1.1472 +/* bool call (in nsIXPConnectWrappedNative wrapper, in JSContextPtr cx, in JSObjectPtr obj, in uint32_t argc, in JSValPtr argv, in JSValPtr vp); */ 1.1473 +NS_IMETHODIMP 1.1474 +nsXPCComponents_ID::Call(nsIXPConnectWrappedNative *wrapper, JSContext *cx, JSObject *objArg, 1.1475 + const CallArgs &args, bool *_retval) 1.1476 +{ 1.1477 + RootedObject obj(cx, objArg); 1.1478 + return CallOrConstruct(wrapper, cx, obj, args, _retval); 1.1479 +} 1.1480 + 1.1481 +/* bool construct (in nsIXPConnectWrappedNative wrapper, in JSContextPtr cx, in JSObjectPtr obj, in uint32_t argc, in JSValPtr argv, in JSValPtr vp); */ 1.1482 +NS_IMETHODIMP 1.1483 +nsXPCComponents_ID::Construct(nsIXPConnectWrappedNative *wrapper, JSContext *cx, JSObject *objArg, 1.1484 + const CallArgs &args, bool *_retval) 1.1485 +{ 1.1486 + RootedObject obj(cx, objArg); 1.1487 + return CallOrConstruct(wrapper, cx, obj, args, _retval); 1.1488 +} 1.1489 + 1.1490 +// static 1.1491 +nsresult 1.1492 +nsXPCComponents_ID::CallOrConstruct(nsIXPConnectWrappedNative *wrapper, 1.1493 + JSContext *cx, HandleObject obj, 1.1494 + const CallArgs &args, bool *_retval) 1.1495 +{ 1.1496 + // make sure we have at least one arg 1.1497 + 1.1498 + if (args.length() < 1) 1.1499 + return ThrowAndFail(NS_ERROR_XPC_NOT_ENOUGH_ARGS, cx, _retval); 1.1500 + 1.1501 + // Do the security check if necessary 1.1502 + 1.1503 + nsIXPCSecurityManager* sm = nsXPConnect::XPConnect()->GetDefaultSecurityManager(); 1.1504 + if (sm && NS_FAILED(sm->CanCreateInstance(cx, nsJSID::GetCID()))) { 1.1505 + // the security manager vetoed. It should have set an exception. 1.1506 + *_retval = false; 1.1507 + return NS_OK; 1.1508 + } 1.1509 + 1.1510 + // convert the first argument into a string and see if it looks like an id 1.1511 + 1.1512 + JSString* jsstr; 1.1513 + JSAutoByteString bytes; 1.1514 + nsID id; 1.1515 + 1.1516 + if (!(jsstr = ToString(cx, args[0])) || 1.1517 + !bytes.encodeLatin1(cx, jsstr) || 1.1518 + !id.Parse(bytes.ptr())) { 1.1519 + return ThrowAndFail(NS_ERROR_XPC_BAD_ID_STRING, cx, _retval); 1.1520 + } 1.1521 + 1.1522 + // make the new object and return it. 1.1523 + 1.1524 + JSObject* newobj = xpc_NewIDObject(cx, obj, id); 1.1525 + if (!newobj) 1.1526 + return NS_ERROR_UNEXPECTED; 1.1527 + 1.1528 + args.rval().setObject(*newobj); 1.1529 + return NS_OK; 1.1530 +} 1.1531 + 1.1532 +/* bool hasInstance (in nsIXPConnectWrappedNative wrapper, in JSContextPtr cx, in JSObjectPtr obj, in jsval val, out bool bp); */ 1.1533 +NS_IMETHODIMP 1.1534 +nsXPCComponents_ID::HasInstance(nsIXPConnectWrappedNative *wrapper, 1.1535 + JSContext *cx, JSObject *obj, 1.1536 + HandleValue val, bool *bp, bool *_retval) 1.1537 +{ 1.1538 + if (bp) 1.1539 + *bp = JSValIsInterfaceOfType(cx, val, NS_GET_IID(nsIJSID)); 1.1540 + return NS_OK; 1.1541 +} 1.1542 + 1.1543 +/***************************************************************************/ 1.1544 +// JavaScript Constructor for nsIXPCException objects (Components.Exception) 1.1545 + 1.1546 +class nsXPCComponents_Exception : 1.1547 + public nsIXPCComponents_Exception, 1.1548 + public nsIXPCScriptable, 1.1549 + public nsIClassInfo 1.1550 +{ 1.1551 +public: 1.1552 + // all the interface method declarations... 1.1553 + NS_DECL_ISUPPORTS 1.1554 + NS_DECL_NSIXPCCOMPONENTS_EXCEPTION 1.1555 + NS_DECL_NSIXPCSCRIPTABLE 1.1556 + NS_DECL_NSICLASSINFO 1.1557 + 1.1558 + 1.1559 +public: 1.1560 + nsXPCComponents_Exception(); 1.1561 + virtual ~nsXPCComponents_Exception(); 1.1562 + 1.1563 +private: 1.1564 + static nsresult CallOrConstruct(nsIXPConnectWrappedNative *wrapper, 1.1565 + JSContext *cx, HandleObject obj, 1.1566 + const CallArgs &args, bool *_retval); 1.1567 +}; 1.1568 + 1.1569 +/***************************************************************************/ 1.1570 +/* void getInterfaces (out uint32_t count, [array, size_is (count), retval] 1.1571 + out nsIIDPtr array); */ 1.1572 +NS_IMETHODIMP 1.1573 +nsXPCComponents_Exception::GetInterfaces(uint32_t *aCount, nsIID * **aArray) 1.1574 +{ 1.1575 + const uint32_t count = 2; 1.1576 + *aCount = count; 1.1577 + nsIID **array; 1.1578 + *aArray = array = static_cast<nsIID**>(nsMemory::Alloc(count * sizeof(nsIID*))); 1.1579 + if (!array) 1.1580 + return NS_ERROR_OUT_OF_MEMORY; 1.1581 + 1.1582 + uint32_t index = 0; 1.1583 + nsIID* clone; 1.1584 +#define PUSH_IID(id) \ 1.1585 + clone = static_cast<nsIID *>(nsMemory::Clone(&NS_GET_IID( id ), \ 1.1586 + sizeof(nsIID))); \ 1.1587 + if (!clone) \ 1.1588 + goto oom; \ 1.1589 + array[index++] = clone; 1.1590 + 1.1591 + PUSH_IID(nsIXPCComponents_Exception) 1.1592 + PUSH_IID(nsIXPCScriptable) 1.1593 +#undef PUSH_IID 1.1594 + 1.1595 + return NS_OK; 1.1596 +oom: 1.1597 + while (index) 1.1598 + nsMemory::Free(array[--index]); 1.1599 + nsMemory::Free(array); 1.1600 + *aArray = nullptr; 1.1601 + return NS_ERROR_OUT_OF_MEMORY; 1.1602 +} 1.1603 + 1.1604 +/* nsISupports getHelperForLanguage (in uint32_t language); */ 1.1605 +NS_IMETHODIMP 1.1606 +nsXPCComponents_Exception::GetHelperForLanguage(uint32_t language, 1.1607 + nsISupports **retval) 1.1608 +{ 1.1609 + *retval = nullptr; 1.1610 + return NS_OK; 1.1611 +} 1.1612 + 1.1613 +/* readonly attribute string contractID; */ 1.1614 +NS_IMETHODIMP 1.1615 +nsXPCComponents_Exception::GetContractID(char * *aContractID) 1.1616 +{ 1.1617 + *aContractID = nullptr; 1.1618 + return NS_ERROR_NOT_AVAILABLE; 1.1619 +} 1.1620 + 1.1621 +/* readonly attribute string classDescription; */ 1.1622 +NS_IMETHODIMP 1.1623 +nsXPCComponents_Exception::GetClassDescription(char * *aClassDescription) 1.1624 +{ 1.1625 + static const char classDescription[] = "XPCComponents_Exception"; 1.1626 + *aClassDescription = (char*)nsMemory::Clone(classDescription, sizeof(classDescription)); 1.1627 + return *aClassDescription ? NS_OK : NS_ERROR_OUT_OF_MEMORY; 1.1628 +} 1.1629 + 1.1630 +/* readonly attribute nsCIDPtr classID; */ 1.1631 +NS_IMETHODIMP 1.1632 +nsXPCComponents_Exception::GetClassID(nsCID * *aClassID) 1.1633 +{ 1.1634 + *aClassID = nullptr; 1.1635 + return NS_OK; 1.1636 +} 1.1637 + 1.1638 +/* readonly attribute uint32_t implementationLanguage; */ 1.1639 +NS_IMETHODIMP 1.1640 +nsXPCComponents_Exception::GetImplementationLanguage(uint32_t *aImplementationLanguage) 1.1641 +{ 1.1642 + *aImplementationLanguage = nsIProgrammingLanguage::CPLUSPLUS; 1.1643 + return NS_OK; 1.1644 +} 1.1645 + 1.1646 +/* readonly attribute uint32_t flags; */ 1.1647 +NS_IMETHODIMP 1.1648 +nsXPCComponents_Exception::GetFlags(uint32_t *aFlags) 1.1649 +{ 1.1650 + *aFlags = 0; 1.1651 + return NS_OK; 1.1652 +} 1.1653 + 1.1654 +/* [notxpcom] readonly attribute nsCID classIDNoAlloc; */ 1.1655 +NS_IMETHODIMP 1.1656 +nsXPCComponents_Exception::GetClassIDNoAlloc(nsCID *aClassIDNoAlloc) 1.1657 +{ 1.1658 + return NS_ERROR_NOT_AVAILABLE; 1.1659 +} 1.1660 + 1.1661 +nsXPCComponents_Exception::nsXPCComponents_Exception() 1.1662 +{ 1.1663 +} 1.1664 + 1.1665 +nsXPCComponents_Exception::~nsXPCComponents_Exception() 1.1666 +{ 1.1667 + // empty 1.1668 +} 1.1669 + 1.1670 +NS_INTERFACE_MAP_BEGIN(nsXPCComponents_Exception) 1.1671 + NS_INTERFACE_MAP_ENTRY(nsIXPCComponents_Exception) 1.1672 + NS_INTERFACE_MAP_ENTRY(nsIXPCScriptable) 1.1673 + NS_INTERFACE_MAP_ENTRY(nsIClassInfo) 1.1674 + NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIXPCComponents_Exception) 1.1675 +NS_INTERFACE_MAP_END 1.1676 + 1.1677 +NS_IMPL_ADDREF(nsXPCComponents_Exception) 1.1678 +NS_IMPL_RELEASE(nsXPCComponents_Exception) 1.1679 + 1.1680 +// The nsIXPCScriptable map declaration that will generate stubs for us... 1.1681 +#define XPC_MAP_CLASSNAME nsXPCComponents_Exception 1.1682 +#define XPC_MAP_QUOTED_CLASSNAME "nsXPCComponents_Exception" 1.1683 +#define XPC_MAP_WANT_CALL 1.1684 +#define XPC_MAP_WANT_CONSTRUCT 1.1685 +#define XPC_MAP_WANT_HASINSTANCE 1.1686 +#define XPC_MAP_FLAGS nsIXPCScriptable::ALLOW_PROP_MODS_DURING_RESOLVE 1.1687 +#include "xpc_map_end.h" /* This will #undef the above */ 1.1688 + 1.1689 + 1.1690 +/* bool call (in nsIXPConnectWrappedNative wrapper, in JSContextPtr cx, in JSObjectPtr obj, in uint32_t argc, in JSValPtr argv, in JSValPtr vp); */ 1.1691 +NS_IMETHODIMP 1.1692 +nsXPCComponents_Exception::Call(nsIXPConnectWrappedNative *wrapper, JSContext *cx, JSObject *objArg, 1.1693 + const CallArgs &args, bool *_retval) 1.1694 +{ 1.1695 + RootedObject obj(cx, objArg); 1.1696 + return CallOrConstruct(wrapper, cx, obj, args, _retval); 1.1697 +} 1.1698 + 1.1699 +/* bool construct (in nsIXPConnectWrappedNative wrapper, in JSContextPtr cx, in JSObjectPtr obj, in uint32_t argc, in JSValPtr argv, in JSValPtr vp); */ 1.1700 +NS_IMETHODIMP 1.1701 +nsXPCComponents_Exception::Construct(nsIXPConnectWrappedNative *wrapper, JSContext *cx, 1.1702 + JSObject *objArg, const CallArgs &args, bool *_retval) 1.1703 +{ 1.1704 + RootedObject obj(cx, objArg); 1.1705 + return CallOrConstruct(wrapper, cx, obj, args, _retval); 1.1706 +} 1.1707 + 1.1708 +struct MOZ_STACK_CLASS ExceptionArgParser 1.1709 +{ 1.1710 + ExceptionArgParser(JSContext *context, 1.1711 + nsXPConnect *xpconnect) 1.1712 + : eMsg("exception") 1.1713 + , eResult(NS_ERROR_FAILURE) 1.1714 + , cx(context) 1.1715 + , xpc(xpconnect) 1.1716 + {} 1.1717 + 1.1718 + // Public exception parameter values. During construction, these are 1.1719 + // initialized to the appropriate defaults. 1.1720 + const char* eMsg; 1.1721 + nsresult eResult; 1.1722 + nsCOMPtr<nsIStackFrame> eStack; 1.1723 + nsCOMPtr<nsISupports> eData; 1.1724 + 1.1725 + // Parse the constructor arguments into the above |eFoo| parameter values. 1.1726 + bool parse(const CallArgs &args) { 1.1727 + /* 1.1728 + * The Components.Exception takes a series of arguments, all of them 1.1729 + * optional: 1.1730 + * 1.1731 + * Argument 0: Exception message (defaults to 'exception'). 1.1732 + * Argument 1: Result code (defaults to NS_ERROR_FAILURE) _or_ options 1.1733 + * object (see below). 1.1734 + * Argument 2: Stack (defaults to the current stack, which we trigger 1.1735 + * by leaving this nullptr in the parser). 1.1736 + * Argument 3: Optional user data (defaults to nullptr). 1.1737 + * 1.1738 + * To dig our way out of this clunky API, we now support passing an 1.1739 + * options object as the second parameter (as opposed to a result code). 1.1740 + * If this is the case, all subsequent arguments are ignored, and the 1.1741 + * following properties are parsed out of the object (using the 1.1742 + * associated default if the property does not exist): 1.1743 + * 1.1744 + * result: Result code (see argument 1). 1.1745 + * stack: Call stack (see argument 2). 1.1746 + * data: User data (see argument 3). 1.1747 + */ 1.1748 + if (args.length() > 0 && !parseMessage(args[0])) 1.1749 + return false; 1.1750 + if (args.length() > 1) { 1.1751 + if (args[1].isObject()) { 1.1752 + RootedObject obj(cx, &args[1].toObject()); 1.1753 + return parseOptionsObject(obj); 1.1754 + } 1.1755 + if (!parseResult(args[1])) 1.1756 + return false; 1.1757 + } 1.1758 + if (args.length() > 2) { 1.1759 + if (!parseStack(args[2])) 1.1760 + return false; 1.1761 + } 1.1762 + if (args.length() > 3) { 1.1763 + if (!parseData(args[3])) 1.1764 + return false; 1.1765 + } 1.1766 + return true; 1.1767 + } 1.1768 + 1.1769 + protected: 1.1770 + 1.1771 + /* 1.1772 + * Parsing helpers. 1.1773 + */ 1.1774 + 1.1775 + bool parseMessage(HandleValue v) { 1.1776 + JSString *str = ToString(cx, v); 1.1777 + if (!str) 1.1778 + return false; 1.1779 + eMsg = messageBytes.encodeLatin1(cx, str); 1.1780 + return !!eMsg; 1.1781 + } 1.1782 + 1.1783 + bool parseResult(HandleValue v) { 1.1784 + return JS::ToUint32(cx, v, (uint32_t*) &eResult); 1.1785 + } 1.1786 + 1.1787 + bool parseStack(HandleValue v) { 1.1788 + if (!v.isObject()) { 1.1789 + // eStack has already been initialized to null, which is what we want 1.1790 + // for any non-object values (including null). 1.1791 + return true; 1.1792 + } 1.1793 + 1.1794 + return NS_SUCCEEDED(xpc->WrapJS(cx, &v.toObject(), 1.1795 + NS_GET_IID(nsIStackFrame), 1.1796 + getter_AddRefs(eStack))); 1.1797 + } 1.1798 + 1.1799 + bool parseData(HandleValue v) { 1.1800 + if (!v.isObject()) { 1.1801 + // eData has already been initialized to null, which is what we want 1.1802 + // for any non-object values (including null). 1.1803 + return true; 1.1804 + } 1.1805 + 1.1806 + return NS_SUCCEEDED(xpc->WrapJS(cx, &v.toObject(), 1.1807 + NS_GET_IID(nsISupports), 1.1808 + getter_AddRefs(eData))); 1.1809 + } 1.1810 + 1.1811 + bool parseOptionsObject(HandleObject obj) { 1.1812 + RootedValue v(cx); 1.1813 + 1.1814 + if (!getOption(obj, "result", &v) || 1.1815 + (!v.isUndefined() && !parseResult(v))) 1.1816 + return false; 1.1817 + 1.1818 + if (!getOption(obj, "stack", &v) || 1.1819 + (!v.isUndefined() && !parseStack(v))) 1.1820 + return false; 1.1821 + 1.1822 + if (!getOption(obj, "data", &v) || 1.1823 + (!v.isUndefined() && !parseData(v))) 1.1824 + return false; 1.1825 + 1.1826 + return true; 1.1827 + } 1.1828 + 1.1829 + bool getOption(HandleObject obj, const char *name, MutableHandleValue rv) { 1.1830 + // Look for the property. 1.1831 + bool found; 1.1832 + if (!JS_HasProperty(cx, obj, name, &found)) 1.1833 + return false; 1.1834 + 1.1835 + // If it wasn't found, indicate with undefined. 1.1836 + if (!found) { 1.1837 + rv.setUndefined(); 1.1838 + return true; 1.1839 + } 1.1840 + 1.1841 + // Get the property. 1.1842 + return JS_GetProperty(cx, obj, name, rv); 1.1843 + } 1.1844 + 1.1845 + /* 1.1846 + * Internal data members. 1.1847 + */ 1.1848 + 1.1849 + // If there's a non-default exception string, hold onto the allocated bytes. 1.1850 + JSAutoByteString messageBytes; 1.1851 + 1.1852 + // Various bits and pieces that are helpful to have around. 1.1853 + JSContext *cx; 1.1854 + nsXPConnect *xpc; 1.1855 +}; 1.1856 + 1.1857 +// static 1.1858 +nsresult 1.1859 +nsXPCComponents_Exception::CallOrConstruct(nsIXPConnectWrappedNative *wrapper, 1.1860 + JSContext *cx, HandleObject obj, 1.1861 + const CallArgs &args, bool *_retval) 1.1862 +{ 1.1863 + nsXPConnect* xpc = nsXPConnect::XPConnect(); 1.1864 + 1.1865 + // Do the security check if necessary 1.1866 + 1.1867 + nsIXPCSecurityManager* sm = xpc->GetDefaultSecurityManager(); 1.1868 + if (sm && NS_FAILED(sm->CanCreateInstance(cx, Exception::GetCID()))) { 1.1869 + // the security manager vetoed. It should have set an exception. 1.1870 + *_retval = false; 1.1871 + return NS_OK; 1.1872 + } 1.1873 + 1.1874 + // Parse the arguments to the Exception constructor. 1.1875 + ExceptionArgParser parser(cx, xpc); 1.1876 + if (!parser.parse(args)) 1.1877 + return ThrowAndFail(NS_ERROR_XPC_BAD_CONVERT_JS, cx, _retval); 1.1878 + 1.1879 + nsCOMPtr<nsIException> e = new Exception(nsCString(parser.eMsg), 1.1880 + parser.eResult, 1.1881 + EmptyCString(), 1.1882 + parser.eStack, 1.1883 + parser.eData); 1.1884 + 1.1885 + nsCOMPtr<nsIXPConnectJSObjectHolder> holder; 1.1886 + RootedObject newObj(cx); 1.1887 + 1.1888 + if (NS_FAILED(xpc->WrapNative(cx, obj, e, NS_GET_IID(nsIXPCException), 1.1889 + getter_AddRefs(holder))) || !holder || 1.1890 + // Assign, not compare 1.1891 + !(newObj = holder->GetJSObject())) { 1.1892 + return ThrowAndFail(NS_ERROR_XPC_CANT_CREATE_WN, cx, _retval); 1.1893 + } 1.1894 + 1.1895 + args.rval().setObject(*newObj); 1.1896 + return NS_OK; 1.1897 +} 1.1898 + 1.1899 +/* bool hasInstance (in nsIXPConnectWrappedNative wrapper, in JSContextPtr cx, in JSObjectPtr obj, in jsval val, out bool bp); */ 1.1900 +NS_IMETHODIMP 1.1901 +nsXPCComponents_Exception::HasInstance(nsIXPConnectWrappedNative *wrapper, 1.1902 + JSContext * cx, JSObject * obj, 1.1903 + HandleValue val, bool *bp, 1.1904 + bool *_retval) 1.1905 +{ 1.1906 + using namespace mozilla::dom; 1.1907 + 1.1908 + RootedValue v(cx, val); 1.1909 + if (bp) { 1.1910 + Exception* e; 1.1911 + *bp = NS_SUCCEEDED(UNWRAP_OBJECT(Exception, v.toObjectOrNull(), e)) || 1.1912 + JSValIsInterfaceOfType(cx, v, NS_GET_IID(nsIException)); 1.1913 + } 1.1914 + return NS_OK; 1.1915 +} 1.1916 + 1.1917 +/***************************************************************************/ 1.1918 +// This class is for the thing returned by "new Component.Constructor". 1.1919 + 1.1920 +// XXXjband we use this CID for security check, but security system can't see 1.1921 +// it since it has no registed factory. Security really kicks in when we try 1.1922 +// to build a wrapper around an instance. 1.1923 + 1.1924 +// {B4A95150-E25A-11d3-8F61-0010A4E73D9A} 1.1925 +#define NS_XPCCONSTRUCTOR_CID \ 1.1926 +{ 0xb4a95150, 0xe25a, 0x11d3, \ 1.1927 + { 0x8f, 0x61, 0x0, 0x10, 0xa4, 0xe7, 0x3d, 0x9a } } 1.1928 + 1.1929 +class nsXPCConstructor : 1.1930 + public nsIXPCConstructor, 1.1931 + public nsIXPCScriptable, 1.1932 + public nsIClassInfo 1.1933 +{ 1.1934 +public: 1.1935 + NS_DEFINE_STATIC_CID_ACCESSOR(NS_XPCCONSTRUCTOR_CID) 1.1936 +public: 1.1937 + // all the interface method declarations... 1.1938 + NS_DECL_ISUPPORTS 1.1939 + NS_DECL_NSIXPCCONSTRUCTOR 1.1940 + NS_DECL_NSIXPCSCRIPTABLE 1.1941 + NS_DECL_NSICLASSINFO 1.1942 + 1.1943 +public: 1.1944 + nsXPCConstructor(); // not implemented 1.1945 + nsXPCConstructor(nsIJSCID* aClassID, 1.1946 + nsIJSIID* aInterfaceID, 1.1947 + const char* aInitializer); 1.1948 + virtual ~nsXPCConstructor(); 1.1949 + 1.1950 +private: 1.1951 + nsresult CallOrConstruct(nsIXPConnectWrappedNative *wrapper, 1.1952 + JSContext *cx, HandleObject obj, 1.1953 + const CallArgs &args, bool *_retval); 1.1954 +private: 1.1955 + nsRefPtr<nsIJSCID> mClassID; 1.1956 + nsRefPtr<nsIJSIID> mInterfaceID; 1.1957 + char* mInitializer; 1.1958 +}; 1.1959 + 1.1960 +/***************************************************************************/ 1.1961 +/* void getInterfaces (out uint32_t count, [array, size_is (count), retval] 1.1962 + out nsIIDPtr array); */ 1.1963 +NS_IMETHODIMP 1.1964 +nsXPCConstructor::GetInterfaces(uint32_t *aCount, nsIID * **aArray) 1.1965 +{ 1.1966 + const uint32_t count = 2; 1.1967 + *aCount = count; 1.1968 + nsIID **array; 1.1969 + *aArray = array = static_cast<nsIID**>(nsMemory::Alloc(count * sizeof(nsIID*))); 1.1970 + if (!array) 1.1971 + return NS_ERROR_OUT_OF_MEMORY; 1.1972 + 1.1973 + uint32_t index = 0; 1.1974 + nsIID* clone; 1.1975 +#define PUSH_IID(id) \ 1.1976 + clone = static_cast<nsIID *>(nsMemory::Clone(&NS_GET_IID( id ), \ 1.1977 + sizeof(nsIID))); \ 1.1978 + if (!clone) \ 1.1979 + goto oom; \ 1.1980 + array[index++] = clone; 1.1981 + 1.1982 + PUSH_IID(nsIXPCConstructor) 1.1983 + PUSH_IID(nsIXPCScriptable) 1.1984 +#undef PUSH_IID 1.1985 + 1.1986 + return NS_OK; 1.1987 +oom: 1.1988 + while (index) 1.1989 + nsMemory::Free(array[--index]); 1.1990 + nsMemory::Free(array); 1.1991 + *aArray = nullptr; 1.1992 + return NS_ERROR_OUT_OF_MEMORY; 1.1993 +} 1.1994 + 1.1995 +/* nsISupports getHelperForLanguage (in uint32_t language); */ 1.1996 +NS_IMETHODIMP 1.1997 +nsXPCConstructor::GetHelperForLanguage(uint32_t language, 1.1998 + nsISupports **retval) 1.1999 +{ 1.2000 + *retval = nullptr; 1.2001 + return NS_OK; 1.2002 +} 1.2003 + 1.2004 +/* readonly attribute string contractID; */ 1.2005 +NS_IMETHODIMP 1.2006 +nsXPCConstructor::GetContractID(char * *aContractID) 1.2007 +{ 1.2008 + *aContractID = nullptr; 1.2009 + return NS_ERROR_NOT_AVAILABLE; 1.2010 +} 1.2011 + 1.2012 +/* readonly attribute string classDescription; */ 1.2013 +NS_IMETHODIMP 1.2014 +nsXPCConstructor::GetClassDescription(char * *aClassDescription) 1.2015 +{ 1.2016 + static const char classDescription[] = "XPCConstructor"; 1.2017 + *aClassDescription = (char*)nsMemory::Clone(classDescription, sizeof(classDescription)); 1.2018 + return *aClassDescription ? NS_OK : NS_ERROR_OUT_OF_MEMORY; 1.2019 +} 1.2020 + 1.2021 +/* readonly attribute nsCIDPtr classID; */ 1.2022 +NS_IMETHODIMP 1.2023 +nsXPCConstructor::GetClassID(nsCID * *aClassID) 1.2024 +{ 1.2025 + *aClassID = nullptr; 1.2026 + return NS_OK; 1.2027 +} 1.2028 + 1.2029 +/* readonly attribute uint32_t implementationLanguage; */ 1.2030 +NS_IMETHODIMP 1.2031 +nsXPCConstructor::GetImplementationLanguage(uint32_t *aImplementationLanguage) 1.2032 +{ 1.2033 + *aImplementationLanguage = nsIProgrammingLanguage::CPLUSPLUS; 1.2034 + return NS_OK; 1.2035 +} 1.2036 + 1.2037 +/* readonly attribute uint32_t flags; */ 1.2038 +NS_IMETHODIMP 1.2039 +nsXPCConstructor::GetFlags(uint32_t *aFlags) 1.2040 +{ 1.2041 + *aFlags = 0; 1.2042 + return NS_OK; 1.2043 +} 1.2044 + 1.2045 +/* [notxpcom] readonly attribute nsCID classIDNoAlloc; */ 1.2046 +NS_IMETHODIMP 1.2047 +nsXPCConstructor::GetClassIDNoAlloc(nsCID *aClassIDNoAlloc) 1.2048 +{ 1.2049 + return NS_ERROR_NOT_AVAILABLE; 1.2050 +} 1.2051 + 1.2052 +nsXPCConstructor::nsXPCConstructor(nsIJSCID* aClassID, 1.2053 + nsIJSIID* aInterfaceID, 1.2054 + const char* aInitializer) 1.2055 + : mClassID(aClassID), 1.2056 + mInterfaceID(aInterfaceID) 1.2057 +{ 1.2058 + mInitializer = aInitializer ? 1.2059 + (char*) nsMemory::Clone(aInitializer, strlen(aInitializer)+1) : 1.2060 + nullptr; 1.2061 +} 1.2062 + 1.2063 +nsXPCConstructor::~nsXPCConstructor() 1.2064 +{ 1.2065 + if (mInitializer) 1.2066 + nsMemory::Free(mInitializer); 1.2067 +} 1.2068 + 1.2069 +/* readonly attribute nsIJSCID classID; */ 1.2070 +NS_IMETHODIMP 1.2071 +nsXPCConstructor::GetClassID(nsIJSCID * *aClassID) 1.2072 +{ 1.2073 + nsRefPtr<nsIJSCID> rval = mClassID; 1.2074 + rval.forget(aClassID); 1.2075 + return NS_OK; 1.2076 +} 1.2077 + 1.2078 +/* readonly attribute nsIJSIID interfaceID; */ 1.2079 +NS_IMETHODIMP 1.2080 +nsXPCConstructor::GetInterfaceID(nsIJSIID * *aInterfaceID) 1.2081 +{ 1.2082 + nsRefPtr<nsIJSIID> rval = mInterfaceID; 1.2083 + rval.forget(aInterfaceID); 1.2084 + return NS_OK; 1.2085 +} 1.2086 + 1.2087 +/* readonly attribute string initializer; */ 1.2088 +NS_IMETHODIMP 1.2089 +nsXPCConstructor::GetInitializer(char * *aInitializer) 1.2090 +{ 1.2091 + XPC_STRING_GETTER_BODY(aInitializer, mInitializer); 1.2092 +} 1.2093 + 1.2094 +NS_INTERFACE_MAP_BEGIN(nsXPCConstructor) 1.2095 + NS_INTERFACE_MAP_ENTRY(nsIXPCConstructor) 1.2096 + NS_INTERFACE_MAP_ENTRY(nsIXPCScriptable) 1.2097 + NS_INTERFACE_MAP_ENTRY(nsIClassInfo) 1.2098 + NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIXPCConstructor) 1.2099 +NS_INTERFACE_MAP_END 1.2100 + 1.2101 +NS_IMPL_ADDREF(nsXPCConstructor) 1.2102 +NS_IMPL_RELEASE(nsXPCConstructor) 1.2103 + 1.2104 +// The nsIXPCScriptable map declaration that will generate stubs for us... 1.2105 +#define XPC_MAP_CLASSNAME nsXPCConstructor 1.2106 +#define XPC_MAP_QUOTED_CLASSNAME "nsXPCConstructor" 1.2107 +#define XPC_MAP_WANT_CALL 1.2108 +#define XPC_MAP_WANT_CONSTRUCT 1.2109 +#define XPC_MAP_FLAGS 0 1.2110 +#include "xpc_map_end.h" /* This will #undef the above */ 1.2111 + 1.2112 + 1.2113 +/* bool call (in nsIXPConnectWrappedNative wrapper, in JSContextPtr cx, in JSObjectPtr obj, in uint32_t argc, in JSValPtr argv, in JSValPtr vp); */ 1.2114 +NS_IMETHODIMP 1.2115 +nsXPCConstructor::Call(nsIXPConnectWrappedNative *wrapper, JSContext *cx, JSObject *objArg, 1.2116 + const CallArgs &args, bool *_retval) 1.2117 +{ 1.2118 + RootedObject obj(cx, objArg); 1.2119 + return CallOrConstruct(wrapper, cx, obj, args, _retval); 1.2120 + 1.2121 +} 1.2122 + 1.2123 +/* bool construct (in nsIXPConnectWrappedNative wrapper, in JSContextPtr cx, in JSObjectPtr obj, in uint32_t argc, in JSValPtr argv, in JSValPtr vp); */ 1.2124 +NS_IMETHODIMP 1.2125 +nsXPCConstructor::Construct(nsIXPConnectWrappedNative *wrapper, JSContext *cx, JSObject *objArg, 1.2126 + const CallArgs &args, bool *_retval) 1.2127 +{ 1.2128 + RootedObject obj(cx, objArg); 1.2129 + return CallOrConstruct(wrapper, cx, obj, args, _retval); 1.2130 +} 1.2131 + 1.2132 +// static 1.2133 +nsresult 1.2134 +nsXPCConstructor::CallOrConstruct(nsIXPConnectWrappedNative *wrapper,JSContext *cx, 1.2135 + HandleObject obj, const CallArgs &args, bool *_retval) 1.2136 +{ 1.2137 + nsXPConnect* xpc = nsXPConnect::XPConnect(); 1.2138 + 1.2139 + // security check not required because we are going to call through the 1.2140 + // code which is reflected into JS which will do that for us later. 1.2141 + 1.2142 + nsCOMPtr<nsIXPConnectJSObjectHolder> cidHolder; 1.2143 + nsCOMPtr<nsIXPConnectJSObjectHolder> iidHolder; 1.2144 + RootedObject cidObj(cx); 1.2145 + RootedObject iidObj(cx); 1.2146 + 1.2147 + if (NS_FAILED(xpc->WrapNative(cx, obj, mClassID, NS_GET_IID(nsIJSCID), 1.2148 + getter_AddRefs(cidHolder))) || !cidHolder || 1.2149 + // Assign, not compare 1.2150 + !(cidObj = cidHolder->GetJSObject()) || 1.2151 + NS_FAILED(xpc->WrapNative(cx, obj, mInterfaceID, NS_GET_IID(nsIJSIID), 1.2152 + getter_AddRefs(iidHolder))) || !iidHolder || 1.2153 + // Assign, not compare 1.2154 + !(iidObj = iidHolder->GetJSObject())) { 1.2155 + return ThrowAndFail(NS_ERROR_XPC_CANT_CREATE_WN, cx, _retval); 1.2156 + } 1.2157 + 1.2158 + JS::Rooted<JS::Value> arg(cx, ObjectValue(*iidObj)); 1.2159 + RootedValue rval(cx); 1.2160 + if (!JS_CallFunctionName(cx, cidObj, "createInstance", arg, &rval) || 1.2161 + rval.isPrimitive()) { 1.2162 + // createInstance will have thrown an exception 1.2163 + *_retval = false; 1.2164 + return NS_OK; 1.2165 + } 1.2166 + 1.2167 + args.rval().set(rval); 1.2168 + 1.2169 + // call initializer method if supplied 1.2170 + if (mInitializer) { 1.2171 + RootedObject newObj(cx, &rval.toObject()); 1.2172 + // first check existence of function property for better error reporting 1.2173 + RootedValue fun(cx); 1.2174 + if (!JS_GetProperty(cx, newObj, mInitializer, &fun) || 1.2175 + fun.isPrimitive()) { 1.2176 + return ThrowAndFail(NS_ERROR_XPC_BAD_INITIALIZER_NAME, cx, _retval); 1.2177 + } 1.2178 + 1.2179 + RootedValue dummy(cx); 1.2180 + if (!JS_CallFunctionValue(cx, newObj, fun, args, &dummy)) { 1.2181 + // function should have thrown an exception 1.2182 + *_retval = false; 1.2183 + return NS_OK; 1.2184 + } 1.2185 + } 1.2186 + 1.2187 + return NS_OK; 1.2188 +} 1.2189 + 1.2190 +/*******************************************************/ 1.2191 +// JavaScript Constructor for nsIXPCConstructor objects (Components.Constructor) 1.2192 + 1.2193 +class nsXPCComponents_Constructor : 1.2194 + public nsIXPCComponents_Constructor, 1.2195 + public nsIXPCScriptable, 1.2196 + public nsIClassInfo 1.2197 +{ 1.2198 +public: 1.2199 + // all the interface method declarations... 1.2200 + NS_DECL_ISUPPORTS 1.2201 + NS_DECL_NSIXPCCOMPONENTS_CONSTRUCTOR 1.2202 + NS_DECL_NSIXPCSCRIPTABLE 1.2203 + NS_DECL_NSICLASSINFO 1.2204 + 1.2205 +public: 1.2206 + nsXPCComponents_Constructor(); 1.2207 + virtual ~nsXPCComponents_Constructor(); 1.2208 + 1.2209 +private: 1.2210 + static nsresult CallOrConstruct(nsIXPConnectWrappedNative *wrapper, 1.2211 + JSContext *cx, HandleObject obj, 1.2212 + const CallArgs &args, bool *_retval); 1.2213 +}; 1.2214 + 1.2215 +/***************************************************************************/ 1.2216 +/* void getInterfaces (out uint32_t count, [array, size_is (count), retval] 1.2217 + out nsIIDPtr array); */ 1.2218 +NS_IMETHODIMP 1.2219 +nsXPCComponents_Constructor::GetInterfaces(uint32_t *aCount, nsIID * **aArray) 1.2220 +{ 1.2221 + const uint32_t count = 2; 1.2222 + *aCount = count; 1.2223 + nsIID **array; 1.2224 + *aArray = array = static_cast<nsIID**>(nsMemory::Alloc(count * sizeof(nsIID*))); 1.2225 + if (!array) 1.2226 + return NS_ERROR_OUT_OF_MEMORY; 1.2227 + 1.2228 + uint32_t index = 0; 1.2229 + nsIID* clone; 1.2230 +#define PUSH_IID(id) \ 1.2231 + clone = static_cast<nsIID *>(nsMemory::Clone(&NS_GET_IID( id ), \ 1.2232 + sizeof(nsIID))); \ 1.2233 + if (!clone) \ 1.2234 + goto oom; \ 1.2235 + array[index++] = clone; 1.2236 + 1.2237 + PUSH_IID(nsIXPCComponents_Constructor) 1.2238 + PUSH_IID(nsIXPCScriptable) 1.2239 +#undef PUSH_IID 1.2240 + 1.2241 + return NS_OK; 1.2242 +oom: 1.2243 + while (index) 1.2244 + nsMemory::Free(array[--index]); 1.2245 + nsMemory::Free(array); 1.2246 + *aArray = nullptr; 1.2247 + return NS_ERROR_OUT_OF_MEMORY; 1.2248 +} 1.2249 + 1.2250 +/* nsISupports getHelperForLanguage (in uint32_t language); */ 1.2251 +NS_IMETHODIMP 1.2252 +nsXPCComponents_Constructor::GetHelperForLanguage(uint32_t language, 1.2253 + nsISupports **retval) 1.2254 +{ 1.2255 + *retval = nullptr; 1.2256 + return NS_OK; 1.2257 +} 1.2258 + 1.2259 +/* readonly attribute string contractID; */ 1.2260 +NS_IMETHODIMP 1.2261 +nsXPCComponents_Constructor::GetContractID(char * *aContractID) 1.2262 +{ 1.2263 + *aContractID = nullptr; 1.2264 + return NS_ERROR_NOT_AVAILABLE; 1.2265 +} 1.2266 + 1.2267 +/* readonly attribute string classDescription; */ 1.2268 +NS_IMETHODIMP 1.2269 +nsXPCComponents_Constructor::GetClassDescription(char * *aClassDescription) 1.2270 +{ 1.2271 + static const char classDescription[] = "XPCComponents_Constructor"; 1.2272 + *aClassDescription = (char*)nsMemory::Clone(classDescription, sizeof(classDescription)); 1.2273 + return *aClassDescription ? NS_OK : NS_ERROR_OUT_OF_MEMORY; 1.2274 +} 1.2275 + 1.2276 +/* readonly attribute nsCIDPtr classID; */ 1.2277 +NS_IMETHODIMP 1.2278 +nsXPCComponents_Constructor::GetClassID(nsCID * *aClassID) 1.2279 +{ 1.2280 + *aClassID = nullptr; 1.2281 + return NS_OK; 1.2282 +} 1.2283 + 1.2284 +/* readonly attribute uint32_t implementationLanguage; */ 1.2285 +NS_IMETHODIMP 1.2286 +nsXPCComponents_Constructor::GetImplementationLanguage(uint32_t *aImplementationLanguage) 1.2287 +{ 1.2288 + *aImplementationLanguage = nsIProgrammingLanguage::CPLUSPLUS; 1.2289 + return NS_OK; 1.2290 +} 1.2291 + 1.2292 +/* readonly attribute uint32_t flags; */ 1.2293 +NS_IMETHODIMP 1.2294 +nsXPCComponents_Constructor::GetFlags(uint32_t *aFlags) 1.2295 +{ 1.2296 + *aFlags = 0; 1.2297 + return NS_OK; 1.2298 +} 1.2299 + 1.2300 +/* [notxpcom] readonly attribute nsCID classIDNoAlloc; */ 1.2301 +NS_IMETHODIMP 1.2302 +nsXPCComponents_Constructor::GetClassIDNoAlloc(nsCID *aClassIDNoAlloc) 1.2303 +{ 1.2304 + return NS_ERROR_NOT_AVAILABLE; 1.2305 +} 1.2306 + 1.2307 +nsXPCComponents_Constructor::nsXPCComponents_Constructor() 1.2308 +{ 1.2309 +} 1.2310 + 1.2311 +nsXPCComponents_Constructor::~nsXPCComponents_Constructor() 1.2312 +{ 1.2313 + // empty 1.2314 +} 1.2315 + 1.2316 +NS_INTERFACE_MAP_BEGIN(nsXPCComponents_Constructor) 1.2317 + NS_INTERFACE_MAP_ENTRY(nsIXPCComponents_Constructor) 1.2318 + NS_INTERFACE_MAP_ENTRY(nsIXPCScriptable) 1.2319 + NS_INTERFACE_MAP_ENTRY(nsIClassInfo) 1.2320 + NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIXPCComponents_Constructor) 1.2321 +NS_INTERFACE_MAP_END 1.2322 + 1.2323 +NS_IMPL_ADDREF(nsXPCComponents_Constructor) 1.2324 +NS_IMPL_RELEASE(nsXPCComponents_Constructor) 1.2325 + 1.2326 +// The nsIXPCScriptable map declaration that will generate stubs for us... 1.2327 +#define XPC_MAP_CLASSNAME nsXPCComponents_Constructor 1.2328 +#define XPC_MAP_QUOTED_CLASSNAME "nsXPCComponents_Constructor" 1.2329 +#define XPC_MAP_WANT_CALL 1.2330 +#define XPC_MAP_WANT_CONSTRUCT 1.2331 +#define XPC_MAP_WANT_HASINSTANCE 1.2332 +#define XPC_MAP_FLAGS nsIXPCScriptable::ALLOW_PROP_MODS_DURING_RESOLVE 1.2333 +#include "xpc_map_end.h" /* This will #undef the above */ 1.2334 + 1.2335 + 1.2336 +/* bool call (in nsIXPConnectWrappedNative wrapper, in JSContextPtr cx, in JSObjectPtr obj, in uint32_t argc, in JSValPtr argv, in JSValPtr vp); */ 1.2337 +NS_IMETHODIMP 1.2338 +nsXPCComponents_Constructor::Call(nsIXPConnectWrappedNative *wrapper, JSContext *cx, 1.2339 + JSObject *objArg, const CallArgs &args, bool *_retval) 1.2340 +{ 1.2341 + RootedObject obj(cx, objArg); 1.2342 + return CallOrConstruct(wrapper, cx, obj, args, _retval); 1.2343 +} 1.2344 + 1.2345 +/* bool construct (in nsIXPConnectWrappedNative wrapper, in JSContextPtr cx, in JSObjectPtr obj, in uint32_t argc, in JSValPtr argv, in JSValPtr vp); */ 1.2346 +NS_IMETHODIMP 1.2347 +nsXPCComponents_Constructor::Construct(nsIXPConnectWrappedNative *wrapper, JSContext *cx, 1.2348 + JSObject *objArg, const CallArgs &args, bool *_retval) 1.2349 +{ 1.2350 + RootedObject obj(cx, objArg); 1.2351 + return CallOrConstruct(wrapper, cx, obj, args, _retval); 1.2352 +} 1.2353 + 1.2354 +// static 1.2355 +nsresult 1.2356 +nsXPCComponents_Constructor::CallOrConstruct(nsIXPConnectWrappedNative *wrapper, 1.2357 + JSContext *cx, HandleObject obj, 1.2358 + const CallArgs &args, bool *_retval) 1.2359 +{ 1.2360 + // make sure we have at least one arg 1.2361 + 1.2362 + if (args.length() < 1) 1.2363 + return ThrowAndFail(NS_ERROR_XPC_NOT_ENOUGH_ARGS, cx, _retval); 1.2364 + 1.2365 + // get the various other object pointers we need 1.2366 + 1.2367 + nsXPConnect* xpc = nsXPConnect::XPConnect(); 1.2368 + XPCWrappedNativeScope* scope = GetObjectScope(obj); 1.2369 + nsCOMPtr<nsIXPCComponents> comp; 1.2370 + 1.2371 + if (!xpc || !scope || !(comp = do_QueryInterface(scope->GetComponents()))) 1.2372 + return ThrowAndFail(NS_ERROR_XPC_UNEXPECTED, cx, _retval); 1.2373 + 1.2374 + // Do the security check if necessary 1.2375 + 1.2376 + nsIXPCSecurityManager* sm = xpc->GetDefaultSecurityManager(); 1.2377 + if (sm && NS_FAILED(sm->CanCreateInstance(cx, nsXPCConstructor::GetCID()))) { 1.2378 + // the security manager vetoed. It should have set an exception. 1.2379 + *_retval = false; 1.2380 + return NS_OK; 1.2381 + } 1.2382 + 1.2383 + // initialization params for the Constructor object we will create 1.2384 + nsCOMPtr<nsIJSCID> cClassID; 1.2385 + nsCOMPtr<nsIJSIID> cInterfaceID; 1.2386 + const char* cInitializer = nullptr; 1.2387 + JSAutoByteString cInitializerBytes; 1.2388 + 1.2389 + if (args.length() >= 3) { 1.2390 + // args[2] is an initializer function or property name 1.2391 + RootedString str(cx, ToString(cx, args[2])); 1.2392 + if (!str || !(cInitializer = cInitializerBytes.encodeLatin1(cx, str))) 1.2393 + return ThrowAndFail(NS_ERROR_XPC_BAD_CONVERT_JS, cx, _retval); 1.2394 + } 1.2395 + 1.2396 + if (args.length() >= 2) { 1.2397 + // args[1] is an iid name string 1.2398 + // XXXjband support passing "Components.interfaces.foo"? 1.2399 + 1.2400 + nsCOMPtr<nsIXPCComponents_Interfaces> ifaces; 1.2401 + nsCOMPtr<nsIXPConnectJSObjectHolder> holder; 1.2402 + RootedObject ifacesObj(cx); 1.2403 + 1.2404 + // we do the lookup by asking the Components.interfaces object 1.2405 + // for the property with this name - i.e. we let its caching of these 1.2406 + // nsIJSIID objects work for us. 1.2407 + 1.2408 + if (NS_FAILED(comp->GetInterfaces(getter_AddRefs(ifaces))) || 1.2409 + NS_FAILED(xpc->WrapNative(cx, obj, ifaces, 1.2410 + NS_GET_IID(nsIXPCComponents_Interfaces), 1.2411 + getter_AddRefs(holder))) || !holder || 1.2412 + // Assign, not compare 1.2413 + !(ifacesObj = holder->GetJSObject())) { 1.2414 + return ThrowAndFail(NS_ERROR_XPC_UNEXPECTED, cx, _retval); 1.2415 + } 1.2416 + 1.2417 + RootedString str(cx, ToString(cx, args[1])); 1.2418 + RootedId id(cx); 1.2419 + if (!str || !JS_StringToId(cx, str, &id)) 1.2420 + return ThrowAndFail(NS_ERROR_XPC_BAD_CONVERT_JS, cx, _retval); 1.2421 + 1.2422 + RootedValue val(cx); 1.2423 + if (!JS_GetPropertyById(cx, ifacesObj, id, &val) || val.isPrimitive()) 1.2424 + return ThrowAndFail(NS_ERROR_XPC_BAD_IID, cx, _retval); 1.2425 + 1.2426 + nsCOMPtr<nsIXPConnectWrappedNative> wn; 1.2427 + if (NS_FAILED(xpc->GetWrappedNativeOfJSObject(cx, &val.toObject(), 1.2428 + getter_AddRefs(wn))) || !wn || 1.2429 + !(cInterfaceID = do_QueryWrappedNative(wn))) { 1.2430 + return ThrowAndFail(NS_ERROR_XPC_UNEXPECTED, cx, _retval); 1.2431 + } 1.2432 + } else { 1.2433 + nsCOMPtr<nsIInterfaceInfo> info; 1.2434 + xpc->GetInfoForIID(&NS_GET_IID(nsISupports), getter_AddRefs(info)); 1.2435 + 1.2436 + if (info) { 1.2437 + cInterfaceID = nsJSIID::NewID(info); 1.2438 + } 1.2439 + if (!cInterfaceID) 1.2440 + return ThrowAndFail(NS_ERROR_XPC_UNEXPECTED, cx, _retval); 1.2441 + } 1.2442 + 1.2443 + // a new scope to avoid warnings about shadowed names 1.2444 + { 1.2445 + // argv[0] is a contractid name string 1.2446 + // XXXjband support passing "Components.classes.foo"? 1.2447 + 1.2448 + // we do the lookup by asking the Components.classes object 1.2449 + // for the property with this name - i.e. we let its caching of these 1.2450 + // nsIJSCID objects work for us. 1.2451 + 1.2452 + nsCOMPtr<nsIXPCComponents_Classes> classes; 1.2453 + nsCOMPtr<nsIXPConnectJSObjectHolder> holder; 1.2454 + RootedObject classesObj(cx); 1.2455 + 1.2456 + if (NS_FAILED(comp->GetClasses(getter_AddRefs(classes))) || 1.2457 + NS_FAILED(xpc->WrapNative(cx, obj, classes, 1.2458 + NS_GET_IID(nsIXPCComponents_Classes), 1.2459 + getter_AddRefs(holder))) || !holder || 1.2460 + // Assign, not compare 1.2461 + !(classesObj = holder->GetJSObject())) { 1.2462 + return ThrowAndFail(NS_ERROR_XPC_UNEXPECTED, cx, _retval); 1.2463 + } 1.2464 + 1.2465 + RootedString str(cx, ToString(cx, args[0])); 1.2466 + RootedId id(cx); 1.2467 + if (!str || !JS_StringToId(cx, str, &id)) 1.2468 + return ThrowAndFail(NS_ERROR_XPC_BAD_CONVERT_JS, cx, _retval); 1.2469 + 1.2470 + RootedValue val(cx); 1.2471 + if (!JS_GetPropertyById(cx, classesObj, id, &val) || val.isPrimitive()) 1.2472 + return ThrowAndFail(NS_ERROR_XPC_BAD_CID, cx, _retval); 1.2473 + 1.2474 + nsCOMPtr<nsIXPConnectWrappedNative> wn; 1.2475 + if (NS_FAILED(xpc->GetWrappedNativeOfJSObject(cx, JSVAL_TO_OBJECT(val), 1.2476 + getter_AddRefs(wn))) || !wn || 1.2477 + !(cClassID = do_QueryWrappedNative(wn))) { 1.2478 + return ThrowAndFail(NS_ERROR_XPC_UNEXPECTED, cx, _retval); 1.2479 + } 1.2480 + } 1.2481 + 1.2482 + nsCOMPtr<nsIXPCConstructor> ctor = new nsXPCConstructor(cClassID, cInterfaceID, cInitializer); 1.2483 + nsCOMPtr<nsIXPConnectJSObjectHolder> holder2; 1.2484 + RootedObject newObj(cx); 1.2485 + 1.2486 + if (NS_FAILED(xpc->WrapNative(cx, obj, ctor, NS_GET_IID(nsIXPCConstructor), 1.2487 + getter_AddRefs(holder2))) || !holder2 || 1.2488 + // Assign, not compare 1.2489 + !(newObj = holder2->GetJSObject())) { 1.2490 + return ThrowAndFail(NS_ERROR_XPC_CANT_CREATE_WN, cx, _retval); 1.2491 + } 1.2492 + 1.2493 + args.rval().setObject(*newObj); 1.2494 + return NS_OK; 1.2495 +} 1.2496 + 1.2497 +/* bool hasInstance (in nsIXPConnectWrappedNative wrapper, in JSContextPtr cx, in JSObjectPtr obj, in jsval val, out bool bp); */ 1.2498 +NS_IMETHODIMP 1.2499 +nsXPCComponents_Constructor::HasInstance(nsIXPConnectWrappedNative *wrapper, 1.2500 + JSContext * cx, JSObject * obj, 1.2501 + HandleValue val, bool *bp, 1.2502 + bool *_retval) 1.2503 +{ 1.2504 + if (bp) 1.2505 + *bp = JSValIsInterfaceOfType(cx, val, NS_GET_IID(nsIXPCConstructor)); 1.2506 + return NS_OK; 1.2507 +} 1.2508 + 1.2509 +class nsXPCComponents_Utils : 1.2510 + public nsIXPCComponents_Utils, 1.2511 + public nsIXPCScriptable 1.2512 +{ 1.2513 +public: 1.2514 + // all the interface method declarations... 1.2515 + NS_DECL_ISUPPORTS 1.2516 + NS_DECL_NSIXPCSCRIPTABLE 1.2517 + NS_DECL_NSIXPCCOMPONENTS_UTILS 1.2518 + 1.2519 +public: 1.2520 + nsXPCComponents_Utils() { } 1.2521 + virtual ~nsXPCComponents_Utils() { } 1.2522 + 1.2523 +private: 1.2524 + nsCOMPtr<nsIXPCComponents_utils_Sandbox> mSandbox; 1.2525 +}; 1.2526 + 1.2527 +NS_INTERFACE_MAP_BEGIN(nsXPCComponents_Utils) 1.2528 + NS_INTERFACE_MAP_ENTRY(nsIXPCComponents_Utils) 1.2529 + NS_INTERFACE_MAP_ENTRY(nsIXPCScriptable) 1.2530 + NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIXPCComponents_Utils) 1.2531 +NS_INTERFACE_MAP_END 1.2532 + 1.2533 +NS_IMPL_ADDREF(nsXPCComponents_Utils) 1.2534 +NS_IMPL_RELEASE(nsXPCComponents_Utils) 1.2535 + 1.2536 +// The nsIXPCScriptable map declaration that will generate stubs for us... 1.2537 +#define XPC_MAP_CLASSNAME nsXPCComponents_Utils 1.2538 +#define XPC_MAP_QUOTED_CLASSNAME "nsXPCComponents_Utils" 1.2539 +#define XPC_MAP_FLAGS nsIXPCScriptable::ALLOW_PROP_MODS_DURING_RESOLVE 1.2540 +#include "xpc_map_end.h" /* This will #undef the above */ 1.2541 + 1.2542 +NS_IMETHODIMP 1.2543 +nsXPCComponents_Utils::GetSandbox(nsIXPCComponents_utils_Sandbox **aSandbox) 1.2544 +{ 1.2545 + NS_ENSURE_ARG_POINTER(aSandbox); 1.2546 + if (!mSandbox) 1.2547 + mSandbox = NewSandboxConstructor(); 1.2548 + 1.2549 + nsCOMPtr<nsIXPCComponents_utils_Sandbox> rval = mSandbox; 1.2550 + rval.forget(aSandbox); 1.2551 + return NS_OK; 1.2552 +} 1.2553 + 1.2554 +/* void reportError (); */ 1.2555 +NS_IMETHODIMP 1.2556 +nsXPCComponents_Utils::ReportError(HandleValue error, JSContext *cx) 1.2557 +{ 1.2558 + // This function shall never fail! Silently eat any failure conditions. 1.2559 + 1.2560 + nsCOMPtr<nsIConsoleService> console(do_GetService(NS_CONSOLESERVICE_CONTRACTID)); 1.2561 + 1.2562 + nsCOMPtr<nsIScriptError> scripterr(do_CreateInstance(NS_SCRIPTERROR_CONTRACTID)); 1.2563 + 1.2564 + if (!scripterr || !console) 1.2565 + return NS_OK; 1.2566 + 1.2567 + const uint64_t innerWindowID = nsJSUtils::GetCurrentlyRunningCodeInnerWindowID(cx); 1.2568 + 1.2569 + RootedObject errorObj(cx, error.isObject() ? &error.toObject() : nullptr); 1.2570 + JSErrorReport *err = errorObj ? JS_ErrorFromException(cx, errorObj) : nullptr; 1.2571 + if (err) { 1.2572 + // It's a proper JS Error 1.2573 + nsAutoString fileUni; 1.2574 + CopyUTF8toUTF16(err->filename, fileUni); 1.2575 + 1.2576 + uint32_t column = err->uctokenptr - err->uclinebuf; 1.2577 + 1.2578 + const char16_t* ucmessage = 1.2579 + static_cast<const char16_t*>(err->ucmessage); 1.2580 + const char16_t* uclinebuf = 1.2581 + static_cast<const char16_t*>(err->uclinebuf); 1.2582 + 1.2583 + nsresult rv = scripterr->InitWithWindowID( 1.2584 + ucmessage ? nsDependentString(ucmessage) : EmptyString(), 1.2585 + fileUni, 1.2586 + uclinebuf ? nsDependentString(uclinebuf) : EmptyString(), 1.2587 + err->lineno, 1.2588 + column, err->flags, "XPConnect JavaScript", innerWindowID); 1.2589 + NS_ENSURE_SUCCESS(rv, NS_OK); 1.2590 + 1.2591 + console->LogMessage(scripterr); 1.2592 + return NS_OK; 1.2593 + } 1.2594 + 1.2595 + // It's not a JS Error object, so we synthesize as best we're able. 1.2596 + RootedString msgstr(cx, ToString(cx, error)); 1.2597 + if (!msgstr) 1.2598 + return NS_OK; 1.2599 + 1.2600 + nsCOMPtr<nsIStackFrame> frame; 1.2601 + nsXPConnect *xpc = nsXPConnect::XPConnect(); 1.2602 + xpc->GetCurrentJSStack(getter_AddRefs(frame)); 1.2603 + 1.2604 + nsString fileName; 1.2605 + int32_t lineNo = 0; 1.2606 + if (frame) { 1.2607 + frame->GetFilename(fileName); 1.2608 + frame->GetLineNumber(&lineNo); 1.2609 + } 1.2610 + 1.2611 + const jschar *msgchars = JS_GetStringCharsZ(cx, msgstr); 1.2612 + if (!msgchars) 1.2613 + return NS_OK; 1.2614 + 1.2615 + nsresult rv = scripterr->InitWithWindowID( 1.2616 + nsDependentString(static_cast<const char16_t *>(msgchars)), 1.2617 + fileName, EmptyString(), lineNo, 0, 0, 1.2618 + "XPConnect JavaScript", innerWindowID); 1.2619 + NS_ENSURE_SUCCESS(rv, NS_OK); 1.2620 + 1.2621 + console->LogMessage(scripterr); 1.2622 + return NS_OK; 1.2623 +} 1.2624 + 1.2625 +/* void evalInSandbox(in AString source, in nativeobj sandbox); */ 1.2626 +NS_IMETHODIMP 1.2627 +nsXPCComponents_Utils::EvalInSandbox(const nsAString& source, 1.2628 + HandleValue sandboxVal, 1.2629 + HandleValue version, 1.2630 + const nsACString& filenameArg, 1.2631 + int32_t lineNumber, 1.2632 + JSContext *cx, 1.2633 + uint8_t optionalArgc, 1.2634 + MutableHandleValue retval) 1.2635 +{ 1.2636 + RootedObject sandbox(cx); 1.2637 + if (!JS_ValueToObject(cx, sandboxVal, &sandbox) || !sandbox) 1.2638 + return NS_ERROR_INVALID_ARG; 1.2639 + 1.2640 + // Optional third argument: JS version, as a string. 1.2641 + JSVersion jsVersion = JSVERSION_DEFAULT; 1.2642 + if (optionalArgc >= 1) { 1.2643 + JSString *jsVersionStr = ToString(cx, version); 1.2644 + if (!jsVersionStr) 1.2645 + return NS_ERROR_INVALID_ARG; 1.2646 + 1.2647 + JSAutoByteString bytes(cx, jsVersionStr); 1.2648 + if (!bytes) 1.2649 + return NS_ERROR_INVALID_ARG; 1.2650 + 1.2651 + jsVersion = JS_StringToVersion(bytes.ptr()); 1.2652 + // Explicitly check for "latest", which we support for sandboxes but 1.2653 + // isn't in the set of web-exposed version strings. 1.2654 + if (jsVersion == JSVERSION_UNKNOWN && 1.2655 + !strcmp(bytes.ptr(), "latest")) 1.2656 + { 1.2657 + jsVersion = JSVERSION_LATEST; 1.2658 + } 1.2659 + if (jsVersion == JSVERSION_UNKNOWN) 1.2660 + return NS_ERROR_INVALID_ARG; 1.2661 + } 1.2662 + 1.2663 + // Optional fourth and fifth arguments: filename and line number. 1.2664 + int32_t lineNo = (optionalArgc >= 3) ? lineNumber : 1; 1.2665 + nsCString filename; 1.2666 + if (!filenameArg.IsVoid()) { 1.2667 + filename.Assign(filenameArg); 1.2668 + } else { 1.2669 + // Get the current source info from xpc. 1.2670 + nsresult rv; 1.2671 + nsCOMPtr<nsIXPConnect> xpc = do_GetService(nsIXPConnect::GetCID(), &rv); 1.2672 + NS_ENSURE_SUCCESS(rv, rv); 1.2673 + 1.2674 + nsCOMPtr<nsIStackFrame> frame; 1.2675 + xpc->GetCurrentJSStack(getter_AddRefs(frame)); 1.2676 + if (frame) { 1.2677 + nsString frameFile; 1.2678 + frame->GetFilename(frameFile); 1.2679 + CopyUTF16toUTF8(frameFile, filename); 1.2680 + frame->GetLineNumber(&lineNo); 1.2681 + } 1.2682 + } 1.2683 + 1.2684 + return xpc::EvalInSandbox(cx, sandbox, source, filename, lineNo, 1.2685 + jsVersion, false, retval); 1.2686 +} 1.2687 + 1.2688 +NS_IMETHODIMP 1.2689 +nsXPCComponents_Utils::GetSandboxMetadata(HandleValue sandboxVal, 1.2690 + JSContext *cx, MutableHandleValue rval) 1.2691 +{ 1.2692 + if (!sandboxVal.isObject()) 1.2693 + return NS_ERROR_INVALID_ARG; 1.2694 + 1.2695 + RootedObject sandbox(cx, &sandboxVal.toObject()); 1.2696 + sandbox = js::CheckedUnwrap(sandbox); 1.2697 + if (!sandbox || !xpc::IsSandbox(sandbox)) 1.2698 + return NS_ERROR_INVALID_ARG; 1.2699 + 1.2700 + return xpc::GetSandboxMetadata(cx, sandbox, rval); 1.2701 +} 1.2702 + 1.2703 +NS_IMETHODIMP 1.2704 +nsXPCComponents_Utils::SetSandboxMetadata(HandleValue sandboxVal, 1.2705 + HandleValue metadataVal, 1.2706 + JSContext *cx) 1.2707 +{ 1.2708 + if (!sandboxVal.isObject()) 1.2709 + return NS_ERROR_INVALID_ARG; 1.2710 + 1.2711 + RootedObject sandbox(cx, &sandboxVal.toObject()); 1.2712 + sandbox = js::CheckedUnwrap(sandbox); 1.2713 + if (!sandbox || !xpc::IsSandbox(sandbox)) 1.2714 + return NS_ERROR_INVALID_ARG; 1.2715 + 1.2716 + nsresult rv = xpc::SetSandboxMetadata(cx, sandbox, metadataVal); 1.2717 + NS_ENSURE_SUCCESS(rv, rv); 1.2718 + 1.2719 + return NS_OK; 1.2720 +} 1.2721 + 1.2722 +/* JSObject import (in AUTF8String registryLocation, 1.2723 + * [optional] in JSObject targetObj); 1.2724 + */ 1.2725 +NS_IMETHODIMP 1.2726 +nsXPCComponents_Utils::Import(const nsACString& registryLocation, 1.2727 + HandleValue targetObj, 1.2728 + JSContext* cx, 1.2729 + uint8_t optionalArgc, 1.2730 + MutableHandleValue retval) 1.2731 +{ 1.2732 + nsCOMPtr<xpcIJSModuleLoader> moduleloader = 1.2733 + do_GetService(MOZJSCOMPONENTLOADER_CONTRACTID); 1.2734 + if (!moduleloader) 1.2735 + return NS_ERROR_FAILURE; 1.2736 + return moduleloader->Import(registryLocation, targetObj, cx, optionalArgc, retval); 1.2737 +} 1.2738 + 1.2739 +/* unload (in AUTF8String registryLocation); 1.2740 + */ 1.2741 +NS_IMETHODIMP 1.2742 +nsXPCComponents_Utils::Unload(const nsACString & registryLocation) 1.2743 +{ 1.2744 + nsCOMPtr<xpcIJSModuleLoader> moduleloader = 1.2745 + do_GetService(MOZJSCOMPONENTLOADER_CONTRACTID); 1.2746 + if (!moduleloader) 1.2747 + return NS_ERROR_FAILURE; 1.2748 + return moduleloader->Unload(registryLocation); 1.2749 +} 1.2750 + 1.2751 +/* 1.2752 + * JSObject importGlobalProperties (in jsval aPropertyList); 1.2753 + */ 1.2754 +NS_IMETHODIMP 1.2755 +nsXPCComponents_Utils::ImportGlobalProperties(HandleValue aPropertyList, 1.2756 + JSContext* cx) 1.2757 +{ 1.2758 + RootedObject global(cx, CurrentGlobalOrNull(cx)); 1.2759 + MOZ_ASSERT(global); 1.2760 + GlobalProperties options(false); 1.2761 + NS_ENSURE_TRUE(aPropertyList.isObject(), NS_ERROR_INVALID_ARG); 1.2762 + RootedObject propertyList(cx, &aPropertyList.toObject()); 1.2763 + NS_ENSURE_TRUE(JS_IsArrayObject(cx, propertyList), NS_ERROR_INVALID_ARG); 1.2764 + if (!options.Parse(cx, propertyList) || 1.2765 + !options.Define(cx, global)) 1.2766 + { 1.2767 + return NS_ERROR_FAILURE; 1.2768 + } 1.2769 + 1.2770 + return NS_OK; 1.2771 +} 1.2772 + 1.2773 +/* xpcIJSWeakReference getWeakReference (); */ 1.2774 +NS_IMETHODIMP 1.2775 +nsXPCComponents_Utils::GetWeakReference(HandleValue object, JSContext *cx, 1.2776 + xpcIJSWeakReference **_retval) 1.2777 +{ 1.2778 + nsRefPtr<xpcJSWeakReference> ref = new xpcJSWeakReference(); 1.2779 + nsresult rv = ref->Init(cx, object); 1.2780 + NS_ENSURE_SUCCESS(rv, rv); 1.2781 + ref.forget(_retval); 1.2782 + return NS_OK; 1.2783 +} 1.2784 + 1.2785 +/* void forceGC (); */ 1.2786 +NS_IMETHODIMP 1.2787 +nsXPCComponents_Utils::ForceGC() 1.2788 +{ 1.2789 + JSRuntime* rt = nsXPConnect::GetRuntimeInstance()->Runtime(); 1.2790 + PrepareForFullGC(rt); 1.2791 + GCForReason(rt, gcreason::COMPONENT_UTILS); 1.2792 + return NS_OK; 1.2793 +} 1.2794 + 1.2795 +/* void forceCC (); */ 1.2796 +NS_IMETHODIMP 1.2797 +nsXPCComponents_Utils::ForceCC() 1.2798 +{ 1.2799 + nsJSContext::CycleCollectNow(); 1.2800 + return NS_OK; 1.2801 +} 1.2802 + 1.2803 +/* void forceShrinkingGC (); */ 1.2804 +NS_IMETHODIMP 1.2805 +nsXPCComponents_Utils::ForceShrinkingGC() 1.2806 +{ 1.2807 + JSRuntime* rt = nsXPConnect::GetRuntimeInstance()->Runtime(); 1.2808 + PrepareForFullGC(rt); 1.2809 + ShrinkingGC(rt, gcreason::COMPONENT_UTILS); 1.2810 + return NS_OK; 1.2811 +} 1.2812 + 1.2813 +class PreciseGCRunnable : public nsRunnable 1.2814 +{ 1.2815 + public: 1.2816 + PreciseGCRunnable(ScheduledGCCallback* aCallback, bool aShrinking) 1.2817 + : mCallback(aCallback), mShrinking(aShrinking) {} 1.2818 + 1.2819 + NS_IMETHOD Run() 1.2820 + { 1.2821 + JSRuntime* rt = nsXPConnect::GetRuntimeInstance()->Runtime(); 1.2822 + 1.2823 + JSContext *cx; 1.2824 + JSContext *iter = nullptr; 1.2825 + while ((cx = JS_ContextIterator(rt, &iter)) != nullptr) { 1.2826 + if (JS_IsRunning(cx)) { 1.2827 + return NS_DispatchToMainThread(this); 1.2828 + } 1.2829 + } 1.2830 + 1.2831 + PrepareForFullGC(rt); 1.2832 + if (mShrinking) 1.2833 + ShrinkingGC(rt, gcreason::COMPONENT_UTILS); 1.2834 + else 1.2835 + GCForReason(rt, gcreason::COMPONENT_UTILS); 1.2836 + 1.2837 + mCallback->Callback(); 1.2838 + return NS_OK; 1.2839 + } 1.2840 + 1.2841 + private: 1.2842 + nsRefPtr<ScheduledGCCallback> mCallback; 1.2843 + bool mShrinking; 1.2844 +}; 1.2845 + 1.2846 +/* void schedulePreciseGC(in ScheduledGCCallback callback); */ 1.2847 +NS_IMETHODIMP 1.2848 +nsXPCComponents_Utils::SchedulePreciseGC(ScheduledGCCallback* aCallback) 1.2849 +{ 1.2850 + nsRefPtr<PreciseGCRunnable> event = new PreciseGCRunnable(aCallback, false); 1.2851 + return NS_DispatchToMainThread(event); 1.2852 +} 1.2853 + 1.2854 +/* void schedulePreciseShrinkingGC(in ScheduledGCCallback callback); */ 1.2855 +NS_IMETHODIMP 1.2856 +nsXPCComponents_Utils::SchedulePreciseShrinkingGC(ScheduledGCCallback* aCallback) 1.2857 +{ 1.2858 + nsRefPtr<PreciseGCRunnable> event = new PreciseGCRunnable(aCallback, true); 1.2859 + return NS_DispatchToMainThread(event); 1.2860 +} 1.2861 + 1.2862 +/* void unlinkGhostWindows(); */ 1.2863 +NS_IMETHODIMP 1.2864 +nsXPCComponents_Utils::UnlinkGhostWindows() 1.2865 +{ 1.2866 +#ifdef DEBUG 1.2867 + nsWindowMemoryReporter::UnlinkGhostWindows(); 1.2868 + return NS_OK; 1.2869 +#else 1.2870 + return NS_ERROR_NOT_IMPLEMENTED; 1.2871 +#endif 1.2872 +} 1.2873 + 1.2874 +/* [implicit_jscontext] jsval nondeterministicGetWeakMapKeys(in jsval aMap); */ 1.2875 +NS_IMETHODIMP 1.2876 +nsXPCComponents_Utils::NondeterministicGetWeakMapKeys(HandleValue aMap, 1.2877 + JSContext *aCx, 1.2878 + MutableHandleValue aKeys) 1.2879 +{ 1.2880 + if (!aMap.isObject()) { 1.2881 + aKeys.setUndefined(); 1.2882 + return NS_OK; 1.2883 + } 1.2884 + RootedObject objRet(aCx); 1.2885 + RootedObject mapObj(aCx, &aMap.toObject()); 1.2886 + if (!JS_NondeterministicGetWeakMapKeys(aCx, mapObj, &objRet)) 1.2887 + return NS_ERROR_OUT_OF_MEMORY; 1.2888 + aKeys.set(objRet ? ObjectValue(*objRet) : UndefinedValue()); 1.2889 + return NS_OK; 1.2890 +} 1.2891 + 1.2892 +/* void getDebugObject(); */ 1.2893 +NS_IMETHODIMP 1.2894 +nsXPCComponents_Utils::GetJSTestingFunctions(JSContext *cx, 1.2895 + MutableHandleValue retval) 1.2896 +{ 1.2897 + JSObject *obj = js::GetTestingFunctions(cx); 1.2898 + if (!obj) 1.2899 + return NS_ERROR_XPC_JAVASCRIPT_ERROR; 1.2900 + retval.setObject(*obj); 1.2901 + return NS_OK; 1.2902 +} 1.2903 + 1.2904 +/* void getGlobalForObject(); */ 1.2905 +NS_IMETHODIMP 1.2906 +nsXPCComponents_Utils::GetGlobalForObject(HandleValue object, 1.2907 + JSContext *cx, 1.2908 + MutableHandleValue retval) 1.2909 +{ 1.2910 + // First argument must be an object. 1.2911 + if (object.isPrimitive()) 1.2912 + return NS_ERROR_XPC_BAD_CONVERT_JS; 1.2913 + 1.2914 + // Wrappers are parented to their the global in their home compartment. But 1.2915 + // when getting the global for a cross-compartment wrapper, we really want 1.2916 + // a wrapper for the foreign global. So we need to unwrap before getting the 1.2917 + // parent, enter the compartment for the duration of the call, and wrap the 1.2918 + // result. 1.2919 + Rooted<JSObject*> obj(cx, &object.toObject()); 1.2920 + obj = js::UncheckedUnwrap(obj); 1.2921 + { 1.2922 + JSAutoCompartment ac(cx, obj); 1.2923 + obj = JS_GetGlobalForObject(cx, obj); 1.2924 + } 1.2925 + 1.2926 + if (!JS_WrapObject(cx, &obj)) 1.2927 + return NS_ERROR_FAILURE; 1.2928 + 1.2929 + // Outerize if necessary. 1.2930 + if (JSObjectOp outerize = js::GetObjectClass(obj)->ext.outerObject) 1.2931 + obj = outerize(cx, obj); 1.2932 + 1.2933 + retval.setObject(*obj); 1.2934 + return NS_OK; 1.2935 +} 1.2936 + 1.2937 +/* jsval createObjectIn(in jsval vobj); */ 1.2938 +bool 1.2939 +xpc::CreateObjectIn(JSContext *cx, HandleValue vobj, CreateObjectInOptions &options, 1.2940 + MutableHandleValue rval) 1.2941 +{ 1.2942 + if (!vobj.isObject()) { 1.2943 + JS_ReportError(cx, "Expected an object as the target scope"); 1.2944 + return false; 1.2945 + } 1.2946 + 1.2947 + RootedObject scope(cx, js::CheckedUnwrap(&vobj.toObject())); 1.2948 + if (!scope) { 1.2949 + JS_ReportError(cx, "Permission denied to create object in the target scope"); 1.2950 + return false; 1.2951 + } 1.2952 + 1.2953 + bool define = !JSID_IS_VOID(options.defineAs); 1.2954 + 1.2955 + if (define && js::IsScriptedProxy(scope)) { 1.2956 + JS_ReportError(cx, "Defining property on proxy object is not allowed"); 1.2957 + return false; 1.2958 + } 1.2959 + 1.2960 + RootedObject obj(cx); 1.2961 + { 1.2962 + JSAutoCompartment ac(cx, scope); 1.2963 + obj = JS_NewObject(cx, nullptr, JS::NullPtr(), scope); 1.2964 + if (!obj) 1.2965 + return false; 1.2966 + 1.2967 + if (define) { 1.2968 + if (!JS_DefinePropertyById(cx, scope, options.defineAs, ObjectValue(*obj), 1.2969 + JS_PropertyStub, JS_StrictPropertyStub, 1.2970 + JSPROP_ENUMERATE)) 1.2971 + return false; 1.2972 + } 1.2973 + } 1.2974 + 1.2975 + rval.setObject(*obj); 1.2976 + if (!WrapperFactory::WaiveXrayAndWrap(cx, rval)) 1.2977 + return false; 1.2978 + 1.2979 + return true; 1.2980 +} 1.2981 + 1.2982 +/* boolean isProxy(in value vobj); */ 1.2983 +NS_IMETHODIMP 1.2984 +nsXPCComponents_Utils::IsProxy(HandleValue vobj, JSContext *cx, bool *rval) 1.2985 +{ 1.2986 + if (!vobj.isObject()) { 1.2987 + *rval = false; 1.2988 + return NS_OK; 1.2989 + } 1.2990 + 1.2991 + RootedObject obj(cx, &vobj.toObject()); 1.2992 + obj = js::CheckedUnwrap(obj, /* stopAtOuter = */ false); 1.2993 + NS_ENSURE_TRUE(obj, NS_ERROR_FAILURE); 1.2994 + 1.2995 + *rval = js::IsScriptedProxy(obj); 1.2996 + return NS_OK; 1.2997 +} 1.2998 + 1.2999 +/* jsval evalInWindow(in string source, in jsval window); */ 1.3000 +NS_IMETHODIMP 1.3001 +nsXPCComponents_Utils::EvalInWindow(const nsAString &source, HandleValue window, 1.3002 + JSContext *cx, MutableHandleValue rval) 1.3003 +{ 1.3004 + if (!window.isObject()) 1.3005 + return NS_ERROR_INVALID_ARG; 1.3006 + 1.3007 + RootedObject rwindow(cx, &window.toObject()); 1.3008 + if (!xpc::EvalInWindow(cx, source, rwindow, rval)) 1.3009 + return NS_ERROR_FAILURE; 1.3010 + return NS_OK; 1.3011 +} 1.3012 + 1.3013 +/* jsval exportFunction(in jsval vfunction, in jsval vscope, in jsval voptions); */ 1.3014 +NS_IMETHODIMP 1.3015 +nsXPCComponents_Utils::ExportFunction(HandleValue vfunction, HandleValue vscope, 1.3016 + HandleValue voptions, JSContext *cx, 1.3017 + MutableHandleValue rval) 1.3018 +{ 1.3019 + if (!xpc::ExportFunction(cx, vfunction, vscope, voptions, rval)) 1.3020 + return NS_ERROR_FAILURE; 1.3021 + return NS_OK; 1.3022 +} 1.3023 + 1.3024 +/* jsval createObjectIn(in jsval vobj, [optional] in jsval voptions); */ 1.3025 +NS_IMETHODIMP 1.3026 +nsXPCComponents_Utils::CreateObjectIn(HandleValue vobj, HandleValue voptions, 1.3027 + JSContext *cx, MutableHandleValue rval) 1.3028 +{ 1.3029 + RootedObject optionsObject(cx, voptions.isObject() ? &voptions.toObject() 1.3030 + : nullptr); 1.3031 + CreateObjectInOptions options(cx, optionsObject); 1.3032 + if (voptions.isObject() && 1.3033 + !options.Parse()) 1.3034 + { 1.3035 + return NS_ERROR_FAILURE; 1.3036 + } 1.3037 + 1.3038 + if (!xpc::CreateObjectIn(cx, vobj, options, rval)) 1.3039 + return NS_ERROR_FAILURE; 1.3040 + return NS_OK; 1.3041 +} 1.3042 + 1.3043 +/* void makeObjectPropsNormal(jsval vobj); */ 1.3044 +NS_IMETHODIMP 1.3045 +nsXPCComponents_Utils::MakeObjectPropsNormal(HandleValue vobj, JSContext *cx) 1.3046 +{ 1.3047 + if (!cx) 1.3048 + return NS_ERROR_FAILURE; 1.3049 + 1.3050 + // first argument must be an object 1.3051 + if (vobj.isPrimitive()) 1.3052 + return NS_ERROR_XPC_BAD_CONVERT_JS; 1.3053 + 1.3054 + RootedObject obj(cx, js::UncheckedUnwrap(&vobj.toObject())); 1.3055 + JSAutoCompartment ac(cx, obj); 1.3056 + AutoIdArray ida(cx, JS_Enumerate(cx, obj)); 1.3057 + if (!ida) 1.3058 + return NS_ERROR_FAILURE; 1.3059 + 1.3060 + RootedId id(cx); 1.3061 + RootedValue v(cx); 1.3062 + for (size_t i = 0; i < ida.length(); ++i) { 1.3063 + id = ida[i]; 1.3064 + 1.3065 + if (!JS_GetPropertyById(cx, obj, id, &v)) 1.3066 + return NS_ERROR_FAILURE; 1.3067 + 1.3068 + if (v.isPrimitive()) 1.3069 + continue; 1.3070 + 1.3071 + RootedObject propobj(cx, &v.toObject()); 1.3072 + // TODO Deal with non-functions. 1.3073 + if (!js::IsWrapper(propobj) || !JS_ObjectIsCallable(cx, propobj)) 1.3074 + continue; 1.3075 + 1.3076 + if (!NewFunctionForwarder(cx, id, propobj, /* doclone = */ false, &v) || 1.3077 + !JS_SetPropertyById(cx, obj, id, v)) 1.3078 + return NS_ERROR_FAILURE; 1.3079 + } 1.3080 + 1.3081 + return NS_OK; 1.3082 +} 1.3083 + 1.3084 +NS_IMETHODIMP 1.3085 +nsXPCComponents_Utils::IsDeadWrapper(HandleValue obj, bool *out) 1.3086 +{ 1.3087 + *out = false; 1.3088 + if (obj.isPrimitive()) 1.3089 + return NS_ERROR_INVALID_ARG; 1.3090 + 1.3091 + // Make sure to unwrap first. Once a proxy is nuked, it ceases to be a 1.3092 + // wrapper, meaning that, if passed to another compartment, we'll generate 1.3093 + // a CCW for it. Make sure that IsDeadWrapper sees through the confusion. 1.3094 + *out = JS_IsDeadWrapper(js::CheckedUnwrap(&obj.toObject())); 1.3095 + return NS_OK; 1.3096 +} 1.3097 + 1.3098 +/* void recomputerWrappers(jsval vobj); */ 1.3099 +NS_IMETHODIMP 1.3100 +nsXPCComponents_Utils::RecomputeWrappers(HandleValue vobj, JSContext *cx) 1.3101 +{ 1.3102 + // Determine the compartment of the given object, if any. 1.3103 + JSCompartment *c = vobj.isObject() 1.3104 + ? js::GetObjectCompartment(js::UncheckedUnwrap(&vobj.toObject())) 1.3105 + : nullptr; 1.3106 + 1.3107 + // If no compartment was given, recompute all. 1.3108 + if (!c) 1.3109 + js::RecomputeWrappers(cx, js::AllCompartments(), js::AllCompartments()); 1.3110 + // Otherwise, recompute wrappers for the given compartment. 1.3111 + else 1.3112 + js::RecomputeWrappers(cx, js::SingleCompartment(c), js::AllCompartments()) && 1.3113 + js::RecomputeWrappers(cx, js::AllCompartments(), js::SingleCompartment(c)); 1.3114 + 1.3115 + return NS_OK; 1.3116 +} 1.3117 + 1.3118 +/* jsval setWantXrays(jsval vscope); */ 1.3119 +NS_IMETHODIMP 1.3120 +nsXPCComponents_Utils::SetWantXrays(HandleValue vscope, JSContext *cx) 1.3121 +{ 1.3122 + if (!vscope.isObject()) 1.3123 + return NS_ERROR_INVALID_ARG; 1.3124 + JSObject *scopeObj = js::UncheckedUnwrap(&vscope.toObject()); 1.3125 + JSCompartment *compartment = js::GetObjectCompartment(scopeObj); 1.3126 + EnsureCompartmentPrivate(scopeObj)->wantXrays = true; 1.3127 + bool ok = js::RecomputeWrappers(cx, js::SingleCompartment(compartment), 1.3128 + js::AllCompartments()); 1.3129 + NS_ENSURE_TRUE(ok, NS_ERROR_FAILURE); 1.3130 + return NS_OK; 1.3131 +} 1.3132 + 1.3133 +/* jsval forcePrivilegedComponentsForScope(jsval vscope); */ 1.3134 +NS_IMETHODIMP 1.3135 +nsXPCComponents_Utils::ForcePrivilegedComponentsForScope(HandleValue vscope, 1.3136 + JSContext *cx) 1.3137 +{ 1.3138 + if (!vscope.isObject()) 1.3139 + return NS_ERROR_INVALID_ARG; 1.3140 + JSObject *scopeObj = js::UncheckedUnwrap(&vscope.toObject()); 1.3141 + XPCWrappedNativeScope *scope = GetObjectScope(scopeObj); 1.3142 + scope->ForcePrivilegedComponents(); 1.3143 + return NS_OK; 1.3144 +} 1.3145 + 1.3146 +/* jsval getComponentsForScope(jsval vscope); */ 1.3147 +NS_IMETHODIMP 1.3148 +nsXPCComponents_Utils::GetComponentsForScope(HandleValue vscope, JSContext *cx, 1.3149 + MutableHandleValue rval) 1.3150 +{ 1.3151 + if (!vscope.isObject()) 1.3152 + return NS_ERROR_INVALID_ARG; 1.3153 + JSObject *scopeObj = js::UncheckedUnwrap(&vscope.toObject()); 1.3154 + XPCWrappedNativeScope *scope = GetObjectScope(scopeObj); 1.3155 + RootedObject components(cx); 1.3156 + if (!scope->GetComponentsJSObject(&components)) 1.3157 + return NS_ERROR_FAILURE; 1.3158 + if (!JS_WrapObject(cx, &components)) 1.3159 + return NS_ERROR_FAILURE; 1.3160 + rval.setObject(*components); 1.3161 + return NS_OK; 1.3162 +} 1.3163 + 1.3164 +NS_IMETHODIMP 1.3165 +nsXPCComponents_Utils::Dispatch(HandleValue runnableArg, HandleValue scope, 1.3166 + JSContext *cx) 1.3167 +{ 1.3168 + RootedValue runnable(cx, runnableArg); 1.3169 + // Enter the given compartment, if any, and rewrap runnable. 1.3170 + Maybe<JSAutoCompartment> ac; 1.3171 + if (scope.isObject()) { 1.3172 + JSObject *scopeObj = js::UncheckedUnwrap(&scope.toObject()); 1.3173 + if (!scopeObj) 1.3174 + return NS_ERROR_FAILURE; 1.3175 + ac.construct(cx, scopeObj); 1.3176 + if (!JS_WrapValue(cx, &runnable)) 1.3177 + return NS_ERROR_FAILURE; 1.3178 + } 1.3179 + 1.3180 + // Get an XPCWrappedJS for |runnable|. 1.3181 + if (!runnable.isObject()) 1.3182 + return NS_ERROR_INVALID_ARG; 1.3183 + 1.3184 + nsCOMPtr<nsIRunnable> run; 1.3185 + nsresult rv = nsXPConnect::XPConnect()->WrapJS(cx, &runnable.toObject(), 1.3186 + NS_GET_IID(nsIRunnable), 1.3187 + getter_AddRefs(run)); 1.3188 + NS_ENSURE_SUCCESS(rv, rv); 1.3189 + MOZ_ASSERT(run); 1.3190 + 1.3191 + // Dispatch. 1.3192 + return NS_DispatchToMainThread(run); 1.3193 +} 1.3194 + 1.3195 +#define GENERATE_JSCONTEXTOPTION_GETTER_SETTER(_attr, _getter, _setter) \ 1.3196 + NS_IMETHODIMP \ 1.3197 + nsXPCComponents_Utils::Get## _attr(JSContext* cx, bool* aValue) \ 1.3198 + { \ 1.3199 + *aValue = ContextOptionsRef(cx)._getter(); \ 1.3200 + return NS_OK; \ 1.3201 + } \ 1.3202 + NS_IMETHODIMP \ 1.3203 + nsXPCComponents_Utils::Set## _attr(JSContext* cx, bool aValue) \ 1.3204 + { \ 1.3205 + ContextOptionsRef(cx)._setter(aValue); \ 1.3206 + return NS_OK; \ 1.3207 + } 1.3208 + 1.3209 +#define GENERATE_JSRUNTIMEOPTION_GETTER_SETTER(_attr, _getter, _setter) \ 1.3210 + NS_IMETHODIMP \ 1.3211 + nsXPCComponents_Utils::Get## _attr(JSContext* cx, bool* aValue) \ 1.3212 + { \ 1.3213 + *aValue = RuntimeOptionsRef(cx)._getter(); \ 1.3214 + return NS_OK; \ 1.3215 + } \ 1.3216 + NS_IMETHODIMP \ 1.3217 + nsXPCComponents_Utils::Set## _attr(JSContext* cx, bool aValue) \ 1.3218 + { \ 1.3219 + RuntimeOptionsRef(cx)._setter(aValue); \ 1.3220 + return NS_OK; \ 1.3221 + } 1.3222 + 1.3223 +GENERATE_JSCONTEXTOPTION_GETTER_SETTER(Strict, extraWarnings, setExtraWarnings) 1.3224 +GENERATE_JSCONTEXTOPTION_GETTER_SETTER(Werror, werror, setWerror) 1.3225 +GENERATE_JSCONTEXTOPTION_GETTER_SETTER(Strict_mode, strictMode, setStrictMode) 1.3226 +GENERATE_JSRUNTIMEOPTION_GETTER_SETTER(Ion, ion, setIon) 1.3227 + 1.3228 +#undef GENERATE_JSCONTEXTOPTION_GETTER_SETTER 1.3229 +#undef GENERATE_JSRUNTIMEOPTION_GETTER_SETTER 1.3230 + 1.3231 +NS_IMETHODIMP 1.3232 +nsXPCComponents_Utils::SetGCZeal(int32_t aValue, JSContext* cx) 1.3233 +{ 1.3234 +#ifdef JS_GC_ZEAL 1.3235 + JS_SetGCZeal(cx, uint8_t(aValue), JS_DEFAULT_ZEAL_FREQ); 1.3236 +#endif 1.3237 + return NS_OK; 1.3238 +} 1.3239 + 1.3240 +NS_IMETHODIMP 1.3241 +nsXPCComponents_Utils::NukeSandbox(HandleValue obj, JSContext *cx) 1.3242 +{ 1.3243 + NS_ENSURE_TRUE(obj.isObject(), NS_ERROR_INVALID_ARG); 1.3244 + JSObject *wrapper = &obj.toObject(); 1.3245 + NS_ENSURE_TRUE(IsWrapper(wrapper), NS_ERROR_INVALID_ARG); 1.3246 + JSObject *sb = UncheckedUnwrap(wrapper); 1.3247 + NS_ENSURE_TRUE(IsSandbox(sb), NS_ERROR_INVALID_ARG); 1.3248 + NukeCrossCompartmentWrappers(cx, AllCompartments(), 1.3249 + SingleCompartment(GetObjectCompartment(sb)), 1.3250 + NukeWindowReferences); 1.3251 + return NS_OK; 1.3252 +} 1.3253 + 1.3254 +NS_IMETHODIMP 1.3255 +nsXPCComponents_Utils::BlockScriptForGlobal(HandleValue globalArg, 1.3256 + JSContext *cx) 1.3257 +{ 1.3258 + NS_ENSURE_TRUE(globalArg.isObject(), NS_ERROR_INVALID_ARG); 1.3259 + RootedObject global(cx, UncheckedUnwrap(&globalArg.toObject(), 1.3260 + /* stopAtOuter = */ false)); 1.3261 + NS_ENSURE_TRUE(JS_IsGlobalObject(global), NS_ERROR_INVALID_ARG); 1.3262 + if (nsContentUtils::IsSystemPrincipal(xpc::GetObjectPrincipal(global))) { 1.3263 + JS_ReportError(cx, "Script may not be disabled for system globals"); 1.3264 + return NS_ERROR_FAILURE; 1.3265 + } 1.3266 + Scriptability::Get(global).Block(); 1.3267 + return NS_OK; 1.3268 +} 1.3269 + 1.3270 +NS_IMETHODIMP 1.3271 +nsXPCComponents_Utils::UnblockScriptForGlobal(HandleValue globalArg, 1.3272 + JSContext *cx) 1.3273 +{ 1.3274 + NS_ENSURE_TRUE(globalArg.isObject(), NS_ERROR_INVALID_ARG); 1.3275 + RootedObject global(cx, UncheckedUnwrap(&globalArg.toObject(), 1.3276 + /* stopAtOuter = */ false)); 1.3277 + NS_ENSURE_TRUE(JS_IsGlobalObject(global), NS_ERROR_INVALID_ARG); 1.3278 + if (nsContentUtils::IsSystemPrincipal(xpc::GetObjectPrincipal(global))) { 1.3279 + JS_ReportError(cx, "Script may not be disabled for system globals"); 1.3280 + return NS_ERROR_FAILURE; 1.3281 + } 1.3282 + Scriptability::Get(global).Unblock(); 1.3283 + return NS_OK; 1.3284 +} 1.3285 + 1.3286 +NS_IMETHODIMP 1.3287 +nsXPCComponents_Utils::IsXrayWrapper(HandleValue obj, bool* aRetval) 1.3288 +{ 1.3289 + *aRetval = 1.3290 + obj.isObject() && xpc::WrapperFactory::IsXrayWrapper(&obj.toObject()); 1.3291 + return NS_OK; 1.3292 +} 1.3293 + 1.3294 +NS_IMETHODIMP 1.3295 +nsXPCComponents_Utils::WaiveXrays(HandleValue aVal, JSContext *aCx, MutableHandleValue aRetval) 1.3296 +{ 1.3297 + RootedValue value(aCx, aVal); 1.3298 + if (!xpc::WrapperFactory::WaiveXrayAndWrap(aCx, &value)) 1.3299 + return NS_ERROR_FAILURE; 1.3300 + aRetval.set(value); 1.3301 + return NS_OK; 1.3302 +} 1.3303 + 1.3304 +NS_IMETHODIMP 1.3305 +nsXPCComponents_Utils::UnwaiveXrays(HandleValue aVal, JSContext *aCx, MutableHandleValue aRetval) 1.3306 +{ 1.3307 + if (!aVal.isObject()) { 1.3308 + aRetval.set(aVal); 1.3309 + return NS_OK; 1.3310 + } 1.3311 + 1.3312 + RootedObject obj(aCx, js::UncheckedUnwrap(&aVal.toObject())); 1.3313 + if (!JS_WrapObject(aCx, &obj)) 1.3314 + return NS_ERROR_FAILURE; 1.3315 + aRetval.setObject(*obj); 1.3316 + return NS_OK; 1.3317 +} 1.3318 + 1.3319 +NS_IMETHODIMP 1.3320 +nsXPCComponents_Utils::GetClassName(HandleValue aObj, bool aUnwrap, JSContext *aCx, char **aRv) 1.3321 +{ 1.3322 + if (!aObj.isObject()) 1.3323 + return NS_ERROR_INVALID_ARG; 1.3324 + RootedObject obj(aCx, &aObj.toObject()); 1.3325 + if (aUnwrap) 1.3326 + obj = js::UncheckedUnwrap(obj, /* stopAtOuter = */ false); 1.3327 + *aRv = NS_strdup(js::GetObjectClass(obj)->name); 1.3328 + NS_ENSURE_TRUE(*aRv, NS_ERROR_OUT_OF_MEMORY); 1.3329 + return NS_OK; 1.3330 +} 1.3331 + 1.3332 +NS_IMETHODIMP 1.3333 +nsXPCComponents_Utils::GetDOMClassInfo(const nsAString& aClassName, 1.3334 + nsIClassInfo** aClassInfo) 1.3335 +{ 1.3336 + *aClassInfo = nullptr; 1.3337 + return NS_ERROR_NOT_AVAILABLE; 1.3338 +} 1.3339 + 1.3340 +NS_IMETHODIMP 1.3341 +nsXPCComponents_Utils::GetIncumbentGlobal(HandleValue aCallback, 1.3342 + JSContext *aCx, MutableHandleValue aOut) 1.3343 +{ 1.3344 + nsCOMPtr<nsIGlobalObject> global = mozilla::dom::GetIncumbentGlobal(); 1.3345 + RootedValue globalVal(aCx); 1.3346 + 1.3347 + if (!global) { 1.3348 + globalVal = NullValue(); 1.3349 + } else { 1.3350 + // Note: We rely on the wrap call for outerization. 1.3351 + globalVal = ObjectValue(*global->GetGlobalJSObject()); 1.3352 + if (!JS_WrapValue(aCx, &globalVal)) 1.3353 + return NS_ERROR_FAILURE; 1.3354 + } 1.3355 + 1.3356 + // Invoke the callback, if passed. 1.3357 + if (aCallback.isObject()) { 1.3358 + RootedValue ignored(aCx); 1.3359 + if (!JS_CallFunctionValue(aCx, JS::NullPtr(), aCallback, globalVal, &ignored)) 1.3360 + return NS_ERROR_FAILURE; 1.3361 + } 1.3362 + 1.3363 + aOut.set(globalVal); 1.3364 + return NS_OK; 1.3365 +} 1.3366 + 1.3367 +/* 1.3368 + * Below is a bunch of awkward junk to allow JS test code to trigger the 1.3369 + * creation of an XPCWrappedJS, such that it ends up in the map. We need to 1.3370 + * hand the caller some sort of reference to hold onto (to prevent the 1.3371 + * refcount from dropping to zero as soon as the function returns), but trying 1.3372 + * to return a bonafide XPCWrappedJS to script causes all sorts of trouble. So 1.3373 + * we create a benign holder class instead, which acts as an opaque reference 1.3374 + * that script can use to keep the XPCWrappedJS alive and in the map. 1.3375 + */ 1.3376 + 1.3377 +class WrappedJSHolder : public nsISupports 1.3378 +{ 1.3379 + NS_DECL_ISUPPORTS 1.3380 + WrappedJSHolder() {} 1.3381 + virtual ~WrappedJSHolder() {} 1.3382 + 1.3383 + nsRefPtr<nsXPCWrappedJS> mWrappedJS; 1.3384 +}; 1.3385 +NS_IMPL_ISUPPORTS0(WrappedJSHolder); 1.3386 + 1.3387 +NS_IMETHODIMP 1.3388 +nsXPCComponents_Utils::GenerateXPCWrappedJS(HandleValue aObj, HandleValue aScope, 1.3389 + JSContext *aCx, nsISupports **aOut) 1.3390 +{ 1.3391 + if (!aObj.isObject()) 1.3392 + return NS_ERROR_INVALID_ARG; 1.3393 + RootedObject obj(aCx, &aObj.toObject()); 1.3394 + RootedObject scope(aCx, aScope.isObject() ? js::UncheckedUnwrap(&aScope.toObject()) 1.3395 + : CurrentGlobalOrNull(aCx)); 1.3396 + JSAutoCompartment ac(aCx, scope); 1.3397 + if (!JS_WrapObject(aCx, &obj)) 1.3398 + return NS_ERROR_FAILURE; 1.3399 + 1.3400 + nsRefPtr<WrappedJSHolder> holder = new WrappedJSHolder(); 1.3401 + nsresult rv = nsXPCWrappedJS::GetNewOrUsed(obj, NS_GET_IID(nsISupports), 1.3402 + getter_AddRefs(holder->mWrappedJS)); 1.3403 + holder.forget(aOut); 1.3404 + return rv; 1.3405 +} 1.3406 + 1.3407 +NS_IMETHODIMP 1.3408 +nsXPCComponents_Utils::GetWatchdogTimestamp(const nsAString& aCategory, PRTime *aOut) 1.3409 +{ 1.3410 + WatchdogTimestampCategory category; 1.3411 + if (aCategory.EqualsLiteral("RuntimeStateChange")) 1.3412 + category = TimestampRuntimeStateChange; 1.3413 + else if (aCategory.EqualsLiteral("WatchdogWakeup")) 1.3414 + category = TimestampWatchdogWakeup; 1.3415 + else if (aCategory.EqualsLiteral("WatchdogHibernateStart")) 1.3416 + category = TimestampWatchdogHibernateStart; 1.3417 + else if (aCategory.EqualsLiteral("WatchdogHibernateStop")) 1.3418 + category = TimestampWatchdogHibernateStop; 1.3419 + else 1.3420 + return NS_ERROR_INVALID_ARG; 1.3421 + *aOut = XPCJSRuntime::Get()->GetWatchdogTimestamp(category); 1.3422 + return NS_OK; 1.3423 +} 1.3424 + 1.3425 +NS_IMETHODIMP 1.3426 +nsXPCComponents_Utils::GetJSEngineTelemetryValue(JSContext *cx, MutableHandleValue rval) 1.3427 +{ 1.3428 + RootedObject obj(cx, JS_NewObject(cx, nullptr, JS::NullPtr(), JS::NullPtr())); 1.3429 + if (!obj) 1.3430 + return NS_ERROR_OUT_OF_MEMORY; 1.3431 + 1.3432 + unsigned attrs = JSPROP_ENUMERATE | JSPROP_READONLY | JSPROP_PERMANENT; 1.3433 + 1.3434 + size_t i = JS_SetProtoCalled(cx); 1.3435 + RootedValue v(cx, DoubleValue(i)); 1.3436 + if (!JS_DefineProperty(cx, obj, "setProto", v, attrs)) 1.3437 + return NS_ERROR_OUT_OF_MEMORY; 1.3438 + 1.3439 + i = JS_GetCustomIteratorCount(cx); 1.3440 + v.setDouble(i); 1.3441 + if (!JS_DefineProperty(cx, obj, "customIter", v, attrs)) 1.3442 + return NS_ERROR_OUT_OF_MEMORY; 1.3443 + 1.3444 + rval.setObject(*obj); 1.3445 + return NS_OK; 1.3446 +} 1.3447 + 1.3448 +class MOZ_STACK_CLASS CloneIntoOptions : public OptionsBase 1.3449 +{ 1.3450 +public: 1.3451 + CloneIntoOptions(JSContext *cx = xpc_GetSafeJSContext(), 1.3452 + JSObject *options = nullptr) 1.3453 + : OptionsBase(cx, options) 1.3454 + , cloneFunctions(false) 1.3455 + {} 1.3456 + 1.3457 + virtual bool Parse() 1.3458 + { 1.3459 + return ParseBoolean("cloneFunctions", &cloneFunctions); 1.3460 + } 1.3461 + 1.3462 + bool cloneFunctions; 1.3463 +}; 1.3464 + 1.3465 +class MOZ_STACK_CLASS CloneIntoCallbacksData 1.3466 +{ 1.3467 +public: 1.3468 + CloneIntoCallbacksData(JSContext *aCx, CloneIntoOptions *aOptions) 1.3469 + : mOptions(aOptions) 1.3470 + , mFunctions(aCx) 1.3471 + {} 1.3472 + 1.3473 + CloneIntoOptions *mOptions; 1.3474 + AutoObjectVector mFunctions; 1.3475 +}; 1.3476 + 1.3477 +static JSObject* 1.3478 +CloneIntoReadStructuredClone(JSContext *cx, 1.3479 + JSStructuredCloneReader *reader, 1.3480 + uint32_t tag, 1.3481 + uint32_t value, 1.3482 + void* closure) 1.3483 +{ 1.3484 + CloneIntoCallbacksData* data = static_cast<CloneIntoCallbacksData*>(closure); 1.3485 + MOZ_ASSERT(data); 1.3486 + 1.3487 + if (tag == mozilla::dom::SCTAG_DOM_BLOB || tag == mozilla::dom::SCTAG_DOM_FILELIST) { 1.3488 + MOZ_ASSERT(!value, "Data should be empty"); 1.3489 + 1.3490 + nsISupports *supports; 1.3491 + if (JS_ReadBytes(reader, &supports, sizeof(supports))) { 1.3492 + RootedValue val(cx); 1.3493 + if (NS_SUCCEEDED(nsContentUtils::WrapNative(cx, supports, &val))) 1.3494 + return val.toObjectOrNull(); 1.3495 + } 1.3496 + } 1.3497 + 1.3498 + if (tag == mozilla::dom::SCTAG_DOM_FUNCTION) { 1.3499 + MOZ_ASSERT(value < data->mFunctions.length()); 1.3500 + 1.3501 + RootedValue functionValue(cx); 1.3502 + RootedObject obj(cx, data->mFunctions[value]); 1.3503 + 1.3504 + if (!JS_WrapObject(cx, &obj)) 1.3505 + return nullptr; 1.3506 + 1.3507 + if (!xpc::NewFunctionForwarder(cx, obj, false, &functionValue)) 1.3508 + return nullptr; 1.3509 + 1.3510 + return &functionValue.toObject(); 1.3511 + } 1.3512 + 1.3513 + return nullptr; 1.3514 +} 1.3515 + 1.3516 +static bool 1.3517 +CloneIntoWriteStructuredClone(JSContext *cx, 1.3518 + JSStructuredCloneWriter *writer, 1.3519 + HandleObject obj, 1.3520 + void *closure) 1.3521 +{ 1.3522 + CloneIntoCallbacksData* data = static_cast<CloneIntoCallbacksData*>(closure); 1.3523 + MOZ_ASSERT(data); 1.3524 + 1.3525 + nsCOMPtr<nsIXPConnectWrappedNative> wrappedNative; 1.3526 + nsContentUtils::XPConnect()->GetWrappedNativeOfJSObject(cx, obj, getter_AddRefs(wrappedNative)); 1.3527 + if (wrappedNative) { 1.3528 + uint32_t scTag = 0; 1.3529 + nsISupports *supports = wrappedNative->Native(); 1.3530 + 1.3531 + nsCOMPtr<nsIDOMBlob> blob = do_QueryInterface(supports); 1.3532 + if (blob) 1.3533 + scTag = mozilla::dom::SCTAG_DOM_BLOB; 1.3534 + else { 1.3535 + nsCOMPtr<nsIDOMFileList> list = do_QueryInterface(supports); 1.3536 + if (list) 1.3537 + scTag = mozilla::dom::SCTAG_DOM_FILELIST; 1.3538 + } 1.3539 + 1.3540 + if (scTag) { 1.3541 + return JS_WriteUint32Pair(writer, scTag, 0) && 1.3542 + JS_WriteBytes(writer, &supports, sizeof(supports)); 1.3543 + } 1.3544 + } 1.3545 + 1.3546 + if (data->mOptions->cloneFunctions && JS_ObjectIsCallable(cx, obj)) { 1.3547 + data->mFunctions.append(obj); 1.3548 + return JS_WriteUint32Pair(writer, mozilla::dom::SCTAG_DOM_FUNCTION, 1.3549 + data->mFunctions.length() - 1); 1.3550 + } 1.3551 + 1.3552 + return false; 1.3553 +} 1.3554 + 1.3555 +// These functions serialize raw XPCOM pointers in the data stream, and thus 1.3556 +// should only be used when the read and write are done together 1.3557 +// synchronously. 1.3558 +static JSStructuredCloneCallbacks CloneIntoCallbacks = { 1.3559 + CloneIntoReadStructuredClone, 1.3560 + CloneIntoWriteStructuredClone, 1.3561 + nullptr 1.3562 +}; 1.3563 + 1.3564 +bool 1.3565 +xpc::CloneInto(JSContext *aCx, HandleValue aValue, HandleValue aScope, 1.3566 + HandleValue aOptions, MutableHandleValue aCloned) 1.3567 +{ 1.3568 + if (!aScope.isObject()) 1.3569 + return false; 1.3570 + 1.3571 + RootedObject scope(aCx, &aScope.toObject()); 1.3572 + scope = js::CheckedUnwrap(scope); 1.3573 + if(!scope) { 1.3574 + JS_ReportError(aCx, "Permission denied to clone object into scope"); 1.3575 + return false; 1.3576 + } 1.3577 + 1.3578 + if (!aOptions.isUndefined() && !aOptions.isObject()) { 1.3579 + JS_ReportError(aCx, "Invalid argument"); 1.3580 + return false; 1.3581 + } 1.3582 + 1.3583 + RootedObject optionsObject(aCx, aOptions.isObject() ? &aOptions.toObject() 1.3584 + : nullptr); 1.3585 + CloneIntoOptions options(aCx, optionsObject); 1.3586 + if (aOptions.isObject() && !options.Parse()) 1.3587 + return false; 1.3588 + 1.3589 + { 1.3590 + CloneIntoCallbacksData data(aCx, &options); 1.3591 + JSAutoCompartment ac(aCx, scope); 1.3592 + if (!JS_StructuredClone(aCx, aValue, aCloned, &CloneIntoCallbacks, &data)) 1.3593 + return false; 1.3594 + } 1.3595 + 1.3596 + return JS_WrapValue(aCx, aCloned); 1.3597 +} 1.3598 + 1.3599 +NS_IMETHODIMP 1.3600 +nsXPCComponents_Utils::CloneInto(HandleValue aValue, HandleValue aScope, 1.3601 + HandleValue aOptions, JSContext *aCx, 1.3602 + MutableHandleValue aCloned) 1.3603 +{ 1.3604 + return xpc::CloneInto(aCx, aValue, aScope, aOptions, aCloned) ? 1.3605 + NS_OK : NS_ERROR_FAILURE; 1.3606 +} 1.3607 + 1.3608 +NS_IMETHODIMP 1.3609 +nsXPCComponents_Utils::GetWebIDLCallerPrincipal(nsIPrincipal **aResult) 1.3610 +{ 1.3611 + // This API may only be when the Entry Settings Object corresponds to a 1.3612 + // JS-implemented WebIDL call. In all other cases, the value will be null, 1.3613 + // and we throw. 1.3614 + nsCOMPtr<nsIPrincipal> callerPrin = mozilla::dom::GetWebIDLCallerPrincipal(); 1.3615 + if (!callerPrin) 1.3616 + return NS_ERROR_NOT_AVAILABLE; 1.3617 + callerPrin.forget(aResult); 1.3618 + return NS_OK; 1.3619 +} 1.3620 + 1.3621 +NS_IMETHODIMP 1.3622 +nsXPCComponents_Utils::GetObjectPrincipal(HandleValue val, JSContext *cx, 1.3623 + nsIPrincipal **result) 1.3624 +{ 1.3625 + if (!val.isObject()) 1.3626 + return NS_ERROR_INVALID_ARG; 1.3627 + RootedObject obj(cx, &val.toObject()); 1.3628 + obj = js::CheckedUnwrap(obj); 1.3629 + MOZ_ASSERT(obj); 1.3630 + 1.3631 + nsCOMPtr<nsIPrincipal> prin = nsContentUtils::GetObjectPrincipal(obj); 1.3632 + prin.forget(result); 1.3633 + return NS_OK; 1.3634 +} 1.3635 + 1.3636 +/***************************************************************************/ 1.3637 +/***************************************************************************/ 1.3638 +/***************************************************************************/ 1.3639 + 1.3640 + 1.3641 +nsXPCComponentsBase::nsXPCComponentsBase(XPCWrappedNativeScope* aScope) 1.3642 + : mScope(aScope) 1.3643 +{ 1.3644 + MOZ_ASSERT(aScope, "aScope must not be null"); 1.3645 +} 1.3646 + 1.3647 +nsXPCComponents::nsXPCComponents(XPCWrappedNativeScope* aScope) 1.3648 + : nsXPCComponentsBase(aScope) 1.3649 +{ 1.3650 +} 1.3651 + 1.3652 +nsXPCComponentsBase::~nsXPCComponentsBase() 1.3653 +{ 1.3654 +} 1.3655 + 1.3656 +nsXPCComponents::~nsXPCComponents() 1.3657 +{ 1.3658 +} 1.3659 + 1.3660 +void 1.3661 +nsXPCComponentsBase::ClearMembers() 1.3662 +{ 1.3663 + mInterfaces = nullptr; 1.3664 + mInterfacesByID = nullptr; 1.3665 + mResults = nullptr; 1.3666 +} 1.3667 + 1.3668 +void 1.3669 +nsXPCComponents::ClearMembers() 1.3670 +{ 1.3671 + mClasses = nullptr; 1.3672 + mClassesByID = nullptr; 1.3673 + mID = nullptr; 1.3674 + mException = nullptr; 1.3675 + mConstructor = nullptr; 1.3676 + mUtils = nullptr; 1.3677 + 1.3678 + nsXPCComponentsBase::ClearMembers(); 1.3679 +} 1.3680 + 1.3681 +/*******************************************/ 1.3682 +#define XPC_IMPL_GET_OBJ_METHOD(_class, _n) \ 1.3683 +NS_IMETHODIMP _class::Get##_n(nsIXPCComponents_##_n * *a##_n) { \ 1.3684 + NS_ENSURE_ARG_POINTER(a##_n); \ 1.3685 + if (!m##_n) \ 1.3686 + m##_n = new nsXPCComponents_##_n(); \ 1.3687 + nsRefPtr<nsXPCComponents_##_n> ret = m##_n; \ 1.3688 + ret.forget(a##_n); \ 1.3689 + return NS_OK; \ 1.3690 +} 1.3691 + 1.3692 +XPC_IMPL_GET_OBJ_METHOD(nsXPCComponentsBase, Interfaces) 1.3693 +XPC_IMPL_GET_OBJ_METHOD(nsXPCComponentsBase, InterfacesByID) 1.3694 +XPC_IMPL_GET_OBJ_METHOD(nsXPCComponents, Classes) 1.3695 +XPC_IMPL_GET_OBJ_METHOD(nsXPCComponents, ClassesByID) 1.3696 +XPC_IMPL_GET_OBJ_METHOD(nsXPCComponentsBase, Results) 1.3697 +XPC_IMPL_GET_OBJ_METHOD(nsXPCComponents, ID) 1.3698 +XPC_IMPL_GET_OBJ_METHOD(nsXPCComponents, Exception) 1.3699 +XPC_IMPL_GET_OBJ_METHOD(nsXPCComponents, Constructor) 1.3700 +XPC_IMPL_GET_OBJ_METHOD(nsXPCComponents, Utils) 1.3701 + 1.3702 +#undef XPC_IMPL_GET_OBJ_METHOD 1.3703 +/*******************************************/ 1.3704 + 1.3705 +NS_IMETHODIMP 1.3706 +nsXPCComponentsBase::IsSuccessCode(nsresult result, bool *out) 1.3707 +{ 1.3708 + *out = NS_SUCCEEDED(result); 1.3709 + return NS_OK; 1.3710 +} 1.3711 + 1.3712 +NS_IMETHODIMP 1.3713 +nsXPCComponents::GetStack(nsIStackFrame * *aStack) 1.3714 +{ 1.3715 + nsresult rv; 1.3716 + nsXPConnect* xpc = nsXPConnect::XPConnect(); 1.3717 + rv = xpc->GetCurrentJSStack(aStack); 1.3718 + return rv; 1.3719 +} 1.3720 + 1.3721 +NS_IMETHODIMP 1.3722 +nsXPCComponents::GetManager(nsIComponentManager * *aManager) 1.3723 +{ 1.3724 + MOZ_ASSERT(aManager, "bad param"); 1.3725 + return NS_GetComponentManager(aManager); 1.3726 +} 1.3727 + 1.3728 +NS_IMETHODIMP 1.3729 +nsXPCComponents::GetLastResult(JSContext *aCx, MutableHandleValue aOut) 1.3730 +{ 1.3731 + XPCContext* xpcc = XPCContext::GetXPCContext(aCx); 1.3732 + if (!xpcc) 1.3733 + return NS_ERROR_FAILURE; 1.3734 + nsresult res = xpcc->GetLastResult(); 1.3735 + aOut.setNumber(static_cast<uint32_t>(res)); 1.3736 + return NS_OK; 1.3737 +} 1.3738 + 1.3739 +NS_IMETHODIMP 1.3740 +nsXPCComponents::GetReturnCode(JSContext *aCx, MutableHandleValue aOut) 1.3741 +{ 1.3742 + XPCContext* xpcc = XPCContext::GetXPCContext(aCx); 1.3743 + if (!xpcc) 1.3744 + return NS_ERROR_FAILURE; 1.3745 + nsresult res = xpcc->GetPendingResult(); 1.3746 + aOut.setNumber(static_cast<uint32_t>(res)); 1.3747 + return NS_OK; 1.3748 +} 1.3749 + 1.3750 +NS_IMETHODIMP 1.3751 +nsXPCComponents::SetReturnCode(JSContext *aCx, HandleValue aCode) 1.3752 +{ 1.3753 + XPCContext* xpcc = XPCContext::GetXPCContext(aCx); 1.3754 + if (!xpcc) 1.3755 + return NS_ERROR_FAILURE; 1.3756 + nsresult rv; 1.3757 + if (!ToUint32(aCx, aCode, (uint32_t*)&rv)) 1.3758 + return NS_ERROR_FAILURE; 1.3759 + xpcc->SetPendingResult(rv); 1.3760 + xpcc->SetLastResult(rv); 1.3761 + return NS_OK; 1.3762 +} 1.3763 + 1.3764 +// static 1.3765 +/* void reportError (); */ 1.3766 +NS_IMETHODIMP nsXPCComponents::ReportError(HandleValue error, JSContext *cx) 1.3767 +{ 1.3768 + NS_WARNING("Components.reportError deprecated, use Components.utils.reportError"); 1.3769 + 1.3770 + nsCOMPtr<nsIXPCComponents_Utils> utils; 1.3771 + nsresult rv = GetUtils(getter_AddRefs(utils)); 1.3772 + if (NS_FAILED(rv)) 1.3773 + return rv; 1.3774 + 1.3775 + return utils->ReportError(error, cx); 1.3776 +} 1.3777 + 1.3778 +/**********************************************/ 1.3779 + 1.3780 +class ComponentsSH : public nsIXPCScriptable 1.3781 +{ 1.3782 +public: 1.3783 + ComponentsSH(unsigned dummy) 1.3784 + { 1.3785 + } 1.3786 + 1.3787 + NS_DECL_ISUPPORTS 1.3788 + NS_DECL_NSIXPCSCRIPTABLE 1.3789 + // The NS_IMETHODIMP isn't really accurate here, but NS_CALLBACK requires 1.3790 + // the referent to be declared __stdcall on Windows, and this is the only 1.3791 + // macro that does that. 1.3792 + static NS_IMETHODIMP Get(uint32_t aLangId, nsISupports **helper) 1.3793 + { 1.3794 + *helper = &singleton; 1.3795 + return NS_OK; 1.3796 + } 1.3797 + 1.3798 +private: 1.3799 + static ComponentsSH singleton; 1.3800 +}; 1.3801 + 1.3802 +ComponentsSH ComponentsSH::singleton(0); 1.3803 + 1.3804 +// Singleton refcounting. 1.3805 +NS_IMETHODIMP_(MozExternalRefCountType) ComponentsSH::AddRef(void) { return 1; } 1.3806 +NS_IMETHODIMP_(MozExternalRefCountType) ComponentsSH::Release(void) { return 1; } 1.3807 + 1.3808 +NS_INTERFACE_MAP_BEGIN(ComponentsSH) 1.3809 + NS_INTERFACE_MAP_ENTRY(nsIXPCScriptable) 1.3810 + NS_INTERFACE_MAP_ENTRY(nsISupports) 1.3811 +NS_INTERFACE_MAP_END 1.3812 + 1.3813 +#define NSXPCCOMPONENTSBASE_CID \ 1.3814 +{ 0xc62998e5, 0x95f1, 0x4058, \ 1.3815 + { 0xa5, 0x09, 0xec, 0x21, 0x66, 0x18, 0x92, 0xb9 } } 1.3816 + 1.3817 +#define NSXPCCOMPONENTS_CID \ 1.3818 +{ 0x3649f405, 0xf0ec, 0x4c28, \ 1.3819 + { 0xae, 0xb0, 0xaf, 0x9a, 0x51, 0xe4, 0x4c, 0x81 } } 1.3820 + 1.3821 +NS_IMPL_CLASSINFO(nsXPCComponentsBase, &ComponentsSH::Get, nsIClassInfo::DOM_OBJECT, NSXPCCOMPONENTSBASE_CID) 1.3822 +NS_IMPL_ISUPPORTS_CI(nsXPCComponentsBase, nsIXPCComponentsBase) 1.3823 + 1.3824 +NS_IMPL_CLASSINFO(nsXPCComponents, &ComponentsSH::Get, nsIClassInfo::DOM_OBJECT, NSXPCCOMPONENTS_CID) 1.3825 +// Below is more or less what NS_IMPL_ISUPPORTS_CI_INHERITED1 would look like 1.3826 +// if it existed. 1.3827 +NS_IMPL_ADDREF_INHERITED(nsXPCComponents, nsXPCComponentsBase) 1.3828 +NS_IMPL_RELEASE_INHERITED(nsXPCComponents, nsXPCComponentsBase) 1.3829 +NS_INTERFACE_MAP_BEGIN(nsXPCComponents) 1.3830 + NS_INTERFACE_MAP_ENTRY(nsIXPCComponents) 1.3831 + NS_IMPL_QUERY_CLASSINFO(nsXPCComponents) 1.3832 +NS_INTERFACE_MAP_END_INHERITING(nsXPCComponentsBase) 1.3833 +NS_IMPL_CI_INTERFACE_GETTER(nsXPCComponents, nsIXPCComponents) 1.3834 + 1.3835 +// The nsIXPCScriptable map declaration that will generate stubs for us 1.3836 +#define XPC_MAP_CLASSNAME ComponentsSH 1.3837 +#define XPC_MAP_QUOTED_CLASSNAME "nsXPCComponents" 1.3838 +#define XPC_MAP_WANT_PRECREATE 1.3839 +#include "xpc_map_end.h" /* This will #undef the above */ 1.3840 + 1.3841 +NS_IMETHODIMP 1.3842 +ComponentsSH::PreCreate(nsISupports *nativeObj, JSContext *cx, JSObject *globalObj, JSObject **parentObj) 1.3843 +{ 1.3844 + nsXPCComponentsBase *self = static_cast<nsXPCComponentsBase*>(nativeObj); 1.3845 + // this should never happen 1.3846 + if (!self->GetScope()) { 1.3847 + NS_WARNING("mScope must not be null when nsXPCComponents::PreCreate is called"); 1.3848 + return NS_ERROR_FAILURE; 1.3849 + } 1.3850 + *parentObj = self->GetScope()->GetGlobalJSObject(); 1.3851 + return NS_OK; 1.3852 +}