Bug 1645645 - Fix error handling in gfxDWriteFontList::CreateFontEntry to avoid risk of null-deref. r=jwatt
authorJonathan Kew <jkew@mozilla.com>
Tue, 16 Jun 2020 14:52:15 +0000
changeset 599955 d3d13c4bbf9b82cce19a16f95b374ad330c97730
parent 599954 7ee9e9729d0bea9fb2a922490bfcc09f921eae08
child 599956 a3c14239c007ca80dba220c5448621a6d7620438
push id13310
push userffxbld-merge
push dateMon, 29 Jun 2020 14:50:06 +0000
treeherdermozilla-beta@15a59a0afa5c [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersjwatt
bugs1645645
milestone79.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1645645 - Fix error handling in gfxDWriteFontList::CreateFontEntry to avoid risk of null-deref. r=jwatt Differential Revision: https://phabricator.services.mozilla.com/D79612
gfx/thebes/gfxDWriteFontList.cpp
--- a/gfx/thebes/gfxDWriteFontList.cpp
+++ b/gfx/thebes/gfxDWriteFontList.cpp
@@ -937,58 +937,57 @@ gfxFontEntry* gfxDWriteFontList::CreateF
     fontlist::Face* aFace, const fontlist::Family* aFamily) {
   IDWriteFontCollection* collection =
 #ifdef MOZ_BUNDLED_FONTS
       aFamily->IsBundled() ? mBundledFonts : mSystemFonts;
 #else
       mSystemFonts;
 #endif
   RefPtr<IDWriteFontFamily> family;
-  HRESULT hr =
-      collection->GetFontFamily(aFamily->Index(), getter_AddRefs(family));
-  // Check that the family name is what we expected; if not, fall back to search
-  // by name. It's sad we have to do this, but it is possible for Windows to
-  // have given different versions of the system font collection to the parent
-  // and child processes.
-  bool foundFamily = false;
+  bool foundExpectedFamily = false;
   const nsCString& familyName =
       aFamily->DisplayName().AsString(SharedFontList());
-  if (SUCCEEDED(hr) && family) {
-    RefPtr<IDWriteLocalizedStrings> names;
-    hr = family->GetFamilyNames(getter_AddRefs(names));
-    if (SUCCEEDED(hr) && names) {
-      nsAutoCString name;
-      if (GetEnglishOrFirstName(name, names)) {
-        foundFamily = name.Equals(familyName);
+  if (aFamily->Index() < collection->GetFontFamilyCount()) {
+    HRESULT hr =
+        collection->GetFontFamily(aFamily->Index(), getter_AddRefs(family));
+    // Check that the family name is what we expected; if not, fall back to
+    // search by name. It's sad we have to do this, but it is possible for
+    // Windows to have given different versions of the system font collection
+    // to the parent and child processes.
+    if (SUCCEEDED(hr) && family) {
+      RefPtr<IDWriteLocalizedStrings> names;
+      hr = family->GetFamilyNames(getter_AddRefs(names));
+      if (SUCCEEDED(hr) && names) {
+        nsAutoCString name;
+        if (GetEnglishOrFirstName(name, names)) {
+          foundExpectedFamily = name.Equals(familyName);
+        }
       }
     }
   }
-  if (!foundFamily) {
+  if (!foundExpectedFamily) {
     // Try to get family by name instead of index (to deal with the case of
     // collection mismatch).
     UINT32 index;
     BOOL exists;
     NS_ConvertUTF8toUTF16 name16(familyName);
-    hr = collection->FindFamilyName(
+    HRESULT hr = collection->FindFamilyName(
         reinterpret_cast<const WCHAR*>(name16.BeginReading()), &index, &exists);
-    if (SUCCEEDED(hr) && exists && index != UINT_MAX) {
-      hr = collection->GetFontFamily(index, getter_AddRefs(family));
-      if (FAILED(hr) || !family) {
-        return nullptr;
-      }
+    if (FAILED(hr) || !exists || index == UINT_MAX ||
+        FAILED(collection->GetFontFamily(index, getter_AddRefs(family))) ||
+        !family) {
+      return nullptr;
     }
   }
   RefPtr<IDWriteFont> font;
-  family->GetFont(aFace->mIndex, getter_AddRefs(font));
-  if (!font) {
+  if (FAILED(family->GetFont(aFace->mIndex, getter_AddRefs(font))) || !font) {
     return nullptr;
   }
   nsAutoCString faceName;
-  hr = GetDirectWriteFontName(font, faceName);
-  if (FAILED(hr)) {
+  if (FAILED(GetDirectWriteFontName(font, faceName))) {
     return nullptr;
   }
   auto fe = new gfxDWriteFontEntry(faceName, font, !aFamily->IsBundled());
   fe->mStyleRange = aFace->mStyle;
   fe->mStretchRange = aFace->mStretch;
   fe->mWeightRange = aFace->mWeight;
   fe->mShmemFace = aFace;
   fe->mIsBadUnderlineFont = aFamily->IsBadUnderlineFamily();