[tor-commits] [torbrowser/master] Rebase Firefox patches for FF12.

mikeperry at torproject.org mikeperry at torproject.org
Wed Apr 25 00:45:06 UTC 2012


commit 412864331301d3dc15f59121ef476b1faf1013e1
Author: Mike Perry <mikeperry-git at fscked.org>
Date:   Tue Apr 24 17:28:39 2012 -0700

    Rebase Firefox patches for FF12.
    
    Hey, one of them even got merged!
---
 ...nents.interfaces-lookupMethod-from-conten.patch |   10 +-
 ...0002-Make-Permissions-Manager-memory-only.patch |    8 +-
 ...-Make-Intermediate-Cert-Store-memory-only.patch |    4 +-
 ...th-headers-before-the-modify-request-obse.patch |   52 -----
 .../firefox/0004-Add-a-string-based-cacheKey.patch |   85 +++++++
 .../firefox/0005-Add-a-string-based-cacheKey.patch |   85 -------
 .../0005-Block-all-plugins-except-flash.patch      |   85 +++++++
 ...ontent-pref-service-memory-only-clearable.patch |   37 +++
 ...ize-HTTP-request-order-and-pipeline-depth.patch |  234 --------------------
 .../0007-Block-all-plugins-except-flash.patch      |   85 -------
 ...owser-exit-when-not-launched-from-Vidalia.patch |   46 ++++
 .../0008-Disable-SSL-Session-ID-tracking.patch     |   28 +++
 ...ontent-pref-service-memory-only-clearable.patch |   37 ---
 ...owser-exit-when-not-launched-from-Vidalia.patch |   46 ----
 ...observer-event-to-close-persistent-connec.patch |   40 ++++
 .../0010-Disable-SSL-Session-ID-tracking.patch     |   28 ---
 ...e-client-values-only-to-CSS-Media-Queries.patch |   72 ++++++
 ...11-Limit-the-number-of-fonts-per-document.patch |  228 +++++++++++++++++++
 ...observer-event-to-close-persistent-connec.patch |   40 ----
 ...e-client-values-only-to-CSS-Media-Queries.patch |   72 ------
 ...ize-HTTP-request-order-and-pipeline-depth.patch |  234 ++++++++++++++++++++
 ...13-Limit-the-number-of-fonts-per-document.patch |  228 -------------------
 22 files changed, 866 insertions(+), 918 deletions(-)

diff --git a/src/current-patches/firefox/0001-Block-Components.interfaces-lookupMethod-from-conten.patch b/src/current-patches/firefox/0001-Block-Components.interfaces-lookupMethod-from-conten.patch
index bdc2f8d..159399a 100644
--- a/src/current-patches/firefox/0001-Block-Components.interfaces-lookupMethod-from-conten.patch
+++ b/src/current-patches/firefox/0001-Block-Components.interfaces-lookupMethod-from-conten.patch
@@ -1,7 +1,7 @@
-From 7b56d6e4ae963f13bb7469d803be823e366ec00c Mon Sep 17 00:00:00 2001
+From 878aa170944f7d44a76f0eb09214d46b6028c549 Mon Sep 17 00:00:00 2001
 From: Mike Perry <mikeperry-git at torproject.org>
 Date: Wed, 1 Feb 2012 15:40:40 -0800
-Subject: [PATCH 01/13] Block Components.interfaces,lookupMethod from content
+Subject: [PATCH 01/12] Block Components.interfaces,lookupMethod from content
 
 This patch removes the ability of content script to access
 Components.interfaces.* as well as call or access Components.lookupMethod.
@@ -20,10 +20,10 @@ https://trac.torproject.org/projects/tor/ticket/2874
  1 files changed, 6 insertions(+), 2 deletions(-)
 
 diff --git a/js/xpconnect/src/XPCComponents.cpp b/js/xpconnect/src/XPCComponents.cpp
-index ef3e5ac..e986db4 100644
+index 716cfdb..56e3f55 100644
 --- a/js/xpconnect/src/XPCComponents.cpp
 +++ b/js/xpconnect/src/XPCComponents.cpp
-@@ -4236,7 +4236,9 @@ nsXPCComponents::CanCreateWrapper(const nsIID * iid, char **_retval)
+@@ -4261,7 +4261,9 @@ nsXPCComponents::CanCreateWrapper(const nsIID * iid, char **_retval)
  NS_IMETHODIMP
  nsXPCComponents::CanCallMethod(const nsIID * iid, const PRUnichar *methodName, char **_retval)
  {
@@ -34,7 +34,7 @@ index ef3e5ac..e986db4 100644
      *_retval = xpc_CheckAccessList(methodName, allowed);
      return NS_OK;
  }
