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:
Cosmin Sabou 2021-03-22 20:34:36 +02:00
Родитель 5d72e8e6fb
Коммит cac540c776
16 изменённых файлов: 69 добавлений и 618 удалений

Просмотреть файл

@ -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.