XPCRuntimeService.cpp (7434B)
1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ 2 /* vim: set ts=8 sts=2 et sw=2 tw=80: */ 3 /* This Source Code Form is subject to the terms of the Mozilla Public 4 * License, v. 2.0. If a copy of the MPL was not distributed with this 5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 6 7 #include "xpcprivate.h" 8 #include "xpc_make_class.h" 9 10 #include "nsContentUtils.h" 11 #include "SystemGlobal.h" 12 #include "mozilla/Result.h" 13 #include "mozilla/dom/BindingUtils.h" 14 #include "mozilla/dom/WebIDLGlobalNameHash.h" 15 #include "mozilla/dom/IndexedDatabaseManager.h" 16 #include "mozilla/ipc/BackgroundUtils.h" 17 #include "mozilla/ipc/PBackgroundSharedTypes.h" 18 #include "mozilla/net/CookieJarSettings.h" 19 20 using namespace mozilla::dom; 21 22 NS_IMPL_ISUPPORTS(SystemGlobal, nsIXPCScriptable, nsIGlobalObject, nsIClassInfo, 23 nsIScriptObjectPrincipal, nsISupportsWeakReference) 24 25 SystemGlobal::SystemGlobal() 26 : mAgentClusterId(nsID::GenerateUUID()), 27 mPrincipal(nsContentUtils::GetSystemPrincipal()), 28 mCookieJarSettings(mozilla::net::CookieJarSettings::Create(mPrincipal)), 29 mWrapper(nullptr) {} 30 // XXX(nika): It appears we don't have support for mayresolve hooks in 31 // nsIXPCScriptable, and I don't really want to add it because I'd rather just 32 // kill nsIXPCScriptable alltogether, so we don't use it here. 33 34 // The nsIXPCScriptable map declaration that will generate stubs for us... 35 #define XPC_MAP_CLASSNAME SystemGlobal 36 #define XPC_MAP_QUOTED_CLASSNAME "SystemGlobal" 37 #define XPC_MAP_FLAGS \ 38 (XPC_SCRIPTABLE_WANT_RESOLVE | XPC_SCRIPTABLE_WANT_NEWENUMERATE | \ 39 XPC_SCRIPTABLE_WANT_FINALIZE | XPC_SCRIPTABLE_WANT_PRECREATE | \ 40 XPC_SCRIPTABLE_USE_JSSTUB_FOR_ADDPROPERTY | \ 41 XPC_SCRIPTABLE_USE_JSSTUB_FOR_DELPROPERTY | \ 42 XPC_SCRIPTABLE_DONT_ENUM_QUERY_INTERFACE | \ 43 XPC_SCRIPTABLE_IS_GLOBAL_OBJECT | \ 44 XPC_SCRIPTABLE_DONT_REFLECT_INTERFACE_NAMES) 45 #include "xpc_map_end.h" /* This will #undef the above */ 46 47 JSObject* SystemGlobal::GetGlobalJSObject() { 48 if (mWrapper) { 49 return mWrapper->GetFlatJSObject(); 50 } 51 return nullptr; 52 } 53 54 JSObject* SystemGlobal::GetGlobalJSObjectPreserveColor() const { 55 if (mWrapper) { 56 return mWrapper->GetFlatJSObjectPreserveColor(); 57 } 58 return nullptr; 59 } 60 61 void SystemGlobal::SetGlobalObject(JSObject* global) { 62 nsISupports* p = XPCWrappedNative::Get(global); 63 MOZ_ASSERT(p); 64 mWrapper = static_cast<XPCWrappedNative*>(p); 65 } 66 67 NS_IMETHODIMP 68 SystemGlobal::Resolve(nsIXPConnectWrappedNative* wrapper, JSContext* cx, 69 JSObject* objArg, jsid idArg, bool* resolvedp, 70 bool* _retval) { 71 JS::RootedObject obj(cx, objArg); 72 JS::RootedId id(cx, idArg); 73 *_retval = 74 WebIDLGlobalNameHash::ResolveForSystemGlobal(cx, obj, id, resolvedp); 75 if (!*_retval) { 76 return NS_ERROR_FAILURE; 77 } 78 79 if (*resolvedp) { 80 return NS_OK; 81 } 82 83 XPCJSContext* xpccx = XPCJSContext::Get(); 84 if (id == xpccx->GetStringID(XPCJSContext::IDX_FETCH)) { 85 *_retval = xpc::SandboxCreateFetch(cx, obj); 86 if (!*_retval) { 87 return NS_ERROR_FAILURE; 88 } 89 *resolvedp = true; 90 } else if (id == xpccx->GetStringID(XPCJSContext::IDX_CRYPTO)) { 91 *_retval = xpc::SandboxCreateCrypto(cx, obj); 92 if (!*_retval) { 93 return NS_ERROR_FAILURE; 94 } 95 *resolvedp = true; 96 } else if (id == xpccx->GetStringID(XPCJSContext::IDX_INDEXEDDB)) { 97 *_retval = IndexedDatabaseManager::DefineIndexedDB(cx, obj); 98 if (!*_retval) { 99 return NS_ERROR_FAILURE; 100 } 101 *resolvedp = true; 102 } else if (id == xpccx->GetStringID(XPCJSContext::IDX_STRUCTUREDCLONE)) { 103 *_retval = xpc::SandboxCreateStructuredClone(cx, obj); 104 if (!*_retval) { 105 return NS_ERROR_FAILURE; 106 } 107 *resolvedp = true; 108 } else if (id == xpccx->GetStringID(XPCJSContext::IDX_LOCKS)) { 109 *_retval = xpc::SandboxCreateLocks(cx, obj); 110 if (!*_retval) { 111 return NS_ERROR_FAILURE; 112 } 113 *resolvedp = true; 114 } 115 116 return NS_OK; 117 } 118 119 NS_IMETHODIMP 120 SystemGlobal::NewEnumerate(nsIXPConnectWrappedNative* wrapper, JSContext* cx, 121 JSObject* objArg, 122 JS::MutableHandleIdVector properties, 123 bool enumerableOnly, bool* _retval) { 124 JS::RootedObject obj(cx, objArg); 125 126 XPCJSContext* xpccx = XPCJSContext::Get(); 127 if (!properties.append(xpccx->GetStringID(XPCJSContext::IDX_FETCH)) || 128 !properties.append(xpccx->GetStringID(XPCJSContext::IDX_CRYPTO)) || 129 !properties.append(xpccx->GetStringID(XPCJSContext::IDX_INDEXEDDB)) || 130 !properties.append( 131 xpccx->GetStringID(XPCJSContext::IDX_STRUCTUREDCLONE)) || 132 !properties.append(xpccx->GetStringID(XPCJSContext::IDX_LOCKS))) { 133 return NS_ERROR_FAILURE; 134 } 135 136 *_retval = WebIDLGlobalNameHash::NewEnumerateSystemGlobal(cx, obj, properties, 137 enumerableOnly); 138 return *_retval ? NS_OK : NS_ERROR_FAILURE; 139 } 140 141 /***************************************************************************/ 142 NS_IMETHODIMP 143 SystemGlobal::GetInterfaces(nsTArray<nsIID>& aArray) { 144 aArray = nsTArray<nsIID>{NS_GET_IID(nsIXPCScriptable), 145 NS_GET_IID(nsIScriptObjectPrincipal)}; 146 return NS_OK; 147 } 148 149 NS_IMETHODIMP 150 SystemGlobal::GetScriptableHelper(nsIXPCScriptable** retval) { 151 nsCOMPtr<nsIXPCScriptable> scriptable = this; 152 scriptable.forget(retval); 153 return NS_OK; 154 } 155 156 NS_IMETHODIMP 157 SystemGlobal::GetContractID(nsACString& aContractID) { 158 aContractID.SetIsVoid(true); 159 return NS_ERROR_NOT_AVAILABLE; 160 } 161 162 NS_IMETHODIMP 163 SystemGlobal::GetClassDescription(nsACString& aClassDescription) { 164 aClassDescription.AssignLiteral("SystemGlobal"); 165 return NS_OK; 166 } 167 168 NS_IMETHODIMP 169 SystemGlobal::GetClassID(nsCID** aClassID) { 170 *aClassID = nullptr; 171 return NS_OK; 172 } 173 174 NS_IMETHODIMP 175 SystemGlobal::GetFlags(uint32_t* aFlags) { 176 *aFlags = 0; 177 return NS_OK; 178 } 179 180 NS_IMETHODIMP 181 SystemGlobal::GetClassIDNoAlloc(nsCID* aClassIDNoAlloc) { 182 return NS_ERROR_NOT_AVAILABLE; 183 } 184 185 NS_IMETHODIMP 186 SystemGlobal::Finalize(nsIXPConnectWrappedNative* wrapper, JS::GCContext* gcx, 187 JSObject* obj) { 188 nsCOMPtr<nsIGlobalObject> bsp(do_QueryInterface(wrapper->Native())); 189 MOZ_ASSERT(bsp); 190 static_cast<SystemGlobal*>(bsp.get())->ForgetGlobalObject(); 191 return NS_OK; 192 } 193 194 NS_IMETHODIMP 195 SystemGlobal::PreCreate(nsISupports* nativeObj, JSContext* cx, 196 JSObject* globalObj, JSObject** parentObj) { 197 // We do the same trick here as for WindowSH. Return the js global 198 // as parent, so XPConenct can find the right scope and the wrapper 199 // that already exists. 200 nsCOMPtr<nsIGlobalObject> global(do_QueryInterface(nativeObj)); 201 MOZ_ASSERT(global, "nativeObj not a global object!"); 202 203 JSObject* jsglobal = global->GetGlobalJSObject(); 204 if (jsglobal) { 205 *parentObj = jsglobal; 206 } 207 return NS_OK; 208 } 209 210 mozilla::Result<mozilla::ipc::PrincipalInfo, nsresult> 211 SystemGlobal::GetStorageKey() { 212 MOZ_ASSERT(NS_IsMainThread()); 213 214 mozilla::ipc::PrincipalInfo principalInfo; 215 nsresult rv = PrincipalToPrincipalInfo(mPrincipal, &principalInfo); 216 if (NS_FAILED(rv)) { 217 return mozilla::Err(rv); 218 } 219 220 MOZ_ASSERT(principalInfo.type() == 221 mozilla::ipc::PrincipalInfo::TSystemPrincipalInfo); 222 223 return std::move(principalInfo); 224 }