diff --git a/dom/security/trusted-types/TrustedTypeUtils.cpp b/dom/security/trusted-types/TrustedTypeUtils.cpp index c3512f949259..9f2d92c408e8 100644 --- a/dom/security/trusted-types/TrustedTypeUtils.cpp +++ b/dom/security/trusted-types/TrustedTypeUtils.cpp @@ -239,6 +239,10 @@ MOZ_CAN_RUN_SCRIPT inline const nsAString* GetTrustedTypesCompliantString( TrustedScriptOrNullIsEmptyString>) { return aInput.IsNullIsEmptyString(); } + if constexpr (std::is_same_v) { + return aInput.IsUSVString(); + } if constexpr (std::is_same_v) { Unused << aInput; return true; @@ -262,6 +266,10 @@ MOZ_CAN_RUN_SCRIPT inline const nsAString* GetTrustedTypesCompliantString( TrustedScriptOrNullIsEmptyString>) { return &aInput.GetAsNullIsEmptyString(); } + if constexpr (std::is_same_v) { + return &aInput.GetAsUSVString(); + } if constexpr (std::is_same_v) { return aInput; } @@ -283,7 +291,9 @@ MOZ_CAN_RUN_SCRIPT inline const nsAString* GetTrustedTypesCompliantString( return aInput.IsTrustedScript(); } if constexpr (std::is_same_v) { + TrustedScriptURLOrString> || + std::is_same_v) { return aInput.IsTrustedScriptURL(); } if constexpr (std::is_same_v) { @@ -308,7 +318,9 @@ MOZ_CAN_RUN_SCRIPT inline const nsAString* GetTrustedTypesCompliantString( return &aInput.GetAsTrustedScript().mData; } if constexpr (std::is_same_v) { + TrustedScriptURLOrString> || + std::is_same_v) { return &aInput.GetAsTrustedScriptURL().mData; } Unused << aInput; @@ -433,6 +445,8 @@ IMPL_GET_TRUSTED_TYPES_COMPLIANT_STRING(FunctionOrTrustedScriptOrString, TrustedScript, nsIGlobalObject); IMPL_GET_TRUSTED_TYPES_COMPLIANT_STRING(TrustedScriptURLOrString, TrustedScriptURL, const nsINode); +IMPL_GET_TRUSTED_TYPES_COMPLIANT_STRING(TrustedScriptURLOrUSVString, + TrustedScriptURL, nsIGlobalObject); MOZ_CAN_RUN_SCRIPT const nsAString* GetTrustedTypesCompliantStringForTrustedHTML(const nsAString& aInput, diff --git a/dom/security/trusted-types/TrustedTypeUtils.h b/dom/security/trusted-types/TrustedTypeUtils.h index 95450941c9c7..717fe2e84c97 100644 --- a/dom/security/trusted-types/TrustedTypeUtils.h +++ b/dom/security/trusted-types/TrustedTypeUtils.h @@ -34,6 +34,7 @@ class TrustedScriptOrNullIsEmptyString; class FunctionOrTrustedScriptOrString; class TrustedScriptURL; class TrustedScriptURLOrString; +class TrustedScriptURLOrUSVString; class TrustedHTMLOrTrustedScriptOrTrustedScriptURLOrString; namespace TrustedTypeUtils { @@ -92,6 +93,10 @@ MOZ_CAN_RUN_SCRIPT const nsAString* GetTrustedTypesCompliantString( const TrustedScriptURLOrString& aInput, const nsAString& aSink, const nsAString& aSinkGroup, const nsINode& aNode, Maybe& aResultHolder, ErrorResult& aError); +MOZ_CAN_RUN_SCRIPT const nsAString* GetTrustedTypesCompliantString( + const TrustedScriptURLOrUSVString& aInput, const nsAString& aSink, + const nsAString& aSinkGroup, nsIGlobalObject& aGlobalObject, + Maybe& aResultHolder, ErrorResult& aError); MOZ_CAN_RUN_SCRIPT const nsAString* GetTrustedTypesCompliantStringForTrustedHTML(const nsAString& aInput, const nsAString& aSink, diff --git a/dom/webidl/SharedWorker.webidl b/dom/webidl/SharedWorker.webidl index 3a4d9b3ebefe..42ddd5f05cd3 100644 --- a/dom/webidl/SharedWorker.webidl +++ b/dom/webidl/SharedWorker.webidl @@ -7,7 +7,7 @@ [Exposed=Window] interface SharedWorker : EventTarget { [Throws] - constructor(USVString scriptURL, + constructor((TrustedScriptURL or USVString) scriptURL, optional (DOMString or WorkerOptions) options = {}); readonly attribute MessagePort port; diff --git a/dom/webidl/Worker.webidl b/dom/webidl/Worker.webidl index f4ff5c4dc0c9..0296fbea3b59 100644 --- a/dom/webidl/Worker.webidl +++ b/dom/webidl/Worker.webidl @@ -15,7 +15,7 @@ [Exposed=(Window,DedicatedWorker,SharedWorker)] interface Worker : EventTarget { [Throws] - constructor(USVString scriptURL, optional WorkerOptions options = {}); + constructor((TrustedScriptURL or USVString) scriptURL, optional WorkerOptions options = {}); undefined terminate(); diff --git a/dom/workers/Worker.cpp b/dom/workers/Worker.cpp index 6d85948d96fe..154042689f02 100644 --- a/dom/workers/Worker.cpp +++ b/dom/workers/Worker.cpp @@ -21,6 +21,8 @@ #include "nsDebug.h" #include "mozilla/dom/WorkerStatus.h" #include "mozilla/RefPtr.h" +#include "mozilla/dom/TrustedTypeUtils.h" +#include "mozilla/dom/TrustedTypesConstants.h" #ifdef XP_WIN # undef PostMessage @@ -29,10 +31,9 @@ namespace mozilla::dom { /* static */ -already_AddRefed Worker::Constructor(const GlobalObject& aGlobal, - const nsAString& aScriptURL, - const WorkerOptions& aOptions, - ErrorResult& aRv) { +already_AddRefed Worker::Constructor( + const GlobalObject& aGlobal, const TrustedScriptURLOrUSVString& aScriptURL, + const WorkerOptions& aOptions, ErrorResult& aRv) { JSContext* cx = aGlobal.Context(); nsCOMPtr globalObject = @@ -45,8 +46,18 @@ already_AddRefed Worker::Constructor(const GlobalObject& aGlobal, return nullptr; } + constexpr nsLiteralString sink = u"Worker constructor"_ns; + Maybe compliantStringHolder; + const nsAString* compliantString = + TrustedTypeUtils::GetTrustedTypesCompliantString( + aScriptURL, sink, kTrustedTypesOnlySinkGroup, *globalObject, + compliantStringHolder, aRv); + if (aRv.Failed()) { + return nullptr; + } + RefPtr workerPrivate = WorkerPrivate::Constructor( - cx, aScriptURL, false /* aIsChromeWorker */, WorkerKindDedicated, + cx, *compliantString, false /* aIsChromeWorker */, WorkerKindDedicated, aOptions.mCredentials, aOptions.mType, aOptions.mName, VoidCString(), nullptr /*aLoadInfo */, aRv); if (NS_WARN_IF(aRv.Failed())) { diff --git a/dom/workers/Worker.h b/dom/workers/Worker.h index 6a0e295fc264..1e0fdc8d003f 100644 --- a/dom/workers/Worker.h +++ b/dom/workers/Worker.h @@ -24,15 +24,18 @@ struct StructuredSerializeOptions; struct WorkerOptions; class WorkerPrivate; +class TrustedScriptURLOrUSVString; + class Worker : public DOMEventTargetHelper, public SupportsWeakPtr { public: NS_DECL_ISUPPORTS_INHERITED NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS_INHERITED(Worker, DOMEventTargetHelper) - static already_AddRefed Constructor(const GlobalObject& aGlobal, - const nsAString& aScriptURL, - const WorkerOptions& aOptions, - ErrorResult& aRv); + // TODO(bug 1749042): Mark as MOZ_CAN_RUN_SCRIPT when IDL constructors can be. + MOZ_CAN_RUN_SCRIPT_BOUNDARY static already_AddRefed Constructor( + const GlobalObject& aGlobal, + const TrustedScriptURLOrUSVString& aScriptURL, + const WorkerOptions& aOptions, ErrorResult& aRv); JSObject* WrapObject(JSContext* aCx, JS::Handle aGivenProto) override; diff --git a/dom/workers/sharedworkers/SharedWorker.cpp b/dom/workers/sharedworkers/SharedWorker.cpp index 5bad6ab40e98..4dfd500fb570 100644 --- a/dom/workers/sharedworkers/SharedWorker.cpp +++ b/dom/workers/sharedworkers/SharedWorker.cpp @@ -19,6 +19,8 @@ #include "mozilla/dom/RemoteWorkerTypes.h" #include "mozilla/dom/SharedWorkerBinding.h" #include "mozilla/dom/SharedWorkerChild.h" +#include "mozilla/dom/TrustedTypeUtils.h" +#include "mozilla/dom/TrustedTypesConstants.h" #include "mozilla/dom/WorkerBinding.h" #include "mozilla/dom/WorkerLoadInfo.h" #include "mozilla/dom/WorkerPrivate.h" @@ -58,7 +60,7 @@ SharedWorker::~SharedWorker() { // static already_AddRefed SharedWorker::Constructor( - const GlobalObject& aGlobal, const nsAString& aScriptURL, + const GlobalObject& aGlobal, const TrustedScriptURLOrUSVString& aScriptURL, const StringOrWorkerOptions& aOptions, ErrorResult& aRv) { AssertIsOnMainThread(); @@ -74,7 +76,7 @@ already_AddRefed SharedWorker::Constructor( // static already_AddRefed SharedWorker::Constructor( - const GlobalObject& aGlobal, const nsAString& aScriptURL, + const GlobalObject& aGlobal, const TrustedScriptURLOrUSVString& aScriptURL, const WorkerOptions& aOptions, ErrorResult& aRv) { AssertIsOnMainThread(); @@ -130,10 +132,22 @@ already_AddRefed SharedWorker::Constructor( JSContext* cx = aGlobal.Context(); + constexpr nsLiteralString sink = u"SharedWorker constructor"_ns; + Maybe compliantStringHolder; + nsCOMPtr global = do_QueryInterface(window); + const nsAString* compliantString = + TrustedTypeUtils::GetTrustedTypesCompliantString( + aScriptURL, sink, kTrustedTypesOnlySinkGroup, *global, + compliantStringHolder, aRv); + if (aRv.Failed()) { + return nullptr; + } + WorkerLoadInfo loadInfo; - aRv = WorkerPrivate::GetLoadInfo( - cx, window, nullptr, aScriptURL, aOptions.mType, aOptions.mCredentials, - false, WorkerPrivate::OverrideLoadGroup, WorkerKindShared, &loadInfo); + aRv = WorkerPrivate::GetLoadInfo(cx, window, nullptr, *compliantString, + aOptions.mType, aOptions.mCredentials, false, + WorkerPrivate::OverrideLoadGroup, + WorkerKindShared, &loadInfo); if (NS_WARN_IF(aRv.Failed())) { return nullptr; } @@ -203,7 +217,6 @@ already_AddRefed SharedWorker::Constructor( // We don't actually care about this MessageChannel, but we use it to 'steal' // its 2 connected ports. - nsCOMPtr global = do_QueryInterface(window); RefPtr channel = MessageChannel::Constructor(global, aRv); if (NS_WARN_IF(aRv.Failed())) { return nullptr; @@ -247,7 +260,7 @@ already_AddRefed SharedWorker::Constructor( } RemoteWorkerData remoteWorkerData( - nsString(aScriptURL), baseURL, resolvedScriptURL, aOptions, + nsString(*compliantString), baseURL, resolvedScriptURL, aOptions, loadingPrincipalInfo, principalInfo, partitionedPrincipalInfo, loadInfo.mUseRegularPrincipal, loadInfo.mUsingStorageAccess, cjsData, loadInfo.mDomain, isSecureContext, ipcClientInfo, loadInfo.mReferrerInfo, diff --git a/dom/workers/sharedworkers/SharedWorker.h b/dom/workers/sharedworkers/SharedWorker.h index 300c799e8120..c70d15d46e7d 100644 --- a/dom/workers/sharedworkers/SharedWorker.h +++ b/dom/workers/sharedworkers/SharedWorker.h @@ -28,6 +28,7 @@ class StringOrWorkerOptions; struct WorkerOptions; class SharedWorkerChild; +class TrustedScriptURLOrUSVString; /** * DOM binding. Holds a SharedWorkerChild. Must exist on the main thread because @@ -44,8 +45,10 @@ class SharedWorker final : public DOMEventTargetHelper { bool mFrozen; public: - static already_AddRefed Constructor( - const GlobalObject& aGlobal, const nsAString& aScriptURL, + // TODO(bug 1749042): Mark as MOZ_CAN_RUN_SCRIPT when IDL constructors can be. + MOZ_CAN_RUN_SCRIPT_BOUNDARY static already_AddRefed Constructor( + const GlobalObject& aGlobal, + const TrustedScriptURLOrUSVString& aScriptURL, const StringOrWorkerOptions& aOptions, ErrorResult& aRv); MessagePort* Port(); @@ -81,8 +84,9 @@ class SharedWorker final : public DOMEventTargetHelper { void Thaw(); private: - static already_AddRefed Constructor( - const GlobalObject& aGlobal, const nsAString& aScriptURL, + MOZ_CAN_RUN_SCRIPT static already_AddRefed Constructor( + const GlobalObject& aGlobal, + const TrustedScriptURLOrUSVString& aScriptURL, const WorkerOptions& aOptions, ErrorResult& aRv); SharedWorker(nsPIDOMWindowInner* aWindow, SharedWorkerChild* aActor, diff --git a/testing/web-platform/meta/trusted-types/worker-constructor.https.html.ini b/testing/web-platform/meta/trusted-types/worker-constructor.https.html.ini index 6f98cb7394d2..69ec6eee4dfd 100644 --- a/testing/web-platform/meta/trusted-types/worker-constructor.https.html.ini +++ b/testing/web-platform/meta/trusted-types/worker-constructor.https.html.ini @@ -1,12 +1,6 @@ [worker-constructor.https.html] expected: if tsan: CRASH - [Block Worker creation via string] - expected: FAIL - - [Block SharedWorker creation via string] - expected: FAIL - [Block ServiceWorker creation via String] expected: FAIL