High firefox Logic Error 🔧 Commit mapped

Overview

High
Severity
—
CVSS
No
Exploited ITW
Fixed
Fix Status
Impacthigh
DescriptionUse-after-free in the CSS Parsing and Computation component
ComponentLayout
Bug ClassLogic Error
Tracker2079062
Fix commite358158e58ce (firefox) +34/-25
CISA KEVNot listed
CreditedMozilla
Disclosed2026-10-27

Changed Functions

FunctionChangeNotes
if
layout/style/FontFaceSet.cpp
modified

Files Changed

  • layout/style/FontFaceSet.cpp
  • layout/style/FontFaceSet.h
diff --git a/layout/style/FontFaceSet.cpp b/layout/style/FontFaceSet.cpp
index 638454ab5eb..26b5d6827d6 100644
--- a/layout/style/FontFaceSet.cpp
+++ b/layout/style/FontFaceSet.cpp
@@ -405,14 +405,26 @@ void FontFaceSet::DispatchLoadingEventAndReplaceReadyPromise() {
   mResolveLazilyCreatedReadyPromise = false;
 }
 
-void FontFaceSet::MaybeResolve() {
-  if (mReady) {
-    mReady->MaybeResolve(this);
-  } else {
-    mResolveLazilyCreatedReadyPromise = true;
+static RefPtr<FontFaceSetLoadEvent> MakeLoadEvent(
+    FontFaceSet* aFontFaceSet, const nsAString& aType,
+    nsTArray<OwningNonNull<FontFace>>&& aFontFaces) {
+  FontFaceSetLoadEventInit init;
+  init.mBubbles = false;
+  init.mCancelable = false;
+  init.mFontfaces = std::move(aFontFaces);
+  return FontFaceSetLoadEvent::Constructor(aFontFaceSet, aType, init);
+}
+
+static RefPtr<FontFaceSetLoadEvent> MaybeMakeLoadEvent(
+    FontFaceSet* aFontFaceSet, const nsAString& aType,
+    nsTArray<OwningNonNull<FontFace>>&& aFontFaces) {
+  if (aFontFaces.IsEmpty()) {
+    return nullptr;
   }
+  return MakeLoadEvent(aFontFaceSet, aType, std::move(aFontFaces));
+}
 
-  // Now dispatch the loadingdone/loadingerror events.
+void FontFaceSet::MaybeResolve() {
   nsTArray<OwningNonNull<FontFace>> loaded;
   nsTArray<OwningNonNull<FontFace>> failed;
 
@@ -444,22 +456,22 @@ void FontFaceSet::MaybeResolve() {
   checkStatus(mRuleFaces);
   checkStatus(mNonRuleFaces);
 
-  DispatchLoadingFinishedEvent(u"loadingdone"_ns, std::move(loaded));
-
-  if (!failed.IsEmpty()) {
-    DispatchLoadingFinishedEvent(u"loadingerror"_ns, std::move(failed));
-  }
-}
-
-void FontFaceSet::DispatchLoadingFinishedEvent(
-    const nsAString& aType, nsTArray<OwningNonNull<FontFace>>&& aFontFaces) {
-  FontFaceSetLoadEventInit init;
-  init.mBubbles = false;
-  init.mCancelable = false;
-  init.mFontfaces = std::move(aFontFaces);
-  RefPtr<FontFaceSetLoadEvent> event =
-      FontFaceSetLoadEvent::Constructor(this, aType, init);
-  (new AsyncEventDispatcher(this, event.forget()))->PostDOMEvent();
+  NS_DispatchToCurrentThread(NS_NewRunnableFunction(
+      "FontFaceSet::DoResolveAndDispatchLoadEvents",
+      [self = RefPtr{this},
+       loadingdone = MakeLoadEvent(this, u"loadingdone"_ns, std::move(loaded)),
+       loadingerror =
+           MaybeMakeLoadEvent(this, u"loadingerror"_ns, std::move(failed))] {
+        if (self->mReady) {
+          self->mReady->MaybeResolve(self);
+        } else {
+          self->mResolveLazilyCreatedReadyPromise = true;
+        }
+        self->DispatchEvent(*loadingdone);
+        if (loadingerror) {
+          self->DispatchEvent(*loadingerror);
+        }
+      }));
 }
 
 void FontFaceSet::FlushUserFontSet() { mImpl->FlushUserFontSet(); }
diff --git a/layout/style/FontFaceSet.h b/layout/style/FontFaceSet.h
index 465c3b24132..706fdd9dec4 100644
--- a/layout/style/FontFaceSet.h
+++ b/layout/style/FontFaceSet.h
@@ -95,9 +95,6 @@ class FontFaceSet final : public DOMEventTargetHelper {
 
   void MaybeResolve();
 
-  void DispatchLoadingFinishedEvent(
-      const nsAString& aType, nsTArray<OwningNonNull<FontFace>>&& aFontFaces);
-
   void DispatchLoadingEventAndReplaceReadyPromise();
   void DispatchCheckLoadingFinishedAfterDelay();
 
Loading diff…