Bug 1536094 - Support dynamic import from content scripts (sandboxed code) r=smaug,jonco

Firstly we need to find a usable ScriptLoader for code in the content script sandbox,
for that we use the normal ScriptLoader associated with DOMWindow wrapped by the sandbox.

Secondly we need to execute the module in the global of the sandbox instead of the
"ScriptGlobal" the ScriptLoader is actually associated with. The main
behavior change here comes from using xpc::NativeGlobal in HostImportModuleDynamically
and passing that global around inside ScriptFetchOptions.

To ensure that content-scripts and the webpage don't share imported modules,
the module map (mFetchingModules and mFetchedModules) now uses a complex key
of <URI, Global>. The Global is a nullptr for normal imports from a webpage.

Differential Revision: https://phabricator.services.mozilla.com/D107076
This commit is contained in:
Tom Schuster
2021-03-22 16:22:27 +00:00
parent bf4f90c497
commit a19e58735e
14 changed files with 277 additions and 68 deletions

View File

@@ -22,6 +22,7 @@
#include "mozilla/Vector.h"
#include "nsCOMPtr.h"
#include "nsCycleCollectionParticipant.h"
#include "nsIGlobalObject.h"
#include "nsIScriptElement.h"
#include "ScriptKind.h"
@@ -55,13 +56,17 @@ class ScriptFetchOptions {
ScriptFetchOptions(mozilla::CORSMode aCORSMode,
enum ReferrerPolicy aReferrerPolicy, Element* aElement,
nsIPrincipal* aTriggeringPrincipal);
nsIPrincipal* aTriggeringPrincipal,
nsIGlobalObject* aWebExtGlobal);
const mozilla::CORSMode mCORSMode;
const enum ReferrerPolicy mReferrerPolicy;
bool mIsPreload;
nsCOMPtr<Element> mElement;
nsCOMPtr<nsIPrincipal> mTriggeringPrincipal;
// Global that initiated this request, when using a WebExtension
// content-script.
nsCOMPtr<nsIGlobalObject> mWebExtGlobal;
};
/*
@@ -258,6 +263,13 @@ 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;
}
// Make this request a preload (speculative) request.
void SetIsPreloadRequest() {
MOZ_ASSERT(!GetScriptElement());