diff --git a/application/palemoon/configure.in b/application/palemoon/configure.in index 70ddf66210..0ccc5dc16a 100644 --- a/application/palemoon/configure.in +++ b/application/palemoon/configure.in @@ -7,13 +7,26 @@ dnl file, You can obtain one at http://mozilla.org/MPL/2.0/. dnl Things we need to carry from confvars.sh AC_DEFINE(MOZ_PHOENIX) AC_SUBST(MOZ_PHOENIX) + AC_DEFINE(MC_PALEMOON) AC_SUBST(MC_PALEMOON) -AC_DEFINE(MOZ_PHOENIX_EXTENSIONS) -AC_SUBST(MOZ_PHOENIX_EXTENSIONS) dnl Optional parts of the build. +dnl ======================================================== +dnl = Enable Phoenix Extension Support +dnl ======================================================== +MOZ_ARG_ENABLE_BOOL(phoenix-extensions, +[ --enable-phoenix-extensions Enable Phoenix Extension Support], + MOZ_PHOENIX_EXTENSIONS=1, + MOZ_PHOENIX_EXTENSIONS=) + +if test -n "$MOZ_PHOENIX_EXTENSIONS"; then + AC_DEFINE(MOZ_PHOENIX_EXTENSIONS) +fi + +AC_SUBST(MOZ_PHOENIX_EXTENSIONS) + dnl ======================================================== dnl = Disable Sync dnl ======================================================== diff --git a/application/palemoon/confvars.sh b/application/palemoon/confvars.sh index 755f24f219..2c55912de0 100644 --- a/application/palemoon/confvars.sh +++ b/application/palemoon/confvars.sh @@ -65,7 +65,7 @@ MOZ_DEVTOOLS=1 # Allows installation of Firefox GUID targeted extensions despite having # a different Application ID # On UXP this is a possible feature only for the Tycho Add-ons Manager -MOZ_PHOENIX_EXTENSIONS=1 +MOZ_PHOENIX_EXTENSIONS= # Platform Feature: Sync Service MOZ_SERVICES_COMMON=1 diff --git a/build/moz.configure/old.configure b/build/moz.configure/old.configure index 9d1a33c66e..32db54184d 100644 --- a/build/moz.configure/old.configure +++ b/build/moz.configure/old.configure @@ -311,6 +311,7 @@ def old_configure_options(*options): '--disable-browser-statusbar', '--disable-sync', '--disable-personas', + '--enable-phoenix-extensions', # Below are configure flags used by Basilisk '--disable-webextensions', diff --git a/dom/abort/AbortSignal.cpp b/dom/abort/AbortSignal.cpp index 20f36d2abb..7ee6c49a93 100644 --- a/dom/abort/AbortSignal.cpp +++ b/dom/abort/AbortSignal.cpp @@ -56,9 +56,16 @@ AbortSignal::Aborted() const void AbortSignal::Abort() { - MOZ_ASSERT(!mAborted); + // Re-entrancy guard + if (mAborted) { + return; + } mAborted = true; + // We might be deleted as a result of aborting a follower, so ensure we + // stay alive until all followers have been aborted. + RefPtr pinThis = this; + // Let's inform the followers. for (uint32_t i = 0; i < mFollowers.Length(); ++i) { mFollowers[i]->Aborted(); diff --git a/dom/abort/moz.build b/dom/abort/moz.build index cb48ee15f4..eacc9ddc74 100644 --- a/dom/abort/moz.build +++ b/dom/abort/moz.build @@ -14,7 +14,7 @@ EXPORTS.mozilla.dom += [ 'AbortSignal.h', ] -UNIFIED_SOURCES += [ +SOURCES += [ 'AbortController.cpp', 'AbortSignal.cpp', ] diff --git a/dom/base/nsDocument.cpp b/dom/base/nsDocument.cpp index dc4b23f2ce..76490e6b44 100644 --- a/dom/base/nsDocument.cpp +++ b/dom/base/nsDocument.cpp @@ -12446,3 +12446,16 @@ nsIDocument::GetSelection(ErrorResult& aRv) return nsGlobalWindow::Cast(window)->GetSelection(aRv); } + +bool +nsIDocument::ModuleScriptsEnabled() +{ + static bool sEnabledForContent = false; + static bool sCachedPref = false; + if (!sCachedPref) { + sCachedPref = true; + Preferences::AddBoolVarCache(&sEnabledForContent, "dom.moduleScripts.enabled", false); + } + + return nsContentUtils::IsChromeDoc(this) || sEnabledForContent; +} \ No newline at end of file diff --git a/dom/base/nsIDocument.h b/dom/base/nsIDocument.h index 33aac3a3d6..21cd0aaf7c 100644 --- a/dom/base/nsIDocument.h +++ b/dom/base/nsIDocument.h @@ -2851,6 +2851,8 @@ public: return mIsWebComponentsEnabled; } + bool ModuleScriptsEnabled(); + protected: bool GetUseCounter(mozilla::UseCounter aUseCounter) { diff --git a/dom/bindings/BindingUtils.cpp b/dom/bindings/BindingUtils.cpp index ee321772e6..aeccc84bcc 100644 --- a/dom/bindings/BindingUtils.cpp +++ b/dom/bindings/BindingUtils.cpp @@ -2516,6 +2516,12 @@ ConstructJSImplementation(const char* aContractId, { AutoNoJSAPI nojsapi; + nsCOMPtr window = do_QueryInterface(aGlobal); + if (!window->IsCurrentInnerWindow()) { + aRv.Throw(NS_ERROR_FAILURE); + return; + } + // Get the XPCOM component containing the JS implementation. nsresult rv; nsCOMPtr implISupports = do_CreateInstance(aContractId, &rv); @@ -2530,7 +2536,6 @@ ConstructJSImplementation(const char* aContractId, // and our global is a window. nsCOMPtr gpi = do_QueryInterface(implISupports); - nsCOMPtr window = do_QueryInterface(aGlobal); if (gpi) { JS::Rooted initReturn(RootingCx()); rv = gpi->Init(window, &initReturn); diff --git a/dom/html/HTMLMediaElement.cpp b/dom/html/HTMLMediaElement.cpp index 912602793a..d0561599af 100644 --- a/dom/html/HTMLMediaElement.cpp +++ b/dom/html/HTMLMediaElement.cpp @@ -9,6 +9,7 @@ #include "mozilla/dom/HTMLSourceElement.h" #include "mozilla/dom/ElementInlines.h" #include "mozilla/dom/Promise.h" +#include "mozilla/Preferences.h" #include "mozilla/ArrayUtils.h" #include "mozilla/MathAlgorithms.h" #include "mozilla/AsyncEventDispatcher.h" @@ -1245,7 +1246,18 @@ void HTMLMediaElement::NoSupportedMediaSourceError(const nsACString& aErrorDetai if (mDecoder) { ShutdownDecoder(); } - mErrorSink->SetError(MEDIA_ERR_SRC_NOT_SUPPORTED, aErrorDetails); + + // aErrorDetails can include sensitive details like MimeType or HTTP Status + // Code. We should not leak this and pass a Generic Error Message unless the + // user has explicitly enabled error reporting for debugging purposes. + bool reportDetails = Preferences::GetBool("media.sourceErrorDetails.enabled", false); + if (reportDetails) { + mErrorSink->SetError(MEDIA_ERR_SRC_NOT_SUPPORTED, aErrorDetails); + } else { + mErrorSink->SetError(MEDIA_ERR_SRC_NOT_SUPPORTED, + NS_LITERAL_CSTRING("Failed to open media")); + } + ChangeDelayLoadStatus(false); UpdateAudioChannelPlayingState(); RejectPromises(TakePendingPlayPromises(), NS_ERROR_DOM_MEDIA_NOT_SUPPORTED_ERR); diff --git a/dom/html/HTMLScriptElement.cpp b/dom/html/HTMLScriptElement.cpp index 5b727280f5..f1463d6aa4 100644 --- a/dom/html/HTMLScriptElement.cpp +++ b/dom/html/HTMLScriptElement.cpp @@ -280,12 +280,20 @@ HTMLScriptElement::GetScriptCharset(nsAString& charset) } void -HTMLScriptElement::FreezeUriAsyncDefer() +HTMLScriptElement::FreezeExecutionAttrs(nsIDocument* aOwnerDoc) { if (mFrozen) { return; } + MOZ_ASSERT(!mIsModule && !mAsync && !mDefer && !mExternal); + + // Determine whether this is a classic script or a module script. + nsAutoString type; + GetScriptType(type); + mIsModule = aOwnerDoc->ModuleScriptsEnabled() && + !type.IsEmpty() && type.LowerCaseEqualsASCII("module"); + // variation of this code in nsSVGScriptElement - check if changes // need to be transfered when modifying. Note that we don't use GetSrc here // because it will return the base URL when the attr value is "". @@ -300,14 +308,13 @@ HTMLScriptElement::FreezeUriAsyncDefer() // At this point mUri will be null for invalid URLs. mExternal = true; - - bool defer, async; - GetAsync(&async); - GetDefer(&defer); - - mDefer = !async && defer; - mAsync = async; } + + bool defer, async; + GetAsync(&async); + mAsync = (mExternal || mIsModule) && async; + GetDefer(&defer); + mDefer = mExternal && !async && defer; mFrozen = true; } diff --git a/dom/html/HTMLScriptElement.h b/dom/html/HTMLScriptElement.h index 6edeb98322..198df1ed0d 100644 --- a/dom/html/HTMLScriptElement.h +++ b/dom/html/HTMLScriptElement.h @@ -41,7 +41,7 @@ public: virtual bool GetScriptType(nsAString& type) override; virtual void GetScriptText(nsAString& text) override; virtual void GetScriptCharset(nsAString& charset) override; - virtual void FreezeUriAsyncDefer() override; + virtual void FreezeExecutionAttrs(nsIDocument* aOwnerDoc) override; virtual CORSMode GetCORSMode() const override; // nsIContent diff --git a/dom/script/ModuleLoadRequest.cpp b/dom/script/ModuleLoadRequest.cpp index d622143044..743f30fb97 100644 --- a/dom/script/ModuleLoadRequest.cpp +++ b/dom/script/ModuleLoadRequest.cpp @@ -17,26 +17,54 @@ NS_INTERFACE_MAP_END_INHERITING(ScriptLoadRequest) NS_IMPL_CYCLE_COLLECTION_INHERITED(ModuleLoadRequest, ScriptLoadRequest, mBaseURL, mLoader, - mParent, mModuleScript, mImports) NS_IMPL_ADDREF_INHERITED(ModuleLoadRequest, ScriptLoadRequest) NS_IMPL_RELEASE_INHERITED(ModuleLoadRequest, ScriptLoadRequest) -ModuleLoadRequest::ModuleLoadRequest(nsIScriptElement* aElement, +ModuleLoadRequest::ModuleLoadRequest(nsIURI* aURI, + nsIScriptElement* aElement, uint32_t aVersion, CORSMode aCORSMode, const SRIMetadata &aIntegrity, + nsIURI* aReferrer, + mozilla::net::ReferrerPolicy aReferrerPolicy, ScriptLoader* aLoader) : ScriptLoadRequest(ScriptKind::Module, + aURI, aElement, aVersion, aCORSMode, - aIntegrity), + aIntegrity, + aReferrer, + aReferrerPolicy), mIsTopLevel(true), - mLoader(aLoader) -{} + mLoader(aLoader), + mVisitedSet(new VisitedURLSet()) +{ + mVisitedSet->PutEntry(aURI); +} + +ModuleLoadRequest::ModuleLoadRequest(nsIURI* aURI, + ModuleLoadRequest* aParent) + : ScriptLoadRequest(ScriptKind::Module, + aURI, + aParent->mElement, + aParent->mJSVersion, + aParent->mCORSMode, + SRIMetadata(), + aParent->mURI, + aParent->mReferrerPolicy), + mIsTopLevel(false), + mLoader(aParent->mLoader), + mVisitedSet(aParent->mVisitedSet) +{ + MOZ_ASSERT(mVisitedSet->Contains(aURI)); + + mIsInline = false; + mScriptMode = aParent->mScriptMode; +} void ModuleLoadRequest::Cancel() { @@ -83,7 +111,7 @@ ModuleLoadRequest::ModuleLoaded() // been loaded. mModuleScript = mLoader->GetFetchedModule(mURI); - if (!mModuleScript || mModuleScript->IsErrored()) { + if (!mModuleScript || mModuleScript->HasParseError()) { ModuleErrored(); return; } @@ -95,7 +123,7 @@ void ModuleLoadRequest::ModuleErrored() { mLoader->CheckModuleDependenciesLoaded(this); - MOZ_ASSERT(!mModuleScript || mModuleScript->IsErrored()); + MOZ_ASSERT(!mModuleScript || mModuleScript->HasParseError()); CancelImports(); SetReady(); @@ -132,8 +160,7 @@ ModuleLoadRequest::LoadFinished() { mLoader->ProcessLoadedModuleTree(this); mLoader = nullptr; - mParent = nullptr; } } // dom namespace -} // mozilla namespace \ No newline at end of file +} // mozilla namespace diff --git a/dom/script/ModuleLoadRequest.h b/dom/script/ModuleLoadRequest.h index 7b06dd2cf3..eefb7dad5f 100644 --- a/dom/script/ModuleLoadRequest.h +++ b/dom/script/ModuleLoadRequest.h @@ -8,6 +8,7 @@ #define mozilla_dom_ModuleLoadRequest_h #include "mozilla/dom/ScriptLoader.h" +#include "nsURIHashKey.h" #include "mozilla/MozPromise.h" namespace mozilla { @@ -16,6 +17,16 @@ namespace dom { class ModuleScript; class ScriptLoader; +// A reference counted set of URLs we have visited in the process of loading a +// module graph. +class VisitedURLSet : public nsTHashtable +{ + NS_INLINE_DECL_REFCOUNTING(VisitedURLSet) + +private: + ~VisitedURLSet() = default; +}; + // A load request for a module, created for every top level module script and // every module import. Load request can share a ModuleScript if there are // multiple imports of the same module. @@ -31,12 +42,20 @@ public: NS_DECL_ISUPPORTS_INHERITED NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(ModuleLoadRequest, ScriptLoadRequest) - ModuleLoadRequest(nsIScriptElement* aElement, + // Create a top-level module load request. + ModuleLoadRequest(nsIURI* aURI, + nsIScriptElement* aElement, uint32_t aVersion, CORSMode aCORSMode, const SRIMetadata& aIntegrity, + nsIURI* aReferrer, + mozilla::net::ReferrerPolicy, ScriptLoader* aLoader); + // Create a module load request for an imported module. + ModuleLoadRequest(nsIURI* aURI, + ModuleLoadRequest* aParent); + bool IsTopLevel() const { return mIsTopLevel; } @@ -55,7 +74,7 @@ private: public: // Is this a request for a top level module script or an import? - bool mIsTopLevel; + const bool mIsTopLevel; // The base URL used for resolving relative module imports. nsCOMPtr mBaseURL; @@ -64,10 +83,6 @@ public: // finishes. RefPtr mLoader; - // The importing module, or nullptr for top level module scripts. Used to - // implement the ancestor list checked when fetching module dependencies. - RefPtr mParent; - // Set to a module script object after a successful load or nullptr on // failure. RefPtr mModuleScript; @@ -79,9 +94,13 @@ public: // Array of imported modules. nsTArray> mImports; + + // Set of module URLs visited while fetching the module graph this request is + // part of. + RefPtr mVisitedSet; }; } // dom namespace } // mozilla namespace -#endif // mozilla_dom_ModuleLoadRequest_h \ No newline at end of file +#endif // mozilla_dom_ModuleLoadRequest_h diff --git a/dom/script/ModuleScript.cpp b/dom/script/ModuleScript.cpp index 28b97a3cb5..1bf9d0b0fc 100644 --- a/dom/script/ModuleScript.cpp +++ b/dom/script/ModuleScript.cpp @@ -26,7 +26,8 @@ NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(ModuleScript) NS_IMPL_CYCLE_COLLECTION_UNLINK(mLoader) NS_IMPL_CYCLE_COLLECTION_UNLINK(mBaseURL) tmp->UnlinkModuleRecord(); - tmp->mError.setUndefined(); + tmp->mParseError.setUndefined(); + tmp->mErrorToRethrow.setUndefined(); NS_IMPL_CYCLE_COLLECTION_UNLINK_END NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(ModuleScript) @@ -35,7 +36,8 @@ NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END NS_IMPL_CYCLE_COLLECTION_TRACE_BEGIN(ModuleScript) NS_IMPL_CYCLE_COLLECTION_TRACE_JS_MEMBER_CALLBACK(mModuleRecord) - NS_IMPL_CYCLE_COLLECTION_TRACE_JS_MEMBER_CALLBACK(mError) + NS_IMPL_CYCLE_COLLECTION_TRACE_JS_MEMBER_CALLBACK(mParseError) + NS_IMPL_CYCLE_COLLECTION_TRACE_JS_MEMBER_CALLBACK(mErrorToRethrow) NS_IMPL_CYCLE_COLLECTION_TRACE_END NS_IMPL_CYCLE_COLLECTING_ADDREF(ModuleScript) @@ -48,7 +50,8 @@ ModuleScript::ModuleScript(ScriptLoader *aLoader, nsIURI* aBaseURL) MOZ_ASSERT(mLoader); MOZ_ASSERT(mBaseURL); MOZ_ASSERT(!mModuleRecord); - MOZ_ASSERT(mError.isUndefined()); + MOZ_ASSERT(!HasParseError()); + MOZ_ASSERT(!HasErrorToRethrow()); } void @@ -74,7 +77,8 @@ void ModuleScript::SetModuleRecord(JS::Handle aModuleRecord) { MOZ_ASSERT(!mModuleRecord); - MOZ_ASSERT(mError.isUndefined()); + MOZ_ASSERT(!HasParseError()); + MOZ_ASSERT(!HasErrorToRethrow()); mModuleRecord = aModuleRecord; @@ -85,37 +89,24 @@ ModuleScript::SetModuleRecord(JS::Handle aModuleRecord) } void -ModuleScript::SetPreInstantiationError(const JS::Value& aError) +ModuleScript::SetParseError(const JS::Value& aError) { MOZ_ASSERT(!aError.isUndefined()); + MOZ_ASSERT(!HasParseError()); + MOZ_ASSERT(!HasErrorToRethrow()); UnlinkModuleRecord(); - mError = aError; - + mParseError = aError; HoldJSObjects(this); } -bool -ModuleScript::IsErrored() const +void +ModuleScript::SetErrorToRethrow(const JS::Value& aError) { - if (!mModuleRecord) { - MOZ_ASSERT(!mError.isUndefined()); - return true; - } + MOZ_ASSERT(!aError.isUndefined()); + MOZ_ASSERT(!HasErrorToRethrow()); - return JS::IsModuleErrored(mModuleRecord); -} - -JS::Value -ModuleScript::Error() const -{ - MOZ_ASSERT(IsErrored()); - - if (!mModuleRecord) { - return mError; - } - - return JS::GetModuleError(mModuleRecord); + mErrorToRethrow = aError; } } // dom namespace diff --git a/dom/script/ModuleScript.h b/dom/script/ModuleScript.h index 5713598592..f765aa0fad 100644 --- a/dom/script/ModuleScript.h +++ b/dom/script/ModuleScript.h @@ -23,7 +23,8 @@ class ModuleScript final : public nsISupports RefPtr mLoader; nsCOMPtr mBaseURL; JS::Heap mModuleRecord; - JS::Heap mError; + JS::Heap mParseError; + JS::Heap mErrorToRethrow; ~ModuleScript(); @@ -35,14 +36,17 @@ public: nsIURI* aBaseURL); void SetModuleRecord(JS::Handle aModuleRecord); - void SetPreInstantiationError(const JS::Value& aError); + void SetParseError(const JS::Value& aError); + void SetErrorToRethrow(const JS::Value& aError); ScriptLoader* Loader() const { return mLoader; } JSObject* ModuleRecord() const { return mModuleRecord; } nsIURI* BaseURL() const { return mBaseURL; } - bool IsErrored() const; - JS::Value Error() const; + JS::Value ParseError() const { return mParseError; } + JS::Value ErrorToRethrow() const { return mErrorToRethrow; } + bool HasParseError() const { return !mParseError.isUndefined(); } + bool HasErrorToRethrow() const { return !mErrorToRethrow.isUndefined(); } void UnlinkModuleRecord(); }; diff --git a/dom/script/ScriptElement.cpp b/dom/script/ScriptElement.cpp index 0cb17dcb06..eb20dbf32e 100644 --- a/dom/script/ScriptElement.cpp +++ b/dom/script/ScriptElement.cpp @@ -21,11 +21,11 @@ using namespace mozilla::dom; NS_IMETHODIMP ScriptElement::ScriptAvailable(nsresult aResult, nsIScriptElement *aElement, - bool aIsInline, + bool aIsInlineClassicScript, nsIURI *aURI, int32_t aLineNo) { - if (!aIsInline && NS_FAILED(aResult)) { + if (!aIsInlineClassicScript && NS_FAILED(aResult)) { nsCOMPtr parser = do_QueryReferent(mCreatorParser); if (parser) { parser->PushDefinedInsertionPoint(); @@ -128,11 +128,11 @@ ScriptElement::MaybeProcessScript() return false; } - FreezeUriAsyncDefer(); + nsIDocument* ownerDoc = cont->OwnerDoc(); + FreezeExecutionAttrs(ownerDoc); mAlreadyStarted = true; - nsIDocument* ownerDoc = cont->OwnerDoc(); nsCOMPtr parser = ((nsIScriptElement*) this)->GetCreatorParser(); if (parser) { nsCOMPtr sink = parser->GetContentSink(); diff --git a/dom/script/ScriptLoader.cpp b/dom/script/ScriptLoader.cpp index a530989742..0052c72fe4 100644 --- a/dom/script/ScriptLoader.cpp +++ b/dom/script/ScriptLoader.cpp @@ -140,6 +140,18 @@ ScriptLoadRequest::AsModuleRequest() return static_cast(this); } +void +ScriptLoadRequest::SetScriptMode(bool aDeferAttr, bool aAsyncAttr) +{ + if (aAsyncAttr) { + mScriptMode = ScriptMode::eAsync; + } else if (aDeferAttr || IsModuleRequest()) { + mScriptMode = ScriptMode::eDeferred; + } else { + mScriptMode = ScriptMode::eBlocking; + } +} + ////////////////////////////////////////////////////////////// // ScriptLoadRequestList @@ -299,8 +311,12 @@ ScriptLoader::~ScriptLoader() //