Bug 1931295 - Implement Trusted Types support for Worker/SharedWorker's constructors for Window. r=smaug

Differential Revision: https://phabricator.services.mozilla.com/D229344
This commit is contained in:
Frédéric Wang
2024-11-29 12:18:21 +00:00
parent 6088184f0f
commit e218132855
9 changed files with 74 additions and 30 deletions

View File

@@ -239,6 +239,10 @@ MOZ_CAN_RUN_SCRIPT inline const nsAString* GetTrustedTypesCompliantString(
TrustedScriptOrNullIsEmptyString>) {
return aInput.IsNullIsEmptyString();
}
if constexpr (std::is_same_v<TrustedTypeOrStringArg,
TrustedScriptURLOrUSVString>) {
return aInput.IsUSVString();
}
if constexpr (std::is_same_v<TrustedTypeOrStringArg, const nsAString*>) {
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<TrustedTypeOrStringArg,
TrustedScriptURLOrUSVString>) {
return &aInput.GetAsUSVString();
}
if constexpr (std::is_same_v<TrustedTypeOrStringArg, const nsAString*>) {
return aInput;
}
@@ -283,7 +291,9 @@ MOZ_CAN_RUN_SCRIPT inline const nsAString* GetTrustedTypesCompliantString(
return aInput.IsTrustedScript();
}
if constexpr (std::is_same_v<TrustedTypeOrStringArg,
TrustedScriptURLOrString>) {
TrustedScriptURLOrString> ||
std::is_same_v<TrustedTypeOrStringArg,
TrustedScriptURLOrUSVString>) {
return aInput.IsTrustedScriptURL();
}
if constexpr (std::is_same_v<TrustedTypeOrStringArg, const nsAString*>) {
@@ -308,7 +318,9 @@ MOZ_CAN_RUN_SCRIPT inline const nsAString* GetTrustedTypesCompliantString(
return &aInput.GetAsTrustedScript().mData;
}
if constexpr (std::is_same_v<TrustedTypeOrStringArg,
TrustedScriptURLOrString>) {
TrustedScriptURLOrString> ||
std::is_same_v<TrustedTypeOrStringArg,
TrustedScriptURLOrUSVString>) {
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,

View File

@@ -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<nsAutoString>& aResultHolder, ErrorResult& aError);
MOZ_CAN_RUN_SCRIPT const nsAString* GetTrustedTypesCompliantString(
const TrustedScriptURLOrUSVString& aInput, const nsAString& aSink,
const nsAString& aSinkGroup, nsIGlobalObject& aGlobalObject,
Maybe<nsAutoString>& aResultHolder, ErrorResult& aError);
MOZ_CAN_RUN_SCRIPT const nsAString*
GetTrustedTypesCompliantStringForTrustedHTML(const nsAString& aInput,
const nsAString& aSink,

View File

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

View File

@@ -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();

View File

@@ -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> Worker::Constructor(const GlobalObject& aGlobal,
const nsAString& aScriptURL,
const WorkerOptions& aOptions,
ErrorResult& aRv) {
already_AddRefed<Worker> Worker::Constructor(
const GlobalObject& aGlobal, const TrustedScriptURLOrUSVString& aScriptURL,
const WorkerOptions& aOptions, ErrorResult& aRv) {
JSContext* cx = aGlobal.Context();
nsCOMPtr<nsIGlobalObject> globalObject =
@@ -45,8 +46,18 @@ already_AddRefed<Worker> Worker::Constructor(const GlobalObject& aGlobal,
return nullptr;
}
constexpr nsLiteralString sink = u"Worker constructor"_ns;
Maybe<nsAutoString> compliantStringHolder;
const nsAString* compliantString =
TrustedTypeUtils::GetTrustedTypesCompliantString(
aScriptURL, sink, kTrustedTypesOnlySinkGroup, *globalObject,
compliantStringHolder, aRv);
if (aRv.Failed()) {
return nullptr;
}
RefPtr<WorkerPrivate> 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())) {

View File

@@ -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<Worker> 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<Worker> Constructor(
const GlobalObject& aGlobal,
const TrustedScriptURLOrUSVString& aScriptURL,
const WorkerOptions& aOptions, ErrorResult& aRv);
JSObject* WrapObject(JSContext* aCx,
JS::Handle<JSObject*> aGivenProto) override;

View File

@@ -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> 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> SharedWorker::Constructor(
// static
already_AddRefed<SharedWorker> 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> SharedWorker::Constructor(
JSContext* cx = aGlobal.Context();
constexpr nsLiteralString sink = u"SharedWorker constructor"_ns;
Maybe<nsAutoString> compliantStringHolder;
nsCOMPtr<nsIGlobalObject> 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> SharedWorker::Constructor(
// We don't actually care about this MessageChannel, but we use it to 'steal'
// its 2 connected ports.
nsCOMPtr<nsIGlobalObject> global = do_QueryInterface(window);
RefPtr<MessageChannel> channel = MessageChannel::Constructor(global, aRv);
if (NS_WARN_IF(aRv.Failed())) {
return nullptr;
@@ -247,7 +260,7 @@ already_AddRefed<SharedWorker> 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,

View File

@@ -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<SharedWorker> 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<SharedWorker> 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<SharedWorker> Constructor(
const GlobalObject& aGlobal, const nsAString& aScriptURL,
MOZ_CAN_RUN_SCRIPT static already_AddRefed<SharedWorker> Constructor(
const GlobalObject& aGlobal,
const TrustedScriptURLOrUSVString& aScriptURL,
const WorkerOptions& aOptions, ErrorResult& aRv);
SharedWorker(nsPIDOMWindowInner* aWindow, SharedWorkerChild* aActor,

View File

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