1 From 4ed1e1c2372216cfcf377b369a9d44bb9f60ee14 Mon Sep 17 00:00:00 2001
2 From: Mike Perry <mikeperry-git@torproject.org>
3 Date: Wed, 1 Feb 2012 16:01:21 -0800
4 Subject: [PATCH 13/13] Limit the number of fonts per document.
7 browser.display.max_font_count and browser.display.max_font_attempts.
8 max_font_count sets a limit on the number of fonts actually used in the
9 document, and max_font_attempts sets a limit on the total number of CSS
10 queries that a document is allowed to perform.
12 Once either limit is reached, the browser behaves as if
13 browser.display.use_document_fonts was set to 0 for subsequent font queries.
15 If a pref is not set or is negative, that limit does not apply.
17 This is done to address:
18 https://www.torproject.org/projects/torbrowser/design/#fingerprinting-linkability
20 layout/base/nsPresContext.cpp | 100 +++++++++++++++++++++++++++++++++++++++++
21 layout/base/nsPresContext.h | 9 ++++
22 layout/style/nsRuleNode.cpp | 13 ++++-
23 3 files changed, 119 insertions(+), 3 deletions(-)
25 diff --git a/layout/base/nsPresContext.cpp b/layout/base/nsPresContext.cpp
26 index e1587db..9690d9c 100644
27 --- a/layout/base/nsPresContext.cpp
28 +++ b/layout/base/nsPresContext.cpp
30 #include "FrameLayerBuilder.h"
31 #include "nsDOMMediaQueryList.h"
32 #include "nsSMILAnimationController.h"
33 +#include "nsString.h"
34 +#include "nsUnicharUtils.h"
37 #include "nsBidiPresUtils.h"
38 @@ -706,6 +708,10 @@ nsPresContext::GetUserPreferences()
41 Preferences::GetInt("browser.display.use_document_fonts") != 0;
43 + Preferences::GetInt("browser.display.max_font_count", -1);
45 + Preferences::GetInt("browser.display.max_font_attempts", -1);
47 // * replace backslashes with Yen signs? (bug 245770)
48 mEnableJapaneseTransform =
49 @@ -1300,6 +1306,100 @@ nsPresContext::GetDefaultFont(PRUint8 aFontID) const
54 +nsPresContext::FontUseCountReached(const nsFont &font) {
55 + if (mMaxFonts < 0) {
59 + for (PRUint32 i = 0; i < mFontsUsed.Length(); i++) {
60 + if (mFontsUsed[i].name.Equals(font.name,
61 + nsCaseInsensitiveStringComparator())
62 + // XXX: Style is sometimes filled with garbage??
63 + /*&& mFontsUsed[i].style == font.style*/) {
64 + // seen it before: OK
69 + if (mFontsUsed.Length() >= mMaxFonts) {
77 +nsPresContext::FontAttemptCountReached(const nsFont &font) {
78 + if (mMaxFontAttempts < 0) {
82 + for (PRUint32 i = 0; i < mFontsTried.Length(); i++) {
83 + if (mFontsTried[i].name.Equals(font.name,
84 + nsCaseInsensitiveStringComparator())
85 + // XXX: Style is sometimes filled with garbage??
86 + /*&& mFontsTried[i].style == font.style*/) {
87 + // seen it before: OK
92 + if (mFontsTried.Length() >= mMaxFontAttempts) {
100 +nsPresContext::AddFontUse(const nsFont &font) {
101 + if (mMaxFonts < 0) {
105 + for (PRUint32 i = 0; i < mFontsUsed.Length(); i++) {
106 + if (mFontsUsed[i].name.Equals(font.name,
107 + nsCaseInsensitiveStringComparator())
108 + // XXX: Style is sometimes filled with garbage??
109 + /*&& mFontsUsed[i].style == font.style*/) {
110 + // seen it before: OK
115 + if (mFontsUsed.Length() >= mMaxFonts) {
119 + mFontsUsed.AppendElement(font);
124 +nsPresContext::AddFontAttempt(const nsFont &font) {
125 + if (mMaxFontAttempts < 0) {
129 + for (PRUint32 i = 0; i < mFontsTried.Length(); i++) {
130 + if (mFontsTried[i].name.Equals(font.name,
131 + nsCaseInsensitiveStringComparator())
132 + // XXX: Style is sometimes filled with garbage??
133 + /*&& mFontsTried[i].style == font.style*/) {
134 + // seen it before: OK
139 + if (mFontsTried.Length() >= mMaxFontAttempts) {
143 + mFontsTried.AppendElement(font);
148 nsPresContext::SetFullZoom(float aZoom)
150 diff --git a/layout/base/nsPresContext.h b/layout/base/nsPresContext.h
151 index ecd01d8..552a69a 100644
152 --- a/layout/base/nsPresContext.h
153 +++ b/layout/base/nsPresContext.h
154 @@ -548,6 +548,13 @@ public:
158 + nsTArray<nsFont> mFontsUsed; // currently for font-count limiting only
159 + nsTArray<nsFont> mFontsTried; // currently for font-count limiting only
160 + void AddFontUse(const nsFont &font);
161 + void AddFontAttempt(const nsFont &font);
162 + PRBool FontUseCountReached(const nsFont &font);
163 + PRBool FontAttemptCountReached(const nsFont &font);
165 PRInt32 MinFontSize() const {
166 return NS_MAX(mMinFontSize, mMinimumFontSizePref);
168 @@ -1117,6 +1124,8 @@ protected:
169 PRUint32 mInterruptChecksToSkip;
171 mozilla::TimeStamp mReflowStartTime;
172 + PRInt32 mMaxFontAttempts;
175 unsigned mHasPendingInterrupt : 1;
176 unsigned mInterruptsEnabled : 1;
177 diff --git a/layout/style/nsRuleNode.cpp b/layout/style/nsRuleNode.cpp
178 index 27336bf..827585a 100644
179 --- a/layout/style/nsRuleNode.cpp
180 +++ b/layout/style/nsRuleNode.cpp
181 @@ -3091,6 +3091,7 @@ nsRuleNode::ComputeFontData(void* aStartStruct,
183 // See if there is a minimum font-size constraint to honor
184 nscoord minimumFontSize = mPresContext->MinFontSize();
185 + PRBool isXUL = PR_FALSE;
187 if (minimumFontSize < 0)
189 @@ -3102,10 +3103,10 @@ nsRuleNode::ComputeFontData(void* aStartStruct,
190 // We only need to know this to determine if we have to use the
191 // document fonts (overriding the useDocumentFonts flag), or to
192 // determine if we have to override the minimum font-size constraint.
193 - if ((!useDocumentFonts || minimumFontSize > 0) && mPresContext->IsChrome()) {
194 + if (mPresContext->IsChrome()) {
195 // if we are not using document fonts, but this is a XUL document,
196 // then we use the document fonts anyway
197 - useDocumentFonts = true;
202 @@ -3120,9 +3121,13 @@ nsRuleNode::ComputeFontData(void* aStartStruct,
204 nsFont::GetGenericID(font->mFont.name, &generic);
206 + mPresContext->AddFontAttempt(font->mFont);
208 // If we aren't allowed to use document fonts, then we are only entitled
209 // to use the user's default variable-width font and fixed-width font
210 - if (!useDocumentFonts) {
211 + if (!isXUL && (!useDocumentFonts ||
212 + mPresContext->FontAttemptCountReached(font->mFont) ||
213 + mPresContext->FontUseCountReached(font->mFont))) {
214 // Extract the generic from the specified font family...
215 nsAutoString genericName;
216 if (!font->mFont.EnumerateFamilies(ExtractGeneric, &genericName)) {
217 @@ -3158,6 +3163,8 @@ nsRuleNode::ComputeFontData(void* aStartStruct,
218 minimumFontSize, font);
221 + if (font->mGenericID == kGenericFont_NONE)
222 + mPresContext->AddFontUse(font->mFont);
223 COMPUTE_END_INHERITED(Font, font)