From 523f5e3554a1672c06f13d7eaf09e59b5b2866ce Mon Sep 17 00:00:00 2001 From: Nika Layzell Date: Wed, 12 Oct 2022 23:57:23 +0000 Subject: [PATCH] Bug 1793995 - Part 4: Split out the threadsafe core from MatchGlob, r=kmag The outer cycle-collected wrapper type is unfortunately still required by WebIDL in order to keep the JS API working. Differential Revision: https://phabricator.services.mozilla.com/D158882 --- toolkit/components/extensions/MatchGlob.h | 66 ++++++++++++------- .../components/extensions/MatchPattern.cpp | 45 +++++++------ toolkit/components/extensions/MatchPattern.h | 2 +- .../extensions/WebExtensionPolicy.cpp | 11 ++-- 4 files changed, 73 insertions(+), 51 deletions(-) diff --git a/toolkit/components/extensions/MatchGlob.h b/toolkit/components/extensions/MatchGlob.h index 0d3bafa70197..cfbb5f2f16c5 100644 --- a/toolkit/components/extensions/MatchGlob.h +++ b/toolkit/components/extensions/MatchGlob.h @@ -23,15 +23,11 @@ namespace extensions { class MatchPattern; -class MatchGlob final : public nsISupports, public nsWrapperCache { +class MatchGlobCore final { public: - NS_DECL_CYCLE_COLLECTING_ISUPPORTS - NS_DECL_CYCLE_COLLECTION_WRAPPERCACHE_CLASS(MatchGlob) + NS_INLINE_DECL_THREADSAFE_REFCOUNTING(MatchGlobCore) - static already_AddRefed Constructor(dom::GlobalObject& aGlobal, - const nsACString& aGlob, - bool aAllowQuestion, - ErrorResult& aRv); + MatchGlobCore(const nsACString& aGlob, bool aAllowQuestion, ErrorResult& aRv); bool Matches(const nsACString& aString) const; @@ -39,21 +35,8 @@ class MatchGlob final : public nsISupports, public nsWrapperCache { void GetGlob(nsACString& aGlob) const { aGlob = mGlob; } - nsISupports* GetParentObject() const { return mParent; } - - virtual JSObject* WrapObject(JSContext* aCx, - JS::Handle aGivenProto) override; - - protected: - virtual ~MatchGlob(); - private: - friend class MatchPattern; - - explicit MatchGlob(nsISupports* aParent, const nsACString& aGlob, - bool aAllowQuestion, ErrorResult& aRv); - - nsCOMPtr mParent; + ~MatchGlobCore() = default; // The original glob string that this glob object represents. const nsCString mGlob; @@ -71,7 +54,44 @@ class MatchGlob final : public nsISupports, public nsWrapperCache { RustRegex mRegExp; }; -class MatchGlobSet final : public CopyableTArray> { +class MatchGlob final : public nsISupports, public nsWrapperCache { + public: + NS_DECL_CYCLE_COLLECTING_ISUPPORTS + NS_DECL_CYCLE_COLLECTION_WRAPPERCACHE_CLASS(MatchGlob) + + static already_AddRefed Constructor(dom::GlobalObject& aGlobal, + const nsACString& aGlob, + bool aAllowQuestion, + ErrorResult& aRv); + + explicit MatchGlob(nsISupports* aParent, + already_AddRefed aCore) + : mParent(aParent), mCore(std::move(aCore)) {} + + bool Matches(const nsACString& aString) const { + return Core()->Matches(aString); + } + + bool IsWildcard() const { return Core()->IsWildcard(); } + + void GetGlob(nsACString& aGlob) const { Core()->GetGlob(aGlob); } + + MatchGlobCore* Core() const { return mCore; } + + nsISupports* GetParentObject() const { return mParent; } + + virtual JSObject* WrapObject(JSContext* aCx, + JS::Handle aGivenProto) override; + + private: + ~MatchGlob() = default; + + nsCOMPtr mParent; + + RefPtr mCore; +}; + +class MatchGlobSet final : public CopyableTArray> { public: // Note: We can't use the nsTArray constructors directly, since the static // analyzer doesn't handle their MOZ_IMPLICIT annotations correctly. @@ -80,7 +100,7 @@ class MatchGlobSet final : public CopyableTArray> { explicit MatchGlobSet(const nsTArray& aOther) : CopyableTArray(aOther) {} MOZ_IMPLICIT MatchGlobSet(nsTArray&& aOther) : CopyableTArray(std::move(aOther)) {} - MOZ_IMPLICIT MatchGlobSet(std::initializer_list> aIL) + MOZ_IMPLICIT MatchGlobSet(std::initializer_list> aIL) : CopyableTArray(aIL) {} bool Matches(const nsACString& aValue) const; diff --git a/toolkit/components/extensions/MatchPattern.cpp b/toolkit/components/extensions/MatchPattern.cpp index ba60bb63e518..967792803af0 100644 --- a/toolkit/components/extensions/MatchPattern.cpp +++ b/toolkit/components/extensions/MatchPattern.cpp @@ -338,7 +338,7 @@ void MatchPattern::Init(JSContext* aCx, const nsAString& aPattern, return; } - mPath = new MatchGlob(this, path, false, aRv); + mPath = new MatchGlobCore(path, false, aRv); } bool MatchPattern::MatchesDomain(const nsACString& aDomain) const { @@ -586,27 +586,12 @@ NS_IMPL_CYCLE_COLLECTING_ADDREF(MatchPatternSet) NS_IMPL_CYCLE_COLLECTING_RELEASE(MatchPatternSet) /***************************************************************************** - * MatchGlob + * MatchGlobCore *****************************************************************************/ -MatchGlob::~MatchGlob() = default; - -/* static */ -already_AddRefed MatchGlob::Constructor(dom::GlobalObject& aGlobal, - const nsACString& aGlob, - bool aAllowQuestion, - ErrorResult& aRv) { - RefPtr glob = - new MatchGlob(aGlobal.GetAsSupports(), aGlob, aAllowQuestion, aRv); - if (aRv.Failed()) { - return nullptr; - } - return glob.forget(); -} - -MatchGlob::MatchGlob(nsISupports* aParent, const nsACString& aGlob, - bool aAllowQuestion, ErrorResult& aRv) - : mParent(aParent), mGlob(aGlob) { +MatchGlobCore::MatchGlobCore(const nsACString& aGlob, bool aAllowQuestion, + ErrorResult& aRv) + : mGlob(aGlob) { // Check for a literal match with no glob metacharacters. auto index = mGlob.FindCharInSet(aAllowQuestion ? "*?" : "*"); if (index < 0) { @@ -660,7 +645,7 @@ MatchGlob::MatchGlob(nsISupports* aParent, const nsACString& aGlob, } } -bool MatchGlob::Matches(const nsACString& aString) const { +bool MatchGlobCore::Matches(const nsACString& aString) const { if (mRegExp) { return mRegExp.IsMatch(aString); } @@ -672,6 +657,24 @@ bool MatchGlob::Matches(const nsACString& aString) const { return mPathLiteral == aString; } +/***************************************************************************** + * MatchGlob + *****************************************************************************/ + +/* static */ +already_AddRefed MatchGlob::Constructor(dom::GlobalObject& aGlobal, + const nsACString& aGlob, + bool aAllowQuestion, + ErrorResult& aRv) { + RefPtr glob = + new MatchGlob(aGlobal.GetAsSupports(), + MakeAndAddRef(aGlob, aAllowQuestion, aRv)); + if (aRv.Failed()) { + return nullptr; + } + return glob.forget(); +} + JSObject* MatchGlob::WrapObject(JSContext* aCx, JS::Handle aGivenProto) { return MatchGlob_Binding::Wrap(aCx, this, aGivenProto); diff --git a/toolkit/components/extensions/MatchPattern.h b/toolkit/components/extensions/MatchPattern.h index ae0c3ebab8de..9a32cbbcc9cb 100644 --- a/toolkit/components/extensions/MatchPattern.h +++ b/toolkit/components/extensions/MatchPattern.h @@ -214,7 +214,7 @@ class MatchPattern final : public nsISupports, public nsWrapperCache { // The glob against which the URL path must match. If null, the path is // ignored entirely. If non-null, the path must match this glob. - RefPtr mPath; + RefPtr mPath; public: // A quick way to check if a particular URL matches without diff --git a/toolkit/components/extensions/WebExtensionPolicy.cpp b/toolkit/components/extensions/WebExtensionPolicy.cpp index a35348eb7359..a6d459e43ddd 100644 --- a/toolkit/components/extensions/WebExtensionPolicy.cpp +++ b/toolkit/components/extensions/WebExtensionPolicy.cpp @@ -83,13 +83,13 @@ static nsISubstitutingProtocolHandler* Proto() { bool ParseGlobs(GlobalObject& aGlobal, Sequence aGlobs, - nsTArray>& aResult, ErrorResult& aRv) { + nsTArray>& aResult, ErrorResult& aRv) { for (auto& elem : aGlobs) { if (elem.IsMatchGlob()) { - aResult.AppendElement(elem.GetAsMatchGlob()); + aResult.AppendElement(elem.GetAsMatchGlob()->Core()); } else { - RefPtr glob = - MatchGlob::Constructor(aGlobal, elem.GetAsUTF8String(), true, aRv); + RefPtr glob = + new MatchGlobCore(elem.GetAsUTF8String(), true, aRv); if (aRv.Failed()) { return false; } @@ -903,8 +903,7 @@ JSObject* WebExtensionContentScript::WrapObject( } NS_IMPL_CYCLE_COLLECTION_WRAPPERCACHE(MozDocumentMatcher, mMatches, - mExcludeMatches, mIncludeGlobs, - mExcludeGlobs, mExtension) + mExcludeMatches, mExtension) NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(MozDocumentMatcher) NS_WRAPPERCACHE_INTERFACE_MAP_ENTRY