From 3cf06a4c85de9aabc860bc7bdd6e4a7c6f2f6224 Mon Sep 17 00:00:00 2001 From: "Mr. M" Date: Tue, 14 Apr 2026 00:42:06 +0200 Subject: [PATCH] no-bug: Make sure to clear memory on shutdown --- src/zen/boosts/actors/ZenBoostsParent.sys.mjs | 23 +++++++++++++++---- src/zen/boosts/nsZenBoostsBackend.cpp | 17 +++++++------- src/zen/boosts/nsZenBoostsBackend.h | 3 +-- 3 files changed, 27 insertions(+), 16 deletions(-) diff --git a/src/zen/boosts/actors/ZenBoostsParent.sys.mjs b/src/zen/boosts/actors/ZenBoostsParent.sys.mjs index c1fdf94dc..e4a390da1 100644 --- a/src/zen/boosts/actors/ZenBoostsParent.sys.mjs +++ b/src/zen/boosts/actors/ZenBoostsParent.sys.mjs @@ -16,6 +16,16 @@ export class ZenBoostsParent extends JSWindowActorParent { "zen-boosts-disable-picker", ]; + // Topics the content child is allowed to forward to the observer service. + // Anything outside this set is rejected to prevent content-triggered + // notifications on unrelated chrome observers. + static ALLOWED_NOTIFY_TOPICS = new Set([ + "zap-state-update", + "zap-list-update", + "selector-picker-state-update", + "selector-picker-picked", + ]); + /** * Creates a new ZenBoostsParent actor instance and sets up an observer * for boost update notifications. @@ -91,11 +101,14 @@ export class ZenBoostsParent extends JSWindowActorParent { break; } case "ZenBoost:Notify": { - Services.obs.notifyObservers( - null, - message.data.topic, - message.data.msg - ); + const { topic, msg } = message.data ?? {}; + if (!ZenBoostsParent.ALLOWED_NOTIFY_TOPICS.has(topic)) { + console.warn( + `[ZenBoostsParent]: Rejected notify for disallowed topic: ${topic}` + ); + break; + } + Services.obs.notifyObservers(null, topic, msg); break; } case "ZenBoost:ZapSelector": { diff --git a/src/zen/boosts/nsZenBoostsBackend.cpp b/src/zen/boosts/nsZenBoostsBackend.cpp index 6c31bbd28..d9899b180 100644 --- a/src/zen/boosts/nsZenBoostsBackend.cpp +++ b/src/zen/boosts/nsZenBoostsBackend.cpp @@ -7,6 +7,7 @@ #include "nsIXULRuntime.h" #include "nsPresContext.h" +#include "mozilla/ClearOnShutdown.h" #include "mozilla/StaticPtr.h" #include "mozilla/ServoStyleConsts.h" @@ -266,17 +267,19 @@ inline static void GetZenBoostsDataFromBrowsingContext( } // namespace +static mozilla::StaticAutoPtr sZenBoostsBackend; + auto nsZenBoostsBackend::GetInstance() -> nsZenBoostsBackend* { - static nsZenBoostsBackend* zenBoosts; if (!XRE_IsContentProcess()) { // Zen boosts are only supported in content, so if we're in the parent // process, just return null. return nullptr; } - if (!zenBoosts) { - zenBoosts = new nsZenBoostsBackend(); + if (!sZenBoostsBackend) { + sZenBoostsBackend = new nsZenBoostsBackend(); + mozilla::ClearOnShutdown(&sZenBoostsBackend); } - return zenBoosts; + return sZenBoostsBackend.get(); } auto nsZenBoostsBackend::onPresShellEntered(mozilla::dom::Document* aDocument) @@ -284,12 +287,8 @@ auto nsZenBoostsBackend::onPresShellEntered(mozilla::dom::Document* aDocument) // Note that aDocument can be null when entering anonymous content frames. // We explicitly do this to prevent applying boosts to anonymous content, such // as devtools or screenshots. - mozilla::dom::BrowsingContext* browsingContext = + mCurrentBrowsingContext = aDocument ? aDocument->GetBrowsingContext() : nullptr; - if (!browsingContext) { - return; - } - mCurrentBrowsingContext = browsingContext; } [[nodiscard]] ZEN_HOT_FUNCTION auto diff --git a/src/zen/boosts/nsZenBoostsBackend.h b/src/zen/boosts/nsZenBoostsBackend.h index f621a07bc..cad828eaf 100644 --- a/src/zen/boosts/nsZenBoostsBackend.h +++ b/src/zen/boosts/nsZenBoostsBackend.h @@ -25,6 +25,7 @@ struct nsZenAccentOklab { class nsZenBoostsBackend final { public: explicit nsZenBoostsBackend() = default; + ~nsZenBoostsBackend() = default; /** * Indicates whether the current frame being rendered is for anonymous @@ -64,8 +65,6 @@ class nsZenBoostsBackend final { } private: - ~nsZenBoostsBackend() = default; - /** * The presshell of the current document being rendered. */