[tor-commits] [tor-browser/tor-browser-38.1.0esr-5.0-1] Bug #13313: Pref 'font.system.whitelist' restricts set of permitted fonts

gk at torproject.org gk at torproject.org
Tue Jul 28 18:17:51 UTC 2015


commit 2a36205b70076fc26145400addaa383142d71c81
Author: Arthur Edelstein <arthuredelstein at gmail.com>
Date:   Thu Jul 23 09:44:20 2015 -0700

    Bug #13313: Pref 'font.system.whitelist' restricts set of permitted fonts
---
 gfx/thebes/gfxDWriteFontList.cpp     |    4 ++++
 gfx/thebes/gfxFT2FontList.cpp        |   28 +++++++++++++++-------------
 gfx/thebes/gfxFontUtils.cpp          |   25 +++++++++++++++++++++++++
 gfx/thebes/gfxFontUtils.h            |   11 +++++++++++
 gfx/thebes/gfxFontconfigUtils.cpp    |   31 +++++++++++++++++++++++++++++++
 gfx/thebes/gfxFontconfigUtils.h      |    3 +++
 gfx/thebes/gfxGDIFontList.cpp        |    2 +-
 gfx/thebes/gfxMacPlatformFontList.mm |    7 +++++++
 8 files changed, 97 insertions(+), 14 deletions(-)

diff --git a/gfx/thebes/gfxDWriteFontList.cpp b/gfx/thebes/gfxDWriteFontList.cpp
index 5eb2488..2e28fbf 100644
--- a/gfx/thebes/gfxDWriteFontList.cpp
+++ b/gfx/thebes/gfxDWriteFontList.cpp
@@ -1146,6 +1146,10 @@ gfxDWriteFontList::GetFontsFromCollection(IDWriteFontCollection* aCollection)
 
         nsDependentString familyName(enName.Elements());
 
