зеркало из https://github.com/mozilla/gecko-dev.git
Backed out 3 changesets (bug 1536094) for causing valgrind failures.
Backed out changeset dfe051a9c91a (bug 1536094) Backed out changeset c73979442002 (bug 1536094) Backed out changeset 863933e887e8 (bug 1536094)
This commit is contained in:
Родитель
5d72e8e6fb
Коммит
cac540c776
|
@ -1040,7 +1040,7 @@ nsresult EventListenerManager::CompileEventHandlerInternal(
|
|||
|
||||
RefPtr<ScriptFetchOptions> fetchOptions = new ScriptFetchOptions(
|
||||
CORS_NONE, aElement->OwnerDoc()->GetReferrerPolicy(), aElement,
|
||||
aElement->OwnerDoc()->NodePrincipal(), nullptr);
|
||||
aElement->OwnerDoc()->NodePrincipal());
|
||||
|
||||
RefPtr<EventScript> eventScript = new EventScript(fetchOptions, uri);
|
||||
|
||||
|
|
|
@ -317,7 +317,6 @@ ModuleSourceMalformed=Module source URI is malformed: “%S”.
|
|||
# LOCALIZATION NOTE: Do not translate "<script>".
|
||||
ScriptSourceNotAllowed=<script> source URI is not allowed in this document: “%S”.
|
||||
ModuleSourceNotAllowed=Module source URI is not allowed in this document: “%S”.
|
||||
WebExtContentScriptModuleSourceNotAllowed=WebExtension content scripts may only load modules with moz-extension URLs and not: “%S”.
|
||||
ModuleResolveFailure=Error resolving module specifier “%S”. Relative module specifiers must start with “./”, “../” or “/”.
|
||||
# LOCALIZATION NOTE: %1$S is the invalid property value and %2$S is the property name.
|
||||
InvalidKeyframePropertyValue=Keyframe property value “%1$S” is invalid according to the syntax for “%2$S”.
|
||||
|
|
|
@ -149,7 +149,7 @@ void ModuleLoadRequest::ModuleLoaded() {
|
|||
|
||||
LOG(("ScriptLoadRequest (%p): Module loaded", this));
|
||||
|
||||
mModuleScript = mLoader->GetFetchedModule(mURI, GetWebExtGlobal());
|
||||
mModuleScript = mLoader->GetFetchedModule(mURI);
|
||||
if (!mModuleScript || mModuleScript->HasParseError()) {
|
||||
ModuleErrored();
|
||||
return;
|
||||
|
|
|
@ -8,10 +8,10 @@
|
|||
#define mozilla_dom_ModuleLoadRequest_h
|
||||
|
||||
#include "ScriptLoadRequest.h"
|
||||
#include "mozilla/MozPromise.h"
|
||||
#include "js/RootingAPI.h"
|
||||
#include "js/Value.h"
|
||||
#include "nsURIHashKey.h"
|
||||
#include "mozilla/MozPromise.h"
|
||||
#include "nsTHashtable.h"
|
||||
|
||||
namespace mozilla {
|
||||
|
|
|
@ -1,38 +0,0 @@
|
|||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#include "ModuleMapKey.h"
|
||||
|
||||
using namespace mozilla::dom;
|
||||
|
||||
ModuleMapKey::ModuleMapKey(const nsIURI* aURI, nsIGlobalObject* aWebExtGlobal)
|
||||
: nsURIHashKey(aURI), mWebExtGlobal(aWebExtGlobal) {}
|
||||
|
||||
ModuleMapKey::ModuleMapKey(const ModuleMapKey* aKey)
|
||||
: nsURIHashKey(aKey->mKey) {
|
||||
*this = *aKey;
|
||||
}
|
||||
|
||||
ModuleMapKey::ModuleMapKey(ModuleMapKey&& aToMove) noexcept
|
||||
: nsURIHashKey(std::move(aToMove)) {
|
||||
mWebExtGlobal = std::move(aToMove.mWebExtGlobal);
|
||||
}
|
||||
|
||||
bool ModuleMapKey::KeyEquals(KeyTypePointer aOther) const {
|
||||
if (mWebExtGlobal != aOther->mWebExtGlobal) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return nsURIHashKey::KeyEquals(
|
||||
static_cast<const nsURIHashKey*>(aOther)->GetKey());
|
||||
}
|
||||
|
||||
// static
|
||||
PLDHashNumber ModuleMapKey::HashKey(KeyTypePointer aKey) {
|
||||
PLDHashNumber hash = nsURIHashKey::HashKey(aKey->mKey);
|
||||
// XXX This seems wrong.
|
||||
hash =
|
||||
AddToHash(hash, reinterpret_cast<uintptr_t>(aKey->mWebExtGlobal.get()));
|
||||
return hash;
|
||||
}
|
|
@ -1,47 +0,0 @@
|
|||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#ifndef ModuleMapKey_h__
|
||||
#define ModuleMapKey_h__
|
||||
|
||||
#include "nsURIHashKey.h"
|
||||
#include "nsIGlobalObject.h"
|
||||
|
||||
namespace mozilla::dom {
|
||||
|
||||
class ModuleMapKey : public nsURIHashKey {
|
||||
public:
|
||||
using KeyType = ModuleMapKey&;
|
||||
using KeyTypePointer = const ModuleMapKey*;
|
||||
|
||||
ModuleMapKey() = default;
|
||||
ModuleMapKey(const nsIURI* aURI, nsIGlobalObject* aWebExtGlobal);
|
||||
explicit ModuleMapKey(const ModuleMapKey* aKey);
|
||||
ModuleMapKey(ModuleMapKey&& aToMove) noexcept;
|
||||
|
||||
ModuleMapKey& operator=(const ModuleMapKey& aOther) = default;
|
||||
|
||||
KeyType GetKey() { return *this; }
|
||||
KeyTypePointer GetKeyPointer() const { return this; }
|
||||
static KeyTypePointer KeyToPointer(KeyType aKey) { return &aKey; }
|
||||
|
||||
bool KeyEquals(KeyTypePointer aOther) const;
|
||||
static PLDHashNumber HashKey(KeyTypePointer aKey);
|
||||
|
||||
nsCOMPtr<nsIGlobalObject> mWebExtGlobal;
|
||||
};
|
||||
|
||||
inline void ImplCycleCollectionUnlink(ModuleMapKey& aField) {
|
||||
ImplCycleCollectionUnlink(aField.mWebExtGlobal);
|
||||
}
|
||||
|
||||
inline void ImplCycleCollectionTraverse(
|
||||
nsCycleCollectionTraversalCallback& aCallback, ModuleMapKey& aField,
|
||||
const char* aName, uint32_t aFlags = 0) {
|
||||
ImplCycleCollectionTraverse(aCallback, aField.mWebExtGlobal, aName, aFlags);
|
||||
}
|
||||
|
||||
} // namespace mozilla::dom
|
||||
|
||||
#endif
|
|
@ -27,8 +27,7 @@ namespace dom {
|
|||
// ScriptFetchOptions
|
||||
//////////////////////////////////////////////////////////////
|
||||
|
||||
NS_IMPL_CYCLE_COLLECTION(ScriptFetchOptions, mElement, mTriggeringPrincipal,
|
||||
mWebExtGlobal)
|
||||
NS_IMPL_CYCLE_COLLECTION(ScriptFetchOptions, mElement, mTriggeringPrincipal)
|
||||
|
||||
NS_IMPL_CYCLE_COLLECTION_ROOT_NATIVE(ScriptFetchOptions, AddRef)
|
||||
NS_IMPL_CYCLE_COLLECTION_UNROOT_NATIVE(ScriptFetchOptions, Release)
|
||||
|
@ -36,14 +35,12 @@ NS_IMPL_CYCLE_COLLECTION_UNROOT_NATIVE(ScriptFetchOptions, Release)
|
|||
ScriptFetchOptions::ScriptFetchOptions(mozilla::CORSMode aCORSMode,
|
||||
ReferrerPolicy aReferrerPolicy,
|
||||
Element* aElement,
|
||||
nsIPrincipal* aTriggeringPrincipal,
|
||||
nsIGlobalObject* aWebExtGlobal)
|
||||
nsIPrincipal* aTriggeringPrincipal)
|
||||
: mCORSMode(aCORSMode),
|
||||
mReferrerPolicy(aReferrerPolicy),
|
||||
mIsPreload(false),
|
||||
mElement(aElement),
|
||||
mTriggeringPrincipal(aTriggeringPrincipal),
|
||||
mWebExtGlobal(aWebExtGlobal) {
|
||||
mTriggeringPrincipal(aTriggeringPrincipal) {
|
||||
MOZ_ASSERT(mTriggeringPrincipal);
|
||||
}
|
||||
|
||||
|
@ -62,7 +59,6 @@ NS_IMPL_CYCLE_COLLECTING_RELEASE(ScriptLoadRequest)
|
|||
NS_IMPL_CYCLE_COLLECTION_CLASS(ScriptLoadRequest)
|
||||
|
||||
NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(ScriptLoadRequest)
|
||||
// XXX missing mLoadBlockedDocument ?
|
||||
NS_IMPL_CYCLE_COLLECTION_UNLINK(mFetchOptions, mCacheInfo)
|
||||
tmp->mScript = nullptr;
|
||||
if (Runnable* runnable = tmp->mRunnable.exchange(nullptr)) {
|
||||
|
|
|
@ -22,7 +22,6 @@
|
|||
#include "mozilla/Vector.h"
|
||||
#include "nsCOMPtr.h"
|
||||
#include "nsCycleCollectionParticipant.h"
|
||||
#include "nsIGlobalObject.h"
|
||||
#include "nsIScriptElement.h"
|
||||
#include "ScriptKind.h"
|
||||
|
||||
|
@ -56,17 +55,13 @@ class ScriptFetchOptions {
|
|||
|
||||
ScriptFetchOptions(mozilla::CORSMode aCORSMode,
|
||||
enum ReferrerPolicy aReferrerPolicy, Element* aElement,
|
||||
nsIPrincipal* aTriggeringPrincipal,
|
||||
nsIGlobalObject* aWebExtGlobal);
|
||||
nsIPrincipal* aTriggeringPrincipal);
|
||||
|
||||
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;
|
||||
};
|
||||
|
||||
/*
|
||||
|
@ -263,13 +258,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;
|
||||
}
|
||||
|
||||
// Make this request a preload (speculative) request.
|
||||
void SetIsPreloadRequest() {
|
||||
MOZ_ASSERT(!GetScriptElement());
|
||||
|
|
|
@ -151,57 +151,6 @@ inline void ImplCycleCollectionTraverse(
|
|||
ImplCycleCollectionTraverse(aCallback, aField.mRequest, aName, aFlags);
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////
|
||||
// ScriptLoader::mFetchingModules / ScriptLoader::mFetchingModules
|
||||
//////////////////////////////////////////////////////////////
|
||||
|
||||
inline void ImplCycleCollectionUnlink(
|
||||
nsRefPtrHashtable<ModuleMapKey,
|
||||
mozilla::GenericNonExclusivePromise::Private>& aField) {
|
||||
for (auto iter = aField.Iter(); !iter.Done(); iter.Next()) {
|
||||
ImplCycleCollectionUnlink(iter.Key());
|
||||
|
||||
RefPtr<GenericNonExclusivePromise::Private> promise = iter.UserData();
|
||||
if (promise) {
|
||||
promise->Reject(NS_ERROR_ABORT, __func__);
|
||||
}
|
||||
}
|
||||
|
||||
aField.Clear();
|
||||
}
|
||||
|
||||
inline void ImplCycleCollectionTraverse(
|
||||
nsCycleCollectionTraversalCallback& aCallback,
|
||||
nsRefPtrHashtable<ModuleMapKey,
|
||||
mozilla::GenericNonExclusivePromise::Private>& aField,
|
||||
const char* aName, uint32_t aFlags = 0) {
|
||||
for (auto iter = aField.Iter(); !iter.Done(); iter.Next()) {
|
||||
ImplCycleCollectionTraverse(aCallback, iter.Key(), "mFetchingModules key",
|
||||
aFlags);
|
||||
}
|
||||
}
|
||||
|
||||
inline void ImplCycleCollectionUnlink(
|
||||
nsRefPtrHashtable<ModuleMapKey, ModuleScript>& aField) {
|
||||
for (auto iter = aField.Iter(); !iter.Done(); iter.Next()) {
|
||||
ImplCycleCollectionUnlink(iter.Key());
|
||||
}
|
||||
|
||||
aField.Clear();
|
||||
}
|
||||
|
||||
inline void ImplCycleCollectionTraverse(
|
||||
nsCycleCollectionTraversalCallback& aCallback,
|
||||
nsRefPtrHashtable<ModuleMapKey, ModuleScript>& aField, const char* aName,
|
||||
uint32_t aFlags = 0) {
|
||||
for (auto iter = aField.Iter(); !iter.Done(); iter.Next()) {
|
||||
ImplCycleCollectionTraverse(aCallback, iter.Key(), "mFetchedModules key",
|
||||
aFlags);
|
||||
CycleCollectionNoteChild(aCallback, iter.UserData(), "mFetchedModules data",
|
||||
aFlags);
|
||||
}
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////
|
||||
// ScriptLoader
|
||||
//////////////////////////////////////////////////////////////
|
||||
|
@ -213,8 +162,7 @@ NS_IMPL_CYCLE_COLLECTION(ScriptLoader, mNonAsyncExternalScriptInsertedRequests,
|
|||
mLoadingAsyncRequests, mLoadedAsyncRequests,
|
||||
mDeferRequests, mXSLTRequests, mDynamicImportRequests,
|
||||
mParserBlockingRequest, mBytecodeEncodingQueue,
|
||||
mPreloads, mPendingChildLoaders, mFetchedModules,
|
||||
mFetchingModules)
|
||||
mPreloads, mPendingChildLoaders, mFetchedModules)
|
||||
|
||||
NS_IMPL_CYCLE_COLLECTING_ADDREF(ScriptLoader)
|
||||
NS_IMPL_CYCLE_COLLECTING_RELEASE(ScriptLoader)
|
||||
|
@ -493,23 +441,25 @@ bool ScriptLoader::IsAboutPageLoadingChromeURI(ScriptLoadRequest* aRequest,
|
|||
return true;
|
||||
}
|
||||
|
||||
bool ScriptLoader::ModuleMapContainsURL(nsIURI* aURL,
|
||||
nsIGlobalObject* aGlobal) const {
|
||||
bool ScriptLoader::ModuleMapContainsURL(nsIURI* aURL) const {
|
||||
// Returns whether we have fetched, or are currently fetching, a module script
|
||||
// for a URL.
|
||||
ModuleMapKey key(aURL, aGlobal);
|
||||
return mFetchingModules.Contains(key) || mFetchedModules.Contains(key);
|
||||
return mFetchingModules.Contains(aURL) || mFetchedModules.Contains(aURL);
|
||||
}
|
||||
|
||||
bool ScriptLoader::IsFetchingModule(ModuleLoadRequest* aRequest) const {
|
||||
bool fetching = mFetchingModules.Contains(aRequest->mURI);
|
||||
MOZ_ASSERT_IF(fetching, !mFetchedModules.Contains(aRequest->mURI));
|
||||
return fetching;
|
||||
}
|
||||
|
||||
void ScriptLoader::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));
|
||||
mFetchingModules.InsertOrUpdate(
|
||||
key, RefPtr<GenericNonExclusivePromise::Private>{});
|
||||
aRequest->mURI, RefPtr<GenericNonExclusivePromise::Private>{});
|
||||
}
|
||||
|
||||
void ScriptLoader::SetModuleFetchFinishedAndResumeWaitingRequests(
|
||||
|
@ -525,18 +475,14 @@ void ScriptLoader::SetModuleFetchFinishedAndResumeWaitingRequests(
|
|||
"%u)",
|
||||
aRequest, aRequest->mModuleScript.get(), unsigned(aResult)));
|
||||
|
||||
ModuleMapKey key(aRequest->mURI, aRequest->GetWebExtGlobal());
|
||||
RefPtr<GenericNonExclusivePromise::Private> promise;
|
||||
if (!mFetchingModules.Remove(key, getter_AddRefs(promise))) {
|
||||
LOG(("ScriptLoadRequest (%p): Key not found in mFetchingModules",
|
||||
aRequest));
|
||||
return;
|
||||
}
|
||||
MOZ_ALWAYS_TRUE(
|
||||
mFetchingModules.Remove(aRequest->mURI, getter_AddRefs(promise)));
|
||||
|
||||
RefPtr<ModuleScript> moduleScript(aRequest->mModuleScript);
|
||||
MOZ_ASSERT(NS_FAILED(aResult) == !moduleScript);
|
||||
|
||||
mFetchedModules.InsertOrUpdate(key, RefPtr{moduleScript});
|
||||
mFetchedModules.InsertOrUpdate(aRequest->mURI, RefPtr{moduleScript});
|
||||
|
||||
if (promise) {
|
||||
if (moduleScript) {
|
||||
|
@ -550,11 +496,10 @@ void ScriptLoader::SetModuleFetchFinishedAndResumeWaitingRequests(
|
|||
}
|
||||
|
||||
RefPtr<GenericNonExclusivePromise> ScriptLoader::WaitForModuleFetch(
|
||||
nsIURI* aURL, nsIGlobalObject* aGlobal) {
|
||||
MOZ_ASSERT(ModuleMapContainsURL(aURL, aGlobal));
|
||||
nsIURI* aURL) {
|
||||
MOZ_ASSERT(ModuleMapContainsURL(aURL));
|
||||
|
||||
ModuleMapKey key(aURL, aGlobal);
|
||||
if (auto entry = mFetchingModules.Lookup(key)) {
|
||||
if (auto entry = mFetchingModules.Lookup(aURL)) {
|
||||
if (!entry.Data()) {
|
||||
entry.Data() = new GenericNonExclusivePromise::Private(__func__);
|
||||
}
|
||||
|
@ -562,7 +507,7 @@ RefPtr<GenericNonExclusivePromise> ScriptLoader::WaitForModuleFetch(
|
|||
}
|
||||
|
||||
RefPtr<ModuleScript> ms;
|
||||
MOZ_ALWAYS_TRUE(mFetchedModules.Get(key, getter_AddRefs(ms)));
|
||||
MOZ_ALWAYS_TRUE(mFetchedModules.Get(aURL, getter_AddRefs(ms)));
|
||||
if (!ms) {
|
||||
return GenericNonExclusivePromise::CreateAndReject(NS_ERROR_FAILURE,
|
||||
__func__);
|
||||
|
@ -571,17 +516,15 @@ RefPtr<GenericNonExclusivePromise> ScriptLoader::WaitForModuleFetch(
|
|||
return GenericNonExclusivePromise::CreateAndResolve(true, __func__);
|
||||
}
|
||||
|
||||
ModuleScript* ScriptLoader::GetFetchedModule(nsIURI* aURL,
|
||||
nsIGlobalObject* aGlobal) const {
|
||||
ModuleScript* ScriptLoader::GetFetchedModule(nsIURI* aURL) const {
|
||||
if (LOG_ENABLED()) {
|
||||
nsAutoCString url;
|
||||
aURL->GetAsciiSpec(url);
|
||||
LOG(("GetFetchedModule %s %p", url.get(), aGlobal));
|
||||
LOG(("GetFetchedModule %s", url.get()));
|
||||
}
|
||||
|
||||
bool found;
|
||||
ModuleMapKey key(aURL, aGlobal);
|
||||
ModuleScript* ms = mFetchedModules.GetWeak(key, &found);
|
||||
ModuleScript* ms = mFetchedModules.GetWeak(aURL, &found);
|
||||
MOZ_ASSERT(found);
|
||||
return ms;
|
||||
}
|
||||
|
@ -619,23 +562,14 @@ nsresult ScriptLoader::CreateModuleScript(ModuleLoadRequest* aRequest) {
|
|||
|
||||
LOG(("ScriptLoadRequest (%p): Create module script", aRequest));
|
||||
|
||||
nsCOMPtr<nsIGlobalObject> globalObject;
|
||||
nsCOMPtr<nsIScriptContext> context;
|
||||
if (aRequest->GetWebExtGlobal()) {
|
||||
globalObject = aRequest->GetWebExtGlobal();
|
||||
} else {
|
||||
nsCOMPtr<nsIScriptGlobalObject> scriptGlobal =
|
||||
GetScriptGlobalObject(WebExtGlobal::Handled);
|
||||
if (!scriptGlobal) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
nsCOMPtr<nsIScriptGlobalObject> globalObject = GetScriptGlobalObject();
|
||||
if (!globalObject) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
context = scriptGlobal->GetScriptContext();
|
||||
if (!context) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
globalObject = scriptGlobal;
|
||||
nsCOMPtr<nsIScriptContext> context = globalObject->GetScriptContext();
|
||||
if (!context) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
nsAutoMicroTask mt;
|
||||
|
@ -644,11 +578,8 @@ nsresult ScriptLoader::CreateModuleScript(ModuleLoadRequest* aRequest) {
|
|||
|
||||
AutoEntryScript aes(globalObject, "CompileModule", true);
|
||||
|
||||
bool oldProcessingScriptTag = false;
|
||||
if (context) {
|
||||
oldProcessingScriptTag = context->GetProcessingScriptTag();
|
||||
context->SetProcessingScriptTag(true);
|
||||
}
|
||||
bool oldProcessingScriptTag = context->GetProcessingScriptTag();
|
||||
context->SetProcessingScriptTag(true);
|
||||
|
||||
nsresult rv;
|
||||
{
|
||||
|
@ -713,9 +644,7 @@ nsresult ScriptLoader::CreateModuleScript(ModuleLoadRequest* aRequest) {
|
|||
}
|
||||
}
|
||||
|
||||
if (context) {
|
||||
context->SetProcessingScriptTag(oldProcessingScriptTag);
|
||||
}
|
||||
context->SetProcessingScriptTag(oldProcessingScriptTag);
|
||||
|
||||
LOG(("ScriptLoadRequest (%p): module script == %p", aRequest,
|
||||
aRequest->mModuleScript.get()));
|
||||
|
@ -880,7 +809,6 @@ void ScriptLoader::StartFetchingModuleDependencies(
|
|||
nsCOMArray<nsIURI> urls;
|
||||
nsresult rv = ResolveRequestedModules(aRequest, &urls);
|
||||
if (NS_FAILED(rv)) {
|
||||
aRequest->mModuleScript = nullptr;
|
||||
aRequest->ModuleErrored();
|
||||
return;
|
||||
}
|
||||
|
@ -950,8 +878,6 @@ RefPtr<GenericPromise> ScriptLoader::StartFetchingModuleAndDependencies(
|
|||
MOZ_ASSERT(!childRequest->mModuleScript);
|
||||
LOG(("ScriptLoadRequest (%p): rejecting %p", aParent,
|
||||
&childRequest->mReady));
|
||||
|
||||
ReportErrorToConsole(childRequest, rv);
|
||||
childRequest->mReady.Reject(rv, __func__);
|
||||
return ready;
|
||||
}
|
||||
|
@ -974,13 +900,8 @@ static ScriptLoader* GetCurrentScriptLoader(JSContext* aCx) {
|
|||
return nullptr;
|
||||
}
|
||||
|
||||
nsGlobalWindowInner* innerWindow = nullptr;
|
||||
if (nsCOMPtr<nsPIDOMWindowInner> win = do_QueryInterface(global)) {
|
||||
innerWindow = nsGlobalWindowInner::Cast(win);
|
||||
} else {
|
||||
innerWindow = xpc::SandboxWindowOrNull(object, aCx);
|
||||
}
|
||||
|
||||
nsCOMPtr<nsPIDOMWindowInner> win = do_QueryInterface(global);
|
||||
nsGlobalWindowInner* innerWindow = nsGlobalWindowInner::Cast(win);
|
||||
if (!innerWindow) {
|
||||
return nullptr;
|
||||
}
|
||||
|
@ -1054,19 +975,9 @@ void ScriptLoader::ResolveImportedModule(
|
|||
// previously successful with these same two arguments.
|
||||
MOZ_ASSERT(uri, "Failed to resolve previously-resolved module specifier");
|
||||
|
||||
// Use sandboxed global when doing a WebExtension content-script load.
|
||||
nsCOMPtr<nsIGlobalObject> global;
|
||||
if (BasePrincipal::Cast(nsContentUtils::SubjectPrincipal(aCx))
|
||||
->ContentScriptAddonPolicy()) {
|
||||
global = xpc::CurrentNativeGlobal(aCx);
|
||||
MOZ_ASSERT(global);
|
||||
MOZ_ASSERT(
|
||||
xpc::IsWebExtensionContentScriptSandbox(global->GetGlobalJSObject()));
|
||||
}
|
||||
|
||||
// Let resolved module script be moduleMap[url]. (This entry must exist for us
|
||||
// to have gotten to this point.)
|
||||
ModuleScript* ms = loader->GetFetchedModule(uri, global);
|
||||
ModuleScript* ms = loader->GetFetchedModule(uri);
|
||||
MOZ_ASSERT(ms, "Resolved module not found in module map");
|
||||
MOZ_ASSERT(!ms->HasParseError());
|
||||
MOZ_ASSERT(ms->ModuleRecord());
|
||||
|
@ -1139,24 +1050,9 @@ bool HostImportModuleDynamically(JSContext* aCx,
|
|||
// triggers an inline event handler, as there is no active script
|
||||
// there.
|
||||
Document* document = loader->GetDocument();
|
||||
|
||||
// Use the document's principal for all loads, except WebExtension
|
||||
// content-scripts.
|
||||
// Only remember the global for content-scripts as well.
|
||||
nsCOMPtr<nsIPrincipal> principal = nsContentUtils::SubjectPrincipal(aCx);
|
||||
nsCOMPtr<nsIGlobalObject> global = xpc::CurrentNativeGlobal(aCx);
|
||||
if (!BasePrincipal::Cast(principal)->ContentScriptAddonPolicy()) {
|
||||
principal = document->NodePrincipal();
|
||||
MOZ_ASSERT(global);
|
||||
global = nullptr; // Null global is the usual case for most loads.
|
||||
} else {
|
||||
MOZ_ASSERT(
|
||||
xpc::IsWebExtensionContentScriptSandbox(global->GetGlobalJSObject()));
|
||||
}
|
||||
|
||||
options = new ScriptFetchOptions(mozilla::CORS_NONE,
|
||||
document->GetReferrerPolicy(), nullptr,
|
||||
principal, global);
|
||||
document->NodePrincipal());
|
||||
baseURL = document->GetDocBaseURI();
|
||||
}
|
||||
|
||||
|
@ -1174,7 +1070,6 @@ void ScriptLoader::StartDynamicImport(ModuleLoadRequest* aRequest) {
|
|||
|
||||
nsresult rv = StartLoad(aRequest);
|
||||
if (NS_FAILED(rv)) {
|
||||
ReportErrorToConsole(aRequest, rv);
|
||||
FinishDynamicImportAndReject(aRequest, rv);
|
||||
}
|
||||
}
|
||||
|
@ -1494,20 +1389,12 @@ nsresult ScriptLoader::StartLoad(ScriptLoadRequest* aRequest) {
|
|||
}
|
||||
|
||||
if (aRequest->IsModuleRequest()) {
|
||||
// To prevent dynamic code execution, content scripts can only
|
||||
// load moz-extension URLs.
|
||||
nsCOMPtr<nsIPrincipal> principal = aRequest->TriggeringPrincipal();
|
||||
if (BasePrincipal::Cast(principal)->ContentScriptAddonPolicy() &&
|
||||
!aRequest->mURI->SchemeIs("moz-extension")) {
|
||||
return NS_ERROR_DOM_WEBEXT_CONTENT_SCRIPT_URI;
|
||||
}
|
||||
|
||||
// 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 (ModuleMapContainsURL(request->mURI, aRequest->GetWebExtGlobal())) {
|
||||
if (ModuleMapContainsURL(request->mURI)) {
|
||||
LOG(("ScriptLoadRequest (%p): Waiting for module fetch", aRequest));
|
||||
WaitForModuleFetch(request->mURI, aRequest->GetWebExtGlobal())
|
||||
WaitForModuleFetch(request->mURI)
|
||||
->Then(GetMainThreadSerialEventTarget(), __func__, request,
|
||||
&ModuleLoadRequest::ModuleLoaded,
|
||||
&ModuleLoadRequest::LoadFailed);
|
||||
|
@ -1582,9 +1469,7 @@ nsresult ScriptLoader::StartLoad(ScriptLoadRequest* aRequest) {
|
|||
}
|
||||
}
|
||||
|
||||
// Module requests aren't cached, so ignore WebExtGlobal here.
|
||||
nsCOMPtr<nsIScriptGlobalObject> globalObject =
|
||||
GetScriptGlobalObject(WebExtGlobal::Ignore);
|
||||
nsCOMPtr<nsIScriptGlobalObject> globalObject = GetScriptGlobalObject();
|
||||
if (!globalObject) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
@ -1599,8 +1484,6 @@ nsresult ScriptLoader::StartLoad(ScriptLoadRequest* aRequest) {
|
|||
!js::GlobalHasInstrumentation(globalObject->GetGlobalJSObject()) &&
|
||||
// Bug 1436400: no bytecode cache support for modules yet.
|
||||
!aRequest->IsModuleRequest()) {
|
||||
MOZ_ASSERT(!aRequest->GetWebExtGlobal(),
|
||||
"Can not bytecode cache WebExt code");
|
||||
if (!aRequest->IsLoadingSource()) {
|
||||
// Inform the HTTP cache that we prefer to have information coming from
|
||||
// the bytecode cache instead of the sources, if such entry is already
|
||||
|
@ -1792,7 +1675,7 @@ ScriptLoadRequest* ScriptLoader::CreateLoadRequest(
|
|||
nsIURI* referrer = mDocument->GetDocumentURIAsReferrer();
|
||||
nsCOMPtr<Element> domElement = do_QueryInterface(aElement);
|
||||
ScriptFetchOptions* fetchOptions = new ScriptFetchOptions(
|
||||
aCORSMode, aReferrerPolicy, domElement, aTriggeringPrincipal, nullptr);
|
||||
aCORSMode, aReferrerPolicy, domElement, aTriggeringPrincipal);
|
||||
|
||||
if (aKind == ScriptKind::eClassic) {
|
||||
return new ScriptLoadRequest(aKind, aURI, fetchOptions, aIntegrity,
|
||||
|
@ -2510,7 +2393,7 @@ nsresult ScriptLoader::AttemptAsyncScriptCompile(ScriptLoadRequest* aRequest,
|
|||
return NS_OK;
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIGlobalObject> globalObject = GetGlobalForRequest(aRequest);
|
||||
nsCOMPtr<nsIScriptGlobalObject> globalObject = GetScriptGlobalObject();
|
||||
if (!globalObject) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
@ -2855,18 +2738,7 @@ void ScriptLoader::FireScriptEvaluated(nsresult aResult,
|
|||
aRequest->FireScriptEvaluated(aResult);
|
||||
}
|
||||
|
||||
already_AddRefed<nsIGlobalObject> ScriptLoader::GetGlobalForRequest(
|
||||
ScriptLoadRequest* aRequest) {
|
||||
if (aRequest->GetWebExtGlobal()) {
|
||||
nsCOMPtr<nsIGlobalObject> global = aRequest->GetWebExtGlobal();
|
||||
return global.forget();
|
||||
}
|
||||
|
||||
return GetScriptGlobalObject(WebExtGlobal::Handled);
|
||||
}
|
||||
|
||||
already_AddRefed<nsIScriptGlobalObject> ScriptLoader::GetScriptGlobalObject(
|
||||
WebExtGlobal) {
|
||||
already_AddRefed<nsIScriptGlobalObject> ScriptLoader::GetScriptGlobalObject() {
|
||||
if (!mDocument) {
|
||||
return nullptr;
|
||||
}
|
||||
|
@ -3081,28 +2953,17 @@ nsresult ScriptLoader::EvaluateScript(ScriptLoadRequest* aRequest) {
|
|||
}
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIGlobalObject> globalObject;
|
||||
nsCOMPtr<nsIScriptContext> context;
|
||||
if (aRequest->GetWebExtGlobal()) {
|
||||
// Executing a module from a WebExtension content-script.
|
||||
globalObject = aRequest->GetWebExtGlobal();
|
||||
} else {
|
||||
// Otherwise we have to ensure that there is a nsIScriptContext.
|
||||
nsCOMPtr<nsIScriptGlobalObject> scriptGlobal =
|
||||
GetScriptGlobalObject(WebExtGlobal::Handled);
|
||||
if (!scriptGlobal) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
nsCOMPtr<nsIScriptGlobalObject> globalObject = GetScriptGlobalObject();
|
||||
if (!globalObject) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
// Make sure context is a strong reference since we access it after
|
||||
// we've executed a script, which may cause all other references to
|
||||
// the context to go away.
|
||||
context = scriptGlobal->GetScriptContext();
|
||||
if (!context) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
globalObject = scriptGlobal;
|
||||
// Make sure context is a strong reference since we access it after
|
||||
// we've executed a script, which may cause all other references to
|
||||
// the context to go away.
|
||||
nsCOMPtr<nsIScriptContext> context = globalObject->GetScriptContext();
|
||||
if (!context) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
#ifdef MOZ_GECKO_PROFILER
|
||||
|
@ -3119,10 +2980,7 @@ nsresult ScriptLoader::EvaluateScript(ScriptLoadRequest* aRequest) {
|
|||
JSContext* cx = aes.cx();
|
||||
JS::Rooted<JSObject*> global(cx, globalObject->GetGlobalJSObject());
|
||||
|
||||
Maybe<AutoSetProcessingScriptTag> setProcessingScriptTag;
|
||||
if (context) {
|
||||
setProcessingScriptTag.emplace(context);
|
||||
}
|
||||
AutoSetProcessingScriptTag setProcessingScriptTag(context);
|
||||
|
||||
nsresult rv;
|
||||
{
|
||||
|
@ -3458,9 +3316,7 @@ void ScriptLoader::EncodeBytecode() {
|
|||
return;
|
||||
}
|
||||
|
||||
// Should not be encoding modules at all.
|
||||
nsCOMPtr<nsIScriptGlobalObject> globalObject =
|
||||
GetScriptGlobalObject(WebExtGlobal::Ignore);
|
||||
nsCOMPtr<nsIScriptGlobalObject> globalObject = GetScriptGlobalObject();
|
||||
if (!globalObject) {
|
||||
GiveUpBytecodeEncoding();
|
||||
return;
|
||||
|
@ -3478,8 +3334,6 @@ void ScriptLoader::EncodeBytecode() {
|
|||
RefPtr<ScriptLoadRequest> request;
|
||||
while (!mBytecodeEncodingQueue.isEmpty()) {
|
||||
request = mBytecodeEncodingQueue.StealFirst();
|
||||
MOZ_ASSERT(!request->IsModuleRequest());
|
||||
MOZ_ASSERT(!request->GetWebExtGlobal(), "Not handling global above");
|
||||
EncodeRequestBytecode(aes.cx(), request);
|
||||
request->mScriptBytecode.clearAndFree();
|
||||
request->DropBytecodeCacheReferences();
|
||||
|
@ -3567,8 +3421,7 @@ void ScriptLoader::GiveUpBytecodeEncoding() {
|
|||
// would not keep a large buffer around. If we cannot, we fallback on the
|
||||
// removal of all request from the current list and these large buffers would
|
||||
// be removed at the same time as the source object.
|
||||
nsCOMPtr<nsIScriptGlobalObject> globalObject =
|
||||
GetScriptGlobalObject(WebExtGlobal::Ignore);
|
||||
nsCOMPtr<nsIScriptGlobalObject> globalObject = GetScriptGlobalObject();
|
||||
AutoAllowLegacyScriptExecution exemption;
|
||||
Maybe<AutoEntryScript> aes;
|
||||
|
||||
|
@ -3584,8 +3437,6 @@ void ScriptLoader::GiveUpBytecodeEncoding() {
|
|||
LOG(("ScriptLoadRequest (%p): Cannot serialize bytecode", request.get()));
|
||||
TRACE_FOR_TEST_NONE(request->GetScriptElement(),
|
||||
"scriptloader_bytecode_failed");
|
||||
MOZ_ASSERT(!request->IsModuleRequest());
|
||||
MOZ_ASSERT(!request->GetWebExtGlobal());
|
||||
|
||||
if (aes.isSome()) {
|
||||
JS::RootedScript script(aes->cx(), request->mScript);
|
||||
|
@ -3971,9 +3822,6 @@ void ScriptLoader::ReportErrorToConsole(ScriptLoadRequest* aRequest,
|
|||
message = isScript ? "ScriptSourceMalformed" : "ModuleSourceMalformed";
|
||||
} else if (aResult == NS_ERROR_DOM_BAD_URI) {
|
||||
message = isScript ? "ScriptSourceNotAllowed" : "ModuleSourceNotAllowed";
|
||||
} else if (aResult == NS_ERROR_DOM_WEBEXT_CONTENT_SCRIPT_URI) {
|
||||
MOZ_ASSERT(!isScript);
|
||||
message = "WebExtContentScriptModuleSourceNotAllowed";
|
||||
} else if (net::UrlClassifierFeatureFactory::IsClassifierBlockingErrorCode(
|
||||
aResult)) {
|
||||
// Blocking classifier error codes already show their own console messages.
|
||||
|
|
|
@ -24,7 +24,6 @@
|
|||
#include "mozilla/MaybeOneOf.h"
|
||||
#include "mozilla/MozPromise.h"
|
||||
#include "ScriptKind.h"
|
||||
#include "ModuleMapKey.h"
|
||||
|
||||
class nsCycleCollectionTraversalCallback;
|
||||
class nsIChannel;
|
||||
|
@ -627,16 +626,7 @@ class ScriptLoader final : public nsISupports {
|
|||
|
||||
void GiveUpBytecodeEncoding();
|
||||
|
||||
already_AddRefed<nsIGlobalObject> GetGlobalForRequest(
|
||||
ScriptLoadRequest* aRequest);
|
||||
|
||||
// This is a marker class to ensure proper handling of requests with a
|
||||
// WebExtGlobal.
|
||||
enum class WebExtGlobal { Ignore, Handled };
|
||||
|
||||
already_AddRefed<nsIScriptGlobalObject> GetScriptGlobalObject(
|
||||
WebExtGlobal aWebExtGlobal);
|
||||
|
||||
already_AddRefed<nsIScriptGlobalObject> GetScriptGlobalObject();
|
||||
nsresult FillCompileOptionsForRequest(const mozilla::dom::AutoJSAPI& jsapi,
|
||||
ScriptLoadRequest* aRequest,
|
||||
JS::Handle<JSObject*> aScopeChain,
|
||||
|
@ -668,10 +658,11 @@ class ScriptLoader final : public nsISupports {
|
|||
void SetModuleFetchFinishedAndResumeWaitingRequests(
|
||||
ModuleLoadRequest* aRequest, nsresult aResult);
|
||||
|
||||
bool ModuleMapContainsURL(nsIURI* aURL, nsIGlobalObject* aGlobal) const;
|
||||
RefPtr<mozilla::GenericNonExclusivePromise> WaitForModuleFetch(
|
||||
nsIURI* aURL, nsIGlobalObject* aGlobal);
|
||||
ModuleScript* GetFetchedModule(nsIURI* aURL, nsIGlobalObject* aGlobal) const;
|
||||
bool IsFetchingModule(ModuleLoadRequest* aRequest) const;
|
||||
|
||||
bool ModuleMapContainsURL(nsIURI* aURL) const;
|
||||
RefPtr<mozilla::GenericNonExclusivePromise> WaitForModuleFetch(nsIURI* aURL);
|
||||
ModuleScript* GetFetchedModule(nsIURI* aURL) const;
|
||||
|
||||
friend JSObject* HostResolveImportedModule(
|
||||
JSContext* aCx, JS::Handle<JS::Value> aReferencingPrivate,
|
||||
|
@ -758,9 +749,9 @@ class ScriptLoader final : public nsISupports {
|
|||
bool mGiveUpEncoding;
|
||||
|
||||
// Module map
|
||||
nsRefPtrHashtable<ModuleMapKey, mozilla::GenericNonExclusivePromise::Private>
|
||||
nsRefPtrHashtable<nsURIHashKey, mozilla::GenericNonExclusivePromise::Private>
|
||||
mFetchingModules;
|
||||
nsRefPtrHashtable<ModuleMapKey, ModuleScript> mFetchedModules;
|
||||
nsRefPtrHashtable<nsURIHashKey, ModuleScript> mFetchedModules;
|
||||
|
||||
nsCOMPtr<nsIConsoleReportCollector> mReporter;
|
||||
|
||||
|
|
|
@ -20,7 +20,6 @@ EXPORTS += [
|
|||
EXPORTS.mozilla.dom += [
|
||||
"AutoEntryScript.h",
|
||||
"LoadedScript.h",
|
||||
"ModuleMapKey.h",
|
||||
"ScriptDecoding.h",
|
||||
"ScriptElement.h",
|
||||
"ScriptKind.h",
|
||||
|
@ -33,7 +32,6 @@ UNIFIED_SOURCES += [
|
|||
"AutoEntryScript.cpp",
|
||||
"LoadedScript.cpp",
|
||||
"ModuleLoadRequest.cpp",
|
||||
"ModuleMapKey.cpp",
|
||||
"nsIScriptElement.cpp",
|
||||
"ScriptElement.cpp",
|
||||
"ScriptLoader.cpp",
|
||||
|
|
|
@ -558,11 +558,6 @@ bool IsSandboxPrototypeProxy(JSObject* obj) {
|
|||
return js::IsProxy(obj) && js::GetProxyHandler(obj) == &sandboxProxyHandler;
|
||||
}
|
||||
|
||||
bool IsWebExtensionContentScriptSandbox(JSObject* obj) {
|
||||
return IsSandbox(obj) &&
|
||||
CompartmentPrivate::Get(obj)->isWebExtensionContentScript;
|
||||
}
|
||||
|
||||
} // namespace xpc
|
||||
|
||||
// A proxy handler that lets us wrap callables and invoke them with
|
||||
|
|
|
@ -138,7 +138,6 @@ bool AllowContentXBLScope(JS::Realm* realm);
|
|||
JSObject* NACScope(JSObject* global);
|
||||
|
||||
bool IsSandboxPrototypeProxy(JSObject* obj);
|
||||
bool IsWebExtensionContentScriptSandbox(JSObject* obj);
|
||||
|
||||
// The JSContext argument represents the Realm that's asking the question. This
|
||||
// is needed to properly answer without exposing information unnecessarily
|
||||
|
|
|
@ -1,274 +0,0 @@
|
|||
"use strict";
|
||||
|
||||
const server = createHttpServer({ hosts: ["example.com"] });
|
||||
|
||||
server.registerPathHandler("/dummy", (request, response) => {
|
||||
response.setStatusLine(request.httpVersion, 200, "OK");
|
||||
response.setHeader("Content-Type", "text/html", false);
|
||||
response.write("<!DOCTYPE html><html></html>");
|
||||
});
|
||||
|
||||
server.registerPathHandler("/script.js", (request, response) => {
|
||||
ok(false, "Unexpected request to /script.js");
|
||||
});
|
||||
|
||||
/* eslint-disable no-unsanitized/method, no-eval, no-implied-eval */
|
||||
|
||||
const MODULE1 = `
|
||||
import {foo} from "./module2.js";
|
||||
export let bar = foo;
|
||||
|
||||
let count = 0;
|
||||
|
||||
export function counter () { return count++; }
|
||||
`;
|
||||
|
||||
const MODULE2 = `export let foo = 2;`;
|
||||
|
||||
add_task(async function test_disallowed_import() {
|
||||
let extension = ExtensionTestUtils.loadExtension({
|
||||
manifest: {
|
||||
content_scripts: [
|
||||
{
|
||||
matches: ["http://example.com/dummy"],
|
||||
js: ["main.js"],
|
||||
},
|
||||
],
|
||||
},
|
||||
|
||||
files: {
|
||||
"main.js": async function() {
|
||||
let disallowedURLs = [
|
||||
"data:text/javascript,void 0",
|
||||
"javascript:void 0",
|
||||
"http://example.com/script.js",
|
||||
URL.createObjectURL(
|
||||
new Blob(["void 0", { type: "text/javascript" }])
|
||||
),
|
||||
];
|
||||
|
||||
for (let url of disallowedURLs) {
|
||||
await browser.test.assertRejects(
|
||||
import(url),
|
||||
/error loading dynamically imported module/,
|
||||
`should reject import("${url}")`
|
||||
);
|
||||
}
|
||||
|
||||
browser.test.sendMessage("done");
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
await extension.startup();
|
||||
let contentPage = await ExtensionTestUtils.loadContentPage(
|
||||
"http://example.com/dummy"
|
||||
);
|
||||
await extension.awaitMessage("done");
|
||||
await extension.unload();
|
||||
await contentPage.close();
|
||||
});
|
||||
|
||||
add_task(async function test_normal_import() {
|
||||
let extension = ExtensionTestUtils.loadExtension({
|
||||
manifest: {
|
||||
content_scripts: [
|
||||
{
|
||||
matches: ["http://example.com/dummy"],
|
||||
js: ["main.js"],
|
||||
},
|
||||
],
|
||||
},
|
||||
|
||||
files: {
|
||||
"main.js": async function() {
|
||||
/* global exportFunction */
|
||||
const url = browser.runtime.getURL("module1.js");
|
||||
let mod = await import(url);
|
||||
browser.test.assertEq(mod.bar, 2);
|
||||
|
||||
browser.test.assertEq(mod.counter(), 0);
|
||||
browser.test.assertEq(mod.counter(), 1);
|
||||
|
||||
await browser.test.assertRejects(
|
||||
window.eval(`import("${url}")`),
|
||||
/error loading dynamically imported module/,
|
||||
"Cannot import script that is not web-accessible from page context"
|
||||
);
|
||||
|
||||
let promise = new Promise((resolve, reject) => {
|
||||
exportFunction(resolve, window, { defineAs: "resolve" });
|
||||
exportFunction(reject, window, { defineAs: "reject" });
|
||||
});
|
||||
|
||||
window.setTimeout(`import("${url}").then(resolve, reject)`, 0);
|
||||
|
||||
await browser.test.assertRejects(
|
||||
promise,
|
||||
/error loading dynamically imported module/,
|
||||
"Cannot import script that is not web-accessible from page context"
|
||||
);
|
||||
|
||||
browser.test.sendMessage("done");
|
||||
},
|
||||
"module1.js": MODULE1,
|
||||
"module2.js": MODULE2,
|
||||
},
|
||||
});
|
||||
|
||||
await extension.startup();
|
||||
let contentPage = await ExtensionTestUtils.loadContentPage(
|
||||
"http://example.com/dummy"
|
||||
);
|
||||
|
||||
await extension.awaitMessage("done");
|
||||
|
||||
// Web page can not import non-web-accessible files.
|
||||
await contentPage.spawn(extension.uuid, async uuid => {
|
||||
let files = ["main.js", "module1.js", "module2.js"];
|
||||
|
||||
for (let file of files) {
|
||||
let url = `moz-extension://${uuid}/${file}`;
|
||||
await Assert.rejects(
|
||||
content.eval(`import("${url}")`),
|
||||
/error loading dynamically imported module/,
|
||||
"Cannot import script that is not web-accessible"
|
||||
);
|
||||
}
|
||||
});
|
||||
|
||||
await extension.unload();
|
||||
await contentPage.close();
|
||||
});
|
||||
|
||||
add_task(async function test_import_web_accessible() {
|
||||
let extension = ExtensionTestUtils.loadExtension({
|
||||
manifest: {
|
||||
content_scripts: [
|
||||
{
|
||||
matches: ["http://example.com/dummy"],
|
||||
js: ["main.js"],
|
||||
},
|
||||
],
|
||||
web_accessible_resources: ["module1.js", "module2.js"],
|
||||
},
|
||||
|
||||
files: {
|
||||
"main.js": async function() {
|
||||
let mod = await import(browser.runtime.getURL("module1.js"));
|
||||
browser.test.assertEq(mod.bar, 2);
|
||||
browser.test.assertEq(mod.counter(), 0);
|
||||
browser.test.sendMessage("done");
|
||||
},
|
||||
"module1.js": MODULE1,
|
||||
"module2.js": MODULE2,
|
||||
},
|
||||
});
|
||||
|
||||
await extension.startup();
|
||||
let contentPage = await ExtensionTestUtils.loadContentPage(
|
||||
"http://example.com/dummy"
|
||||
);
|
||||
await extension.awaitMessage("done");
|
||||
|
||||
// Web page can import web-accessible files,
|
||||
// even after WebExtension imported the same files.
|
||||
await contentPage.spawn(extension.uuid, async uuid => {
|
||||
let base = `moz-extension://${uuid}`;
|
||||
|
||||
await Assert.rejects(
|
||||
content.eval(`import("${base}/main.js")`),
|
||||
/error loading dynamically imported module/,
|
||||
"Cannot import script that is not web-accessible"
|
||||
);
|
||||
|
||||
let promise = content.eval(`import("${base}/module1.js")`);
|
||||
let mod = (await promise.wrappedJSObject).wrappedJSObject;
|
||||
Assert.equal(mod.bar, 2, "exported value should match");
|
||||
Assert.equal(mod.counter(), 0, "Counter should be fresh");
|
||||
Assert.equal(mod.counter(), 1, "Counter should be fresh");
|
||||
|
||||
promise = content.eval(`import("${base}/module2.js")`);
|
||||
mod = (await promise.wrappedJSObject).wrappedJSObject;
|
||||
Assert.equal(mod.foo, 2, "exported value should match");
|
||||
});
|
||||
|
||||
await extension.unload();
|
||||
await contentPage.close();
|
||||
});
|
||||
|
||||
add_task(async function test_import_web_accessible_after_page() {
|
||||
let extension = ExtensionTestUtils.loadExtension({
|
||||
manifest: {
|
||||
content_scripts: [
|
||||
{
|
||||
matches: ["http://example.com/dummy"],
|
||||
js: ["main.js"],
|
||||
},
|
||||
],
|
||||
web_accessible_resources: ["module1.js", "module2.js"],
|
||||
},
|
||||
|
||||
files: {
|
||||
"main.js": async function() {
|
||||
browser.test.onMessage.addListener(async msg => {
|
||||
browser.test.assertEq(msg, "import");
|
||||
|
||||
const url = browser.runtime.getURL("module1.js");
|
||||
let mod = await import(url);
|
||||
browser.test.assertEq(mod.bar, 2);
|
||||
browser.test.assertEq(mod.counter(), 0, "Counter should be fresh");
|
||||
|
||||
let promise = window.eval(`import("${url}")`);
|
||||
let mod2 = (await promise.wrappedJSObject).wrappedJSObject;
|
||||
browser.test.assertEq(
|
||||
mod2.counter(),
|
||||
2,
|
||||
"Counter should have been incremented by page"
|
||||
);
|
||||
|
||||
browser.test.sendMessage("done");
|
||||
});
|
||||
browser.test.sendMessage("ready");
|
||||
},
|
||||
"module1.js": MODULE1,
|
||||
"module2.js": MODULE2,
|
||||
},
|
||||
});
|
||||
|
||||
await extension.startup();
|
||||
let contentPage = await ExtensionTestUtils.loadContentPage(
|
||||
"http://example.com/dummy"
|
||||
);
|
||||
await extension.awaitMessage("ready");
|
||||
|
||||
// The web page imports the web-accessible files first,
|
||||
// when the WebExtension imports the same file, they should
|
||||
// not be shared.
|
||||
await contentPage.spawn(extension.uuid, async uuid => {
|
||||
let base = `moz-extension://${uuid}`;
|
||||
|
||||
await Assert.rejects(
|
||||
content.eval(`import("${base}/main.js")`),
|
||||
/error loading dynamically imported module/,
|
||||
"Cannot import script that is not web-accessible"
|
||||
);
|
||||
|
||||
let promise = content.eval(`import("${base}/module1.js")`);
|
||||
let mod = (await promise.wrappedJSObject).wrappedJSObject;
|
||||
Assert.equal(mod.bar, 2, "exported value should match");
|
||||
Assert.equal(mod.counter(), 0);
|
||||
Assert.equal(mod.counter(), 1);
|
||||
|
||||
promise = content.eval(`import("${base}/module2.js")`);
|
||||
mod = (await promise.wrappedJSObject).wrappedJSObject;
|
||||
Assert.equal(mod.foo, 2, "exported value should match");
|
||||
});
|
||||
|
||||
extension.sendMessage("import");
|
||||
|
||||
await extension.awaitMessage("done");
|
||||
|
||||
await extension.unload();
|
||||
await contentPage.close();
|
||||
});
|
|
@ -61,7 +61,6 @@ skip-if = tsan # Bug 1683730
|
|||
[test_ext_contentscript_css.js]
|
||||
[test_ext_contentscript_exporthelpers.js]
|
||||
[test_ext_contentscript_in_background.js]
|
||||
[test_ext_contentscript_module_import.js]
|
||||
[test_ext_contentscript_restrictSchemes.js]
|
||||
[test_ext_contentscript_teardown.js]
|
||||
skip-if = tsan # Bug 1683730
|
||||
|
|
|
@ -789,9 +789,6 @@ with modules["DOM"]:
|
|||
# objects being loaded.
|
||||
errors["NS_ERROR_RECURSIVE_DOCUMENT_LOAD"] = FAILURE(1038)
|
||||
|
||||
# WebExtension content script may not load this URL.
|
||||
errors["NS_ERROR_DOM_WEBEXT_CONTENT_SCRIPT_URI"] = FAILURE(1039)
|
||||
|
||||
# May be used to indicate when e.g. setting a property value didn't
|
||||
# actually change the value, like for obj.foo = "bar"; obj.foo = "bar";
|
||||
# the second assignment throws NS_SUCCESS_DOM_NO_OPERATION.
|
||||
|
|
Загрузка…
Ссылка в новой задаче