Bug 1742437 - move mWebExtGlobal from ScriptLoadRequest to DOMScriptLoadContext; r=jonco,smaug
Differential Revision: https://phabricator.services.mozilla.com/D136744
This commit is contained in:
@@ -1236,7 +1236,7 @@ nsresult EventListenerManager::CompileEventHandlerInternal(
|
||||
|
||||
RefPtr<ScriptFetchOptions> fetchOptions = new ScriptFetchOptions(
|
||||
CORS_NONE, aElement->OwnerDoc()->GetReferrerPolicy(),
|
||||
aElement->OwnerDoc()->NodePrincipal(), nullptr);
|
||||
aElement->OwnerDoc()->NodePrincipal());
|
||||
|
||||
RefPtr<EventScript> eventScript =
|
||||
new EventScript(fetchOptions, uri, aElement);
|
||||
|
||||
@@ -163,7 +163,8 @@ void ModuleLoadRequest::ModuleLoaded() {
|
||||
|
||||
LOG(("ScriptLoadRequest (%p): Module loaded", this));
|
||||
|
||||
mModuleScript = mLoader->GetFetchedModule(mURI, GetWebExtGlobal());
|
||||
mModuleScript =
|
||||
mLoader->GetFetchedModule(mURI, GetLoadContext()->GetWebExtGlobal());
|
||||
if (!mModuleScript || mModuleScript->HasParseError()) {
|
||||
ModuleErrored();
|
||||
return;
|
||||
|
||||
@@ -114,9 +114,9 @@ void ModuleLoader::SetModuleFetchStarted(ModuleLoadRequest* aRequest) {
|
||||
// Update the module map to indicate that a module is currently being fetched.
|
||||
|
||||
MOZ_ASSERT(aRequest->IsLoading());
|
||||
MOZ_ASSERT(
|
||||
!ModuleMapContainsURL(aRequest->mURI, aRequest->GetWebExtGlobal()));
|
||||
ModuleMapKey key(aRequest->mURI, aRequest->GetWebExtGlobal());
|
||||
MOZ_ASSERT(!ModuleMapContainsURL(aRequest->mURI,
|
||||
aRequest->mLoadContext->GetWebExtGlobal()));
|
||||
ModuleMapKey key(aRequest->mURI, aRequest->mLoadContext->GetWebExtGlobal());
|
||||
mFetchingModules.InsertOrUpdate(
|
||||
key, RefPtr<GenericNonExclusivePromise::Private>{});
|
||||
}
|
||||
@@ -134,7 +134,7 @@ void ModuleLoader::SetModuleFetchFinishedAndResumeWaitingRequests(
|
||||
"%u)",
|
||||
aRequest, aRequest->mModuleScript.get(), unsigned(aResult)));
|
||||
|
||||
ModuleMapKey key(aRequest->mURI, aRequest->GetWebExtGlobal());
|
||||
ModuleMapKey key(aRequest->mURI, aRequest->mLoadContext->GetWebExtGlobal());
|
||||
RefPtr<GenericNonExclusivePromise::Private> promise;
|
||||
if (!mFetchingModules.Remove(key, getter_AddRefs(promise))) {
|
||||
LOG(
|
||||
|
||||
@@ -32,20 +32,17 @@ namespace dom {
|
||||
// ScriptFetchOptions
|
||||
//////////////////////////////////////////////////////////////
|
||||
|
||||
NS_IMPL_CYCLE_COLLECTION(ScriptFetchOptions, mTriggeringPrincipal,
|
||||
mWebExtGlobal)
|
||||
NS_IMPL_CYCLE_COLLECTION(ScriptFetchOptions, mTriggeringPrincipal)
|
||||
|
||||
NS_IMPL_CYCLE_COLLECTION_ROOT_NATIVE(ScriptFetchOptions, AddRef)
|
||||
NS_IMPL_CYCLE_COLLECTION_UNROOT_NATIVE(ScriptFetchOptions, Release)
|
||||
|
||||
ScriptFetchOptions::ScriptFetchOptions(mozilla::CORSMode aCORSMode,
|
||||
ReferrerPolicy aReferrerPolicy,
|
||||
nsIPrincipal* aTriggeringPrincipal,
|
||||
nsIGlobalObject* aWebExtGlobal)
|
||||
nsIPrincipal* aTriggeringPrincipal)
|
||||
: mCORSMode(aCORSMode),
|
||||
mReferrerPolicy(aReferrerPolicy),
|
||||
mTriggeringPrincipal(aTriggeringPrincipal),
|
||||
mWebExtGlobal(aWebExtGlobal) {
|
||||
mTriggeringPrincipal(aTriggeringPrincipal) {
|
||||
MOZ_ASSERT(mTriggeringPrincipal);
|
||||
}
|
||||
|
||||
@@ -109,7 +106,7 @@ NS_IMPL_CYCLE_COLLECTING_RELEASE(DOMScriptLoadContext)
|
||||
NS_IMPL_CYCLE_COLLECTION_CLASS(DOMScriptLoadContext)
|
||||
|
||||
NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(DOMScriptLoadContext)
|
||||
NS_IMPL_CYCLE_COLLECTION_UNLINK(mElement)
|
||||
NS_IMPL_CYCLE_COLLECTION_UNLINK(mElement, mWebExtGlobal)
|
||||
// XXX missing mLoadBlockedDocument ?
|
||||
if (Runnable* runnable = tmp->mRunnable.exchange(nullptr)) {
|
||||
runnable->Release();
|
||||
@@ -118,14 +115,16 @@ NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(DOMScriptLoadContext)
|
||||
NS_IMPL_CYCLE_COLLECTION_UNLINK_END
|
||||
|
||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(DOMScriptLoadContext)
|
||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mLoadBlockedDocument, mRequest, mElement)
|
||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mLoadBlockedDocument, mRequest, mElement,
|
||||
mWebExtGlobal)
|
||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
|
||||
|
||||
NS_IMPL_CYCLE_COLLECTION_TRACE_BEGIN(DOMScriptLoadContext)
|
||||
NS_IMPL_CYCLE_COLLECTION_TRACE_END
|
||||
|
||||
DOMScriptLoadContext::DOMScriptLoadContext(Element* aElement,
|
||||
ScriptLoadRequest* aRequest)
|
||||
ScriptLoadRequest* aRequest,
|
||||
nsIGlobalObject* aWebExtGlobal)
|
||||
: mScriptMode(ScriptMode::eBlocking),
|
||||
mScriptFromHead(false),
|
||||
mIsInline(true),
|
||||
@@ -140,6 +139,7 @@ DOMScriptLoadContext::DOMScriptLoadContext(Element* aElement,
|
||||
mRunnable(nullptr),
|
||||
mIsPreload(false),
|
||||
mElement(aElement),
|
||||
mWebExtGlobal(aWebExtGlobal),
|
||||
mRequest(aRequest),
|
||||
mUnreportedPreloadError(NS_OK) {}
|
||||
|
||||
@@ -280,17 +280,26 @@ void DOMScriptLoadContext::PrioritizeAsPreload() {
|
||||
bool DOMScriptLoadContext::IsPreload() const {
|
||||
if (mRequest->IsModuleRequest() && !mRequest->IsTopLevel()) {
|
||||
ModuleLoadRequest* root = mRequest->AsModuleRequest()->GetRootModule();
|
||||
return root->mLoadContext->IsPreload();
|
||||
return root->GetLoadContext()->IsPreload();
|
||||
}
|
||||
|
||||
MOZ_ASSERT_IF(mIsPreload, !GetScriptElement());
|
||||
return mIsPreload;
|
||||
}
|
||||
|
||||
nsIGlobalObject* DOMScriptLoadContext::GetWebExtGlobal() const {
|
||||
if (mRequest->IsModuleRequest() && !mRequest->IsTopLevel()) {
|
||||
ModuleLoadRequest* root = mRequest->AsModuleRequest()->GetRootModule();
|
||||
return root->GetLoadContext()->GetWebExtGlobal();
|
||||
}
|
||||
|
||||
return mWebExtGlobal;
|
||||
}
|
||||
|
||||
nsIScriptElement* DOMScriptLoadContext::GetScriptElement() const {
|
||||
if (mRequest->IsModuleRequest() && !mRequest->IsTopLevel()) {
|
||||
ModuleLoadRequest* root = mRequest->AsModuleRequest()->GetRootModule();
|
||||
return root->mLoadContext->GetScriptElement();
|
||||
return root->GetLoadContext()->GetScriptElement();
|
||||
}
|
||||
nsCOMPtr<nsIScriptElement> scriptElement = do_QueryInterface(mElement);
|
||||
return scriptElement;
|
||||
|
||||
@@ -44,11 +44,24 @@ class ScriptLoadRequestList;
|
||||
class DOMScriptLoadContext;
|
||||
|
||||
/*
|
||||
* Some options used when fetching script resources. This only loosely
|
||||
* corresponds to HTML's "script fetch options".
|
||||
* ScriptFetchOptions loosely corresponds to HTML's "script fetch options",
|
||||
* https://html.spec.whatwg.org/multipage/webappapis.html#script-fetch-options
|
||||
* with the exception of the following properties:
|
||||
* cryptographic nonce
|
||||
* The cryptographic nonce metadata used for the initial fetch and for
|
||||
* fetching any imported modules. This is handled by the principal.
|
||||
* parser metadata
|
||||
* The parser metadata used for the initial fetch and for fetching any
|
||||
* imported modules. This is not implemented.
|
||||
* integrity metadata
|
||||
* The integrity metadata used for the initial fetch. This is
|
||||
* implemented in ScriptLoadRequest, as it changes for every
|
||||
* ScriptLoadRequest.
|
||||
*
|
||||
* These are common to all modules in a module graph, and hence a single
|
||||
* instance is shared by all ModuleLoadRequest objects in a graph.
|
||||
* In the case of classic scripts without dynamic import, this object is
|
||||
* used once. For modules, this object is propogated throughout the module
|
||||
* tree. If there is a dynamically imported module in any type of script,
|
||||
* the ScriptFetchOptions object will be propogated from its importer.
|
||||
*/
|
||||
|
||||
class ScriptFetchOptions {
|
||||
@@ -60,15 +73,25 @@ class ScriptFetchOptions {
|
||||
|
||||
ScriptFetchOptions(mozilla::CORSMode aCORSMode,
|
||||
enum ReferrerPolicy aReferrerPolicy,
|
||||
nsIPrincipal* aTriggeringPrincipal,
|
||||
nsIGlobalObject* aWebExtGlobal);
|
||||
nsIPrincipal* aTriggeringPrincipal);
|
||||
|
||||
/*
|
||||
* The credentials mode used for the initial fetch (for module scripts)
|
||||
* and for fetching any imported modules (for both module scripts and
|
||||
* classic scripts)
|
||||
*/
|
||||
const mozilla::CORSMode mCORSMode;
|
||||
|
||||
/*
|
||||
* The referrer policy used for the initial fetch and for fetching any
|
||||
* imported modules
|
||||
*/
|
||||
const enum ReferrerPolicy mReferrerPolicy;
|
||||
|
||||
/*
|
||||
* related to cryptographic nonce, used to determine CSP
|
||||
*/
|
||||
nsCOMPtr<nsIPrincipal> mTriggeringPrincipal;
|
||||
// Global that initiated this request, when using a WebExtension
|
||||
// content-script.
|
||||
nsCOMPtr<nsIGlobalObject> mWebExtGlobal;
|
||||
};
|
||||
|
||||
/*
|
||||
@@ -227,13 +250,6 @@ class ScriptLoadRequest
|
||||
return mFetchOptions->mTriggeringPrincipal;
|
||||
}
|
||||
|
||||
// This will return nullptr in most cases,
|
||||
// unless this is a module being imported by a WebExtension content script.
|
||||
// In that case it's the Sandbox global executing that code.
|
||||
nsIGlobalObject* GetWebExtGlobal() const {
|
||||
return mFetchOptions->mWebExtGlobal;
|
||||
}
|
||||
|
||||
void ClearScriptSource();
|
||||
|
||||
void SetScript(JSScript* aScript);
|
||||
@@ -339,7 +355,8 @@ class DOMScriptLoadContext : public PreloaderBase {
|
||||
virtual ~DOMScriptLoadContext();
|
||||
|
||||
public:
|
||||
explicit DOMScriptLoadContext(Element* aElement, ScriptLoadRequest* aRequest);
|
||||
explicit DOMScriptLoadContext(Element* aElement, ScriptLoadRequest* aRequest,
|
||||
nsIGlobalObject* aWebExtGlobal = nullptr);
|
||||
|
||||
NS_DECL_CYCLE_COLLECTING_ISUPPORTS
|
||||
NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS(DOMScriptLoadContext)
|
||||
@@ -363,6 +380,11 @@ class DOMScriptLoadContext : public PreloaderBase {
|
||||
|
||||
bool IsPreload() const;
|
||||
|
||||
// This will return nullptr in most cases,
|
||||
// unless this is a module being imported by a WebExtension content script.
|
||||
// In that case it's the Sandbox global executing that code.
|
||||
nsIGlobalObject* GetWebExtGlobal() const;
|
||||
|
||||
bool CompileStarted() const {
|
||||
return mRequest->InCompilingStage() ||
|
||||
(mRequest->IsReadyToRun() && mWasCompiledOMT);
|
||||
@@ -455,6 +477,9 @@ class DOMScriptLoadContext : public PreloaderBase {
|
||||
// Set on scripts and top level modules.
|
||||
bool mIsPreload;
|
||||
nsCOMPtr<Element> mElement;
|
||||
// Global that initiated this request, when using a WebExtension
|
||||
// content-script.
|
||||
nsCOMPtr<nsIGlobalObject> mWebExtGlobal;
|
||||
|
||||
RefPtr<ScriptLoadRequest> mRequest;
|
||||
|
||||
|
||||
@@ -681,8 +681,8 @@ bool HostImportModuleDynamically(JSContext* aCx,
|
||||
xpc::IsWebExtensionContentScriptSandbox(global->GetGlobalJSObject()));
|
||||
}
|
||||
|
||||
options = new ScriptFetchOptions(
|
||||
mozilla::CORS_NONE, document->GetReferrerPolicy(), principal, global);
|
||||
options = new ScriptFetchOptions(mozilla::CORS_NONE,
|
||||
document->GetReferrerPolicy(), principal);
|
||||
baseURL = document->GetDocBaseURI();
|
||||
}
|
||||
|
||||
@@ -860,11 +860,12 @@ nsresult ScriptLoader::StartModuleLoad(ScriptLoadRequest* aRequest) {
|
||||
// Check whether the module has been fetched or is currently being fetched,
|
||||
// and if so wait for it rather than starting a new fetch.
|
||||
ModuleLoadRequest* request = aRequest->AsModuleRequest();
|
||||
if (mModuleLoader->ModuleMapContainsURL(request->mURI,
|
||||
aRequest->GetWebExtGlobal())) {
|
||||
if (mModuleLoader->ModuleMapContainsURL(
|
||||
request->mURI, aRequest->GetLoadContext()->GetWebExtGlobal())) {
|
||||
LOG(("ScriptLoadRequest (%p): Waiting for module fetch", aRequest));
|
||||
mModuleLoader
|
||||
->WaitForModuleFetch(request->mURI, aRequest->GetWebExtGlobal())
|
||||
->WaitForModuleFetch(request->mURI,
|
||||
aRequest->GetLoadContext()->GetWebExtGlobal())
|
||||
->Then(GetMainThreadSerialEventTarget(), __func__, request,
|
||||
&ModuleLoadRequest::ModuleLoaded,
|
||||
&ModuleLoadRequest::LoadFailed);
|
||||
@@ -956,7 +957,7 @@ nsresult ScriptLoader::StartLoadInternal(ScriptLoadRequest* aRequest,
|
||||
if (cic && StaticPrefs::dom_script_loader_bytecode_cache_enabled() &&
|
||||
// Bug 1436400: no bytecode cache support for modules yet.
|
||||
!aRequest->IsModuleRequest()) {
|
||||
MOZ_ASSERT(!aRequest->GetWebExtGlobal(),
|
||||
MOZ_ASSERT(!aRequest->GetLoadContext()->GetWebExtGlobal(),
|
||||
"Can not bytecode cache WebExt code");
|
||||
if (!aRequest->IsLoadingSource()) {
|
||||
// Inform the HTTP cache that we prefer to have information coming from
|
||||
@@ -1143,8 +1144,8 @@ already_AddRefed<ScriptLoadRequest> ScriptLoader::CreateLoadRequest(
|
||||
const SRIMetadata& aIntegrity, ReferrerPolicy aReferrerPolicy) {
|
||||
nsIURI* referrer = mDocument->GetDocumentURIAsReferrer();
|
||||
nsCOMPtr<Element> domElement = do_QueryInterface(aElement);
|
||||
ScriptFetchOptions* fetchOptions = new ScriptFetchOptions(
|
||||
aCORSMode, aReferrerPolicy, aTriggeringPrincipal, nullptr);
|
||||
ScriptFetchOptions* fetchOptions =
|
||||
new ScriptFetchOptions(aCORSMode, aReferrerPolicy, aTriggeringPrincipal);
|
||||
|
||||
if (aKind == ScriptKind::eClassic) {
|
||||
RefPtr<ScriptLoadRequest> aRequest =
|
||||
@@ -2137,8 +2138,9 @@ void ScriptLoader::FireScriptEvaluated(nsresult aResult,
|
||||
|
||||
already_AddRefed<nsIGlobalObject> ScriptLoader::GetGlobalForRequest(
|
||||
ScriptLoadRequest* aRequest) {
|
||||
if (aRequest->GetWebExtGlobal()) {
|
||||
nsCOMPtr<nsIGlobalObject> global = aRequest->GetWebExtGlobal();
|
||||
if (aRequest->GetLoadContext()->GetWebExtGlobal()) {
|
||||
nsCOMPtr<nsIGlobalObject> global =
|
||||
aRequest->GetLoadContext()->GetWebExtGlobal();
|
||||
return global.forget();
|
||||
}
|
||||
|
||||
@@ -2362,9 +2364,9 @@ nsresult ScriptLoader::EvaluateScriptElement(ScriptLoadRequest* aRequest) {
|
||||
|
||||
nsCOMPtr<nsIGlobalObject> globalObject;
|
||||
nsCOMPtr<nsIScriptContext> context;
|
||||
if (aRequest->GetWebExtGlobal()) {
|
||||
if (aRequest->GetLoadContext()->GetWebExtGlobal()) {
|
||||
// Executing a module from a WebExtension content-script.
|
||||
globalObject = aRequest->GetWebExtGlobal();
|
||||
globalObject = aRequest->GetLoadContext()->GetWebExtGlobal();
|
||||
} else {
|
||||
// Otherwise we have to ensure that there is a nsIScriptContext.
|
||||
nsCOMPtr<nsIScriptGlobalObject> scriptGlobal =
|
||||
@@ -2530,7 +2532,7 @@ nsresult ScriptLoader::EvaluateScript(nsIGlobalObject* aGlobalObject,
|
||||
// Create a ClassicScript object and associate it with the JSScript.
|
||||
RefPtr<ClassicScript> classicScript =
|
||||
new ClassicScript(aRequest->mFetchOptions, aRequest->mBaseURL,
|
||||
aRequest->mLoadContext->mElement);
|
||||
aRequest->GetLoadContext()->mElement);
|
||||
JS::RootedValue classicScriptValue(cx, JS::PrivateValue(classicScript));
|
||||
|
||||
JS::CompileOptions options(cx);
|
||||
@@ -2689,7 +2691,8 @@ void ScriptLoader::EncodeBytecode() {
|
||||
while (!mBytecodeEncodingQueue.isEmpty()) {
|
||||
request = mBytecodeEncodingQueue.StealFirst();
|
||||
MOZ_ASSERT(!request->IsModuleRequest());
|
||||
MOZ_ASSERT(!request->GetWebExtGlobal(), "Not handling global above");
|
||||
MOZ_ASSERT(!request->GetLoadContext()->GetWebExtGlobal(),
|
||||
"Not handling global above");
|
||||
EncodeRequestBytecode(aes.cx(), request);
|
||||
request->mScriptBytecode.clearAndFree();
|
||||
request->DropBytecodeCacheReferences();
|
||||
@@ -2791,7 +2794,7 @@ void ScriptLoader::GiveUpBytecodeEncoding() {
|
||||
TRACE_FOR_TEST_NONE(request->GetLoadContext()->GetScriptElement(),
|
||||
"scriptloader_bytecode_failed");
|
||||
MOZ_ASSERT(!request->IsModuleRequest());
|
||||
MOZ_ASSERT(!request->GetWebExtGlobal());
|
||||
MOZ_ASSERT(!request->GetLoadContext()->GetWebExtGlobal());
|
||||
|
||||
if (aes.isSome()) {
|
||||
JS::RootedScript script(aes->cx(), request->mScript);
|
||||
|
||||
Reference in New Issue
Block a user