-@@ -4245,7 +4247,9 @@ nsXPCComponents::CanCallMethod(const nsIID * iid, const PRUnichar *methodName, c
+@@ -4270,7 +4272,9 @@ nsXPCComponents::CanCallMethod(const nsIID * iid, const PRUnichar *methodName, c
  NS_IMETHODIMP
  nsXPCComponents::CanGetProperty(const nsIID * iid, const PRUnichar *propertyName, char **_retval)
  {
diff --git a/src/current-patches/firefox/0002-Make-Permissions-Manager-memory-only.patch b/src/current-patches/firefox/0002-Make-Permissions-Manager-memory-only.patch
index 1ff64e3..b3a8372 100644
--- a/src/current-patches/firefox/0002-Make-Permissions-Manager-memory-only.patch
+++ b/src/current-patches/firefox/0002-Make-Permissions-Manager-memory-only.patch
@@ -1,7 +1,7 @@
-From 4640f62becabf5adefd190ae119c93e486be9aed Mon Sep 17 00:00:00 2001
+From 5f47c5bdf95633e28b6e338ba8794243b429aefb Mon Sep 17 00:00:00 2001
 From: Mike Perry <mikeperry-git at torproject.org>
 Date: Wed, 1 Feb 2012 15:45:16 -0800
-Subject: [PATCH 02/13] Make Permissions Manager memory-only
+Subject: [PATCH 02/12] Make Permissions Manager memory-only
 
 This patch exposes a pref 'permissions.memory_only' that properly isolates the
 permissions manager to memory, which is responsible for all user specified
@@ -16,7 +16,7 @@ https://trac.torproject.org/projects/tor/ticket/2950
  1 files changed, 31 insertions(+), 3 deletions(-)
 
 diff --git a/extensions/cookie/nsPermissionManager.cpp b/extensions/cookie/nsPermissionManager.cpp
-index 67eb216..12cc7cf 100644
+index cdfe21b..a7a0efb 100644
 --- a/extensions/cookie/nsPermissionManager.cpp
 +++ b/extensions/cookie/nsPermissionManager.cpp
 @@ -58,6 +58,10 @@
@@ -75,7 +75,7 @@ index 67eb216..12cc7cf 100644
      NS_ENSURE_SUCCESS(rv, rv);
  
      mDBConn->GetConnectionReady(&ready);
-@@ -783,7 +806,12 @@ NS_IMETHODIMP nsPermissionManager::Observe(nsISupports *aSubject, const char *aT
+@@ -794,7 +817,12 @@ NS_IMETHODIMP nsPermissionManager::Observe(nsISupports *aSubject, const char *aT
  {
    ENSURE_NOT_CHILD_PROCESS;
  
diff --git a/src/current-patches/firefox/0003-Make-Intermediate-Cert-Store-memory-only.patch b/src/current-patches/firefox/0003-Make-Intermediate-Cert-Store-memory-only.patch
index 49ca58e..8563f82 100644
--- a/src/current-patches/firefox/0003-Make-Intermediate-Cert-Store-memory-only.patch
+++ b/src/current-patches/firefox/0003-Make-Intermediate-Cert-Store-memory-only.patch
@@ -1,7 +1,7 @@
-From b24b0d0fdddb77692a1609109f4c7cfb4b6f11f8 Mon Sep 17 00:00:00 2001
+From 8cb78993225793692fe0560d25db4af55e0553bd Mon Sep 17 00:00:00 2001
 From: Mike Perry <mikeperry-git at fscked.org>
 Date: Fri, 19 Aug 2011 17:58:23 -0700
-Subject: [PATCH 03/13] Make Intermediate Cert Store memory-only.
+Subject: [PATCH 03/12] Make Intermediate Cert Store memory-only.
 
 This patch makes the intermediate SSL cert store exist in memory only.
 
diff --git a/src/current-patches/firefox/0004-Add-HTTP-auth-headers-before-the-modify-request-obse.patch b/src/current-patches/firefox/0004-Add-HTTP-auth-headers-before-the-modify-request-obse.patch
deleted file mode 100644
index 2f0ef83..0000000
--- a/src/current-patches/firefox/0004-Add-HTTP-auth-headers-before-the-modify-request-obse.patch
+++ /dev/null
@@ -1,52 +0,0 @@
-From d09a2b089ef401b08a8668b55b42233c81cbc198 Mon Sep 17 00:00:00 2001
-From: Mike Perry <mikeperry-git at fscked.org>
-Date: Fri, 2 Sep 2011 15:33:20 -0700
-Subject: [PATCH 04/13] Add HTTP auth headers before the modify-request
- observer.
-
-Otherwise, how are we supposed to modify them?
-
-Thanks to Georg Koppen for spotting both the problem and this fix.
----
- netwerk/protocol/http/nsHttpChannel.cpp |   11 +++++++----
- 1 files changed, 7 insertions(+), 4 deletions(-)
-
-diff --git a/netwerk/protocol/http/nsHttpChannel.cpp b/netwerk/protocol/http/nsHttpChannel.cpp
-index 7c88d41..0cab7a4 100644
---- a/netwerk/protocol/http/nsHttpChannel.cpp
-+++ b/netwerk/protocol/http/nsHttpChannel.cpp
-@@ -328,9 +328,6 @@ nsHttpChannel::Connect(bool firstTime)
-         return NS_ERROR_DOCUMENT_NOT_CACHED;
-     }
- 
--    // check to see if authorization headers should be included
--    mAuthProvider->AddAuthorizationHeaders();
--
-     if (mLoadFlags & LOAD_NO_NETWORK_IO) {
-         return NS_ERROR_DOCUMENT_NOT_CACHED;
-     }
-@@ -3743,6 +3740,9 @@ nsHttpChannel::AsyncOpen(nsIStreamListener *listener, nsISupports *context)
- 
-     AddCookiesToRequest();
- 
-+    // check to see if authorization headers should be included
-+    mAuthProvider->AddAuthorizationHeaders();
-+
-     // notify "http-on-modify-request" observers
-     gHttpHandler->OnModifyRequest(this);
- 
-@@ -4847,7 +4847,10 @@ nsHttpChannel::DoAuthRetry(nsAHttpConnection *conn)
-     // this authentication attempt (bug 84794).
-     // TODO: save cookies from auth response and send them here (bug 572151).
-     AddCookiesToRequest();
--    
-+   
-+    // check to see if authorization headers should be included
-+    mAuthProvider->AddAuthorizationHeaders();
-+ 
-     // notify "http-on-modify-request" observers
-     gHttpHandler->OnModifyRequest(this);
- 
--- 
-1.7.5.4
-
diff --git a/src/current-patches/firefox/0004-Add-a-string-based-cacheKey.patch b/src/current-patches/firefox/0004-Add-a-string-based-cacheKey.patch
new file mode 100644
index 0000000..8c5a717
--- /dev/null
+++ b/src/current-patches/firefox/0004-Add-a-string-based-cacheKey.patch
@@ -0,0 +1,85 @@
+From c4212c764149b74a04aad7d15cb3df810512e4ba Mon Sep 17 00:00:00 2001
+From: Mike Perry <mikeperry-git at fscked.org>
+Date: Fri, 2 Sep 2011 20:47:02 -0700
+Subject: [PATCH 04/12] Add a string-based cacheKey.
+
+Used for isolating cache according to same-origin policy.
+---
+ netwerk/base/public/nsICachingChannel.idl |    7 +++++++
+ netwerk/protocol/http/nsHttpChannel.cpp   |   22 ++++++++++++++++++++++
+ netwerk/protocol/http/nsHttpChannel.h     |    1 +
+ 3 files changed, 30 insertions(+), 0 deletions(-)
+
+diff --git a/netwerk/base/public/nsICachingChannel.idl b/netwerk/base/public/nsICachingChannel.idl
+index 2da46d6..4ee5774 100644
+--- a/netwerk/base/public/nsICachingChannel.idl
++++ b/netwerk/base/public/nsICachingChannel.idl
+@@ -98,6 +98,13 @@ interface nsICachingChannel : nsICacheInfoChannel
+     attribute nsISupports cacheKey;
+ 
+     /**
++     * Set/get the cache domain... uniquely identifies the data in the cache
++     * for this channel.  Holding a reference to this key does NOT prevent
++     * the cached data from being removed.
++     */
++    attribute AUTF8String cacheDomain;
++
++    /**
+      * Specifies whether or not the data should be cached to a file.  This
+      * may fail if the disk cache is not present.  The value of this attribute
+      * is usually only settable during the processing of a channel's
+diff --git a/netwerk/protocol/http/nsHttpChannel.cpp b/netwerk/protocol/http/nsHttpChannel.cpp
+index fab0726..5f42b7b 100644
+--- a/netwerk/protocol/http/nsHttpChannel.cpp
++++ b/netwerk/protocol/http/nsHttpChannel.cpp
+@@ -2415,6 +2415,12 @@ nsHttpChannel::AssembleCacheKey(const char *spec, PRUint32 postID,
+         cacheKey.Append(buf);
+     }
+ 
++    if (strlen(mCacheDomain.get()) > 0) {
++        cacheKey.AppendLiteral("domain=");
++        cacheKey.Append(mCacheDomain.get());
++        cacheKey.AppendLiteral("&");
++    }
++
+     if (!cacheKey.IsEmpty()) {
+         cacheKey.AppendLiteral("uri=");
+     }
+@@ -4762,6 +4768,22 @@ nsHttpChannel::SetCacheForOfflineUse(bool value)
+ }
+ 
+ NS_IMETHODIMP
++nsHttpChannel::GetCacheDomain(nsACString &value)
++{
++    value = mCacheDomain;
++
++    return NS_OK;
++}
++
++NS_IMETHODIMP
++nsHttpChannel::SetCacheDomain(const nsACString &value)
++{
++    mCacheDomain = value;
++
++    return NS_OK;
++}
++
++NS_IMETHODIMP
+ nsHttpChannel::GetOfflineCacheClientID(nsACString &value)
+ {
+     value = mOfflineCacheClientID;
+diff --git a/netwerk/protocol/http/nsHttpChannel.h b/netwerk/protocol/http/nsHttpChannel.h
+index b7bba48..605dc80 100644
+--- a/netwerk/protocol/http/nsHttpChannel.h
++++ b/netwerk/protocol/http/nsHttpChannel.h
+@@ -304,6 +304,7 @@ private:
+     nsCOMPtr<nsICacheEntryDescriptor> mOfflineCacheEntry;
+     nsCacheAccessMode                 mOfflineCacheAccess;
+     nsCString                         mOfflineCacheClientID;
++    nsCString                         mCacheDomain;
+ 
+     // auth specific data
+     nsCOMPtr<nsIHttpChannelAuthProvider> mAuthProvider;
+-- 
+1.7.5.4
+
diff --git a/src/current-patches/firefox/0005-Add-a-string-based-cacheKey.patch b/src/current-patches/firefox/0005-Add-a-string-based-cacheKey.patch
deleted file mode 100644
index c0b8be5..0000000
--- a/src/current-patches/firefox/0005-Add-a-string-based-cacheKey.patch
+++ /dev/null
@@ -1,85 +0,0 @@
-From 76dfe3891b66f4a6ba352cf543ca52ff59aa65cd Mon Sep 17 00:00:00 2001
-From: Mike Perry <mikeperry-git at fscked.org>
-Date: Fri, 2 Sep 2011 20:47:02 -0700
-Subject: [PATCH 05/13] Add a string-based cacheKey.
-
-Used for isolating cache according to same-origin policy.
----
- netwerk/base/public/nsICachingChannel.idl |    7 +++++++
- netwerk/protocol/http/nsHttpChannel.cpp   |   22 ++++++++++++++++++++++
- netwerk/protocol/http/nsHttpChannel.h     |    1 +
- 3 files changed, 30 insertions(+), 0 deletions(-)
-
-diff --git a/netwerk/base/public/nsICachingChannel.idl b/netwerk/base/public/nsICachingChannel.idl
-index 2da46d6..4ee5774 100644
---- a/netwerk/base/public/nsICachingChannel.idl
-+++ b/netwerk/base/public/nsICachingChannel.idl
-@@ -98,6 +98,13 @@ interface nsICachingChannel : nsICacheInfoChannel
-     attribute nsISupports cacheKey;
- 
-     /**
-+     * Set/get the cache domain... uniquely identifies the data in the cache
-+     * for this channel.  Holding a reference to this key does NOT prevent
-+     * the cached data from being removed.
-+     */
-+    attribute AUTF8String cacheDomain;
-+
-+    /**
-      * Specifies whether or not the data should be cached to a file.  This
-      * may fail if the disk cache is not present.  The value of this attribute
-      * is usually only settable during the processing of a channel's
-diff --git a/netwerk/protocol/http/nsHttpChannel.cpp b/netwerk/protocol/http/nsHttpChannel.cpp
-index 0cab7a4..2c2803f 100644
---- a/netwerk/protocol/http/nsHttpChannel.cpp
-+++ b/netwerk/protocol/http/nsHttpChannel.cpp
-@@ -2408,6 +2408,12 @@ nsHttpChannel::AssembleCacheKey(const char *spec, PRUint32 postID,
-         cacheKey.Append(buf);
-     }
- 
-+    if (strlen(mCacheDomain.get()) > 0) {
-+        cacheKey.AppendLiteral("domain=");
-+        cacheKey.Append(mCacheDomain.get());
-+        cacheKey.AppendLiteral("&");
-+    }
-+
-     if (!cacheKey.IsEmpty()) {
-         cacheKey.AppendLiteral("uri=");
-     }
-@@ -4747,6 +4753,22 @@ nsHttpChannel::SetCacheForOfflineUse(bool value)
- }
- 
- NS_IMETHODIMP
-+nsHttpChannel::GetCacheDomain(nsACString &value)
-+{
-+    value = mCacheDomain;
-+
-+    return NS_OK;
-+}
-+
-+NS_IMETHODIMP
-+nsHttpChannel::SetCacheDomain(const nsACString &value)
-+{
-+    mCacheDomain = value;
-+
-+    return NS_OK;
-+}
-+
-+NS_IMETHODIMP
- nsHttpChannel::GetOfflineCacheClientID(nsACString &value)
- {
-     value = mOfflineCacheClientID;
-diff --git a/netwerk/protocol/http/nsHttpChannel.h b/netwerk/protocol/http/nsHttpChannel.h
-index 88ce469..53538cf 100644
---- a/netwerk/protocol/http/nsHttpChannel.h
-+++ b/netwerk/protocol/http/nsHttpChannel.h
-@@ -303,6 +303,7 @@ private:
-     nsCOMPtr<nsICacheEntryDescriptor> mOfflineCacheEntry;
-     nsCacheAccessMode                 mOfflineCacheAccess;
-     nsCString                         mOfflineCacheClientID;
-+    nsCString                         mCacheDomain;
- 
-     // auth specific data
-     nsCOMPtr<nsIHttpChannelAuthProvider> mAuthProvider;
--- 
-1.7.5.4
-
diff --git a/src/current-patches/firefox/0005-Block-all-plugins-except-flash.patch b/src/current-patches/firefox/0005-Block-all-plugins-except-flash.patch
new file mode 100644
index 0000000..00bf898
--- /dev/null
+++ b/src/current-patches/firefox/0005-Block-all-plugins-except-flash.patch
@@ -0,0 +1,85 @@
+From 89d6deddce94c720793a33a1c9fc812ad65116a9 Mon Sep 17 00:00:00 2001
+From: Mike Perry <mikeperry-git at torproject.org>
+Date: Wed, 1 Feb 2012 15:50:15 -0800
+Subject: [PATCH 05/12] Block all plugins except flash.
+
+We cannot use the @mozilla.org/extensions/blocklist;1 service, because we
+actually want to stop plugins from ever entering the browser's process space
+and/or executing code (for example, AV plugins that collect statistics/analyse
+urls, magical toolbars that phone home or "help" the user, skype buttons that
+ruin our day, and censorship filters). Hence we rolled our own.
+
+See https://trac.torproject.org/projects/tor/ticket/3547#comment:6 for musings
+on a better way. Until then, it is delta-darwinism for us.
+---
+ dom/plugins/base/nsPluginHost.cpp |   33 +++++++++++++++++++++++++++++++++
+ dom/plugins/base/nsPluginHost.h   |    2 ++
+ 2 files changed, 35 insertions(+), 0 deletions(-)
+
+diff --git a/dom/plugins/base/nsPluginHost.cpp b/dom/plugins/base/nsPluginHost.cpp
+index ed081fc..7384bcc 100644
+--- a/dom/plugins/base/nsPluginHost.cpp
++++ b/dom/plugins/base/nsPluginHost.cpp
+@@ -1985,6 +1985,35 @@ bool nsPluginHost::IsDuplicatePlugin(nsPluginTag * aPluginTag)
+   return false;
+ }
+ 
++PRBool nsPluginHost::GhettoBlacklist(nsIFile *pluginFile)
++{
++    nsCString leaf;
++    const char *leafStr;
++    nsresult rv;
++    
++    rv = pluginFile->GetNativeLeafName(leaf);
++    if (NS_FAILED(rv)) {
++        return PR_TRUE; // fuck 'em. blacklist.
++    }
++
++    leafStr = leaf.get();
++
++    if (!leafStr) {
++        return PR_TRUE; // fuck 'em. blacklist.
++    }
++
++    // libgnashplugin.so, libflashplayer.so, Flash Player-10.4-10.5.plugin,
++    // NPSWF32.dll, NPSWF64.dll
++    if (strstr(leafStr, "libgnashplugin") == leafStr ||
++        strstr(leafStr, "libflashplayer") == leafStr ||
++        strstr(leafStr, "Flash Player") == leafStr ||
++        strstr(leafStr, "NPSWF") == leafStr) {
++        return PR_FALSE;
++    }
++
++    return PR_TRUE; // fuck 'em. blacklist.
++}
++
+ typedef NS_NPAPIPLUGIN_CALLBACK(char *, NP_GETMIMEDESCRIPTION)(void);
+ 
+ nsresult nsPluginHost::ScanPluginsDirectory(nsIFile *pluginsDir,
+@@ -2118,6 +2147,10 @@ nsresult nsPluginHost::ScanPluginsDirectory(nsIFile *pluginsDir,
+       continue;
+     }
+ 
++    if (GhettoBlacklist(localfile)) {
++        continue;
++    }
++
+     // if it is not found in cache info list or has been changed, create a new one
+     if (!pluginTag) {
+       nsPluginFile pluginFile(localfile);
+diff --git a/dom/plugins/base/nsPluginHost.h b/dom/plugins/base/nsPluginHost.h
+index 5630b8d..f54bd32 100644
+--- a/dom/plugins/base/nsPluginHost.h
++++ b/dom/plugins/base/nsPluginHost.h
+@@ -285,6 +285,8 @@ private:
+   // Loads all cached plugins info into mCachedPlugins
+   nsresult ReadPluginInfo();
+ 
++  PRBool GhettoBlacklist(nsIFile *pluginFile);
++
+   // Given a file path, returns the plugins info from our cache
+   // and removes it from the cache.
+   void RemoveCachedPluginsInfo(const char *filePath,
+-- 
+1.7.5.4
+
diff --git a/src/current-patches/firefox/0006-Make-content-pref-service-memory-only-clearable.patch b/src/current-patches/firefox/0006-Make-content-pref-service-memory-only-clearable.patch
new file mode 100644
index 0000000..c494e1e
--- /dev/null
+++ b/src/current-patches/firefox/0006-Make-content-pref-service-memory-only-clearable.patch
@@ -0,0 +1,37 @@
+From b2cc8f517c6589def4cc126af0b5f1898d61541c Mon Sep 17 00:00:00 2001
+From: Mike Perry <mikeperry-git at fscked.org>
+Date: Thu, 8 Sep 2011 08:40:17 -0700
+Subject: [PATCH 06/12] Make content pref service memory-only + clearable
+
+This prevents random urls from being inserted into content-prefs.sqllite in
+the profile directory as content prefs change (includes site-zoom and perhaps
+other site prefs?).
+---
+ .../contentprefs/nsContentPrefService.js           |    4 ++--
+ 1 files changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/toolkit/components/contentprefs/nsContentPrefService.js b/toolkit/components/contentprefs/nsContentPrefService.js
+index 17cac93..1f12609 100644
+--- a/toolkit/components/contentprefs/nsContentPrefService.js
++++ b/toolkit/components/contentprefs/nsContentPrefService.js
+@@ -1242,7 +1242,7 @@ ContentPrefService.prototype = {
+ 
+     var dbConnection;
+ 
+-    if (!dbFile.exists())
++    if (true || !dbFile.exists())
+       dbConnection = this._dbCreate(dbService, dbFile);
+     else {
+       try {
+@@ -1290,7 +1290,7 @@ ContentPrefService.prototype = {
+   },
+ 
+   _dbCreate: function ContentPrefService__dbCreate(aDBService, aDBFile) {
+-    var dbConnection = aDBService.openDatabase(aDBFile);
++    var dbConnection = aDBService.openSpecialDatabase("memory");
+ 
+     try {
+       this._dbCreateSchema(dbConnection);
+-- 
+1.7.5.4
+
diff --git a/src/current-patches/firefox/0006-Randomize-HTTP-request-order-and-pipeline-depth.patch b/src/current-patches/firefox/0006-Randomize-HTTP-request-order-and-pipeline-depth.patch
deleted file mode 100644
index 9687737..0000000
--- a/src/current-patches/firefox/0006-Randomize-HTTP-request-order-and-pipeline-depth.patch
+++ /dev/null
@@ -1,234 +0,0 @@
-From 8e8833ea22369c7597f5844139de37212deb1cd7 Mon Sep 17 00:00:00 2001
-From: Mike Perry <mikeperry-git at torproject.org>
-Date: Thu, 15 Mar 2012 20:05:07 -0700
-Subject: [PATCH 12/12] Randomize HTTP request order and pipeline depth.
-
-This is an experimental defense against
-http://lorre.uni.lu/~andriy/papers/acmccs-wpes11-fingerprinting.pdf
-
-See:
-https://blog.torproject.org/blog/experimental-defense-website-traffic-fingerprinting
-
-This defense has been improved since that blog post to additionally randomize
-the order and concurrency of non-pipelined HTTP requests.
----
- netwerk/protocol/http/nsHttpConnectionMgr.cpp |  133 ++++++++++++++++++++++++-
- netwerk/protocol/http/nsHttpConnectionMgr.h   |    5 +
- 2 files changed, 133 insertions(+), 5 deletions(-)
-
-diff --git a/netwerk/protocol/http/nsHttpConnectionMgr.cpp b/netwerk/protocol/http/nsHttpConnectionMgr.cpp
-index 17d897f..8f50bf6 100644
---- a/netwerk/protocol/http/nsHttpConnectionMgr.cpp
-+++ b/netwerk/protocol/http/nsHttpConnectionMgr.cpp
-@@ -99,6 +99,12 @@ nsHttpConnectionMgr::nsHttpConnectionMgr()
-     LOG(("Creating nsHttpConnectionMgr @%x\n", this));
-     mCT.Init();
-     mAlternateProtocolHash.Init(16);
-+
-+    nsresult rv;
-+    mRandomGenerator = do_GetService("@mozilla.org/security/random-generator;1", &rv);
-+    if (NS_FAILED(rv)) {
-+        mRandomGenerator = nsnull;
-+    }
- }
- 
- nsHttpConnectionMgr::~nsHttpConnectionMgr()
-@@ -353,8 +359,12 @@ nsHttpConnectionMgr::AddTransactionToPipeline(nsHttpPipeline *pipeline)
-         nsConnectionEntry *ent = mCT.Get(ci->HashKey());
-         if (ent) {
-             // search for another request to pipeline...
--            PRInt32 i, count = ent->mPendingQ.Length();
--            for (i=0; i<count; ++i) {
-+            PRInt32 i, h, count = ent->mPendingQ.Length();
-+            PRInt32 ind[count];
-+            ShuffleRequestOrder((PRUint32*)ind, (PRUint32)count);
-+       
-+            for (h=0; h<count; ++h) {
-+                i = ind[h]; // random request sequence
-                 nsHttpTransaction *trans = ent->mPendingQ[i];
-                 if (trans->Caps() & NS_HTTP_ALLOW_PIPELINING) {
-                     pipeline->AddTransaction(trans);
-@@ -895,12 +905,17 @@ nsHttpConnectionMgr::ProcessPendingQForEntry(nsConnectionEntry *ent)
-     if (gHttpHandler->IsSpdyEnabled())
-         ProcessSpdyPendingQ(ent);
- 
--    PRUint32 i, count = ent->mPendingQ.Length();
-+    PRUint32 h, i = 0, count = ent->mPendingQ.Length();
-     if (count > 0) {
-         LOG(("  pending-count=%u\n", count));
-         nsHttpTransaction *trans = nsnull;
-         nsHttpConnection *conn = nsnull;
--        for (i = 0; i < count; ++i) {
-+
-+        PRUint32 ind[count];
-+        ShuffleRequestOrder(ind, count);
-+       
-+        for (h=0; h<count; ++h) {
-+            i = ind[h]; // random request sequence
-             trans = ent->mPendingQ[i];
- 
-             // When this transaction has already established a half-open
-@@ -1011,6 +1026,19 @@ nsHttpConnectionMgr::AtActiveConnectionLimit(nsConnectionEntry *ent, PRUint8 cap
-         maxPersistConns = mMaxPersistConnsPerHost;
-     }
- 
-+    // Fuzz maxConns for website fingerprinting attack
-+    // We create a range of maxConns/5 up to 6*maxConns/5 
-+    // because this function is called repeatedly, and we'll
-+    // end up converging on a the high side of concurrent connections
-+    // after a short while. 
-+    PRUint8 *bytes = nsnull;
-+    nsresult rv = mRandomGenerator->GenerateRandomBytes(1, &bytes);
-+    NS_ENSURE_SUCCESS(rv, rv);
-+
-+    bytes[0] = bytes[0] % (maxConns + 1);
-+    maxConns = (maxConns/5) + bytes[0];
-+    NS_Free(bytes);
-+
-     // use >= just to be safe
-     return (totalCount >= maxConns) || ( (caps & NS_HTTP_ALLOW_KEEPALIVE) &&
-                                          (persistCount >= maxPersistConns) );
-@@ -1227,7 +1255,7 @@ nsHttpConnectionMgr::DispatchTransaction(nsConnectionEntry *ent,
- 
-     if (conn->SupportsPipelining() && (caps & NS_HTTP_ALLOW_PIPELINING)) {
-         LOG(("  looking to build pipeline...\n"));
--        if (BuildPipeline(ent, trans, &pipeline))
-+        if (BuildRandomizedPipeline(ent, trans, &pipeline))
-             trans = pipeline;
-     }
- 
-@@ -1300,6 +1328,101 @@ nsHttpConnectionMgr::BuildPipeline(nsConnectionEntry *ent,
-     return true;
- }
- 
-+
-+// Generate a shuffled request ordering sequence 
-+void
-+nsHttpConnectionMgr::ShuffleRequestOrder(PRUint32 *ind, PRUint32 count)
-+{
-+   PRUint32 i;
-+   PRUint32 *rints;
-+
-+   for (i=0; i<count; ++i) {
-+       ind[i] = i;
-+   }
-+   nsresult rv = mRandomGenerator->GenerateRandomBytes(sizeof(PRUint32)*count,
-+                                                       (PRUint8**)&rints);
-+   if (NS_FAILED(rv))
-+       return; // Leave unshuffled if error
-+
-+   for (i=0; i < count; ++i) {
-+       PRInt32 temp = ind[i];
-+       ind[i] = ind[rints[i]%count]; 
-+       ind[rints[i]%count] = temp;
-+   }
-+   NS_Free(rints);
-+}
-+
-+bool
-+nsHttpConnectionMgr::BuildRandomizedPipeline(nsConnectionEntry *ent,
-+                                   nsAHttpTransaction *firstTrans,
-+                                   nsHttpPipeline **result)
-+{
-+    if (mRandomGenerator == nsnull)
-+        return BuildPipeline(ent, firstTrans, result);
-+    if (mMaxPipelinedRequests < 2)
-+        return PR_FALSE;
-+
-+    nsresult rv;
-+    PRUint8 *bytes = nsnull;
-+
-+    nsHttpPipeline *pipeline = nsnull;
-+    nsHttpTransaction *trans;
-+
-+    PRUint32 i = 0, numAdded = 0, numAllowed = 0;
-+    PRUint32 max = 0;
-+
-+    while (i < ent->mPendingQ.Length()) {
-+        if (ent->mPendingQ[i]->Caps() & NS_HTTP_ALLOW_PIPELINING)
-+            numAllowed++;
-+        i++;
-+    }
-+
-+    rv = mRandomGenerator->GenerateRandomBytes(1, &bytes);
-+    NS_ENSURE_SUCCESS(rv, rv);
-+    // 4...12
-+    max = 4 + (bytes[0] % (mMaxPipelinedRequests + 1));
-+    NS_Free(bytes);
-+
-+    while (numAllowed > 0) {
-+        rv = mRandomGenerator->GenerateRandomBytes(1, &bytes);
-+        NS_ENSURE_SUCCESS(rv, rv);
-+        i = bytes[0] % ent->mPendingQ.Length();
-+        NS_Free(bytes);
-+
-+        trans = ent->mPendingQ[i];
-+
-+        if (!(ent->mPendingQ[i]->Caps() & NS_HTTP_ALLOW_PIPELINING))
-+            continue;
-+
-+        if (numAdded == 0) {
-+            pipeline = new nsHttpPipeline;
-+            if (!pipeline)
-+                return PR_FALSE;
-+            pipeline->AddTransaction(firstTrans);
-+            numAdded = 1;
-+        }
-+        pipeline->AddTransaction(trans);
-+
-+        // remove transaction from pending queue
-+        ent->mPendingQ.RemoveElementAt(i);
-+        NS_RELEASE(trans);
-+
-+        numAllowed--;
-+
-+        if (++numAdded == max)
-+            break;
-+    }
-+
-+    //fprintf(stderr, "Yay!!! pipelined %u/%u transactions\n", numAdded, max);
-+    LOG(("  pipelined %u/%u transactions\n", numAdded, max));
-+
-+    if (numAdded == 0)
-+        return PR_FALSE;
-+
-+    NS_ADDREF(*result = pipeline);
-+    return PR_TRUE;
-+}
-+
- nsresult
- nsHttpConnectionMgr::ProcessNewTransaction(nsHttpTransaction *trans)
- {
-diff --git a/netwerk/protocol/http/nsHttpConnectionMgr.h b/netwerk/protocol/http/nsHttpConnectionMgr.h
-index bb605a1..e372096 100644
---- a/netwerk/protocol/http/nsHttpConnectionMgr.h
-+++ b/netwerk/protocol/http/nsHttpConnectionMgr.h
-@@ -54,6 +54,7 @@
- #include "nsIObserver.h"
- #include "nsITimer.h"
- #include "nsIX509Cert3.h"
-+#include "nsIRandomGenerator.h"
- 
- class nsHttpPipeline;
- 
-@@ -312,6 +313,8 @@ private:
-     nsresult DispatchTransaction(nsConnectionEntry *, nsHttpTransaction *,
-                                  PRUint8 caps, nsHttpConnection *);
-     bool     BuildPipeline(nsConnectionEntry *, nsAHttpTransaction *, nsHttpPipeline **);
-+    bool     BuildRandomizedPipeline(nsConnectionEntry *, nsAHttpTransaction *, nsHttpPipeline **);
-+    void     ShuffleRequestOrder(PRUint32 *, PRUint32);
-     nsresult ProcessNewTransaction(nsHttpTransaction *);
-     nsresult EnsureSocketThreadTargetIfOnline();
-     void     ClosePersistentConnections(nsConnectionEntry *ent);
-@@ -405,6 +408,8 @@ private:
-     PRUint64 mTimeOfNextWakeUp;
-     // Timer for next pruning of dead connections.
-     nsCOMPtr<nsITimer> mTimer;
-+    // Random number generator for reordering HTTP pipeline
-+    nsCOMPtr<nsIRandomGenerator>             mRandomGenerator;
- 
-     //
-     // the connection table
--- 
-1.7.5.4
-
diff --git a/src/current-patches/firefox/0007-Block-all-plugins-except-flash.patch b/src/current-patches/firefox/0007-Block-all-plugins-except-flash.patch
deleted file mode 100644
index b850f62..0000000
--- a/src/current-patches/firefox/0007-Block-all-plugins-except-flash.patch
+++ /dev/null
@@ -1,85 +0,0 @@
-From 10873c626d038b520853539d45a170919d6d0361 Mon Sep 17 00:00:00 2001
-From: Mike Perry <mikeperry-git at torproject.org>
-Date: Wed, 1 Feb 2012 15:50:15 -0800
-Subject: [PATCH 07/13] Block all plugins except flash.
-
-We cannot use the @mozilla.org/extensions/blocklist;1 service, because we
-actually want to stop plugins from ever entering the browser's process space
-and/or executing code (for example, AV plugins that collect statistics/analyse
-urls, magical toolbars that phone home or "help" the user, skype buttons that
-ruin our day, and censorship filters). Hence we rolled our own.
-
-See https://trac.torproject.org/projects/tor/ticket/3547#comment:6 for musings
-on a better way. Until then, it is delta-darwinism for us.
----
- dom/plugins/base/nsPluginHost.cpp |   33 +++++++++++++++++++++++++++++++++
- dom/plugins/base/nsPluginHost.h   |    2 ++
- 2 files changed, 35 insertions(+), 0 deletions(-)
-
-diff --git a/dom/plugins/base/nsPluginHost.cpp b/dom/plugins/base/nsPluginHost.cpp
-index 7fe18b2..d76c4ca 100644
---- a/dom/plugins/base/nsPluginHost.cpp
-+++ b/dom/plugins/base/nsPluginHost.cpp
-@@ -1982,6 +1982,35 @@ bool nsPluginHost::IsDuplicatePlugin(nsPluginTag * aPluginTag)
-   return false;
- }
- 
-+PRBool nsPluginHost::GhettoBlacklist(nsIFile *pluginFile)
-+{
-+    nsCString leaf;
-+    const char *leafStr;
-+    nsresult rv;
-+    
-+    rv = pluginFile->GetNativeLeafName(leaf);
-+    if (NS_FAILED(rv)) {
-+        return PR_TRUE; // fuck 'em. blacklist.
-+    }
-+
-+    leafStr = leaf.get();
-+
-+    if (!leafStr) {
-+        return PR_TRUE; // fuck 'em. blacklist.
-+    }
-+
-+    // libgnashplugin.so, libflashplayer.so, Flash Player-10.4-10.5.plugin,
-+    // NPSWF32.dll, NPSWF64.dll
-+    if (strstr(leafStr, "libgnashplugin") == leafStr ||
-+        strstr(leafStr, "libflashplayer") == leafStr ||
-+        strstr(leafStr, "Flash Player") == leafStr ||
-+        strstr(leafStr, "NPSWF") == leafStr) {
-+        return PR_FALSE;
-+    }
-+
-+    return PR_TRUE; // fuck 'em. blacklist.
-+}
-+
- typedef NS_NPAPIPLUGIN_CALLBACK(char *, NP_GETMIMEDESCRIPTION)(void);
- 
- nsresult nsPluginHost::ScanPluginsDirectory(nsIFile *pluginsDir,
-@@ -2103,6 +2132,10 @@ nsresult nsPluginHost::ScanPluginsDirectory(nsIFile *pluginsDir,
-       continue;
-     }
- 
-+    if (GhettoBlacklist(localfile)) {
-+        continue;
-+    }
-+
-     // if it is not found in cache info list or has been changed, create a new one
-     if (!pluginTag) {
-       nsPluginFile pluginFile(localfile);
-diff --git a/dom/plugins/base/nsPluginHost.h b/dom/plugins/base/nsPluginHost.h
-index 5630b8d..f54bd32 100644
---- a/dom/plugins/base/nsPluginHost.h
-+++ b/dom/plugins/base/nsPluginHost.h
-@@ -285,6 +285,8 @@ private:
-   // Loads all cached plugins info into mCachedPlugins
-   nsresult ReadPluginInfo();
- 
-+  PRBool GhettoBlacklist(nsIFile *pluginFile);
-+
-   // Given a file path, returns the plugins info from our cache
-   // and removes it from the cache.
-   void RemoveCachedPluginsInfo(const char *filePath,
--- 
-1.7.5.4
-
diff --git a/src/current-patches/firefox/0007-Make-Tor-Browser-exit-when-not-launched-from-Vidalia.patch b/src/current-patches/firefox/0007-Make-Tor-Browser-exit-when-not-launched-from-Vidalia.patch
new file mode 100644
index 0000000..f4c3794
--- /dev/null
+++ b/src/current-patches/firefox/0007-Make-Tor-Browser-exit-when-not-launched-from-Vidalia.patch
@@ -0,0 +1,46 @@
+From 57e5abfa15950713acfb5d9a94f636579dde4d12 Mon Sep 17 00:00:00 2001
+From: Mike Perry <mikeperry-git at fscked.org>
+Date: Sun, 9 Oct 2011 22:50:07 -0700
+Subject: [PATCH 07/12] Make Tor Browser exit when not launched from Vidalia
+
+Turns out the Windows 7 UI encourages users to "dock" their Tor Browser app
+for easy relaunch. If they manage to do this, we should fail closed rather
+than opened. Hopefully they will get the hint and dock Vidalia instead.
+
+This is an emergency fix for
+https://trac.torproject.org/projects/tor/ticket/4192. We can do a better
+localized fix w/ a translated alert menu later, if it seems like this might
+actually be common.
+---
+ browser/base/content/browser.js |   15 +++++++++++++++
+ 1 files changed, 15 insertions(+), 0 deletions(-)
+
+diff --git a/browser/base/content/browser.js b/browser/base/content/browser.js
+index 9dfc667..dd1619a 100644
+--- a/browser/base/content/browser.js
++++ b/browser/base/content/browser.js
+@@ -1226,6 +1226,21 @@ function BrowserStartup() {
+ 
+   prepareForStartup();
+ 
++  // If this is not a TBB profile, exit. 
++  // Solves https://trac.torproject.org/projects/tor/ticket/4192
++  var foundPref = false;
++  try {
++    foundPref = gPrefService.prefHasUserValue("torbrowser.version");
++  } catch(e) {
++    //dump("No pref: "+e);
++  }
++  if(!foundPref) {
++    var appStartup = Components.classes["@mozilla.org/toolkit/app-startup;1"]
++                         .getService(Components.interfaces.nsIAppStartup);
++    appStartup.quit(3); // Force all windows to close, and then quit.
++  }
++
++
+   if (uriToLoad && !isLoadingBlank) {
+     if (uriToLoad instanceof Ci.nsISupportsArray) {
+       let count = uriToLoad.Count();
+-- 
+1.7.5.4
+
diff --git a/src/current-patches/firefox/0008-Disable-SSL-Session-ID-tracking.patch b/src/current-patches/firefox/0008-Disable-SSL-Session-ID-tracking.patch
new file mode 100644
index 0000000..a4ba645
--- /dev/null
+++ b/src/current-patches/firefox/0008-Disable-SSL-Session-ID-tracking.patch
@@ -0,0 +1,28 @@
+From 4d7f3122a76e0d5a31ba352880892fecd493252b Mon Sep 17 00:00:00 2001
+From: Mike Perry <mikeperry-git at fscked.org>
+Date: Wed, 7 Dec 2011 19:36:38 -0800
+Subject: [PATCH 08/12] Disable SSL Session ID tracking.
+
+We can't easily bind SSL Session ID tracking to url bar domain,
+so we have to disable them to satisfy
+https://www.torproject.org/projects/torbrowser/design/#identifier-linkability.
+---
+ security/nss/lib/ssl/sslsock.c |    2 +-
+ 1 files changed, 1 insertions(+), 1 deletions(-)
+
+diff --git a/security/nss/lib/ssl/sslsock.c b/security/nss/lib/ssl/sslsock.c
+index 22206f7..31086db 100644
+--- a/security/nss/lib/ssl/sslsock.c
++++ b/security/nss/lib/ssl/sslsock.c
+@@ -173,7 +173,7 @@ static sslOptions ssl_defaults = {
+     PR_FALSE,	/* enableSSL2         */ /* now defaults to off in NSS 3.13 */
+     PR_TRUE,	/* enableSSL3         */
+     PR_TRUE, 	/* enableTLS          */ /* now defaults to on in NSS 3.0 */
+-    PR_FALSE,	/* noCache            */
++    PR_TRUE,	/* noCache            */
+     PR_FALSE,	/* fdx                */
+     PR_FALSE,	/* v2CompatibleHello  */ /* now defaults to off in NSS 3.13 */
+     PR_TRUE,	/* detectRollBack     */
+-- 
+1.7.5.4
+
diff --git a/src/current-patches/firefox/0008-Make-content-pref-service-memory-only-clearable.patch b/src/current-patches/firefox/0008-Make-content-pref-service-memory-only-clearable.patch
deleted file mode 100644
index b123321..0000000
--- a/src/current-patches/firefox/0008-Make-content-pref-service-memory-only-clearable.patch
+++ /dev/null
@@ -1,37 +0,0 @@
-From 9a406718f9cb98f57de4649def8ef501ddbb9775 Mon Sep 17 00:00:00 2001
-From: Mike Perry <mikeperry-git at fscked.org>
-Date: Thu, 8 Sep 2011 08:40:17 -0700
-Subject: [PATCH 08/13] Make content pref service memory-only + clearable
-
-This prevents random urls from being inserted into content-prefs.sqllite in
-the profile directory as content prefs change (includes site-zoom and perhaps
-other site prefs?).
----
- .../contentprefs/nsContentPrefService.js           |    4 ++--
- 1 files changed, 2 insertions(+), 2 deletions(-)
-
-diff --git a/toolkit/components/contentprefs/nsContentPrefService.js b/toolkit/components/contentprefs/nsContentPrefService.js
-index 17cac93..1f12609 100644
---- a/toolkit/components/contentprefs/nsContentPrefService.js
-+++ b/toolkit/components/contentprefs/nsContentPrefService.js
-@@ -1242,7 +1242,7 @@ ContentPrefService.prototype = {
- 
-     var dbConnection;
- 
--    if (!dbFile.exists())
-+    if (true || !dbFile.exists())
-       dbConnection = this._dbCreate(dbService, dbFile);
-     else {
-       try {
-@@ -1290,7 +1290,7 @@ ContentPrefService.prototype = {
-   },
- 
-   _dbCreate: function ContentPrefService__dbCreate(aDBService, aDBFile) {
--    var dbConnection = aDBService.openDatabase(aDBFile);
-+    var dbConnection = aDBService.openSpecialDatabase("memory");
- 
-     try {
-       this._dbCreateSchema(dbConnection);
--- 
-1.7.5.4
-
diff --git a/src/current-patches/firefox/0009-Make-Tor-Browser-exit-when-not-launched-from-Vidalia.patch b/src/current-patches/firefox/0009-Make-Tor-Browser-exit-when-not-launched-from-Vidalia.patch
deleted file mode 100644
index 1744772..0000000
--- a/src/current-patches/firefox/0009-Make-Tor-Browser-exit-when-not-launched-from-Vidalia.patch
+++ /dev/null
@@ -1,46 +0,0 @@
-From af562eedaa61f60241c4a73c2cac6a0a5821a66d Mon Sep 17 00:00:00 2001
-From: Mike Perry <mikeperry-git at fscked.org>
-Date: Sun, 9 Oct 2011 22:50:07 -0700
-Subject: [PATCH 09/13] Make Tor Browser exit when not launched from Vidalia
-
-Turns out the Windows 7 UI encourages users to "dock" their Tor Browser app
-for easy relaunch. If they manage to do this, we should fail closed rather
-than opened. Hopefully they will get the hint and dock Vidalia instead.
-
-This is an emergency fix for
-https://trac.torproject.org/projects/tor/ticket/4192. We can do a better
-localized fix w/ a translated alert menu later, if it seems like this might
-actually be common.
----
- browser/base/content/browser.js |   15 +++++++++++++++
- 1 files changed, 15 insertions(+), 0 deletions(-)
-
-diff --git a/browser/base/content/browser.js b/browser/base/content/browser.js
-index 6abab20..21afee0 100644
---- a/browser/base/content/browser.js
-+++ b/browser/base/content/browser.js
-@@ -1224,6 +1224,21 @@ function BrowserStartup() {
- 
-   prepareForStartup();
- 
-+  // If this is not a TBB profile, exit. 
-+  // Solves https://trac.torproject.org/projects/tor/ticket/4192
-+  var foundPref = false;
-+  try {
-+    foundPref = gPrefService.prefHasUserValue("torbrowser.version");
-+  } catch(e) {
-+    //dump("No pref: "+e);
-+  }
-+  if(!foundPref) {
-+    var appStartup = Components.classes["@mozilla.org/toolkit/app-startup;1"]
-+                         .getService(Components.interfaces.nsIAppStartup);
-+    appStartup.quit(3); // Force all windows to close, and then quit.
-+  }
-+
-+
-   if (uriToLoad && !isLoadingBlank) {
-     if (uriToLoad instanceof Ci.nsISupportsArray) {
-       let count = uriToLoad.Count();
--- 
-1.7.5.4
-
diff --git a/src/current-patches/firefox/0009-Provide-an-observer-event-to-close-persistent-connec.patch b/src/current-patches/firefox/0009-Provide-an-observer-event-to-close-persistent-connec.patch
new file mode 100644
index 0000000..47007bb
--- /dev/null
+++ b/src/current-patches/firefox/0009-Provide-an-observer-event-to-close-persistent-connec.patch
@@ -0,0 +1,40 @@
+From 873acaa3fd6df60fe57f1549cdb45df7e277808d Mon Sep 17 00:00:00 2001
+From: Mike Perry <mikeperry-git at torproject.org>
+Date: Wed, 1 Feb 2012 15:53:28 -0800
+Subject: [PATCH 09/12] Provide an observer event to close persistent
+ connections
+
+We need to prevent linkability across "New Identity", which includes closing
+keep-alive connections.
+---
+ netwerk/protocol/http/nsHttpHandler.cpp |    7 +++++++
+ 1 files changed, 7 insertions(+), 0 deletions(-)
+
+diff --git a/netwerk/protocol/http/nsHttpHandler.cpp b/netwerk/protocol/http/nsHttpHandler.cpp
+index ebc7641..dbcdff7 100644
+--- a/netwerk/protocol/http/nsHttpHandler.cpp
++++ b/netwerk/protocol/http/nsHttpHandler.cpp
+@@ -331,6 +331,7 @@ nsHttpHandler::Init()
+         mObserverService->AddObserver(this, "net:clear-active-logins", true);
+         mObserverService->AddObserver(this, NS_PRIVATE_BROWSING_SWITCH_TOPIC, true);
+         mObserverService->AddObserver(this, "net:prune-dead-connections", true);
++        mObserverService->AddObserver(this, "net:prune-all-connections", PR_TRUE);
+     }
+  
+     return NS_OK;
+@@ -1522,6 +1523,12 @@ nsHttpHandler::Observe(nsISupports *subject,
+             mConnMgr->PruneDeadConnections();
+         }
+     }
++    else if (strcmp(topic, "net:prune-all-connections") == 0) {
++        if (mConnMgr) {
++           mConnMgr->ClosePersistentConnections();
++           mConnMgr->PruneDeadConnections();
++        }
++    }
+   
+     return NS_OK;
+ }
+-- 
+1.7.5.4
+
diff --git a/src/current-patches/firefox/0010-Disable-SSL-Session-ID-tracking.patch b/src/current-patches/firefox/0010-Disable-SSL-Session-ID-tracking.patch
deleted file mode 100644
index 76ce1b6..0000000
--- a/src/current-patches/firefox/0010-Disable-SSL-Session-ID-tracking.patch
+++ /dev/null
@@ -1,28 +0,0 @@
-From 33198fdb4467637fabf292e18530c89e8b6bad4e Mon Sep 17 00:00:00 2001
-From: Mike Perry <mikeperry-git at fscked.org>
-Date: Wed, 7 Dec 2011 19:36:38 -0800
-Subject: [PATCH 10/13] Disable SSL Session ID tracking.
-
-We can't easily bind SSL Session ID tracking to url bar domain,
-so we have to disable them to satisfy
-https://www.torproject.org/projects/torbrowser/design/#identifier-linkability.
----
- security/nss/lib/ssl/sslsock.c |    2 +-
- 1 files changed, 1 insertions(+), 1 deletions(-)
-
-diff --git a/security/nss/lib/ssl/sslsock.c b/security/nss/lib/ssl/sslsock.c
-index 22206f7..31086db 100644
---- a/security/nss/lib/ssl/sslsock.c
-+++ b/security/nss/lib/ssl/sslsock.c
-@@ -173,7 +173,7 @@ static sslOptions ssl_defaults = {
-     PR_FALSE,	/* enableSSL2         */ /* now defaults to off in NSS 3.13 */
-     PR_TRUE,	/* enableSSL3         */
-     PR_TRUE, 	/* enableTLS          */ /* now defaults to on in NSS 3.0 */
--    PR_FALSE,	/* noCache            */
-+    PR_TRUE,	/* noCache            */
-     PR_FALSE,	/* fdx                */
-     PR_FALSE,	/* v2CompatibleHello  */ /* now defaults to off in NSS 3.13 */
-     PR_TRUE,	/* detectRollBack     */
--- 
-1.7.5.4
-
diff --git a/src/current-patches/firefox/0010-Provide-client-values-only-to-CSS-Media-Queries.patch b/src/current-patches/firefox/0010-Provide-client-values-only-to-CSS-Media-Queries.patch
new file mode 100644
index 0000000..5618c19
--- /dev/null
+++ b/src/current-patches/firefox/0010-Provide-client-values-only-to-CSS-Media-Queries.patch
@@ -0,0 +1,72 @@
+From a27dcd387d8c3c1f1e150dcdd3c8aa1872ad14b5 Mon Sep 17 00:00:00 2001
+From: Mike Perry <mikeperry-git at fscked.org>
+Date: Tue, 20 Dec 2011 21:02:49 -0800
+Subject: [PATCH 10/12] Provide client values only to CSS Media Queries
+
+Also disable a bunch of Mozilla extensions that smell like they are
+fingerprintable.
+
+This is done to address
+https://www.torproject.org/projects/torbrowser/design/#fingerprinting-linkability
+---
+ layout/style/nsMediaFeatures.cpp |   10 ++++++----
+ 1 files changed, 6 insertions(+), 4 deletions(-)
+
+diff --git a/layout/style/nsMediaFeatures.cpp b/layout/style/nsMediaFeatures.cpp
+index 6eca06e..c68f191 100644
+--- a/layout/style/nsMediaFeatures.cpp
++++ b/layout/style/nsMediaFeatures.cpp
+@@ -383,14 +383,14 @@ nsMediaFeatures::features[] = {
+         nsMediaFeature::eMinMaxAllowed,
+         nsMediaFeature::eLength,
+         { nsnull },
+-        GetDeviceWidth
++        GetWidth
+     },
+     {
+         &nsGkAtoms::deviceHeight,
+         nsMediaFeature::eMinMaxAllowed,
+         nsMediaFeature::eLength,
+         { nsnull },
+-        GetDeviceHeight
++        GetHeight
+     },
+     {
+         &nsGkAtoms::orientation,
+@@ -411,7 +411,7 @@ nsMediaFeatures::features[] = {
+         nsMediaFeature::eMinMaxAllowed,
+         nsMediaFeature::eIntRatio,
+         { nsnull },
+-        GetDeviceAspectRatio
++        GetAspectRatio
+     },
+     {
+         &nsGkAtoms::color,
+@@ -457,6 +457,7 @@ nsMediaFeatures::features[] = {
+     },
+ 
+     // Mozilla extensions
++/*
+     {
+         &nsGkAtoms::_moz_device_pixel_ratio,
+         nsMediaFeature::eMinMaxAllowed,
+@@ -469,7 +470,7 @@ nsMediaFeatures::features[] = {
+         nsMediaFeature::eMinMaxNotAllowed,
+         nsMediaFeature::eEnumerated,
+         { kOrientationKeywords },
+-        GetDeviceOrientation
++        GetOrientation
+     },
+     {
+         &nsGkAtoms::_moz_is_resource_document,
+@@ -590,6 +591,7 @@ nsMediaFeatures::features[] = {
+         { nsnull },
+         GetWindowsTheme
+     },
++*/
+     // Null-mName terminator:
+     {
+         nsnull,
+-- 
+1.7.5.4
+
diff --git a/src/current-patches/firefox/0011-Limit-the-number-of-fonts-per-document.patch b/src/current-patches/firefox/0011-Limit-the-number-of-fonts-per-document.patch
new file mode 100644
index 0000000..d5d606b
--- /dev/null
+++ b/src/current-patches/firefox/0011-Limit-the-number-of-fonts-per-document.patch
@@ -0,0 +1,228 @@
+From c4d1c23872e2be83f33f2b9bfc5c49d2b98c73a6 Mon Sep 17 00:00:00 2001
+From: Mike Perry <mikeperry-git at torproject.org>
+Date: Wed, 1 Feb 2012 16:01:21 -0800
+Subject: [PATCH 11/12] 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 49b201e..0a8db3c 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"
+@@ -733,6 +735,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 =
+@@ -1334,6 +1340,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 4b70c2f..ae8fcd5 100644
+--- a/layout/base/nsPresContext.h
++++ b/layout/base/nsPresContext.h
+@@ -535,6 +535,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);
+   }
+@@ -1127,6 +1134,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 9eb41ac..47065d0 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 = 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.5.4
+
diff --git a/src/current-patches/firefox/0011-Provide-an-observer-event-to-close-persistent-connec.patch b/src/current-patches/firefox/0011-Provide-an-observer-event-to-close-persistent-connec.patch
deleted file mode 100644
index f442982..0000000
--- a/src/current-patches/firefox/0011-Provide-an-observer-event-to-close-persistent-connec.patch
+++ /dev/null
@@ -1,40 +0,0 @@
-From a0c84e27f2c40d043c85ba3b794d3578e909f558 Mon Sep 17 00:00:00 2001
-From: Mike Perry <mikeperry-git at torproject.org>
-Date: Wed, 1 Feb 2012 15:53:28 -0800
-Subject: [PATCH 11/13] Provide an observer event to close persistent
- connections
-
-We need to prevent linkability across "New Identity", which includes closing
-keep-alive connections.
----
- netwerk/protocol/http/nsHttpHandler.cpp |    7 +++++++
- 1 files changed, 7 insertions(+), 0 deletions(-)
-
-diff --git a/netwerk/protocol/http/nsHttpHandler.cpp b/netwerk/protocol/http/nsHttpHandler.cpp
-index 727b5d6..87b55bc 100644
---- a/netwerk/protocol/http/nsHttpHandler.cpp
-+++ b/netwerk/protocol/http/nsHttpHandler.cpp
-@@ -329,6 +329,7 @@ nsHttpHandler::Init()
-         mObserverService->AddObserver(this, "net:clear-active-logins", true);
-         mObserverService->AddObserver(this, NS_PRIVATE_BROWSING_SWITCH_TOPIC, true);
-         mObserverService->AddObserver(this, "net:prune-dead-connections", true);
-+        mObserverService->AddObserver(this, "net:prune-all-connections", PR_TRUE);
-     }
-  
-     return NS_OK;
-@@ -1533,6 +1534,12 @@ nsHttpHandler::Observe(nsISupports *subject,
-             mConnMgr->PruneDeadConnections();
-         }
-     }
-+    else if (strcmp(topic, "net:prune-all-connections") == 0) {
-+        if (mConnMgr) {
-+           mConnMgr->ClosePersistentConnections();
-+           mConnMgr->PruneDeadConnections();
-+        }
-+    }
-   
-     return NS_OK;
- }
--- 
-1.7.5.4
-
diff --git a/src/current-patches/firefox/0012-Provide-client-values-only-to-CSS-Media-Queries.patch b/src/current-patches/firefox/0012-Provide-client-values-only-to-CSS-Media-Queries.patch
deleted file mode 100644
index abed414..0000000
--- a/src/current-patches/firefox/0012-Provide-client-values-only-to-CSS-Media-Queries.patch
+++ /dev/null
@@ -1,72 +0,0 @@
-From 10f26d027ba5413d7e26aaccd92cbc1c12b42d86 Mon Sep 17 00:00:00 2001
-From: Mike Perry <mikeperry-git at fscked.org>
-Date: Tue, 20 Dec 2011 21:02:49 -0800
-Subject: [PATCH 12/13] Provide client values only to CSS Media Queries
-
-Also disable a bunch of Mozilla extensions that smell like they are
-fingerprintable.
-
-This is done to address
-https://www.torproject.org/projects/torbrowser/design/#fingerprinting-linkability
----
- layout/style/nsMediaFeatures.cpp |   10 ++++++----
- 1 files changed, 6 insertions(+), 4 deletions(-)
-
-diff --git a/layout/style/nsMediaFeatures.cpp b/layout/style/nsMediaFeatures.cpp
-index 6eca06e..c68f191 100644
---- a/layout/style/nsMediaFeatures.cpp
-+++ b/layout/style/nsMediaFeatures.cpp
-@@ -383,14 +383,14 @@ nsMediaFeatures::features[] = {
-         nsMediaFeature::eMinMaxAllowed,
-         nsMediaFeature::eLength,
-         { nsnull },
--        GetDeviceWidth
-+        GetWidth
-     },
-     {
-         &nsGkAtoms::deviceHeight,
-         nsMediaFeature::eMinMaxAllowed,
-         nsMediaFeature::eLength,
-         { nsnull },
--        GetDeviceHeight
-+        GetHeight
-     },
-     {
-         &nsGkAtoms::orientation,
-@@ -411,7 +411,7 @@ nsMediaFeatures::features[] = {
-         nsMediaFeature::eMinMaxAllowed,
-         nsMediaFeature::eIntRatio,
-         { nsnull },
--        GetDeviceAspectRatio
-+        GetAspectRatio
-     },
-     {
-         &nsGkAtoms::color,
-@@ -457,6 +457,7 @@ nsMediaFeatures::features[] = {
-     },
- 
-     // Mozilla extensions
-+/*
-     {
-         &nsGkAtoms::_moz_device_pixel_ratio,
-         nsMediaFeature::eMinMaxAllowed,
-@@ -469,7 +470,7 @@ nsMediaFeatures::features[] = {
-         nsMediaFeature::eMinMaxNotAllowed,
-         nsMediaFeature::eEnumerated,
-         { kOrientationKeywords },
--        GetDeviceOrientation
-+        GetOrientation
-     },
-     {
-         &nsGkAtoms::_moz_is_resource_document,
-@@ -590,6 +591,7 @@ nsMediaFeatures::features[] = {
-         { nsnull },
-         GetWindowsTheme
-     },
-+*/
-     // Null-mName terminator:
-     {
-         nsnull,
--- 
-1.7.5.4
-
diff --git a/src/current-patches/firefox/0012-Randomize-HTTP-request-order-and-pipeline-depth.patch b/src/current-patches/firefox/0012-Randomize-HTTP-request-order-and-pipeline-depth.patch
new file mode 100644
index 0000000..2449c5a
--- /dev/null
+++ b/src/current-patches/firefox/0012-Randomize-HTTP-request-order-and-pipeline-depth.patch
@@ -0,0 +1,234 @@
+From 6147cea4de151dade922b3c2787016f70c222458 Mon Sep 17 00:00:00 2001
+From: Mike Perry <mikeperry-git at torproject.org>
+Date: Tue, 24 Apr 2012 17:21:45 -0700
+Subject: [PATCH 12/12] Randomize HTTP request order and pipeline depth.
+
+This is an experimental defense against
+http://lorre.uni.lu/~andriy/papers/acmccs-wpes11-fingerprinting.pdf
+
+See:
+https://blog.torproject.org/blog/experimental-defense-website-traffic-fingerprinting
+
+This defense has been improved since that blog post to additionally randomize
+the order and concurrency of non-pipelined HTTP requests.
+---
+ netwerk/protocol/http/nsHttpConnectionMgr.cpp |  133 ++++++++++++++++++++++++-
+ netwerk/protocol/http/nsHttpConnectionMgr.h   |    5 +
+ 2 files changed, 133 insertions(+), 5 deletions(-)
+
+diff --git a/netwerk/protocol/http/nsHttpConnectionMgr.cpp b/netwerk/protocol/http/nsHttpConnectionMgr.cpp
+index 6e1099d..3eec5b3 100644
+--- a/netwerk/protocol/http/nsHttpConnectionMgr.cpp
++++ b/netwerk/protocol/http/nsHttpConnectionMgr.cpp
+@@ -100,6 +100,12 @@ nsHttpConnectionMgr::nsHttpConnectionMgr()
+     mCT.Init();
+     mAlternateProtocolHash.Init(16);
+     mSpdyPreferredHash.Init();
++
++    nsresult rv;
++    mRandomGenerator = do_GetService("@mozilla.org/security/random-generator;1", &rv);
++    if (NS_FAILED(rv)) {
++        mRandomGenerator = nsnull;
++    }
+ }
+ 
+ nsHttpConnectionMgr::~nsHttpConnectionMgr()
+@@ -353,8 +359,12 @@ nsHttpConnectionMgr::AddTransactionToPipeline(nsHttpPipeline *pipeline)
+         nsConnectionEntry *ent = mCT.Get(ci->HashKey());
+         if (ent) {
+             // search for another request to pipeline...
+-            PRInt32 i, count = ent->mPendingQ.Length();
+-            for (i=0; i<count; ++i) {
++            PRInt32 i, h, count = ent->mPendingQ.Length();
++            PRInt32 ind[count];
++            ShuffleRequestOrder((PRUint32*)ind, (PRUint32)count);
++       
++            for (h=0; h<count; ++h) {
++                i = ind[h]; // random request sequence
+                 nsHttpTransaction *trans = ent->mPendingQ[i];
+                 if (trans->Caps() & NS_HTTP_ALLOW_PIPELINING) {
+                     pipeline->AddTransaction(trans);
+@@ -898,12 +908,17 @@ nsHttpConnectionMgr::ProcessPendingQForEntry(nsConnectionEntry *ent)
+ 
+     ProcessSpdyPendingQ(ent);
+ 
+-    PRUint32 i, count = ent->mPendingQ.Length();
++    PRUint32 h, i = 0, count = ent->mPendingQ.Length();
+     if (count > 0) {
+         LOG(("  pending-count=%u\n", count));
+         nsHttpTransaction *trans = nsnull;
+         nsHttpConnection *conn = nsnull;
+-        for (i = 0; i < count; ++i) {
++
++        PRUint32 ind[count];
++        ShuffleRequestOrder(ind, count);
++       
++        for (h=0; h<count; ++h) {
++            i = ind[h]; // random request sequence
+             trans = ent->mPendingQ[i];
+ 
+             // When this transaction has already established a half-open
+@@ -1011,6 +1026,19 @@ nsHttpConnectionMgr::AtActiveConnectionLimit(nsConnectionEntry *ent, PRUint8 cap
+         maxPersistConns = mMaxPersistConnsPerHost;
+     }
+ 
++    // Fuzz maxConns for website fingerprinting attack
++    // We create a range of maxConns/5 up to 6*maxConns/5 
++    // because this function is called repeatedly, and we'll
++    // end up converging on a the high side of concurrent connections
++    // after a short while. 
++    PRUint8 *bytes = nsnull;
++    nsresult rv = mRandomGenerator->GenerateRandomBytes(1, &bytes);
++    NS_ENSURE_SUCCESS(rv, rv);
++
++    bytes[0] = bytes[0] % (maxConns + 1);
++    maxConns = (maxConns/5) + bytes[0];
++    NS_Free(bytes);
++
+     // use >= just to be safe
+     return (totalCount >= maxConns) || ( (caps & NS_HTTP_ALLOW_KEEPALIVE) &&
+                                          (persistCount >= maxPersistConns) );
+@@ -1227,7 +1255,7 @@ nsHttpConnectionMgr::DispatchTransaction(nsConnectionEntry *ent,
+ 
+     if (conn->SupportsPipelining() && (caps & NS_HTTP_ALLOW_PIPELINING)) {
+         LOG(("  looking to build pipeline...\n"));
+-        if (BuildPipeline(ent, trans, &pipeline))
++        if (BuildRandomizedPipeline(ent, trans, &pipeline))
+             trans = pipeline;
+     }
+ 
+@@ -1300,6 +1328,101 @@ nsHttpConnectionMgr::BuildPipeline(nsConnectionEntry *ent,
+     return true;
+ }
+ 
++
++// Generate a shuffled request ordering sequence 
++void
++nsHttpConnectionMgr::ShuffleRequestOrder(PRUint32 *ind, PRUint32 count)
++{
++   PRUint32 i;
++   PRUint32 *rints;
++
++   for (i=0; i<count; ++i) {
++       ind[i] = i;
++   }
++   nsresult rv = mRandomGenerator->GenerateRandomBytes(sizeof(PRUint32)*count,
++                                                       (PRUint8**)&rints);
++   if (NS_FAILED(rv))
++       return; // Leave unshuffled if error
++
++   for (i=0; i < count; ++i) {
++       PRInt32 temp = ind[i];
++       ind[i] = ind[rints[i]%count]; 
++       ind[rints[i]%count] = temp;
++   }
++   NS_Free(rints);
++}
++
++bool
++nsHttpConnectionMgr::BuildRandomizedPipeline(nsConnectionEntry *ent,
++                                   nsAHttpTransaction *firstTrans,
++                                   nsHttpPipeline **result)
++{
++    if (mRandomGenerator == nsnull)
++        return BuildPipeline(ent, firstTrans, result);
++    if (mMaxPipelinedRequests < 2)
++        return PR_FALSE;
++
++    nsresult rv;
++    PRUint8 *bytes = nsnull;
++
++    nsHttpPipeline *pipeline = nsnull;
++    nsHttpTransaction *trans;
++
++    PRUint32 i = 0, numAdded = 0, numAllowed = 0;
++    PRUint32 max = 0;
++
++    while (i < ent->mPendingQ.Length()) {
++        if (ent->mPendingQ[i]->Caps() & NS_HTTP_ALLOW_PIPELINING)
++            numAllowed++;
++        i++;
++    }
++
++    rv = mRandomGenerator->GenerateRandomBytes(1, &bytes);
++    NS_ENSURE_SUCCESS(rv, rv);
++    // 4...12
++    max = 4 + (bytes[0] % (mMaxPipelinedRequests + 1));
++    NS_Free(bytes);
++
++    while (numAllowed > 0) {
++        rv = mRandomGenerator->GenerateRandomBytes(1, &bytes);
++        NS_ENSURE_SUCCESS(rv, rv);
++        i = bytes[0] % ent->mPendingQ.Length();
++        NS_Free(bytes);
++
++        trans = ent->mPendingQ[i];
++
++        if (!(ent->mPendingQ[i]->Caps() & NS_HTTP_ALLOW_PIPELINING))
++            continue;
++
++        if (numAdded == 0) {
++            pipeline = new nsHttpPipeline;
++            if (!pipeline)
++                return PR_FALSE;
++            pipeline->AddTransaction(firstTrans);
++            numAdded = 1;
++        }
++        pipeline->AddTransaction(trans);
++
++        // remove transaction from pending queue
++        ent->mPendingQ.RemoveElementAt(i);
++        NS_RELEASE(trans);
++
++        numAllowed--;
++
++        if (++numAdded == max)
++            break;
++    }
++
++    //fprintf(stderr, "Yay!!! pipelined %u/%u transactions\n", numAdded, max);
++    LOG(("  pipelined %u/%u transactions\n", numAdded, max));
++
++    if (numAdded == 0)
++        return PR_FALSE;
++
++    NS_ADDREF(*result = pipeline);
++    return PR_TRUE;
++}
++
+ nsresult
+ nsHttpConnectionMgr::ProcessNewTransaction(nsHttpTransaction *trans)
+ {
+diff --git a/netwerk/protocol/http/nsHttpConnectionMgr.h b/netwerk/protocol/http/nsHttpConnectionMgr.h
+index a13da0f..59ee9b9 100644
+--- a/netwerk/protocol/http/nsHttpConnectionMgr.h
++++ b/netwerk/protocol/http/nsHttpConnectionMgr.h
+@@ -54,6 +54,7 @@
+ #include "nsIObserver.h"
+ #include "nsITimer.h"
+ #include "nsIX509Cert3.h"
++#include "nsIRandomGenerator.h"
+ 
+ class nsHttpPipeline;
+ 
+@@ -317,6 +318,8 @@ private:
+     nsresult DispatchTransaction(nsConnectionEntry *, nsHttpTransaction *,
+                                  PRUint8 caps, nsHttpConnection *);
+     bool     BuildPipeline(nsConnectionEntry *, nsAHttpTransaction *, nsHttpPipeline **);
++    bool     BuildRandomizedPipeline(nsConnectionEntry *, nsAHttpTransaction *, nsHttpPipeline **);
++    void     ShuffleRequestOrder(PRUint32 *, PRUint32);
+     nsresult ProcessNewTransaction(nsHttpTransaction *);
+     nsresult EnsureSocketThreadTargetIfOnline();
+     void     ClosePersistentConnections(nsConnectionEntry *ent);
+@@ -409,6 +412,8 @@ private:
+     PRUint64 mTimeOfNextWakeUp;
+     // Timer for next pruning of dead connections.
+     nsCOMPtr<nsITimer> mTimer;
++    // Random number generator for reordering HTTP pipeline
++    nsCOMPtr<nsIRandomGenerator>             mRandomGenerator;
+ 
+     //
+     // the connection table
+-- 
+1.7.5.4
+
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
deleted file mode 100644
index 7f0f248..0000000
--- a/src/current-patches/firefox/0013-Limit-the-number-of-fonts-per-document.patch
+++ /dev/null
@@ -1,228 +0,0 @@
-From 215f7088f53e25309ec5037c05a25ed9048a625b Mon Sep 17 00:00:00 2001
-From: Mike Perry <mikeperry-git at 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
-





More information about the tor-commits mailing list