commit 2a36205b70076fc26145400addaa383142d71c81 Author: Arthur Edelstein arthuredelstein@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, nsTArraymozilla::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);