Skip to content
Snippets Groups Projects
Verified Commit 0377aef7 authored by Pier Angelo Vendrame's avatar Pier Angelo Vendrame :jack_o_lantern:
Browse files

BB 41901: Hardcode normalized FontSubstitutes.

Windows has a system to set font aliases through the registry.
This allows some customization that could be used as a fingerprinting
vector.
Moreover, this mechanism is used by Windows itself, and different SKUs
might have different default FontSubstitutes.
parent c3a0ab7d
No related branches found
No related tags found
1 merge request!1327TB 43387: Rebased Tor Browser alpha onto 128.6.0esr
......@@ -200,3 +200,68 @@ static const char* kLangPackFonts[] = {
// "Rockwell Nova", // Pan-European Supplemental Fonts - EXCLUDED
// "Verdana Pro", // Pan-European Supplemental Fonts - EXCLUDED
};
struct FontSubstitute {
const char *substituteName;
const char *actualFontName;
};
static const FontSubstitute kFontSubstitutes[] = {
// Common substitutions
{"Arabic Transparent", "Arial"},
{"Arabic Transparent Bold", "Arial Bold"},
{"Arial Baltic", "Arial"},
{"Arial CE", "Arial"},
{"Arial CYR", "Arial"},
{"Arial Greek", "Arial"},
{"Arial TUR", "Arial"},
{"Courier New Baltic", "Courier New"},
{"Courier New CE", "Courier New"},
{"Courier New CYR", "Courier New"},
{"Courier New Greek", "Courier New"},
{"Courier New TUR", "Courier New"},
{"Helv", "MS Sans Serif"},
{"Helvetica", "Arial"},
{"MS Shell Dlg 2", "Tahoma"},
{"Tahoma Armenian", "Tahoma"},
{"Times", "Times New Roman"},
{"Times New Roman Baltic", "Times New Roman"},
{"Times New Roman CE", "Times New Roman"},
{"Times New Roman CYR", "Times New Roman"},
{"Times New Roman Greek", "Times New Roman"},
{"Times New Roman TUR", "Times New Roman"},
{"Tms Rmn", "MS Serif"},
// Common, except Japanese (which uses MS UI Gothic, instead)
{"MS Shell Dlg", "Microsoft Sans Serif"},
// Arabic
{"Arial (Arabic)", "Arial"},
{"Courier New (Arabic)", "Courier New"},
{"Times New Roman (Arabic)", "Times New Roman"},
// Cyrillic + Greek
{"Courier", "Courier New"},
// Greek
{"Fixedsys Greek", "Fixedsys"},
{"MS Serif Greek", "MS Serif"},
{"MS Sans Serif Greek", "MS Sans Serif"},
{"Small Fonts Greek", "Small Fonts"},
{"System Greek", "System"},
// Hebrew
{"Arial (Hebrew)", "Arial"},
{"Courier New (Hebrew)", "Courier New"},
{"David Transparent", "David"},
{"Fixed Miriam Transparent", "Miriam Fixed"},
{"Miriam Transparent", "Miriam"},
{"Rod Transparent", "Rod"},
{"Times New Roman (Hebrew)", "Times New Roman"},
// Japanese
{"標準明朝", "MS 明朝"},
{"標準ゴシック", "MS ゴシック"},
{"ゴシック", "MS ゴシック"},
{"ゴシック", "MS ゴシック"},
{"クーリエ", "Courier"},
{"タイムズロマン", "Times New Roman"},
{"ヘルベチカ", "Arial"},
// Simplified Chinese
{"FangSong_GB2312", "FangSong"},
{"KaiTi_GB2312", "KaiTi"},
};
......@@ -1953,6 +1953,20 @@ static void RemoveCharsetFromFontSubstitute(nsACString& aName) {
#define MAX_VALUE_DATA 512
nsresult gfxDWriteFontList::GetFontSubstitutes() {
if (nsContentUtils::ShouldResistFingerprinting(
"Ignore any fingerprintable user font customization and normalize "
"font substitutes across different Windows SKUs.",
RFPTarget::FontVisibilityLangPack)) {
for (const FontSubstitute& fs : kFontSubstitutes) {
nsAutoCString substituteName(fs.substituteName);
nsAutoCString actualFontName(fs.actualFontName);
BuildKeyNameFromFontName(substituteName);
BuildKeyNameFromFontName(actualFontName);
AddSubstitute(substituteName, actualFontName);
}
return NS_OK;
}
HKEY hKey;
DWORD i, rv, lenAlias, lenActual, valueType;
WCHAR aliasName[MAX_VALUE_NAME];
......@@ -1987,39 +2001,46 @@ nsresult gfxDWriteFontList::GetFontSubstitutes() {
BuildKeyNameFromFontName(substituteName);
RemoveCharsetFromFontSubstitute(actualFontName);
BuildKeyNameFromFontName(actualFontName);
if (SharedFontList()) {
// Skip substitution if the original font is available, unless the option
// to apply substitutions unconditionally is enabled.
if (!StaticPrefs::gfx_windows_font_substitutes_always_AtStartup()) {
// Font substitutions are recorded for the canonical family names; we
// don't need FindFamily to consider localized aliases when searching.
if (SharedFontList()->FindFamily(substituteName,
/*aPrimaryNameOnly*/ true)) {
continue;
}
}
if (SharedFontList()->FindFamily(actualFontName,
AddSubstitute(substituteName, actualFontName);
}
return NS_OK;
}
void gfxDWriteFontList::AddSubstitute(const nsCString& substituteName,
const nsCString& actualFontName) {
if (SharedFontList()) {
// Skip substitution if the original font is available, unless the
// option to apply substitutions unconditionally is enabled.
if (!StaticPrefs::gfx_windows_font_substitutes_always_AtStartup()) {
// Font substitutions are recorded for the canonical family names;
// we don't need FindFamily to consider localized aliases when
// searching.
if (SharedFontList()->FindFamily(substituteName,
/*aPrimaryNameOnly*/ true)) {
mSubstitutions.InsertOrUpdate(substituteName,
MakeUnique<nsCString>(actualFontName));
} else if (mSubstitutions.Get(actualFontName)) {
mSubstitutions.InsertOrUpdate(
substituteName,
MakeUnique<nsCString>(*mSubstitutions.Get(actualFontName)));
} else {
mNonExistingFonts.AppendElement(substituteName);
return;
}
}
if (SharedFontList()->FindFamily(actualFontName,
/*aPrimaryNameOnly*/ true)) {
mSubstitutions.InsertOrUpdate(substituteName,
MakeUnique<nsCString>(actualFontName));
} else if (mSubstitutions.Get(actualFontName)) {
mSubstitutions.InsertOrUpdate(
substituteName,
MakeUnique<nsCString>(*mSubstitutions.Get(actualFontName)));
} else {
gfxFontFamily* ff;
if (!actualFontName.IsEmpty() &&
(ff = mFontFamilies.GetWeak(actualFontName))) {
mFontSubstitutes.InsertOrUpdate(substituteName, RefPtr{ff});
} else {
mNonExistingFonts.AppendElement(substituteName);
}
mNonExistingFonts.AppendElement(substituteName);
}
} else {
gfxFontFamily* ff;
if (!actualFontName.IsEmpty() &&
(ff = mFontFamilies.GetWeak(actualFontName))) {
mFontSubstitutes.InsertOrUpdate(substituteName, RefPtr{ff});
} else {
mNonExistingFonts.AppendElement(substituteName);
}
}
return NS_OK;
}
struct FontSubstitution {
......
......@@ -457,6 +457,9 @@ class gfxDWriteFontList final : public gfxPlatformFontList {
const nsTArray<nsCString>* aForceClassicFams = nullptr)
MOZ_REQUIRES(mLock);
void AddSubstitute(const nsCString& substituteName,
const nsCString& actualFontName);
#ifdef MOZ_BUNDLED_FONTS
already_AddRefed<IDWriteFontCollection> CreateBundledFontsCollection(
IDWriteFactory* aFactory);
......
......@@ -31,6 +31,10 @@
#include "mozilla/StaticPrefs_gfx.h"
#include "mozilla/Telemetry.h"
#include "nsContentUtils.h"
#include "StandardFonts-win10.inc"
#include <usp10.h>
using namespace mozilla;
......@@ -50,6 +54,10 @@ static __inline void BuildKeyNameFromFontName(nsAString& aName) {
if (aName.Length() >= LF_FACESIZE) aName.Truncate(LF_FACESIZE - 1);
ToLowerCase(aName);
}
static __inline void BuildKeyNameFromFontName(nsACString& aName) {
if (aName.Length() >= LF_FACESIZE) aName.Truncate(LF_FACESIZE - 1);
ToLowerCase(aName);
}
// Implementation of gfxPlatformFontList for Win32 GDI,
// using GDI font enumeration APIs to get the list of fonts
......@@ -529,6 +537,26 @@ static void RemoveCharsetFromFontSubstitute(nsAString& aName) {
#define MAX_VALUE_DATA 512
nsresult gfxGDIFontList::GetFontSubstitutes() {
if (nsContentUtils::ShouldResistFingerprinting(
"Ignore any fingerprintable user font customization and normalize "
"font substitutes across different Windows SKUs.",
RFPTarget::FontVisibilityLangPack)) {
for (const FontSubstitute& fs : kFontSubstitutes) {
nsAutoCString substituteName(fs.substituteName);
nsAutoCString actualFontName(fs.actualFontName);
BuildKeyNameFromFontName(substituteName);
BuildKeyNameFromFontName(actualFontName);
gfxFontFamily* ff;
if (!actualFontName.IsEmpty() &&
(ff = mFontFamilies.GetWeak(actualFontName))) {
mFontSubstitutes.InsertOrUpdate(substituteName, RefPtr{ff});
} else {
mNonExistingFonts.AppendElement(substituteName);
}
}
return NS_OK;
}
HKEY hKey;
DWORD i, rv, lenAlias, lenActual, valueType;
WCHAR aliasName[MAX_VALUE_NAME];
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment