commit 6bd23bc373a372b010d5bdfb659ca3e17fcf864c
Author: Mike Perry <mikeperry-git(a)fscked.org>
Date: Wed Dec 28 22:12:08 2011 -0600
Add patch for font limiting.
---
...13-Limit-the-number-of-fonts-per-document.patch | 228 ++++++++++++++++++++
1 files changed, 228 insertions(+), 0 deletions(-)
diff --git a/src/current-patches/firefox/0013-Limit-the-number-of-fonts-per-document.patch b/src/current-patches/firefox/0013-Limit-the-number-of-fonts-per-document.patch
new file mode 100644
index 0000000..989d072
--- /dev/null
+++ b/src/current-patches/firefox/0013-Limit-the-number-of-fonts-per-document.patch
@@ -0,0 +1,228 @@
+From 27c2a4a72504fe9a08cbfdf2210b05263bd693dd Mon Sep 17 00:00:00 2001
+From: Mike Perry <mikeperry-git(a)fscked.org>
+Date: Tue, 27 Dec 2011 15:28:22 -0600
+Subject: [PATCH 13/13] Limit the number of fonts per document.
+
+We create two prefs:
+browser.display.max_font_count and browser.display.max_font_attempts.
+max_font_count sets a limit on the number of fonts actually used in the
+document, and max_font_attempts sets a limit on the total number of CSS
+queries that a document is allowed to perform.
+
+Once either limit is reached, the browser behaves as if
+browser.display.use_document_fonts was set to 0 for subsequent font queries.
+
+If a pref is not set or is negative, that limit does not apply.
+
+This is done to address:
+https://www.torproject.org/projects/torbrowser/design/#fingerprinting-linkability
+---
+ layout/base/nsPresContext.cpp | 100 +++++++++++++++++++++++++++++++++++++++++
+ layout/base/nsPresContext.h | 9 ++++
+ layout/style/nsRuleNode.cpp | 13 ++++-
+ 3 files changed, 119 insertions(+), 3 deletions(-)
+
+diff --git a/layout/base/nsPresContext.cpp b/layout/base/nsPresContext.cpp
+index 0d5b1ce..ab9a7ba 100644
+--- a/layout/base/nsPresContext.cpp
++++ b/layout/base/nsPresContext.cpp
+@@ -98,6 +98,8 @@
+ #include "nsIFrameMessageManager.h"
+ #include "FrameLayerBuilder.h"
+ #include "nsDOMMediaQueryList.h"
++#include "nsString.h"
++#include "nsUnicharUtils.h"
+
+ #ifdef MOZ_SMIL
+ #include "nsSMILAnimationController.h"
+@@ -707,6 +709,10 @@ nsPresContext::GetUserPreferences()
+ // * use fonts?
+ mUseDocumentFonts =
+ Preferences::GetInt("browser.display.use_document_fonts") != 0;
++ mMaxFonts =
++ Preferences::GetInt("browser.display.max_font_count", -1);
++ mMaxFontAttempts =
++ Preferences::GetInt("browser.display.max_font_attempts", -1);
+
+ // * replace backslashes with Yen signs? (bug 245770)
+ mEnableJapaneseTransform =
+@@ -1306,6 +1312,100 @@ nsPresContext::GetDefaultFont(PRUint8 aFontID) const
+ return font;
+ }
+
++PRBool
++nsPresContext::FontUseCountReached(const nsFont &font) {
++ if (mMaxFonts < 0) {
++ return PR_FALSE;
++ }
++
++ for (PRUint32 i = 0; i < mFontsUsed.Length(); i++) {
++ if (mFontsUsed[i].name.Equals(font.name,
++ nsCaseInsensitiveStringComparator())
++ // XXX: Style is sometimes filled with garbage??
++ /*&& mFontsUsed[i].style == font.style*/) {
++ // seen it before: OK
++ return PR_FALSE;
++ }
++ }
++
++ if (mFontsUsed.Length() >= mMaxFonts) {
++ return PR_TRUE;
++ }
++
++ return PR_FALSE;
++}
++
++PRBool
++nsPresContext::FontAttemptCountReached(const nsFont &font) {
++ if (mMaxFontAttempts < 0) {
++ return PR_FALSE;
++ }
++
++ for (PRUint32 i = 0; i < mFontsTried.Length(); i++) {
++ if (mFontsTried[i].name.Equals(font.name,
++ nsCaseInsensitiveStringComparator())
++ // XXX: Style is sometimes filled with garbage??
++ /*&& mFontsTried[i].style == font.style*/) {
++ // seen it before: OK
++ return PR_FALSE;
++ }
++ }
++
++ if (mFontsTried.Length() >= mMaxFontAttempts) {
++ return PR_TRUE;
++ }
++
++ return PR_FALSE;
++}
++
++void
++nsPresContext::AddFontUse(const nsFont &font) {
++ if (mMaxFonts < 0) {
++ return;
++ }
++
++ for (PRUint32 i = 0; i < mFontsUsed.Length(); i++) {
++ if (mFontsUsed[i].name.Equals(font.name,
++ nsCaseInsensitiveStringComparator())
++ // XXX: Style is sometimes filled with garbage??
++ /*&& mFontsUsed[i].style == font.style*/) {
++ // seen it before: OK
++ return;
++ }
++ }
++
++ if (mFontsUsed.Length() >= mMaxFonts) {
++ return;
++ }
++
++ mFontsUsed.AppendElement(font);
++ return;
++}
++
++void
++nsPresContext::AddFontAttempt(const nsFont &font) {
++ if (mMaxFontAttempts < 0) {
++ return;
++ }
++
++ for (PRUint32 i = 0; i < mFontsTried.Length(); i++) {
++ if (mFontsTried[i].name.Equals(font.name,
++ nsCaseInsensitiveStringComparator())
++ // XXX: Style is sometimes filled with garbage??
++ /*&& mFontsTried[i].style == font.style*/) {
++ // seen it before: OK
++ return;
++ }
++ }
++
++ if (mFontsTried.Length() >= mMaxFontAttempts) {
++ return;
++ }
++
++ mFontsTried.AppendElement(font);
++ return;
++}
++
+ void
+ nsPresContext::SetFullZoom(float aZoom)
+ {
+diff --git a/layout/base/nsPresContext.h b/layout/base/nsPresContext.h
+index 2b09cc0..fe8a926 100644
+--- a/layout/base/nsPresContext.h
++++ b/layout/base/nsPresContext.h
+@@ -548,6 +548,13 @@ public:
+ }
+ }
+
++ nsTArray<nsFont> mFontsUsed; // currently for font-count limiting only
++ nsTArray<nsFont> mFontsTried; // currently for font-count limiting only
++ void AddFontUse(const nsFont &font);
++ void AddFontAttempt(const nsFont &font);
++ PRBool FontUseCountReached(const nsFont &font);
++ PRBool FontAttemptCountReached(const nsFont &font);
++
+ PRInt32 MinFontSize() const {
+ return NS_MAX(mMinFontSize, mMinimumFontSizePref);
+ }
+@@ -1123,6 +1130,8 @@ protected:
+ PRUint32 mInterruptChecksToSkip;
+
+ mozilla::TimeStamp mReflowStartTime;
++ PRInt32 mMaxFontAttempts;
++ PRInt32 mMaxFonts;
+
+ unsigned mHasPendingInterrupt : 1;
+ unsigned mInterruptsEnabled : 1;
+diff --git a/layout/style/nsRuleNode.cpp b/layout/style/nsRuleNode.cpp
+index a791723..5d65984 100644
+--- a/layout/style/nsRuleNode.cpp
++++ b/layout/style/nsRuleNode.cpp
+@@ -3087,6 +3087,7 @@ nsRuleNode::ComputeFontData(void* aStartStruct,
+
+ // See if there is a minimum font-size constraint to honor
+ nscoord minimumFontSize = mPresContext->MinFontSize();
++ PRBool isXUL = PR_FALSE;
+
+ if (minimumFontSize < 0)
+ minimumFontSize = 0;
+@@ -3098,10 +3099,10 @@ nsRuleNode::ComputeFontData(void* aStartStruct,
+ // We only need to know this to determine if we have to use the
+ // document fonts (overriding the useDocumentFonts flag), or to
+ // determine if we have to override the minimum font-size constraint.
+- if ((!useDocumentFonts || minimumFontSize > 0) && mPresContext->IsChrome()) {
++ if (mPresContext->IsChrome()) {
+ // if we are not using document fonts, but this is a XUL document,
+ // then we use the document fonts anyway
+- useDocumentFonts = PR_TRUE;
++ isXUL = PR_TRUE;
+ minimumFontSize = 0;
+ }
+
+@@ -3116,9 +3117,13 @@ nsRuleNode::ComputeFontData(void* aStartStruct,
+ // generic?
+ nsFont::GetGenericID(font->mFont.name, &generic);
+
++ mPresContext->AddFontAttempt(font->mFont);
++
+ // If we aren't allowed to use document fonts, then we are only entitled
+ // to use the user's default variable-width font and fixed-width font
+- if (!useDocumentFonts) {
++ if (!isXUL && (!useDocumentFonts ||
++ mPresContext->FontAttemptCountReached(font->mFont) ||
++ mPresContext->FontUseCountReached(font->mFont))) {
+ // Extract the generic from the specified font family...
+ nsAutoString genericName;
+ if (!font->mFont.EnumerateFamilies(ExtractGeneric, &genericName)) {
+@@ -3154,6 +3159,8 @@ nsRuleNode::ComputeFontData(void* aStartStruct,
+ minimumFontSize, font);
+ }
+
++ if (font->mGenericID == kGenericFont_NONE)
++ mPresContext->AddFontUse(font->mFont);
+ COMPUTE_END_INHERITED(Font, font)
+ }
+
+--
+1.7.3.4
+