From d8bbc7858622b6d9c278469aab701ca0b609cddf Mon Sep 17 00:00:00 2001 From: Daniel Baumann Date: Wed, 15 May 2024 05:35:49 +0200 Subject: Merging upstream version 126.0. Signed-off-by: Daniel Baumann --- dom/security/trusted-types/TrustedTypePolicy.cpp | 94 ++++++++++++++++++---- dom/security/trusted-types/TrustedTypePolicy.h | 49 ++++++++--- .../trusted-types/TrustedTypePolicyFactory.cpp | 48 ++++++++++- .../trusted-types/TrustedTypePolicyFactory.h | 21 ++--- dom/security/trusted-types/TrustedTypeUtils.h | 12 ++- 5 files changed, 174 insertions(+), 50 deletions(-) (limited to 'dom/security/trusted-types') diff --git a/dom/security/trusted-types/TrustedTypePolicy.cpp b/dom/security/trusted-types/TrustedTypePolicy.cpp index 3c4e758ed0..62c58ae1f6 100644 --- a/dom/security/trusted-types/TrustedTypePolicy.cpp +++ b/dom/security/trusted-types/TrustedTypePolicy.cpp @@ -6,38 +6,98 @@ #include "mozilla/dom/TrustedTypePolicy.h" -#include "mozilla/AlreadyAddRefed.h" +#include "mozilla/dom/DOMString.h" #include "mozilla/dom/TrustedTypePolicyFactory.h" #include "mozilla/dom/TrustedTypesBinding.h" +#include + namespace mozilla::dom { -NS_IMPL_CYCLE_COLLECTION_WRAPPERCACHE(TrustedTypePolicy, mParentObject) +NS_IMPL_CYCLE_COLLECTION_WRAPPERCACHE(TrustedTypePolicy, mParentObject, + mOptions.mCreateHTMLCallback, + mOptions.mCreateScriptCallback, + mOptions.mCreateScriptURLCallback) + +TrustedTypePolicy::TrustedTypePolicy(TrustedTypePolicyFactory* aParentObject, + const nsAString& aName, Options&& aOptions) + : mParentObject{aParentObject}, + mName{aName}, + mOptions{std::move(aOptions)} {} JSObject* TrustedTypePolicy::WrapObject(JSContext* aCx, JS::Handle aGivenProto) { return TrustedTypePolicy_Binding::Wrap(aCx, this, aGivenProto); } -UniquePtr TrustedTypePolicy::CreateHTML( - JSContext* aJSContext, const nsAString& aInput, - const Sequence& aArguments) const { - // TODO: implement the spec. - return MakeUnique(); +void TrustedTypePolicy::GetName(DOMString& aResult) const { + aResult.SetKnownLiveString(mName); } -UniquePtr TrustedTypePolicy::CreateScript( - JSContext* aJSContext, const nsAString& aInput, - const Sequence& aArguments) const { - // TODO: implement the spec. - return MakeUnique(); +#define IMPL_CREATE_TRUSTED_TYPE(_trustedTypeSuffix) \ + UniquePtr \ + TrustedTypePolicy::Create##_trustedTypeSuffix( \ + JSContext* aJSContext, const nsAString& aInput, \ + const Sequence& aArguments, ErrorResult& aErrorResult) \ + const { \ + /* Invoking the callback could delete the policy and hence the callback. \ + * Hence keep a strong reference to it on the stack. \ + */ \ + RefPtr callbackObject = \ + mOptions.mCreate##_trustedTypeSuffix##Callback; \ + \ + return CreateTrustedType( \ + callbackObject, aInput, aArguments, aErrorResult); \ + } + +IMPL_CREATE_TRUSTED_TYPE(HTML) +IMPL_CREATE_TRUSTED_TYPE(Script) +IMPL_CREATE_TRUSTED_TYPE(ScriptURL) + +template +UniquePtr TrustedTypePolicy::CreateTrustedType( + const RefPtr& aCallbackObject, const nsAString& aValue, + const Sequence& aArguments, ErrorResult& aErrorResult) const { + nsString policyValue; + DetermineTrustedPolicyValue(aCallbackObject, aValue, aArguments, true, + aErrorResult, policyValue); + + if (aErrorResult.Failed()) { + return nullptr; + } + + UniquePtr trustedObject = MakeUnique(std::move(policyValue)); + + // TODO: add special handling for `TrustedScript` when default policy support + // is added. + + return trustedObject; } -UniquePtr TrustedTypePolicy::CreateScriptURL( - JSContext* aJSContext, const nsAString& aInput, - const Sequence& aArguments) const { - // TODO: implement the spec. - return MakeUnique(); +template +void TrustedTypePolicy::DetermineTrustedPolicyValue( + const RefPtr& aCallbackObject, const nsAString& aValue, + const Sequence& aArguments, bool aThrowIfMissing, + ErrorResult& aErrorResult, nsAString& aResult) const { + if (!aCallbackObject) { + // The spec lacks a definition for stringifying null, see + // . + aResult = EmptyString(); + + if (aThrowIfMissing) { + aErrorResult.ThrowTypeError("Function missing."); + } + + return; + } + + nsString callbackResult; + aCallbackObject->Call(aValue, aArguments, callbackResult, aErrorResult, + nullptr, CallbackObject::eRethrowExceptions); + + if (!aErrorResult.Failed()) { + aResult = std::move(callbackResult); + } } } // namespace mozilla::dom diff --git a/dom/security/trusted-types/TrustedTypePolicy.h b/dom/security/trusted-types/TrustedTypePolicy.h index 22d99947b3..d677088285 100644 --- a/dom/security/trusted-types/TrustedTypePolicy.h +++ b/dom/security/trusted-types/TrustedTypePolicy.h @@ -9,19 +9,20 @@ #include "js/TypeDecls.h" #include "js/Value.h" +#include "mozilla/Attributes.h" #include "mozilla/RefPtr.h" #include "mozilla/UniquePtr.h" #include "mozilla/dom/BindingDeclarations.h" -#include "mozilla/dom/DOMString.h" #include "mozilla/dom/TrustedHTML.h" #include "mozilla/dom/TrustedScript.h" #include "mozilla/dom/TrustedScriptURL.h" #include "nsISupportsImpl.h" -#include "nsStringFwd.h" +#include "nsString.h" #include "nsWrapperCache.h" namespace mozilla::dom { +class DOMString; class TrustedTypePolicyFactory; // https://w3c.github.io/trusted-types/dist/spec/#trusted-type-policy @@ -30,8 +31,14 @@ class TrustedTypePolicy : public nsWrapperCache { NS_INLINE_DECL_CYCLE_COLLECTING_NATIVE_REFCOUNTING(TrustedTypePolicy) NS_DECL_CYCLE_COLLECTION_NATIVE_WRAPPERCACHE_CLASS(TrustedTypePolicy) - explicit TrustedTypePolicy(TrustedTypePolicyFactory* aParentObject) - : mParentObject{aParentObject} {} + struct Options { + RefPtr mCreateHTMLCallback; + RefPtr mCreateScriptCallback; + RefPtr mCreateScriptURLCallback; + }; + + TrustedTypePolicy(TrustedTypePolicyFactory* aParentObject, + const nsAString& aName, Options&& aOptions); // Required for Web IDL binding. TrustedTypePolicyFactory* GetParentObject() const { return mParentObject; } @@ -41,30 +48,46 @@ class TrustedTypePolicy : public nsWrapperCache { JS::Handle aGivenProto) override; // https://w3c.github.io/trusted-types/dist/spec/#trustedtypepolicy-name - void GetName(DOMString& aResult) const { - // TODO: impl. - } + void GetName(DOMString& aResult) const; // https://w3c.github.io/trusted-types/dist/spec/#dom-trustedtypepolicy-createhtml - UniquePtr CreateHTML( + MOZ_CAN_RUN_SCRIPT UniquePtr CreateHTML( JSContext* aJSContext, const nsAString& aInput, - const Sequence& aArguments) const; + const Sequence& aArguments, ErrorResult& aErrorResult) const; // https://w3c.github.io/trusted-types/dist/spec/#dom-trustedtypepolicy-createscript - UniquePtr CreateScript( + MOZ_CAN_RUN_SCRIPT UniquePtr CreateScript( JSContext* aJSContext, const nsAString& aInput, - const Sequence& aArguments) const; + const Sequence& aArguments, ErrorResult& aErrorResult) const; // https://w3c.github.io/trusted-types/dist/spec/#dom-trustedtypepolicy-createscripturl - UniquePtr CreateScriptURL( + MOZ_CAN_RUN_SCRIPT UniquePtr CreateScriptURL( JSContext* aJSContext, const nsAString& aInput, - const Sequence& aArguments) const; + const Sequence& aArguments, ErrorResult& aErrorResult) const; private: // Required because this class is ref-counted. virtual ~TrustedTypePolicy() = default; + // https://w3c.github.io/trusted-types/dist/spec/#abstract-opdef-create-a-trusted-type + template + MOZ_CAN_RUN_SCRIPT UniquePtr CreateTrustedType( + const RefPtr& aCallbackObject, const nsAString& aValue, + const Sequence& aArguments, ErrorResult& aErrorResult) const; + + // https://w3c.github.io/trusted-types/dist/spec/#abstract-opdef-get-trusted-type-policy-value + // + // @param aResult may become void. + template + MOZ_CAN_RUN_SCRIPT void DetermineTrustedPolicyValue( + const RefPtr& aCallbackObject, const nsAString& aValue, + const Sequence& aArguments, bool aThrowIfMissing, + ErrorResult& aErrorResult, nsAString& aResult) const; RefPtr mParentObject; + + const nsString mName; + + Options mOptions; }; } // namespace mozilla::dom diff --git a/dom/security/trusted-types/TrustedTypePolicyFactory.cpp b/dom/security/trusted-types/TrustedTypePolicyFactory.cpp index 448c51eb3b..c2544124e3 100644 --- a/dom/security/trusted-types/TrustedTypePolicyFactory.cpp +++ b/dom/security/trusted-types/TrustedTypePolicyFactory.cpp @@ -22,10 +22,50 @@ JSObject* TrustedTypePolicyFactory::WrapObject( already_AddRefed TrustedTypePolicyFactory::CreatePolicy( const nsAString& aPolicyName, const TrustedTypePolicyOptions& aPolicyOptions) { - // TODO: implement the spec. - return MakeRefPtr(this).forget(); + // TODO: add CSP support. + + // TODO: add default policy support; this requires accessing the default + // policy on the C++ side, hence already now ref-counting policy + // objects. + + TrustedTypePolicy::Options options; + + if (aPolicyOptions.mCreateHTML.WasPassed()) { + options.mCreateHTMLCallback = &aPolicyOptions.mCreateHTML.Value(); + } + + if (aPolicyOptions.mCreateScript.WasPassed()) { + options.mCreateScriptCallback = &aPolicyOptions.mCreateScript.Value(); + } + + if (aPolicyOptions.mCreateScriptURL.WasPassed()) { + options.mCreateScriptURLCallback = &aPolicyOptions.mCreateScriptURL.Value(); + } + + RefPtr policy = + MakeRefPtr(this, aPolicyName, std::move(options)); + + mCreatedPolicyNames.AppendElement(aPolicyName); + + return policy.forget(); } +#define IS_TRUSTED_TYPE_IMPL(_trustedTypeSuffix) \ + bool TrustedTypePolicyFactory::Is##_trustedTypeSuffix( \ + JSContext*, const JS::Handle& aValue) const { \ + /** \ + * No need to check the internal slot. \ + * Ensured by the corresponding test: \ + * \ + */ \ + return aValue.isObject() && \ + IS_INSTANCE_OF(Trusted##_trustedTypeSuffix, &aValue.toObject()); \ + } + +IS_TRUSTED_TYPE_IMPL(HTML); +IS_TRUSTED_TYPE_IMPL(Script); +IS_TRUSTED_TYPE_IMPL(ScriptURL); + UniquePtr TrustedTypePolicyFactory::EmptyHTML() { // Preserving the wrapper ensures: // ``` @@ -37,14 +77,14 @@ UniquePtr TrustedTypePolicyFactory::EmptyHTML() { // multiple emptyHML objects. Both, the JS- and the C++-objects. dom::PreserveWrapper(this); - return MakeUnique(); + return MakeUnique(EmptyString()); } UniquePtr TrustedTypePolicyFactory::EmptyScript() { // See the explanation in `EmptyHTML()`. dom::PreserveWrapper(this); - return MakeUnique(); + return MakeUnique(EmptyString()); } } // namespace mozilla::dom diff --git a/dom/security/trusted-types/TrustedTypePolicyFactory.h b/dom/security/trusted-types/TrustedTypePolicyFactory.h index fea5312cf8..61dae94ed9 100644 --- a/dom/security/trusted-types/TrustedTypePolicyFactory.h +++ b/dom/security/trusted-types/TrustedTypePolicyFactory.h @@ -8,13 +8,16 @@ #define DOM_SECURITY_TRUSTED_TYPES_TRUSTEDTYPEPOLICYFACTORY_H_ #include "js/TypeDecls.h" +#include "mozilla/dom/BindingUtils.h" #include "mozilla/dom/TrustedHTML.h" #include "mozilla/dom/TrustedScript.h" +#include "mozilla/dom/TrustedScriptURL.h" #include "mozilla/RefPtr.h" #include "mozilla/UniquePtr.h" #include "nsIGlobalObject.h" #include "nsISupportsImpl.h" #include "nsStringFwd.h" +#include "nsTArray.h" #include "nsWrapperCache.h" template @@ -48,25 +51,15 @@ class TrustedTypePolicyFactory : public nsWrapperCache { const TrustedTypePolicyOptions& aPolicyOptions); // https://w3c.github.io/trusted-types/dist/spec/#dom-trustedtypepolicyfactory-ishtml - bool IsHTML(JSContext* aJSContext, - const JS::Handle& aValue) const { - // TODO: impl. - return false; - } + bool IsHTML(JSContext* aJSContext, const JS::Handle& aValue) const; // https://w3c.github.io/trusted-types/dist/spec/#dom-trustedtypepolicyfactory-isscript bool IsScript(JSContext* aJSContext, - const JS::Handle& aValue) const { - // TODO: impl. - return false; - } + const JS::Handle& aValue) const; // https://w3c.github.io/trusted-types/dist/spec/#dom-trustedtypepolicyfactory-isscripturl bool IsScriptURL(JSContext* aJSContext, - const JS::Handle& aValue) const { - // TODO: impl. - return false; - } + const JS::Handle& aValue) const; // https://w3c.github.io/trusted-types/dist/spec/#dom-trustedtypepolicyfactory-emptyhtml UniquePtr EmptyHTML(); @@ -98,6 +91,8 @@ class TrustedTypePolicyFactory : public nsWrapperCache { virtual ~TrustedTypePolicyFactory() = default; RefPtr mGlobalObject; + + nsTArray mCreatedPolicyNames; }; } // namespace mozilla::dom diff --git a/dom/security/trusted-types/TrustedTypeUtils.h b/dom/security/trusted-types/TrustedTypeUtils.h index 90ffc50c38..508c26c3c2 100644 --- a/dom/security/trusted-types/TrustedTypeUtils.h +++ b/dom/security/trusted-types/TrustedTypeUtils.h @@ -10,20 +10,26 @@ #include "mozilla/dom/DOMString.h" #include "mozilla/dom/NonRefcountedDOMObject.h" #include "mozilla/dom/TrustedTypesBinding.h" -#include "nsStringFwd.h" +#include "nsString.h" #define DECL_TRUSTED_TYPE_CLASS(_class) \ class _class : public mozilla::dom::NonRefcountedDOMObject { \ public: \ + explicit _class(const nsAString& aData) : mData{aData} {} \ + \ /* Required for Web IDL binding. */ \ bool WrapObject(JSContext* aCx, JS::Handle aGivenProto, \ JS::MutableHandle aObject); \ \ - void Stringify(nsAString& aResult) const { /* TODO: impl. */ \ + void Stringify(DOMString& aResult) const { \ + aResult.SetKnownLiveString(mData); \ } \ \ - void ToJSON(DOMString& aResult) const { /* TODO: impl. */ \ + void ToJSON(DOMString& aResult) const { \ + aResult.SetKnownLiveString(mData); \ } \ + \ + const nsString mData; \ }; #define IMPL_TRUSTED_TYPE_CLASS(_class) \ -- cgit v1.2.3