Moderate firefox UAF 🔧 Commit mapped

Overview

Moderate
Severity
—
CVSS
No
Exploited ITW
Fixed
Fix Status
Impactmoderate
DescriptionUse-after-free in the Graphics: Text component
ComponentGraphics
Bug ClassUAF
Tracker2081959
Fix commitcc717c4f27a7 (firefox) +131/-250
CISA KEVNot listed
CreditedMozilla
Disclosed2026-10-27

Background

FreeType / `FT_Face`
FreeType’s font-face handle; it is not itself reference counted. For faces created from a file path, FreeType retains a pointer to the caller-provided filename string, and may read it again later (e.g. when re-instantiating the face for a variation).
`SharedFTFace`
Firefox’s ref-counted (AtomicRefCounted) wrapper around an FT_Face (gfx/2d/2D.h, gfx/2d/Factory.cpp) so the face can be shared via RefPtr. It is responsible for keeping any backing data (file bytes or filename) alive as long as the face lives.
`SharedFTFaceData` / `SharedFTFaceRefCountedData` / `FTUserFontData` (removed)
the old, hand-rolled lifetime scheme: a SharedFTFaceData base with BindData()/ReleaseData() hooks, a CRTP wrapper mapping those to AddRef/Release, and FTUserFontData holding either a RefPtr<FontData> or a std::string mFilename. SharedFTFace stored a raw SharedFTFaceData* mData and called BindData()/ReleaseData() in its ctor/dtor.
`FontData`
a ref-counted holder of in-memory font bytes.
`NewSharedFTFace` / `NewSharedFTFaceFromData` / `CloneFace`
factory entry points that build a SharedFTFace from a filename or an in-memory buffer; CloneFace re-instantiates a face (e.g. for a variation instance) from the same backing data.

Root Cause Analysis

The old design managed the font-backing-data lifetime through a fragile hand-rolled indirection. SharedFTFace held a raw SharedFTFaceData* mData and bound/released it manually (mData->BindData() in the constructor, mData->ReleaseData() in the destructor), while the concrete data object (FTUserFontData, or NativeFontResourceFreeType acting as its own SharedFTFaceRefCountedData) carried the actual RefPtr<FontData> or filename. The most direct lifetime hole is the filename path: Factory::NewSharedFTFace(FT_Library, const char* aFilename, int) passed the caller-owned aFilename straight to NewFTFace, and only on Android, and only if the face had variations, was a copy preserved (via new FTUserFontData(aFilename)). On every other path the FT_Face retained a pointer into a filename buffer the SharedFTFace did not own and did not keep alive — so once the caller’s string went away, any later FreeType access to that filename (notably CloneFace, used for variation instances) read freed memory. The parallel data-backed path depended on the BindData/ReleaseData CRTP contract being honored symmetrically across constructors and factory overloads (including the aSharedData = nullptr default), which is easy to get wrong and leaves the FT_Face’s backing bytes able to outlive or underlive the wrapper.

The patch deletes the entire SharedFTFaceData/SharedFTFaceRefCountedData/FTUserFontData machinery and gives SharedFTFace direct, correctly-scoped ownership of its backing data: a UniquePtr<char[]> mFilename and a RefPtr<FontData> mFontData, with two explicit constructors (SharedFTFace(FT_Face, UniquePtr<char[]>&&, int) and SharedFTFace(FT_Face, FontData*, int)) and an int mFaceIndex. NewSharedFTFace now allocates the filename into a UniquePtr<char[]> before creating the face, passes that owned buffer to FreeType, and moves it into the SharedFTFace so “its lifetime must be at least as long as SharedFTFace, which manages it” — eliminating the dangling-filename read. NewSharedFTFaceFromData holds the bytes via RefPtr<FontData>, and CloneFace becomes a SharedFTFace member that re-clones from the owned mFontData or mFilename. The advisory (“use-after-free in Graphics: Text”) matches: the diff substantiates a lifetime bug in the FreeType face wrapper, with the owned-filename fix being the clearest demonstration. Note the diff is truncated after NativeFontResourceFreeType.h, so the full removal of SharedFTFaceRefCountedData from that class’s base list is only partially shown.