+        if (!gfxFontUtils::IsFontFamilyNameAllowed(familyName)) {
+            continue;
+        }
+
         fam = new gfxDWriteFontFamily(familyName, family);
         if (!fam) {
             continue;
diff --git a/gfx/thebes/gfxFT2FontList.cpp b/gfx/thebes/gfxFT2FontList.cpp
index 671813b..da72559 100644
--- a/gfx/thebes/gfxFT2FontList.cpp
+++ b/gfx/thebes/gfxFT2FontList.cpp
@@ -1044,7 +1044,7 @@ gfxFT2FontList::AddFaceToList(const nsCString& aEntryName, uint32_t aIndex,
         NS_ConvertUTF8toUTF16 name(aFace->family_name);
         BuildKeyNameFromFontName(name);
         gfxFontFamily *family = fontFamilies.GetWeak(name);
-        if (!family) {
+        if (!family && gfxFontUtils::IsFontFamilyNameAllowed(name)) {
             family = new FT2FontFamily(name);
             fontFamilies.Put(name, family);
             if (mSkipSpaceLookupCheckFamilies.Contains(name)) {
@@ -1315,20 +1315,22 @@ gfxFT2FontList::AppendFaceFromFontListEntry(const FontListEntry& aFLE,
             aFLE.isHidden() ? mHiddenFontFamilies : mFontFamilies;
         fe->mStandardFace = (aStdFile == kStandard);
         nsAutoString name(aFLE.familyName());
-        gfxFontFamily *family = fontFamilies.GetWeak(name);
-        if (!family) {
-            family = new FT2FontFamily(name);
-            fontFamilies.Put(name, family);
-            if (mSkipSpaceLookupCheckFamilies.Contains(name)) {
-                family->SetSkipSpaceFeatureCheck(true);
-            }
-            if (mBadUnderlineFamilyNames.Contains(name)) {
-                family->SetBadUnderlineFamily();
+        if (gfxFontUtils::IsFontFamilyNameAllowed(name)) {
+            gfxFontFamily *family = fontFamilies.GetWeak(name);
+            if (!family) {
+                family = new FT2FontFamily(name);
+                fontFamilies.Put(name, family);
+                if (mSkipSpaceLookupCheckFamilies.Contains(name)) {
+                    family->SetSkipSpaceFeatureCheck(true);
+                }
+                if (mBadUnderlineFamilyNames.Contains(name)) {
+                    family->SetBadUnderlineFamily();
+                }
             }
-        }
-        family->AddFontEntry(fe);
+            family->AddFontEntry(fe);
 
-        fe->CheckForBrokenFont(family);
+            fe->CheckForBrokenFont(family);
+        }
     }
 }
 
diff --git a/gfx/thebes/gfxFontUtils.cpp b/gfx/thebes/gfxFontUtils.cpp
index 094f74a..5432c7a 100644
--- a/gfx/thebes/gfxFontUtils.cpp
+++ b/gfx/thebes/gfxFontUtils.cpp
@@ -1771,3 +1771,28 @@ gfxFontUtils::IsCffFont(const uint8_t* aFontData)
 
 #endif
 
+/* static */
+nsTHashtable<nsStringHashKey>* gfxFontUtils::sWhitelistFamilyNames = nullptr;
+
+/* static */
+bool
+gfxFontUtils::IsFontFamilyNameAllowed(const nsAString& aFontFamilyName)
+{
+    if (!sWhitelistFamilyNames) {
+        sWhitelistFamilyNames = new nsTHashtable<nsStringHashKey>();
+        nsAutoTArray<nsString, 10> list;
+        GetPrefsFontList("font.system.whitelist", list);
+        uint32_t numFonts = list.Length();
+        for (uint32_t i = 0; i < numFonts; i++) {
+            nsAutoString key;
+            ToLowerCase(list[i], key);
+            sWhitelistFamilyNames->PutEntry(key);
+        }
+    }
+    nsAutoString fontFamilyNameLower;
+    ToLowerCase(aFontFamilyName, fontFamilyNameLower);
+    // If whitelist is empty, any family name is allowed. If whitelist
+    // has entries, then only allow family names in the whitelist.
+    return sWhitelistFamilyNames->Count() == 0 ||
+           sWhitelistFamilyNames->Contains(fontFamilyNameLower);
+}
diff --git a/gfx/thebes/gfxFontUtils.h b/gfx/thebes/gfxFontUtils.h
index 2da48af..18eaa2d 100644
--- a/gfx/thebes/gfxFontUtils.h
+++ b/gfx/thebes/gfxFontUtils.h
@@ -1,3 +1,4 @@
+
 /* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 4 -*-
  * This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
@@ -9,6 +10,8 @@
 #include "gfxPlatform.h"
 #include "nsComponentManagerUtils.h"
 #include "nsTArray.h"
+#include "nsTHashtable.h"
+#include "nsHashKeys.h"
 #include "nsAutoPtr.h"
 #include "mozilla/Likely.h"
 #include "mozilla/Endian.h"
@@ -971,6 +974,14 @@ public:
                                     nsTArray<uint16_t> &aGlyphs,
                                     nsTArray<mozilla::gfx::Color> &aColors);
 
+    // A list of white-listed system fonts. If the list is empty, we permit
+    // all fonts.
+    static nsTHashtable<nsStringHashKey>* sWhitelistFamilyNames;
+
+    // Returns true only if the font family name is whitelisted or the
+    // whitelist is empty.
+    static bool IsFontFamilyNameAllowed(const nsAString& aFontFamilyName);
+
 protected:
     friend struct MacCharsetMappingComparator;
 
diff --git a/gfx/thebes/gfxFontconfigUtils.cpp b/gfx/thebes/gfxFontconfigUtils.cpp
index f5d3e9c..829a52e 100644
--- a/gfx/thebes/gfxFontconfigUtils.cpp
+++ b/gfx/thebes/gfxFontconfigUtils.cpp
@@ -587,6 +587,9 @@ gfxFontconfigUtils::UpdateFontListInternal(bool aForce)
     ActivateBundledFonts();
 #endif
 
+    ApplyWhitelist();
+    currentConfig = FcConfigGetCurrent();
+
     // These FcFontSets are owned by fontconfig
     FcFontSet *fontSets[] = {
         FcConfigGetFonts(currentConfig, FcSetSystem)
@@ -1087,4 +1090,32 @@ gfxFontconfigUtils::ActivateBundledFonts()
     }
 }
 
+void
+gfxFontconfigUtils::ApplyWhitelist()
+{
+    // Get the font family names in the font file loaded in the old configuration.
+    // If any of the font families are in our whitelist, then add that
+    // file to the new configuration. Otherwise, leave it out.
+    FcPattern *pattern = FcPatternCreate();
+    FcObjectSet *objectSet = FcObjectSetBuild(FC_FILE, FC_FAMILY, nullptr);
+    FcFontSet *fontSet = FcFontList(nullptr, pattern, objectSet);
+    FcConfig *newConfig = FcConfigCreate();
+    for (int i = 0; i < fontSet->nfont; ++i) {
+        FcPattern *font = fontSet->fonts[i];
+        FcChar8 *file, *family;
+        FcPatternGetString(font, FC_FILE, 0, &file);
+        for (int j = 0;
+             FcPatternGetString(font,
+                                FC_FAMILY, j, &family) == FcResultMatch;
+             ++j) {
+            nsAutoCString strFamily((char *) family);
+            if (gfxFontUtils::IsFontFamilyNameAllowed(NS_ConvertUTF8toUTF16(strFamily))) {
+                FcConfigAppFontAddFile(newConfig, file);
+                break;
+            }
+        }
+    }
+    FcConfigSetCurrent(newConfig);
+}
+
 #endif
diff --git a/gfx/thebes/gfxFontconfigUtils.h b/gfx/thebes/gfxFontconfigUtils.h
index de9f27f..7bd0cfc 100644
--- a/gfx/thebes/gfxFontconfigUtils.h
+++ b/gfx/thebes/gfxFontconfigUtils.h
@@ -310,6 +310,9 @@ protected:
     nsCString mBundledFontsPath;
     bool      mBundledFontsInitialized;
 #endif
+
+private:
+    void      ApplyWhitelist();
 };
 
 #endif /* GFX_FONTCONFIG_UTILS_H */
diff --git a/gfx/thebes/gfxGDIFontList.cpp b/gfx/thebes/gfxGDIFontList.cpp
index cce880b..7a0ba3f 100644
--- a/gfx/thebes/gfxGDIFontList.cpp
+++ b/gfx/thebes/gfxGDIFontList.cpp
@@ -697,7 +697,7 @@ gfxGDIFontList::EnumFontFamExProc(ENUMLOGFONTEXW *lpelfe,
 
     gfxGDIFontList *fontList = PlatformFontList();
 
-    if (!fontList->mFontFamilies.GetWeak(name)) {
+    if (gfxFontUtils::IsFontFamilyNameAllowed(name) && !fontList->mFontFamilies.GetWeak(name)) {
         nsDependentString faceName(lf.lfFaceName);
         nsRefPtr<gfxFontFamily> family = new GDIFontFamily(faceName);
         fontList->mFontFamilies.Put(name, family);
diff --git a/gfx/thebes/gfxMacPlatformFontList.mm b/gfx/thebes/gfxMacPlatformFontList.mm
index df859e5..02f5137 100644
--- a/gfx/thebes/gfxMacPlatformFontList.mm
+++ b/gfx/thebes/gfxMacPlatformFontList.mm
@@ -682,6 +682,10 @@ gfxMacPlatformFontList::InitFontList()
         buffer[len] = 0;
         nsAutoString familyName(reinterpret_cast<char16_t*>(buffer.Elements()), len);
 
+        if (!gfxFontUtils::IsFontFamilyNameAllowed(familyName)) {
+            continue;
+        }
+
         // create a family entry
         gfxFontFamily *familyEntry = new gfxMacFontFamily(familyName);
         if (!familyEntry) break;
@@ -726,6 +730,9 @@ gfxMacPlatformFontList::InitSingleFaceList()
         LOG_FONTLIST(("(fontlist-singleface) face name: %s\n",
                       NS_ConvertUTF16toUTF8(singleFaceFonts[i]).get()));
 #endif
+        if (!gfxFontUtils::IsFontFamilyNameAllowed(singleFaceFonts[i])) {
+            continue;
+        }
         gfxFontEntry *fontEntry = LookupLocalFont(singleFaceFonts[i],
                                                   400, 0,
                                                   NS_FONT_STYLE_NORMAL);



More information about the tor-commits mailing list