Bug 1906650: part 1) Make TrustedHTML and analogous classes cycle-collected. r=peterv

Union types in WebIDL for variadic arguments require reference-counting
(https://firefox-source-docs.mozilla.org/dom/webIdlBindings/index.html#union-types).

If this results in an efficiency problem, one might try to change union
types to allow non-reference-counted members. For now, this was agreed
with peterv.

Cycle-collectedness is required from auto-generated <ElementBinding.cpp>.

Differential Revision: https://phabricator.services.mozilla.com/D216169
This commit is contained in:
Mirko Brodesser 2024-07-24 08:02:48 +00:00
parent 27f6dc381c
commit 1801b9b285
5 changed files with 28 additions and 18 deletions

View File

@ -35,7 +35,7 @@ void TrustedTypePolicy::GetName(DOMString& aResult) const {
}
#define IMPL_CREATE_TRUSTED_TYPE(_trustedTypeSuffix) \
UniquePtr<Trusted##_trustedTypeSuffix> \
already_AddRefed<Trusted##_trustedTypeSuffix> \
TrustedTypePolicy::Create##_trustedTypeSuffix( \
JSContext* aJSContext, const nsAString& aInput, \
const Sequence<JS::Value>& aArguments, ErrorResult& aErrorResult) \
@ -55,7 +55,7 @@ IMPL_CREATE_TRUSTED_TYPE(Script)
IMPL_CREATE_TRUSTED_TYPE(ScriptURL)
template <typename T, typename CallbackObject>
UniquePtr<T> TrustedTypePolicy::CreateTrustedType(
already_AddRefed<T> TrustedTypePolicy::CreateTrustedType(
const RefPtr<CallbackObject>& aCallbackObject, const nsAString& aValue,
const Sequence<JS::Value>& aArguments, ErrorResult& aErrorResult) const {
nsString policyValue;
@ -70,12 +70,12 @@ UniquePtr<T> TrustedTypePolicy::CreateTrustedType(
policyValue = EmptyString();
}
UniquePtr<T> trustedObject = MakeUnique<T>(std::move(policyValue));
RefPtr<T> trustedObject = MakeRefPtr<T>(std::move(policyValue));
// TODO: add special handling for `TrustedScript` when default policy support
// is added.
return trustedObject;
return trustedObject.forget();
}
template <typename CallbackObject>

View File

@ -9,9 +9,9 @@
#include "js/TypeDecls.h"
#include "js/Value.h"
#include "mozilla/AlreadyAddRefed.h"
#include "mozilla/Attributes.h"
#include "mozilla/RefPtr.h"
#include "mozilla/UniquePtr.h"
#include "mozilla/dom/BindingDeclarations.h"
#include "mozilla/dom/TrustedHTML.h"
#include "mozilla/dom/TrustedScript.h"
@ -51,17 +51,17 @@ class TrustedTypePolicy : public nsWrapperCache {
void GetName(DOMString& aResult) const;
// https://w3c.github.io/trusted-types/dist/spec/#dom-trustedtypepolicy-createhtml
MOZ_CAN_RUN_SCRIPT UniquePtr<TrustedHTML> CreateHTML(
MOZ_CAN_RUN_SCRIPT already_AddRefed<TrustedHTML> CreateHTML(
JSContext* aJSContext, const nsAString& aInput,
const Sequence<JS::Value>& aArguments, ErrorResult& aErrorResult) const;
// https://w3c.github.io/trusted-types/dist/spec/#dom-trustedtypepolicy-createscript
MOZ_CAN_RUN_SCRIPT UniquePtr<TrustedScript> CreateScript(
MOZ_CAN_RUN_SCRIPT already_AddRefed<TrustedScript> CreateScript(
JSContext* aJSContext, const nsAString& aInput,
const Sequence<JS::Value>& aArguments, ErrorResult& aErrorResult) const;
// https://w3c.github.io/trusted-types/dist/spec/#dom-trustedtypepolicy-createscripturl
MOZ_CAN_RUN_SCRIPT UniquePtr<TrustedScriptURL> CreateScriptURL(
MOZ_CAN_RUN_SCRIPT already_AddRefed<TrustedScriptURL> CreateScriptURL(
JSContext* aJSContext, const nsAString& aInput,
const Sequence<JS::Value>& aArguments, ErrorResult& aErrorResult) const;
@ -71,7 +71,7 @@ class TrustedTypePolicy : public nsWrapperCache {
// https://w3c.github.io/trusted-types/dist/spec/#abstract-opdef-create-a-trusted-type
template <typename T, typename CallbackObject>
MOZ_CAN_RUN_SCRIPT UniquePtr<T> CreateTrustedType(
MOZ_CAN_RUN_SCRIPT already_AddRefed<T> CreateTrustedType(
const RefPtr<CallbackObject>& aCallbackObject, const nsAString& aValue,
const Sequence<JS::Value>& aArguments, ErrorResult& aErrorResult) const;

View File

@ -161,7 +161,7 @@ IS_TRUSTED_TYPE_IMPL(HTML);
IS_TRUSTED_TYPE_IMPL(Script);
IS_TRUSTED_TYPE_IMPL(ScriptURL);
UniquePtr<TrustedHTML> TrustedTypePolicyFactory::EmptyHTML() {
already_AddRefed<TrustedHTML> TrustedTypePolicyFactory::EmptyHTML() {
// Preserving the wrapper ensures:
// ```
// const e = trustedTypes.emptyHTML;
@ -172,14 +172,14 @@ UniquePtr<TrustedHTML> TrustedTypePolicyFactory::EmptyHTML() {
// multiple emptyHML objects. Both, the JS- and the C++-objects.
dom::PreserveWrapper(this);
return MakeUnique<TrustedHTML>(EmptyString());
return MakeRefPtr<TrustedHTML>(EmptyString()).forget();
}
UniquePtr<TrustedScript> TrustedTypePolicyFactory::EmptyScript() {
already_AddRefed<TrustedScript> TrustedTypePolicyFactory::EmptyScript() {
// See the explanation in `EmptyHTML()`.
dom::PreserveWrapper(this);
return MakeUnique<TrustedScript>(EmptyString());
return MakeRefPtr<TrustedScript>(EmptyString()).forget();
}
} // namespace mozilla::dom

View File

@ -12,8 +12,8 @@
#include "mozilla/dom/TrustedHTML.h"
#include "mozilla/dom/TrustedScript.h"
#include "mozilla/dom/TrustedScriptURL.h"
#include "mozilla/AlreadyAddRefed.h"
#include "mozilla/RefPtr.h"
#include "mozilla/UniquePtr.h"
#include "nsIGlobalObject.h"
#include "nsISupportsImpl.h"
#include "nsStringFwd.h"
@ -64,10 +64,10 @@ class TrustedTypePolicyFactory : public nsWrapperCache {
const JS::Handle<JS::Value>& aValue) const;
// https://w3c.github.io/trusted-types/dist/spec/#dom-trustedtypepolicyfactory-emptyhtml
UniquePtr<TrustedHTML> EmptyHTML();
already_AddRefed<TrustedHTML> EmptyHTML();
// https://w3c.github.io/trusted-types/dist/spec/#dom-trustedtypepolicyfactory-emptyscript
UniquePtr<TrustedScript> EmptyScript();
already_AddRefed<TrustedScript> EmptyScript();
// https://w3c.github.io/trusted-types/dist/spec/#dom-trustedtypepolicyfactory-getattributetype
void GetAttributeType(const nsAString& aTagName, const nsAString& aAttribute,

View File

@ -8,13 +8,17 @@
#define DOM_SECURITY_TRUSTED_TYPES_TRUSTEDTYPEUTILS_H_
#include "mozilla/dom/DOMString.h"
#include "mozilla/dom/NonRefcountedDOMObject.h"
#include "mozilla/dom/TrustedTypesBinding.h"
#include "nsCycleCollectionParticipant.h"
#include "nsISupportsImpl.h"
#include "nsString.h"
#define DECL_TRUSTED_TYPE_CLASS(_class) \
class _class : public mozilla::dom::NonRefcountedDOMObject { \
class _class { \
public: \
NS_INLINE_DECL_CYCLE_COLLECTING_NATIVE_REFCOUNTING(_class) \
NS_DECL_CYCLE_COLLECTION_NATIVE_CLASS(_class) \
\
explicit _class(const nsAString& aData) : mData{aData} {} \
\
/* Required for Web IDL binding. */ \
@ -30,9 +34,15 @@
} \
\
const nsString mData; \
\
private: \
/* Required because the class is cycle-colleceted. */ \
~_class() = default; \
};
#define IMPL_TRUSTED_TYPE_CLASS(_class) \
NS_IMPL_CYCLE_COLLECTION(_class) \
\
bool _class::WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto, \
JS::MutableHandle<JSObject*> aObject) { \
return _class##_Binding::Wrap(aCx, this, aGivenProto, aObject); \