Key insight
SharedFTFace did not own the data FreeType kept pointing at — most plainly the file path, which was passed to FT_Face as a borrowed const char* and preserved only in a narrow Android+variations case — so the face could outlive its filename/backing bytes and FreeType would later read freed memory; the fix makes SharedFTFace own the filename (UniquePtr<char[]>) and bytes (RefPtr<FontData>) directly.

Attack Path

  1. Web content a page loads or triggers use of a font that produces a SharedFTFace via the FreeType backend (inferred: GTK/Android FreeType builds; downloadable @font-face or a system font with variations).
  2. Create face from borrowed data NewSharedFTFace/NewSharedFTFaceFromData builds the wrapper while the underlying filename/bytes are owned elsewhere (old code).
  3. Drop the backing data the caller-owned filename string (or the data object under the brittle BindData/ReleaseData pairing) is freed while the SharedFTFace is still alive.
  4. Re-instantiate / draw a later operation (e.g. CloneFace for a variation instance, or any FreeType call reading the filename) dereferences the stale pointer.
  5. Reuse the allocation attacker content grooms the freed buffer to hold controlled bytes (inferred).
  6. Primitive use-after-free of font-backing data in the graphics text path, giving read of freed/attacker-controlled memory and corruption potential (strength inferred).

Impact Assessment

The code runs in the process doing font rasterization (content/renderer on FreeType platforms — Linux/GTK and Android), reachable by ordinary web content that loads fonts, so no special privilege is required beyond rendering a page. The primitive is a use-after-free of a font face’s backing filename/bytes, exploitable for memory disclosure and likely corruption; exact exploit strength is (inferred) from the diff. The fix is a structural ownership refactor (raw SharedFTFaceData* + manual bind/release → UniquePtr/RefPtr owned members), which both closes the dangling-filename read and removes a class of bind/release mismatch bugs. Mozilla rates it moderate.

Changed Functions

FunctionChangeNotes
SharedFTFace
gfx/2d/2D.h
modified
SharedFTFaceData
gfx/2d/2D.h
modified
SharedFTFaceRefCountedData
gfx/2d/2D.h
modified
FTUserFontData
gfx/2d/2D.h
modified
if
gfx/2d/Factory.cpp
modified
mLastLockOwner
gfx/2d/Factory.cpp
modified
mFTLibrary
gfx/2d/NativeFontResourceFreeType.cpp
modified
if
gfx/2d/NativeFontResourceFreeType.cpp
modified
NativeFontResourceFreeType
gfx/2d/NativeFontResourceFreeType.h
modified

Files Changed

  • gfx/2d/2D.h
  • gfx/2d/Factory.cpp
  • gfx/2d/NativeFontResourceFreeType.cpp
  • gfx/2d/NativeFontResourceFreeType.h
  • gfx/2d/ScaledFontFontconfig.cpp
  • gfx/2d/UnscaledFontFreeType.cpp
  • gfx/2d/UnscaledFontFreeType.h
  • gfx/thebes/gfxFT2FontBase.cpp
  • gfx/thebes/gfxFT2FontBase.h
  • gfx/thebes/gfxFT2FontList.cpp
  • gfx/thebes/gfxFT2FontList.h
  • gfx/thebes/gfxFcPlatformFontList.cpp
  • gfx/thebes/gfxFcPlatformFontList.h

Audit Directions

  • Borrowed pointers handed to FreeType
    audit every NewFTFace/FT_New_Face caller for data (filenames, byte buffers) passed as a borrowed pointer that FreeType may retain, confirming an owner with matching lifetime exists.
  • Hand-rolled bind/release lifetime schemes
    search for other BindData/ReleaseData-style manual refcount hooks or raw back-pointers used in place of RefPtr/UniquePtr, which are prone to the asymmetry this bug exhibited.
  • `CloneFace` / variation instancing
    review all paths that re-instantiate an FT_Face from a stored face’s backing data (variations, multiple masters) to ensure the source data is still owned at clone time.
  • Platform divergence
    the old filename-preservation was Android-and-variations-only; look for other #ifdef ANDROID/#ifdef MOZ_WIDGET_* guards that narrow a lifetime guarantee to a subset of platforms.
