+++ /dev/null
-From 215f7088f53e25309ec5037c05a25ed9048a625b Mon Sep 17 00:00:00 2001
-From: Mike Perry <mikeperry-git@torproject.org>
-Date: Wed, 1 Feb 2012 16:01:21 -0800
-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 c7ad359..ac12dff 100644
---- a/layout/base/nsPresContext.cpp
-+++ b/layout/base/nsPresContext.cpp
-@@ -98,6 +98,8 @@
- #include "FrameLayerBuilder.h"
- #include "nsDOMMediaQueryList.h"
- #include "nsSMILAnimationController.h"
-+#include "nsString.h"
-+#include "nsUnicharUtils.h"
-
- #ifdef IBMBIDI
- #include "nsBidiPresUtils.h"
-@@ -731,6 +733,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 =
-@@ -1332,6 +1338,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 39f5b4a..a72d12e 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);
- }
-@@ -1125,6 +1132,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 2918a54..5870693 100644
---- a/layout/style/nsRuleNode.cpp
-+++ b/layout/style/nsRuleNode.cpp
-@@ -3091,6 +3091,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;
-@@ -3102,10 +3103,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 = true;
-+ isXUL = PR_TRUE;
- minimumFontSize = 0;
- }
-
-@@ -3120,9 +3121,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)) {
-@@ -3158,6 +3163,8 @@ nsRuleNode::ComputeFontData(void* aStartStruct,
- minimumFontSize, font);
- }
-
-+ if (font->mGenericID == kGenericFont_NONE)
-+ mPresContext->AddFontUse(font->mFont);
- COMPUTE_END_INHERITED(Font, font)
- }
-
---
-1.7.5.4
-