diff --git a/gfx/2d/2D.h b/gfx/2d/2D.h
index ad556e04ed4..30f6d18986c 100644
--- a/gfx/2d/2D.h
+++ b/gfx/2d/2D.h
@@ -31,6 +31,7 @@
 #include "mozilla/StaticMutex.h"
 #include "mozilla/StaticPtr.h"
 #include "mozilla/ThreadSafeWeakPtr.h"
+#include "mozilla/UniquePtr.h"
 #include "mozilla/gfx/FontData.h"
 #include "nsRegionFwd.h"
 
@@ -1229,81 +1230,25 @@ struct GlyphBuffer {
 };
 
 #ifdef MOZ_ENABLE_FREETYPE
-class SharedFTFace;
-
-/** SharedFTFaceData abstracts data that may be used to back a SharedFTFace.
- * Its main function is to manage the lifetime of the data and ensure that it
- * lasts as long as the face.
- */
-class SharedFTFaceData {
- public:
-  /** Utility for creating a new face from this data. */
-  virtual already_AddRefed<SharedFTFace> CloneFace(int aFaceIndex = 0) {
-    return nullptr;
-  }
-  /** Binds the data's lifetime to the face. */
-  virtual void BindData() = 0;
-  /** Signals that the data is no longer needed by a face. */
-  virtual void ReleaseData() = 0;
-};
-
-/** Wrapper class for ref-counted SharedFTFaceData that handles calling the
- * appropriate ref-counting methods
- */
-template <class T>
-class SharedFTFaceRefCountedData : public SharedFTFaceData {
- public:
-  void BindData() { static_cast<T*>(this)->AddRef(); }
-  void ReleaseData() { static_cast<T*>(this)->Release(); }
-};
-
-// Helper class used for clearing out user font data when FT font
-// face is destroyed. Since multiple faces may use the same data, be
-// careful to assure that the data is only cleared out when all uses
-// expire. The font entry object contains a refptr to FTUserFontData and
-// each FT face created from that font entry contains a refptr to that
-// same FTUserFontData object.
-// This is also attached to FT faces for installed fonts (recording the
-// filename, rather than storing the font data) if variations are present.
-class FTUserFontData final
-    : public mozilla::gfx::SharedFTFaceRefCountedData<FTUserFontData> {
- public:
-  NS_INLINE_DECL_THREADSAFE_REFCOUNTING(FTUserFontData)
-
-  explicit FTUserFontData(FontData* aFontData) : mFontData(aFontData) {}
-  explicit FTUserFontData(const char* aFilename) : mFilename(aFilename) {}
-
-  const uint8_t* GetData() const {
-    return mFontData ? mFontData->Data() : nullptr;
-  }
-  uint32_t Length() const { return mFontData ? mFontData->Length() : 0; }
-
-  already_AddRefed<mozilla::gfx::SharedFTFace> CloneFace(
-      int aFaceIndex = 0) override;
-
- private:
-  ~FTUserFontData() = default;
-
-  std::string mFilename;
-  RefPtr<FontData> mFontData;
-};
-
 /** SharedFTFace is a shared wrapper around an FT_Face. It is ref-counted,
  * unlike FT_Face itself, so that it may be shared among many users with
  * RefPtr. Users should take care to lock SharedFTFace before accessing any
  * FT_Face fields that may change to ensure exclusive access to it. It also
- * allows backing data's lifetime to be bound to it via SharedFTFaceData so
- * that the data will not disappear before the face does.
+ * allows backing data's lifetime to be bound to it so that the data will not
+ * disappear before the face does.
  */
 class SharedFTFace : public external::AtomicRefCounted<SharedFTFace> {
  public:
   MOZ_DECLARE_REFCOUNTED_VIRTUAL_TYPENAME(SharedFTFace)
 
-  explicit SharedFTFace(FT_Face aFace, SharedFTFaceData* aData);
+  SharedFTFace(FT_Face aFace, UniquePtr<char[]>&& aFilename, int aFaceIndex);
+  SharedFTFace(FT_Face aFace, FontData* aFontData, int aFaceIndex);
   virtual ~SharedFTFace();
 
   FT_Face GetFace() const { return mFace; }
-  SharedFTFaceData* GetData() const { return mData; }
+  const char* GetFilename() const { return mFilename.get(); }
+  const RefPtr<FontData>& GetFontData() const { return mFontData; }
+  int GetFaceIndex() const { return mFaceIndex; }
 
   /** Locks the face for exclusive access by a given owner. Returns false if
    * the given owner is acquiring the lock for the first time, and true if
@@ -1328,14 +1273,21 @@ class SharedFTFace : public external::AtomicRefCounted<SharedFTFace> {
     }
   }
 
+  already_AddRefed<mozilla::gfx::SharedFTFace> CloneFace();
+
  private:
-  FT_Face mFace;
-  SharedFTFaceData* mData;
-  Mutex mLock;
+  FT_Face mFace = nullptr;
+  // The filename, if used, must have the same lifetime as the FT_Face.
+  UniquePtr<char[]> mFilename;
+  // Since multiple faces may use the same data, use RefPtr to assure that the
+  // data is only cleared out when all uses expire.
+  RefPtr<FontData> mFontData;
+  int mFaceIndex = 0;
+  Mutex mLock{"SharedFTFace::mLock"};
   // Remember the last owner of the lock, even after unlocking, to allow users
   // to avoid reinitializing state on the FT face if the last owner hasn't
   // changed by the next time it is locked with the same owner.
-  Atomic<const void*> mLastLockOwner;
+  Atomic<const void*> mLastLockOwner{nullptr};
 };
 #endif
 
@@ -2445,14 +2397,12 @@ class GFX2D_API Factory {
 
   static FT_Face NewFTFace(FT_Library aFTLibrary, const char* aFileName,
                            int aFaceIndex);
-  static already_AddRefed<SharedFTFace> NewSharedFTFace(FT_Library aFTLibrary,
-                                                        const char* aFilename,
+  static already_AddRefed<SharedFTFace> NewSharedFTFace(const char* aFilename,
                                                         int aFaceIndex);
   static FT_Face NewFTFaceFromData(FT_Library aFTLibrary, const uint8_t* aData,
                                    uint32_t aLength, int aFaceIndex);
   static already_AddRefed<SharedFTFace> NewSharedFTFaceFromData(
-      FT_Library aFTLibrary, FontData* aFontData, int aFaceIndex,
-      SharedFTFaceData* aSharedData = nullptr);
+      FontData* aFontData, int aFaceIndex);
   static void ReleaseFTFace(FT_Face aFace);
   static FT_Error LoadFTGlyph(FT_Face aFace, uint32_t aGlyphIndex,
                               int32_t aFlags);
diff --git a/gfx/2d/Factory.cpp b/gfx/2d/Factory.cpp
index 0183e748653..44e181a2037 100644
--- a/gfx/2d/Factory.cpp
+++ b/gfx/2d/Factory.cpp
@@ -2,6 +2,8 @@
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
+#include <cstring>
+
 #include "2D.h"
 #include "Swizzle.h"
 
@@ -53,6 +55,7 @@
 #include "PathRecording.h"
 #include "SourceSurfaceRawData.h"
 #include "mozilla/CheckedInt.h"
+#include "mozilla/PodOperations.h"
 
 #ifdef MOZ_ENABLE_FREETYPE
 #  include "ft2build.h"
@@ -117,25 +120,6 @@ namespace mozilla::gfx {
 #ifdef MOZ_ENABLE_FREETYPE
 FT_Library Factory::mFTLibrary = nullptr;
 StaticMutex Factory::mFTLock;
-
-already_AddRefed<SharedFTFace> FTUserFontData::CloneFace(int aFaceIndex) {
-  if (mFontData) {
-    RefPtr<SharedFTFace> face =
-        Factory::NewSharedFTFaceFromData(nullptr, mFontData, aFaceIndex, this);
-    if (!face ||
-        (FT_Select_Charmap(face->GetFace(), FT_ENCODING_UNICODE) != FT_Err_Ok &&
-         FT_Select_Charmap(face->GetFace(), FT_ENCODING_MS_SYMBOL) !=
-             FT_Err_Ok)) {
-      return nullptr;
-    }
-    return face.forget();
-  }
-  FT_Face face = Factory::NewFTFace(nullptr, mFilename.c_str(), aFaceIndex);
-  if (face) {
-    return MakeAndAddRef<SharedFTFace>(face, this);
-  }
-  return nullptr;
-}
 #endif
 
 #ifdef WIN32
@@ -410,12 +394,10 @@ already_AddRefed<NativeFontResource> Factory::CreateNativeFontResource(
       return NativeFontResourceMac::Create(aData, aSize);
 #elif defined(MOZ_WIDGET_GTK)
     case FontType::FONTCONFIG:
-      return NativeFontResourceFontconfig::Create(
-          aData, aSize, static_cast<FT_Library>(aFontContext));
+      return NativeFontResourceFontconfig::Create(aData, aSize);
 #elif defined(MOZ_WIDGET_ANDROID)
     case FontType::FREETYPE:
-      return NativeFontResourceFreeType::Create(
-          aData, aSize, static_cast<FT_Library>(aFontContext));
+      return NativeFontResourceFreeType::Create(aData, aSize);
 #endif
     default:
       gfxWarning()
@@ -486,22 +468,14 @@ void Factory::SetSubpixelOrder(SubpixelOrder aOrder) {
 SubpixelOrder Factory::GetSubpixelOrder() { return mSubpixelOrder; }
 
 #ifdef MOZ_ENABLE_FREETYPE
-SharedFTFace::SharedFTFace(FT_Face aFace, SharedFTFaceData* aData)
-    : mFace(aFace),
-      mData(aData),
-      mLock("SharedFTFace::mLock"),
-      mLastLockOwner(nullptr) {
-  if (mData) {
-    mData->BindData();
-  }
-}
+SharedFTFace::SharedFTFace(FT_Face aFace, UniquePtr<char[]>&& aFilename,
+                           int aFaceIndex)
+    : mFace(aFace), mFilename(std::move(aFilename)), mFaceIndex(aFaceIndex) {}
 
-SharedFTFace::~SharedFTFace() {
-  Factory::ReleaseFTFace(mFace);
-  if (mData) {
-    mData->ReleaseData();
-  }
-}
+SharedFTFace::SharedFTFace(FT_Face aFace, FontData* aFontData, int aFaceIndex)
+    : mFace(aFace), mFontData(aFontData), mFaceIndex(aFaceIndex) {}
+
+SharedFTFace::~SharedFTFace() { Factory::ReleaseFTFace(mFace); }
 
 void Factory::SetFTLibrary(FT_Library aFTLibrary) { mFTLibrary = aFTLibrary; }
 
@@ -545,24 +519,18 @@ FT_Face Factory::NewFTFace(FT_Library aFTLibrary, const char* aFileName,
   return face;
 }
 
-already_AddRefed<SharedFTFace> Factory::NewSharedFTFace(FT_Library aFTLibrary,
-                                                        const char* aFilename,
+already_AddRefed<SharedFTFace> Factory::NewSharedFTFace(const char* aFilename,
                                                         int aFaceIndex) {
-  FT_Face face = NewFTFace(aFTLibrary, aFilename, aFaceIndex);
+  // Allocate filename first so its memory can be passed to FT and SharedFTFace.
+  // Its lifetime must be at least as long as SharedFTFace, which manages it.
+  size_t length = strlen(aFilename) + 1;
+  UniquePtr<char[]> filename = MakeUniqueFallible<char[]>(length);
+  PodCopy(filename.get(), aFilename, length);
+  FT_Face face = NewFTFace(nullptr, filename.get(), aFaceIndex);
   if (!face) {
     return nullptr;
   }
-
-  RefPtr<FTUserFontData> data;
-#  ifdef ANDROID
-  // If the font has variations, we may later need to "clone" it in
-  // UnscaledFontFreeType::CreateScaledFont. To support this, we attach an
-  // FTUserFontData that records the filename used to instantiate the face.
-  if (face->face_flags & FT_FACE_FLAG_MULTIPLE_MASTERS) {
-    data = new FTUserFontData(aFilename);
-  }
-#  endif
-  return MakeAndAddRef<SharedFTFace>(face, data);
+  return MakeAndAddRef<SharedFTFace>(face, std::move(filename), aFaceIndex);
 }
 
 FT_Face Factory::NewFTFaceFromData(FT_Library aFTLibrary, const uint8_t* aData,
@@ -580,14 +548,28 @@ FT_Face Factory::NewFTFaceFromData(FT_Library aFTLibrary, const uint8_t* aData,
 }
 
 already_AddRefed<SharedFTFace> Factory::NewSharedFTFaceFromData(
-    FT_Library aFTLibrary, FontData* aFontData, int aFaceIndex,
-    SharedFTFaceData* aSharedData) {
-  if (FT_Face face = NewFTFaceFromData(aFTLibrary, aFontData->Data(),
-                                       aFontData->Length(), aFaceIndex)) {
-    return MakeAndAddRef<SharedFTFace>(face, aSharedData);
-  } else {
+    FontData* aFontData, int aFaceIndex) {
+  FT_Face face = NewFTFaceFromData(nullptr, aFontData->Data(),
+                                   aFontData->Length(), aFaceIndex);
+  if (!face) {
+    return nullptr;
+  }
+  if (FT_Select_Charmap(face, FT_ENCODING_UNICODE) != FT_Err_Ok &&
+      FT_Select_Charmap(face, FT_ENCODING_MS_SYMBOL) != FT_Err_Ok) {
+    ReleaseFTFace(face);
     return nullptr;
   }
+  return MakeAndAddRef<SharedFTFace>(face, aFontData, aFaceIndex);
+}
+
+already_AddRefed<SharedFTFace> SharedFTFace::CloneFace() {
+  if (mFontData) {
+    return Factory::NewSharedFTFaceFromData(mFontData, mFaceIndex);
+  }
+  if (mFilename) {
+    return Factory::NewSharedFTFace(mFilename.get(), mFaceIndex);
+  }
+  return nullptr;
 }
 
 void Factory::ReleaseFTFace(FT_Face aFace) {
diff --git a/gfx/2d/NativeFontResourceFreeType.cpp b/gfx/2d/NativeFontResourceFreeType.cpp
index 9a6db068a94..2d6358ad168 100644
--- a/gfx/2d/NativeFontResourceFreeType.cpp
+++ b/gfx/2d/NativeFontResourceFreeType.cpp
@@ -9,16 +9,15 @@
 namespace mozilla::gfx {
 
 NativeFontResourceFreeType::NativeFontResourceFreeType(
-    const uint8_t*&& aFontData, uint32_t aDataLength, FT_Library aFTLibrary)
+    const uint8_t*&& aFontData, uint32_t aDataLength)
     : NativeFontResource(aDataLength),
-      mFontData(MakeRefPtr<FontData>(std::move(aFontData), aDataLength)),
-      mFTLibrary(aFTLibrary) {}
+      mFontData(MakeRefPtr<FontData>(std::move(aFontData), aDataLength)) {}
 
 NativeFontResourceFreeType::~NativeFontResourceFreeType() = default;
 
 template <class T>
 already_AddRefed<T> NativeFontResourceFreeType::CreateInternal(
-    const uint8_t* aFontData, uint32_t aDataLength, FT_Library aFTLibrary) {
+    const uint8_t* aFontData, uint32_t aDataLength) {
   if (!aFontData || !aDataLength) {
     return nullptr;
   }
@@ -28,16 +27,15 @@ already_AddRefed<T> NativeFontResourceFreeType::CreateInternal(
   }
   memcpy(fontData, aFontData, aDataLength);
 
-  RefPtr<T> resource = new T(std::move(static_cast<const uint8_t*>(fontData)),
-                             aDataLength, aFTLibrary);
+  RefPtr<T> resource =
+      new T(std::move(static_cast<const uint8_t*>(fontData)), aDataLength);
   return resource.forget();
 }
 
 #ifdef MOZ_WIDGET_ANDROID
 already_AddRefed<NativeFontResourceFreeType> NativeFontResourceFreeType::Create(
-    const uint8_t* aFontData, uint32_t aDataLength, FT_Library aFTLibrary) {
-  return CreateInternal<NativeFontResourceFreeType>(aFontData, aDataLength,
-                                                    aFTLibrary);
+    const uint8_t* aFontData, uint32_t aDataLength) {
+  return CreateInternal<NativeFontResourceFreeType>(aFontData, aDataLength);
 }
 
 already_AddRefed<UnscaledFont> NativeFontResourceFreeType::CreateUnscaledFont(
@@ -52,22 +50,13 @@ already_AddRefed<UnscaledFont> NativeFontResourceFreeType::CreateUnscaledFont(
 
 already_AddRefed<SharedFTFace> NativeFontResourceFreeType::CloneFace(
     int aFaceIndex) {
-  RefPtr<SharedFTFace> face =
-      Factory::NewSharedFTFaceFromData(mFTLibrary, mFontData, aFaceIndex, this);
-  if (!face ||
-      (FT_Select_Charmap(face->GetFace(), FT_ENCODING_UNICODE) != FT_Err_Ok &&
-       FT_Select_Charmap(face->GetFace(), FT_ENCODING_MS_SYMBOL) !=
-           FT_Err_Ok)) {
-    return nullptr;
-  }
-  return face.forget();
+  return Factory::NewSharedFTFaceFromData(mFontData, aFaceIndex);
 }
 
 #ifdef MOZ_WIDGET_GTK
 NativeFontResourceFontconfig::NativeFontResourceFontconfig(
-    const uint8_t*&& aFontData, uint32_t aDataLength, FT_Library aFTLibrary)
-    : NativeFontResourceFreeType(std::move(aFontData), aDataLength,
-                                 aFTLibrary) {}
+    const uint8_t*&& aFontData, uint32_t aDataLength)
+    : NativeFontResourceFreeType(std::move(aFontData), aDataLength) {}
 
 already_AddRefed<UnscaledFont> NativeFontResourceFontconfig::CreateUnscaledFont(
     uint32_t aIndex, const uint8_t* aInstanceData,
@@ -80,10 +69,8 @@ already_AddRefed<UnscaledFont> NativeFontResourceFontconfig::CreateUnscaledFont(
 
 already_AddRefed<NativeFontResourceFontconfig>
 NativeFontResourceFontconfig::Create(const uint8_t* aFontData,
-                                     uint32_t aDataLength,
-                                     FT_Library aFTLibrary) {
-  return CreateInternal<NativeFontResourceFontconfig>(aFontData, aDataLength,
-                                                      aFTLibrary);
+                                     uint32_t aDataLength) {
+  return CreateInternal<NativeFontResourceFontconfig>(aFontData, aDataLength);
 }
 #endif
 
diff --git a/gfx/2d/NativeFontResourceFreeType.h b/gfx/2d/NativeFontResourceFreeType.h
index 194dac7c74a..9b65eca3fe0 100644
--- a/gfx/2d/NativeFontResourceFreeType.h
+++ b/gfx/2d/NativeFontResourceFreeType.h
@@ -12,16 +12,13 @@
 namespace mozilla {
 namespace gfx {
 
-class NativeFontResourceFreeType
-    : public NativeFontResource,
-      public SharedFTFaceRefCountedData<NativeFontResourceFreeType> {
+class NativeFontResourceFreeType : public NativeFontResource {
... (file diff truncated)
Loading diff…