[tor-commits] [torbrowser/master] Move 2.3 patches to alpha.

mikeperry at torproject.org mikeperry at torproject.org
Thu Jun 28 20:44:29 UTC 2012


commit d70e38370fd7cf29ab73db006a1fee6f6a85b035
Author: Mike Perry <mikeperry-git at fscked.org>
Date:   Thu Jun 7 19:01:10 2012 -0700

    Move 2.3 patches to alpha.
---
 ...nents.interfaces-lookupMethod-from-conten.patch |   50 --
 ...0002-Make-Permissions-Manager-memory-only.patch |   94 ----
 ...-Make-Intermediate-Cert-Store-memory-only.patch |   43 --
 .../firefox/0004-Add-a-string-based-cacheKey.patch |   85 ---
 .../0005-Block-all-plugins-except-flash.patch      |   85 ---
 ...ontent-pref-service-memory-only-clearable.patch |   37 --
 .../0007-Disable-SSL-Session-ID-tracking.patch     |   28 -
 ...observer-event-to-close-persistent-connec.patch |   40 --
 ...e-client-values-only-to-CSS-Media-Queries.patch |   72 ---
 .../0010-Rebrand-Firefox-to-TorBrowser.patch       |   50 --
 .../0011-Make-Download-manager-memory-only.patch   |   57 --
 .../0012-Add-DDG-and-StartPage-to-Omnibox.patch    |   84 ---
 ...-nsICacheService.EvictEntries-synchronous.patch |   44 --
 .../firefox/0014-Prevent-WebSocket-DNS-leak.patch  |  132 -----
 ...owser-exit-when-not-launched-from-Vidalia.patch |   45 --
 ...16-Limit-the-number-of-fonts-per-document.patch |  225 --------
 ...ize-HTTP-request-order-and-pipeline-depth.patch |  251 ---------
 ...Adapt-Steven-Michaud-s-Mac-crashfix-patch.patch |  541 --------------------
 ...nents.interfaces-lookupMethod-from-conten.patch |   50 ++
 ...0002-Make-Permissions-Manager-memory-only.patch |   94 ++++
 ...-Make-Intermediate-Cert-Store-memory-only.patch |   43 ++
 .../alpha/0004-Add-a-string-based-cacheKey.patch   |   85 +++
 .../0005-Block-all-plugins-except-flash.patch      |   85 +++
 ...ontent-pref-service-memory-only-clearable.patch |   37 ++
 .../0007-Disable-SSL-Session-ID-tracking.patch     |   28 +
 ...observer-event-to-close-persistent-connec.patch |   40 ++
 ...e-client-values-only-to-CSS-Media-Queries.patch |   72 +++
 .../alpha/0010-Rebrand-Firefox-to-TorBrowser.patch |   50 ++
 .../0011-Make-Download-manager-memory-only.patch   |   57 ++
 .../0012-Add-DDG-and-StartPage-to-Omnibox.patch    |   84 +++
 ...-nsICacheService.EvictEntries-synchronous.patch |   44 ++
 .../alpha/0014-Prevent-WebSocket-DNS-leak.patch    |  132 +++++
 ...owser-exit-when-not-launched-from-Vidalia.patch |   45 ++
 ...16-Limit-the-number-of-fonts-per-document.patch |  225 ++++++++
 ...ize-HTTP-request-order-and-pipeline-depth.patch |  251 +++++++++
 ...Adapt-Steven-Michaud-s-Mac-crashfix-patch.patch |  541 ++++++++++++++++++++
 36 files changed, 1963 insertions(+), 1963 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
deleted file mode 100644
index 5f8f4cc..0000000
--- a/src/current-patches/firefox/0001-Block-Components.interfaces-lookupMethod-from-conten.patch
+++ /dev/null
@@ -1,50 +0,0 @@
-From 801d2dcc512ca5e64b72d56faaab7d8ef0fadf39 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/19] 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.
-
-These two interfaces seem to be exposed to content script only to make our
-lives difficult. Components.lookupMethod can undo our JS hooks, and
-Components.interfaces is useful for fingerprinting the platform, OS, and
-Firebox version.
-
-They appear to have no other legitimate use. See also:
-https://bugzilla.mozilla.org/show_bug.cgi?id=429070
-https://trac.torproject.org/projects/tor/ticket/2873
-https://trac.torproject.org/projects/tor/ticket/2874
----
- js/xpconnect/src/XPCComponents.cpp |    8 ++++++--
- 1 files changed, 6 insertions(+), 2 deletions(-)
-
-diff --git a/js/xpconnect/src/XPCComponents.cpp b/js/xpconnect/src/XPCComponents.cpp
-index a2a1102..49e4c7e 100644
---- a/js/xpconnect/src/XPCComponents.cpp
-+++ b/js/xpconnect/src/XPCComponents.cpp
-@@ -4287,7 +4287,9 @@ nsXPCComponents::CanCreateWrapper(const nsIID * iid, char **_retval)
- NS_IMETHODIMP
- nsXPCComponents::CanCallMethod(const nsIID * iid, const PRUnichar *methodName, char **_retval)
- {
--    static const char* allowed[] = { "isSuccessCode", "lookupMethod", nsnull };
-+    // XXX: Pref observer? Also, is this what we want? Seems like a plan
-+    //static const char* allowed[] = { "isSuccessCode", "lookupMethod", nsnull };
-+    static const char* allowed[] = { "isSuccessCode", nsnull };
-     *_retval = xpc_CheckAccessList(methodName, allowed);
-     return NS_OK;
- }
-@@ -4296,7 +4298,9 @@ nsXPCComponents::CanCallMethod(const nsIID * iid, const PRUnichar *methodName, c
- NS_IMETHODIMP
- nsXPCComponents::CanGetProperty(const nsIID * iid, const PRUnichar *propertyName, char **_retval)
- {
--    static const char* allowed[] = { "interfaces", "interfacesByID", "results", nsnull};
-+    // XXX: Pref observer? Also, is this what we want? Seems like a plan
-+    //    static const char* allowed[] = { "interfaces", "interfacesByID", "results", nsnull};
-+    static const char* allowed[] = { "results", nsnull};
-     *_retval = xpc_CheckAccessList(propertyName, allowed);
-     return NS_OK;
- }
--- 
-1.7.5.4
-
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
deleted file mode 100644
index 264e027..0000000
--- a/src/current-patches/firefox/0002-Make-Permissions-Manager-memory-only.patch
+++ /dev/null
@@ -1,94 +0,0 @@
-From 4c65de64fc28ca767009a0d0acfcefd8f2a73ad8 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/19] 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
-site permissions, as well as stored STS policy.
-
-The pref does successfully clear the permissions manager memory if toggled. It
-does not need to be set in prefs.js, and can be handled by Torbutton.
-
-https://trac.torproject.org/projects/tor/ticket/2950
----
- extensions/cookie/nsPermissionManager.cpp |   34 ++++++++++++++++++++++++++--
- 1 files changed, 31 insertions(+), 3 deletions(-)
-
-diff --git a/extensions/cookie/nsPermissionManager.cpp b/extensions/cookie/nsPermissionManager.cpp
-index cdfe21b..a7a0efb 100644
---- a/extensions/cookie/nsPermissionManager.cpp
-+++ b/extensions/cookie/nsPermissionManager.cpp
-@@ -58,6 +58,10 @@
- #include "mozStorageHelper.h"
- #include "mozStorageCID.h"
- #include "nsXULAppAPI.h"
-+#include "nsCOMPtr.h"
-+#include "nsIPrefService.h"
-+#include "nsIPrefBranch.h"
-+#include "nsIPrefBranch2.h"
- 
- static nsPermissionManager *gPermissionManager = nsnull;
- 
-@@ -203,6 +207,11 @@ nsPermissionManager::Init()
-     mObserverService->AddObserver(this, "profile-do-change", true);
-   }
- 
-+  nsCOMPtr<nsIPrefBranch2> pbi = do_GetService(NS_PREFSERVICE_CONTRACTID);
-+  if (pbi) {
-+    pbi->AddObserver("permissions.", this, PR_FALSE);
-+  }
-+
-   if (IsChildProcess()) {
-     // Get the permissions from the parent process
-     InfallibleTArray<IPC::Permission> perms;
-@@ -251,8 +260,18 @@ nsPermissionManager::InitDB(bool aRemoveFile)
-   if (!storage)
-     return NS_ERROR_UNEXPECTED;
- 
-+  bool memory_db = false;
-+  nsCOMPtr<nsIPrefBranch> prefs = do_GetService(NS_PREFSERVICE_CONTRACTID);
-+  if (prefs) {
-+    prefs->GetBoolPref("permissions.memory_only", &memory_db); 
-+  }
-+
-   // cache a connection to the hosts database
--  rv = storage->OpenDatabase(permissionsFile, getter_AddRefs(mDBConn));
-+  if (memory_db) {
-+    rv = storage->OpenSpecialDatabase("memory", getter_AddRefs(mDBConn));
-+  } else {
-+    rv = storage->OpenDatabase(permissionsFile, getter_AddRefs(mDBConn));
-+  }
-   NS_ENSURE_SUCCESS(rv, rv);
- 
-   bool ready;
-@@ -262,7 +281,11 @@ nsPermissionManager::InitDB(bool aRemoveFile)
-     rv = permissionsFile->Remove(false);
-     NS_ENSURE_SUCCESS(rv, rv);
- 
--    rv = storage->OpenDatabase(permissionsFile, getter_AddRefs(mDBConn));
-+    if (memory_db) {
-+      rv = storage->OpenSpecialDatabase("memory", getter_AddRefs(mDBConn));
-+    } else {
-+      rv = storage->OpenDatabase(permissionsFile, getter_AddRefs(mDBConn));
-+    }
-     NS_ENSURE_SUCCESS(rv, rv);
- 
-     mDBConn->GetConnectionReady(&ready);
-@@ -794,7 +817,12 @@ NS_IMETHODIMP nsPermissionManager::Observe(nsISupports *aSubject, const char *aT
- {
-   ENSURE_NOT_CHILD_PROCESS;
- 
--  if (!nsCRT::strcmp(aTopic, "profile-before-change")) {
-+  if (nsCRT::strcmp(aTopic, NS_PREFBRANCH_PREFCHANGE_TOPIC_ID) == 0) {
-+    if (!nsCRT::strcmp(someData, NS_LITERAL_STRING("permissions.memory_only").get())) {
-+      // XXX: Should we remove the file? Probably not..
-+      InitDB(PR_FALSE);
-+    }
-+  } else if (!nsCRT::strcmp(aTopic, "profile-before-change")) {
-     // The profile is about to change,
-     // or is going away because the application is shutting down.
-     if (!nsCRT::strcmp(someData, NS_LITERAL_STRING("shutdown-cleanse").get())) {
--- 
-1.7.5.4
-
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
deleted file mode 100644
index eff5169..0000000
--- a/src/current-patches/firefox/0003-Make-Intermediate-Cert-Store-memory-only.patch
+++ /dev/null
@@ -1,43 +0,0 @@
-From 6b5b4816ffff9875f8fd3364841fde872a2af7a4 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/19] Make Intermediate Cert Store memory-only.
-
-This patch makes the intermediate SSL cert store exist in memory only.
-
-The pref must be set before startup in prefs.js.
-https://trac.torproject.org/projects/tor/ticket/2949
----
- security/manager/ssl/src/nsNSSComponent.cpp |   15 ++++++++++++++-
- 1 files changed, 14 insertions(+), 1 deletions(-)
-
-diff --git a/security/manager/ssl/src/nsNSSComponent.cpp b/security/manager/ssl/src/nsNSSComponent.cpp
-index 89ad70e..783d0d2 100644
---- a/security/manager/ssl/src/nsNSSComponent.cpp
-+++ b/security/manager/ssl/src/nsNSSComponent.cpp
-@@ -1755,8 +1755,21 @@ nsNSSComponent::InitializeNSS(bool showWarningBox)
-     // Ubuntu 8.04, which loads any nonexistent "<configdir>/libnssckbi.so" as
-     // "/usr/lib/nss/libnssckbi.so".
-     PRUint32 init_flags = NSS_INIT_NOROOTINIT | NSS_INIT_OPTIMIZESPACE;
--    SECStatus init_rv = ::NSS_Initialize(profileStr.get(), "", "",
-+    bool nocertdb = false;
-+    mPrefBranch->GetBoolPref("security.nocertdb", &nocertdb);
-+
-+    // XXX: We can also do the the following to only disable the certdb.
-+    // Leaving this codepath in as a fallback in case InitNODB fails
-+    if (nocertdb)
-+      init_flags |= NSS_INIT_NOCERTDB;
-+
-+    SECStatus init_rv;
-+    if (nocertdb) {
-+        init_rv = ::NSS_NoDB_Init(NULL);
-+    } else {
-+        init_rv = ::NSS_Initialize(profileStr.get(), "", "",
-                                          SECMOD_DB, init_flags);
-+    }
- 
-     if (init_rv != SECSuccess) {
-       PR_LOG(gPIPNSSLog, PR_LOG_DEBUG, ("can not init NSS r/w in %s\n", profileStr.get()));
--- 
-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
deleted file mode 100644
index 0f509a6..0000000
--- a/src/current-patches/firefox/0004-Add-a-string-based-cacheKey.patch
+++ /dev/null
@@ -1,85 +0,0 @@
-From b2dfbf250bc83592e73abf932c5301f1688a277b 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/19] 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 34291f4..92f2d7d 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=");
-     }
-@@ -4784,6 +4790,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 f8e59fe..a5b7d1e 100644
---- a/netwerk/protocol/http/nsHttpChannel.h
-+++ b/netwerk/protocol/http/nsHttpChannel.h
-@@ -306,6 +306,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
deleted file mode 100644
index d0b1104..0000000
--- a/src/current-patches/firefox/0005-Block-all-plugins-except-flash.patch
+++ /dev/null
@@ -1,85 +0,0 @@
-From 47235106c9e1257c66bab774aab330be4dabcfb0 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/19] 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 0c3efa0..e607e68 100644
---- a/dom/plugins/base/nsPluginHost.cpp
-+++ b/dom/plugins/base/nsPluginHost.cpp
-@@ -2002,6 +2002,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,
-@@ -2135,6 +2164,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 1b46957..4f1e890 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
deleted file mode 100644
index 643351d..0000000
--- a/src/current-patches/firefox/0006-Make-content-pref-service-memory-only-clearable.patch
+++ /dev/null
@@ -1,37 +0,0 @@
-From bd560666419266a862d5b0387c7941c8ef7bb624 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/19] 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 68a5561..effc33c 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/0007-Disable-SSL-Session-ID-tracking.patch b/src/current-patches/firefox/0007-Disable-SSL-Session-ID-tracking.patch
deleted file mode 100644
index f1985cf..0000000
--- a/src/current-patches/firefox/0007-Disable-SSL-Session-ID-tracking.patch
+++ /dev/null
@@ -1,28 +0,0 @@
-From 3eebe3b7e2882de39e2c686a38e7084cccfa4c60 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 07/19] 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 28e6210..fa48ecd 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-Provide-an-observer-event-to-close-persistent-connec.patch b/src/current-patches/firefox/0008-Provide-an-observer-event-to-close-persistent-connec.patch
deleted file mode 100644
index 13f16eb..0000000
--- a/src/current-patches/firefox/0008-Provide-an-observer-event-to-close-persistent-connec.patch
+++ /dev/null
@@ -1,40 +0,0 @@
-From 9594d3f2df4f20308406deea30aaccd577587438 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 08/19] 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 dcdf729..672d436 100644
---- a/netwerk/protocol/http/nsHttpHandler.cpp
-+++ b/netwerk/protocol/http/nsHttpHandler.cpp
-@@ -338,6 +338,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;
-@@ -1587,6 +1588,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/0009-Provide-client-values-only-to-CSS-Media-Queries.patch b/src/current-patches/firefox/0009-Provide-client-values-only-to-CSS-Media-Queries.patch
deleted file mode 100644
index a520df9..0000000
--- a/src/current-patches/firefox/0009-Provide-client-values-only-to-CSS-Media-Queries.patch
+++ /dev/null
@@ -1,72 +0,0 @@
-From 4c247867a8aa7401fb91e332cfd1dce10ab5a972 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 09/19] 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/0010-Rebrand-Firefox-to-TorBrowser.patch b/src/current-patches/firefox/0010-Rebrand-Firefox-to-TorBrowser.patch
deleted file mode 100644
index 3df8c83..0000000
--- a/src/current-patches/firefox/0010-Rebrand-Firefox-to-TorBrowser.patch
+++ /dev/null
@@ -1,50 +0,0 @@
-From 8a4f6f4a67a7f2fce746aaaeb9b80ce18da88d73 Mon Sep 17 00:00:00 2001
-From: Erinn Clark <erinn at torproject.org>
-Date: Wed, 25 Apr 2012 09:14:00 -0300
-Subject: [PATCH 10/19] Rebrand Firefox to TorBrowser
-
-This patch does some basic renaming of Firefox to TorBrowser. The rest of the
-branding is done by images and icons.
----
- browser/branding/official/configure.sh             |    2 +-
- browser/branding/official/locales/en-US/brand.dtd  |    6 +++---
- .../official/locales/en-US/brand.properties        |    6 +++---
- 3 files changed, 7 insertions(+), 7 deletions(-)
-
-diff --git a/browser/branding/official/configure.sh b/browser/branding/official/configure.sh
-index 4d3d297..e9b3738 100644
---- a/browser/branding/official/configure.sh
-+++ b/browser/branding/official/configure.sh
-@@ -1,2 +1,2 @@
--MOZ_APP_DISPLAYNAME=Firefox
-+MOZ_APP_DISPLAYNAME=TorBrowser
- MOZ_UA_BUILDID=20100101
-diff --git a/browser/branding/official/locales/en-US/brand.dtd b/browser/branding/official/locales/en-US/brand.dtd
-index 142d79b..c137e04 100644
---- a/browser/branding/official/locales/en-US/brand.dtd
-+++ b/browser/branding/official/locales/en-US/brand.dtd
-@@ -1,4 +1,4 @@
--<!ENTITY  brandShortName        "Firefox">
--<!ENTITY  brandFullName         "Mozilla Firefox">
--<!ENTITY  vendorShortName       "Mozilla">
-+<!ENTITY  brandShortName        "TorBrowser">
-+<!ENTITY  brandFullName         "Tor Browser">
-+<!ENTITY  vendorShortName       "Tor Project">
- <!ENTITY  trademarkInfo.part1   "Firefox and the Firefox logos are trademarks of the Mozilla Foundation.">
-diff --git a/browser/branding/official/locales/en-US/brand.properties b/browser/branding/official/locales/en-US/brand.properties
-index 5f3ad54..62ac2fd 100644
---- a/browser/branding/official/locales/en-US/brand.properties
-+++ b/browser/branding/official/locales/en-US/brand.properties
-@@ -1,6 +1,6 @@
--brandShortName=Firefox
--brandFullName=Mozilla Firefox
--vendorShortName=Mozilla
-+brandShortName=TorBrowser
-+brandFullName=Tor Browser
-+vendorShortName=Tor Project
- 
- homePageSingleStartMain=Firefox Start, a fast home page with built-in search
- homePageImport=Import your home page from %S
--- 
-1.7.5.4
-
diff --git a/src/current-patches/firefox/0011-Make-Download-manager-memory-only.patch b/src/current-patches/firefox/0011-Make-Download-manager-memory-only.patch
deleted file mode 100644
index d9e1b3e..0000000
--- a/src/current-patches/firefox/0011-Make-Download-manager-memory-only.patch
+++ /dev/null
@@ -1,57 +0,0 @@
-From 5cffe3a9aaadfc2e86779d9e050153ad747c5548 Mon Sep 17 00:00:00 2001
-From: Mike Perry <mikeperry-git at torproject.org>
-Date: Wed, 25 Apr 2012 13:39:35 -0700
-Subject: [PATCH 11/19] Make Download manager memory only.
-
-Solves https://trac.torproject.org/projects/tor/ticket/4017.
-
-Yes, this is an ugly hack. We *could* send the observer notification from
-Torbutton to tell the download manager to switch to memory, but then we have
-to dance around and tell it again if the user switches in and out of private
-browsing mode..
-
-The right way to do this is with a pref. Maybe I'll get to that someday, if
-this breaks enough times in conflict.
----
- toolkit/components/downloads/nsDownloadManager.cpp |    4 ++--
- toolkit/components/downloads/nsDownloadManager.h   |    2 +-
- 2 files changed, 3 insertions(+), 3 deletions(-)
-
-diff --git a/toolkit/components/downloads/nsDownloadManager.cpp b/toolkit/components/downloads/nsDownloadManager.cpp
-index cb1f1f6..1de653b 100644
---- a/toolkit/components/downloads/nsDownloadManager.cpp
-+++ b/toolkit/components/downloads/nsDownloadManager.cpp
-@@ -1999,7 +1999,7 @@ nsDownloadManager::Observe(nsISupports *aSubject,
-     if (NS_LITERAL_STRING("memory").Equals(aData))
-       return SwitchDatabaseTypeTo(DATABASE_MEMORY);
-     else if (NS_LITERAL_STRING("disk").Equals(aData))
--      return SwitchDatabaseTypeTo(DATABASE_DISK);
-+      return SwitchDatabaseTypeTo(DATABASE_MEMORY);
-   }
-   else if (strcmp(aTopic, "alertclickcallback") == 0) {
-     nsCOMPtr<nsIDownloadManagerUI> dmui =
-@@ -2076,7 +2076,7 @@ nsDownloadManager::OnLeavePrivateBrowsingMode()
-   (void)ResumeAllDownloads(false);
- 
-   // Switch back to the on-disk DB again
--  (void)SwitchDatabaseTypeTo(DATABASE_DISK);
-+  //(void)SwitchDatabaseTypeTo(DATABASE_DISK);
- 
-   mInPrivateBrowsing = false;
- }
-diff --git a/toolkit/components/downloads/nsDownloadManager.h b/toolkit/components/downloads/nsDownloadManager.h
-index 16a861e..e729cbf 100644
---- a/toolkit/components/downloads/nsDownloadManager.h
-+++ b/toolkit/components/downloads/nsDownloadManager.h
-@@ -92,7 +92,7 @@ public:
- 
-   virtual ~nsDownloadManager();
-   nsDownloadManager() :
--      mDBType(DATABASE_DISK)
-+      mDBType(DATABASE_MEMORY)
-     , mInPrivateBrowsing(false)
- #ifdef DOWNLOAD_SCANNER
-     , mScanner(nsnull)
--- 
-1.7.5.4
-
diff --git a/src/current-patches/firefox/0012-Add-DDG-and-StartPage-to-Omnibox.patch b/src/current-patches/firefox/0012-Add-DDG-and-StartPage-to-Omnibox.patch
deleted file mode 100644
index f3ebe5b..0000000
--- a/src/current-patches/firefox/0012-Add-DDG-and-StartPage-to-Omnibox.patch
+++ /dev/null
@@ -1,84 +0,0 @@
-From 96a520c56fd58f4ffaf89f26094de35425fa0ad4 Mon Sep 17 00:00:00 2001
-From: Mike Perry <mikeperry-git at torproject.org>
-Date: Wed, 25 Apr 2012 15:03:46 -0700
-Subject: [PATCH 12/19] Add DDG and StartPage to Omnibox.
-
-You mean there are search engines that don't require captchas if you don't
-have a cookie? Holy crap. Get those in there now.
----
- browser/locales/en-US/searchplugins/duckduckgo.xml |   29 ++++++++++++++++++++
- browser/locales/en-US/searchplugins/list.txt       |    2 +
- browser/locales/en-US/searchplugins/startpage.xml  |   11 +++++++
- 3 files changed, 42 insertions(+), 0 deletions(-)
- create mode 100644 browser/locales/en-US/searchplugins/duckduckgo.xml
- create mode 100644 browser/locales/en-US/searchplugins/startpage.xml
-
-diff --git a/browser/locales/en-US/searchplugins/duckduckgo.xml b/browser/locales/en-US/searchplugins/duckduckgo.xml
-new file mode 100644
-index 0000000..4f00b4d
---- /dev/null
-+++ b/browser/locales/en-US/searchplugins/duckduckgo.xml
-@@ -0,0 +1,29 @@
-+<SearchPlugin xmlns="http://www.mozilla.org/2006/browser/search/">
-+<ShortName>DuckDuckGo</ShortName>
-+<Description>Duck Duck Go</Description>
-+<InputEncoding>UTF-8</InputEncoding>
-+<Image width="16" height="16">data:image/png;base64,AAABAAEAEBAAAAEAIABoBAAAFgAAACgAAAAQAAAAIAAAAAEAIAAAAAAAAAAAANcNAADXDQAAAAAA
-+AAAAAAAAAAAAAAAAAAAAAAAAAAAAJyDsJmlk8pf6+v3s/v7+++zr/fcnIOyzJyDsgCcg7CYAAAAA
-+AAAAAAAAAAAAAAAAAAAAAAAAAAAnIOwBJyDscCcg7PZttJ7/7Pfs//////++xO7/S5GA/ycg7P8n
-+IOz2JyDscCcg7AEAAAAAAAAAAAAAAAAnIOwBJyDstScg7P8nIOz/Y8p5/2fHZf9Yv0z/YcF2/1rB
-+Uv8nIOz/JyDs/ycg7P8nIOy1JyDsAQAAAAAAAAAAJyDscCcg7P8nIOz/JyDs/4jQoP/p9+n/////
-+/05X3v9LkYD/JyDs/ycg7P8nIOz/JyDs/ycg7HAAAAAAJyDsJicg7PYnIOz/JyDs/zUu7f/+/v//
-+//////////89N+7/JyDs/yUo7f8nIOz/JyDs/ycg7P8nIOz2JyDsJicg7IAnIOz/JyDs/ycg7P9h
-+XPH////////////t/P//GIr2/wfD+/8Gyfz/DKv5/yM57/8nIOz/JyDs/ycg7H8nIOyzJyDs/ycg
-+7P8nIOz/jov1////////////Otz9/w3G/P8cWfH/JSvt/ycg7P8nIOz/JyDs/ycg7P8nIOyzJyDs
-+5icg7P8nIOz/JyDs/7u5+f///////////27l/v8E0v3/BNL9/wTQ/f8Oofn/IT7v/ycg7P8nIOz/
-+JyDs5icg7OYnIOz/JyDs/ycg7P/p6P3/uWsC////////////5fr//6Po/f8Thfb/DKv5/w6f+f8n IOz/JyDs/ycg7OYnIOyzJyDs/ycg7P8nIOz/9/b+/////////////////7lrAv/V1Pv/JyDs/ycg
-+7P8nIOz/JyDs/ycg7P8nIOyzJyDsgCcg7P8nIOz/JyDs/8/N+///////////////////////iIX1
-+/ycg7P8nIOz/JyDs/ycg7P8nIOz/JyDsfycg7CYnIOz2JyDs/ycg7P9FP+7/q6n4/+7u/f/n5v3/
-+fXn0/yoj7P8nIOz/JyDs/ycg7P8nIOz/JyDs9icg7CYAAAAAJyDscCcg7P8nIOz/wsD6/+no/f/Y
-+1/z/eHTz/ycg7P8nIOz/JyDs/ycg7P8nIOz/JyDs/ycg7HAAAAAAAAAAACcg7AEnIOy1JyDs/ycg
-+7P8nIOz/JyDs/ycg7P8nIOz/JyDs/ycg7P8nIOz/JyDs/ycg7LUnIOwBAAAAAAAAAAAAAAAAJyDs
-+AScg7HAnIOz2JyDs/ycg7P8nIOz/JyDs/ycg7P8nIOz/JyDs9icg7HAnIOwBAAAAAAAAAAAAAAAA
-+AAAAAAAAAAAAAAAAJyDsJicg7IAnIOyzJyDs5icg7OYnIOyzJyDsgCcg7CYAAAAAAAAAAAAAAAAA
-+AAAA+B8AAPAPAADAAwAAwAMAAIABAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAABAACAAQAAwAMAAMAD
-+AADwDwAA+B8AAA==</Image>
-+<Url type="text/html" method="POST" template="https://duckduckgo.com/html/">
-+  <Param name="q" value="{searchTerms}"/>
-+</Url>
-+<SearchForm>https://duckduckgo.com/html/</SearchForm>
-+</SearchPlugin>
-diff --git a/browser/locales/en-US/searchplugins/list.txt b/browser/locales/en-US/searchplugins/list.txt
-index 2a1141a..0466f4e 100644
---- a/browser/locales/en-US/searchplugins/list.txt
-+++ b/browser/locales/en-US/searchplugins/list.txt
-@@ -1,7 +1,9 @@
- amazondotcom
- bing
-+duckduckgo
- eBay
- google
-+startpage
- twitter
- wikipedia
- yahoo
-diff --git a/browser/locales/en-US/searchplugins/startpage.xml b/browser/locales/en-US/searchplugins/startpage.xml
-new file mode 100644
-index 0000000..1a310b1
---- /dev/null
-+++ b/browser/locales/en-US/searchplugins/startpage.xml
-@@ -0,0 +1,11 @@
-+<SearchPlugin xmlns="http://www.mozilla.org/2006/browser/search/">
-+<ShortName>Startpage</ShortName>
-+<Description>Start Page</Description>
-+<InputEncoding>UTF-8</InputEncoding>
-+<Image width="16" height="16">data:image/png;base64,AAABAAEAEBAAAAEAIABoBAAAFgAAACgAAAAQAAAAIAAAAAEAIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD2jkj+9YtD/vWLQ/71i0P+9otD/vaLRP72i0T+9YtE/vWLRP72i0T+9otD/vaNRP72jUT+9otF/vaLRf73kkv+9Yc///WJP//1iT//9Yk///rAmf/94Mz/+sCa//aRTv/1iUH/9ok///aJP//2i0H/9otB//aJQv/2iUL/9otC//aNRP/2jUT/9o1E//aNRP/6wpv////////////96dr/95dQ//aNRP/2kET/9pBG//aQRv/2kEb/9pBG//aRR//3lEz/95BH//mueP/7xJ3/959g//efYf/4p23//vDm//3p2//3kEr/95FJ//aRSf/niFH/95FK//aRSv/2mE//95hS/vq4iP/////////////////81bj/95xZ//q4iP//////+bF+//eZT//njFT/PSqi/2xGjv/2mVD/951V/vedVv783cX///////vQrf/++PP///////748//+8uj///////m3gf/olFr/PSuj/w8Pt/9sSJD/951V//eeWf73oVv++8ul///////5sXf/+KRi//vRsf////////////3r3v/olF//Piyk/w8Pt/9sSJH/+J5Z//ieWv/3oV/++KZf/vihXP/97N7//vn0//zTs//6wJP/+bBy//q6iP/onW//Piyl/w8Pt/8fGbH/m2iB/+icY//4pGD/96hl/viqZf74pmD/+Kxr//3iy/////////n1//ivbP/onGj/Pi2m/w8Pt/8uJKz/fFeQ/x8Zsf8+Lqb/6J9r//ivbP74rm3++Klm//mpZv/5q2f/+bR9//m0e//poW7/Pi6n/w8Pt/9sTZj/+Ktp//ira/+rd4P/Dw+3/4xijv/5snH+
 +LN1/vmvbf/5r23/+a5t//mvb//4r2//TTuk/w8Pt/8fGrL/6ah1//ivcP/4r3P/q3yI/w8Pt/+MZpP/+bN5/vm4ev75t3X/+bV1//m1df/5t3X/+Ld3/8qUhP98XZn/Hxqz/+mse//5t3f/2p+B/x8as/8PD7f/u4qK//m7fv76u4D++bl7//m3fP/5uXz/+bl8//m5fP/5t3z/+bl//x8as/9NPKf/fWCb/x8as/8PD7f/bVOh//q5f//6v4X++sGI/vm9g//5voX/+b6F//m9hf/6vYX/+r6F//nCh/+bepr/Hxu0/w8Pt/8PD7f/fWOh//q+hf/6wof/+saN/vrGjf75xIv/+ceL//nEi//5xIv/+sSL//rHi//6x43/+ceN/+m7kP+7lpj/6ruQ//rHkP/6x43/+seQ//rLlf76ypT++seR//rJkf/6yZH/+seR//rJkf/6yZH/+8mR//vJlP/7yZT/+smU//rJlP/6yZT/+8yV//rJlf/6zpn+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA==</Image>
-+
-+<Url type="text/html" method="POST" template="https://startpage.com/do/search">
-+  <Param name="q" value="{searchTerms}"/>
-+</Url>
-+<SearchForm>https://startpage.com/do/search/</SearchForm>
-+</SearchPlugin>
--- 
-1.7.5.4
-
diff --git a/src/current-patches/firefox/0013-Make-nsICacheService.EvictEntries-synchronous.patch b/src/current-patches/firefox/0013-Make-nsICacheService.EvictEntries-synchronous.patch
deleted file mode 100644
index cbc5bc7..0000000
--- a/src/current-patches/firefox/0013-Make-nsICacheService.EvictEntries-synchronous.patch
+++ /dev/null
@@ -1,44 +0,0 @@
-From 1cf939b8ba9e04b33969546436633d263c939000 Mon Sep 17 00:00:00 2001
-From: Mike Perry <mikeperry-git at torproject.org>
-Date: Tue, 1 May 2012 15:02:03 -0700
-Subject: [PATCH 13/19] Make nsICacheService.EvictEntries synchronous
-
-This fixes a race condition that allows cache-based EverCookies to persist for
-a brief time (on the order of minutes?) after cache clearing/"New Identity".
-
-https://trac.torproject.org/projects/tor/ticket/5715
----
- netwerk/cache/nsCacheService.cpp |   15 +++++++++++++--
- 1 files changed, 13 insertions(+), 2 deletions(-)
-
-diff --git a/netwerk/cache/nsCacheService.cpp b/netwerk/cache/nsCacheService.cpp
-index 8c85b68..d43f121 100644
---- a/netwerk/cache/nsCacheService.cpp
-+++ b/netwerk/cache/nsCacheService.cpp
-@@ -1414,10 +1414,21 @@ NS_IMETHODIMP nsCacheService::VisitEntries(nsICacheVisitor *visitor)
-     return NS_OK;
- }
- 
--
- NS_IMETHODIMP nsCacheService::EvictEntries(nsCacheStoragePolicy storagePolicy)
- {
--    return  EvictEntriesForClient(nsnull, storagePolicy);
-+    NS_IMETHODIMP r;
-+    r = EvictEntriesForClient(nsnull, storagePolicy);
-+
-+    // XXX: Bloody hack until we get this notifier in FF14.0:
-+    // https://developer.mozilla.org/en/XPCOM_Interface_Reference/nsICacheListener#onCacheEntryDoomed%28%29
-+    if (storagePolicy == nsICache::STORE_ANYWHERE &&
-+            NS_IsMainThread() && gService && gService->mInitialized) {
-+        nsCacheServiceAutoLock lock;
-+        gService->DoomActiveEntries();
-+        gService->ClearDoomList();
-+        (void) SyncWithCacheIOThread();
-+    }
-+    return r; 
- }
- 
- NS_IMETHODIMP nsCacheService::GetCacheIOTarget(nsIEventTarget * *aCacheIOTarget)
--- 
-1.7.5.4
-
diff --git a/src/current-patches/firefox/0014-Prevent-WebSocket-DNS-leak.patch b/src/current-patches/firefox/0014-Prevent-WebSocket-DNS-leak.patch
deleted file mode 100644
index 667d9c8..0000000
--- a/src/current-patches/firefox/0014-Prevent-WebSocket-DNS-leak.patch
+++ /dev/null
@@ -1,132 +0,0 @@
-From b2f620bbb866f556dc3791bca5478f47a2255376 Mon Sep 17 00:00:00 2001
-From: Mike Perry <mikeperry-git at torproject.org>
-Date: Wed, 2 May 2012 17:44:39 -0700
-Subject: [PATCH 14/19] Prevent WebSocket DNS leak.
-
-This is due to an improper implementation of the WebSocket spec by Mozilla.
-
-"There MUST be no more than one connection in a CONNECTING state.  If multiple
-connections to the same IP address are attempted simultaneously, the client
-MUST serialize them so that there is no more than one connection at a time
-running through the following steps.
-
-If the client cannot determine the IP address of the remote host (for
-example, because all communication is being done through a proxy server that
-performs DNS queries itself), then the client MUST assume for the purposes of
-this step that each host name refers to a distinct remote host,"
-
-https://tools.ietf.org/html/rfc6455#page-15
-
-They implmented the first paragraph, but not the second...
-
-While we're at it, we also prevent the DNS service from being used to look up
-anything other than IP addresses if socks_remote_dns is set to true, so this
-bug can't turn up in other components or due to 3rd party addons.
----
- netwerk/dns/nsDNSService2.cpp                   |   24 ++++++++++++++++++++++-
- netwerk/dns/nsDNSService2.h                     |    1 +
- netwerk/protocol/websocket/WebSocketChannel.cpp |    8 +++++-
- 3 files changed, 30 insertions(+), 3 deletions(-)
-
-diff --git a/netwerk/dns/nsDNSService2.cpp b/netwerk/dns/nsDNSService2.cpp
-index 7458729..40fbaba 100644
---- a/netwerk/dns/nsDNSService2.cpp
-+++ b/netwerk/dns/nsDNSService2.cpp
-@@ -403,6 +403,7 @@ nsDNSService::Init()
-     bool     enableIDN        = true;
-     bool     disableIPv6      = false;
-     bool     disablePrefetch  = false;
-+    bool     disableDNS       = false;
-     int      proxyType        = nsIProtocolProxyService::PROXYCONFIG_DIRECT;
-     
-     nsAdoptingCString ipv4OnlyDomains;
-@@ -426,6 +427,10 @@ nsDNSService::Init()
- 
-         // If a manual proxy is in use, disable prefetch implicitly
-         prefs->GetIntPref("network.proxy.type", &proxyType);
-+
-+        // If the user wants remote DNS, we should fail any lookups that still
-+        // make it here.
-+        prefs->GetBoolPref("network.proxy.socks_remote_dns", &disableDNS);
-     }
- 
-     if (mFirstTime) {
-@@ -443,7 +448,7 @@ nsDNSService::Init()
- 
-             // Monitor these to see if there is a change in proxy configuration
-             // If a manual proxy is in use, disable prefetch implicitly
--            prefs->AddObserver("network.proxy.type", this, false);
-+            prefs->AddObserver("network.proxy.", this, false);
-         }
-     }
- 
-@@ -472,6 +477,7 @@ nsDNSService::Init()
-         mIDN = idn;
-         mIPv4OnlyDomains = ipv4OnlyDomains; // exchanges buffer ownership
-         mDisableIPv6 = disableIPv6;
-+        mDisableDNS = disableDNS;
- 
-         // Disable prefetching either by explicit preference or if a manual proxy is configured 
-         mDisablePrefetch = disablePrefetch || (proxyType == nsIProtocolProxyService::PROXYCONFIG_MANUAL);
-@@ -583,6 +589,14 @@ nsDNSService::AsyncResolve(const nsACString  &hostname,
-         if (mDisablePrefetch && (flags & RESOLVE_SPECULATE))
-             return NS_ERROR_DNS_LOOKUP_QUEUE_FULL;
- 
-+        PRNetAddr tempAddr;
-+        if (mDisableDNS) {
-+            // Allow IP lookups through, but nothing else.
-+            if (PR_StringToNetAddr(hostname.BeginReading(), &tempAddr) != PR_SUCCESS) {
-+                return NS_ERROR_UNKNOWN_PROXY_HOST; // XXX: NS_ERROR_NOT_IMPLEMENTED?
-+            }
-+        }
-+
-         res = mResolver;
-         idn = mIDN;
-     }
-@@ -669,6 +683,14 @@ nsDNSService::Resolve(const nsACString &hostname,
-         MutexAutoLock lock(mLock);
-         res = mResolver;
-         idn = mIDN;
-+
-+        PRNetAddr tempAddr;
-+        if (mDisableDNS) {
-+            // Allow IP lookups through, but nothing else.
-+            if (PR_StringToNetAddr(hostname.BeginReading(), &tempAddr) != PR_SUCCESS) {
-+                return NS_ERROR_UNKNOWN_PROXY_HOST; // XXX: NS_ERROR_NOT_IMPLEMENTED?
-+            }
-+        }
-     }
-     NS_ENSURE_TRUE(res, NS_ERROR_OFFLINE);
- 
-diff --git a/netwerk/dns/nsDNSService2.h b/netwerk/dns/nsDNSService2.h
-index 1749b41..3ec8eba 100644
---- a/netwerk/dns/nsDNSService2.h
-+++ b/netwerk/dns/nsDNSService2.h
-@@ -70,4 +70,5 @@ private:
-     bool                      mDisableIPv6;
-     bool                      mDisablePrefetch;
-     bool                      mFirstTime;
-+    bool                      mDisableDNS;
- };
-diff --git a/netwerk/protocol/websocket/WebSocketChannel.cpp b/netwerk/protocol/websocket/WebSocketChannel.cpp
-index 3578866..b1aaec2 100644
---- a/netwerk/protocol/websocket/WebSocketChannel.cpp
-+++ b/netwerk/protocol/websocket/WebSocketChannel.cpp
-@@ -1884,8 +1884,12 @@ WebSocketChannel::ApplyForAdmission()
-   LOG(("WebSocketChannel::ApplyForAdmission: checking for concurrent open\n"));
-   nsCOMPtr<nsIThread> mainThread;
-   NS_GetMainThread(getter_AddRefs(mainThread));
--  dns->AsyncResolve(hostName, 0, this, mainThread, getter_AddRefs(mDNSRequest));
--  NS_ENSURE_SUCCESS(rv, rv);
-+  rv = dns->AsyncResolve(hostName, 0, this, mainThread, getter_AddRefs(mDNSRequest));
-+  if (NS_FAILED(rv)) {
-+      // Fall back to hostname on dispatch failure
-+      mDNSRequest = nsnull;
-+      OnLookupComplete(nsnull, nsnull, rv);
-+  }
- 
-   return NS_OK;
- }
--- 
-1.7.5.4
-
diff --git a/src/current-patches/firefox/0015-Make-Tor-Browser-exit-when-not-launched-from-Vidalia.patch b/src/current-patches/firefox/0015-Make-Tor-Browser-exit-when-not-launched-from-Vidalia.patch
deleted file mode 100644
index bc27267..0000000
--- a/src/current-patches/firefox/0015-Make-Tor-Browser-exit-when-not-launched-from-Vidalia.patch
+++ /dev/null
@@ -1,45 +0,0 @@
-From 57c38c109e0dd06eff36104570c40feefb03bb39 Mon Sep 17 00:00:00 2001
-From: Mike Perry <mikeperry-git at torproject.org>
-Date: Thu, 7 Jun 2012 14:45:26 -0700
-Subject: [PATCH 15/19] 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 |   14 ++++++++++++++
- 1 files changed, 14 insertions(+), 0 deletions(-)
-
-diff --git a/browser/base/content/browser.js b/browser/base/content/browser.js
-index 6e254ca..57ca373 100644
---- a/browser/base/content/browser.js
-+++ b/browser/base/content/browser.js
-@@ -1234,6 +1234,20 @@ 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 && uriToLoad != "about:blank") {
-     if (uriToLoad instanceof Ci.nsISupportsArray) {
-       let count = uriToLoad.Count();
--- 
-1.7.5.4
-
diff --git a/src/current-patches/firefox/0016-Limit-the-number-of-fonts-per-document.patch b/src/current-patches/firefox/0016-Limit-the-number-of-fonts-per-document.patch
deleted file mode 100644
index 5053dea..0000000
--- a/src/current-patches/firefox/0016-Limit-the-number-of-fonts-per-document.patch
+++ /dev/null
@@ -1,225 +0,0 @@
-From 1fda7ee08947f2df08709afed325a14e6a82f64d Mon Sep 17 00:00:00 2001
-From: Mike Perry <mikeperry-git at torproject.org>
-Date: Thu, 7 Jun 2012 15:09:59 -0700
-Subject: [PATCH 16/19] 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 f3815fb..1ab210e 100644
---- a/layout/base/nsPresContext.cpp
-+++ b/layout/base/nsPresContext.cpp
-@@ -97,6 +97,8 @@
- #include "FrameLayerBuilder.h"
- #include "nsDOMMediaQueryList.h"
- #include "nsSMILAnimationController.h"
-+#include "nsString.h"
-+#include "nsUnicharUtils.h"
- 
- #ifdef IBMBIDI
- #include "nsBidiPresUtils.h"
-@@ -772,6 +774,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 =
-@@ -1381,6 +1387,100 @@ nsPresContext::GetDefaultFont(PRUint8 aFontID, nsIAtom *aLanguage) 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 e367c5f..3d979f1 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);
-+
-   /**
-    * Get the minimum font size for the specified language. If aLanguage
-    * is nsnull, then the document's language is used.
-@@ -1188,6 +1195,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 4b134b2..82b1dd7 100644
---- a/layout/style/nsRuleNode.cpp
-+++ b/layout/style/nsRuleNode.cpp
-@@ -3102,14 +3102,15 @@ nsRuleNode::ComputeFontData(void* aStartStruct,
- 
-   bool useDocumentFonts =
-     mPresContext->GetCachedBoolPref(kPresContext_UseDocumentFonts);
-+  bool isXUL = PR_FALSE;
- 
-   // See if we are in the chrome
-   // We only need to know this to determine if we have to use the
-   // document fonts (overriding the useDocumentFonts flag).
--  if (!useDocumentFonts && 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 = true;
-   }
- 
-   // Figure out if we are a generic font
-@@ -3123,9 +3124,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)) {
-@@ -3161,6 +3166,8 @@ nsRuleNode::ComputeFontData(void* aStartStruct,
-                                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/0017-Randomize-HTTP-request-order-and-pipeline-depth.patch b/src/current-patches/firefox/0017-Randomize-HTTP-request-order-and-pipeline-depth.patch
deleted file mode 100644
index 67c40df..0000000
--- a/src/current-patches/firefox/0017-Randomize-HTTP-request-order-and-pipeline-depth.patch
+++ /dev/null
@@ -1,251 +0,0 @@
-From a14811fde3ebdf0073daafb570a733f601411e21 Mon Sep 17 00:00:00 2001
-From: Mike Perry <mikeperry-git at torproject.org>
-Date: Thu, 7 Jun 2012 15:13:45 -0700
-Subject: [PATCH 17/19] 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 |  136 ++++++++++++++++++++++++-
- netwerk/protocol/http/nsHttpConnectionMgr.h   |    5 +
- 2 files changed, 136 insertions(+), 5 deletions(-)
-
-diff --git a/netwerk/protocol/http/nsHttpConnectionMgr.cpp b/netwerk/protocol/http/nsHttpConnectionMgr.cpp
-index 463584f..e05669c 100644
---- a/netwerk/protocol/http/nsHttpConnectionMgr.cpp
-+++ b/netwerk/protocol/http/nsHttpConnectionMgr.cpp
-@@ -101,6 +101,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()
-@@ -380,8 +386,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 = new PRInt32[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);
-@@ -392,6 +402,8 @@ nsHttpConnectionMgr::AddTransactionToPipeline(nsHttpPipeline *pipeline)
-                     break;
-                 }
-             }
-+
-+            delete [] ind;
-         }
-     }
- }
-@@ -922,12 +934,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 = new PRUint32[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
-@@ -951,6 +968,7 @@ nsHttpConnectionMgr::ProcessPendingQForEntry(nsConnectionEntry *ent)
-                               "something mutated pending queue from "
-                               "GetConnection()");
-         }
-+        delete [] ind;
-         if (conn) {
-             LOG(("  dispatching pending transaction...\n"));
- 
-@@ -1035,6 +1053,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) );
-@@ -1274,7 +1305,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;
-     }
- 
-@@ -1349,6 +1380,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 6b4398b..c33870f 100644
---- a/netwerk/protocol/http/nsHttpConnectionMgr.h
-+++ b/netwerk/protocol/http/nsHttpConnectionMgr.h
-@@ -53,6 +53,7 @@
- #include "nsIObserver.h"
- #include "nsITimer.h"
- #include "nsIX509Cert3.h"
-+#include "nsIRandomGenerator.h"
- 
- class nsHttpPipeline;
- 
-@@ -320,6 +321,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);
-@@ -412,6 +415,8 @@ private:
-     PRUint64 mTimeOfNextWakeUp;
-     // Timer for next pruning of dead connections.
-     nsCOMPtr<nsITimer> mTimer;
-+    // Random number generator for reordering HTTP pipeline
-+    nsCOMPtr<nsIRandomGenerator>             mRandomGenerator;
- 
-     // A 1s tick to call nsHttpConnection::ReadTimeoutTick on
-     // active http/1 connections. Disabled when there are no
--- 
-1.7.5.4
-
diff --git a/src/current-patches/firefox/0018-Adapt-Steven-Michaud-s-Mac-crashfix-patch.patch b/src/current-patches/firefox/0018-Adapt-Steven-Michaud-s-Mac-crashfix-patch.patch
deleted file mode 100644
index 311b44c..0000000
--- a/src/current-patches/firefox/0018-Adapt-Steven-Michaud-s-Mac-crashfix-patch.patch
+++ /dev/null
@@ -1,541 +0,0 @@
-From f427cb05b95348ed98ece917d8578e69e291b0f1 Mon Sep 17 00:00:00 2001
-From: Mike Perry <mikeperry-git at torproject.org>
-Date: Thu, 7 Jun 2012 15:26:13 -0700
-Subject: [PATCH 18/19] Adapt Steven Michaud's Mac crashfix patch
-
-Source is: https://bugzilla.mozilla.org/show_bug.cgi?id=715885#c35
-
-Some minor tweaks were needed to get it to apply and to compile on
-MacOS.
----
- widget/Makefile.in                        |    1 +
- widget/cocoa/nsChildView.mm               |   32 +++++++++++++------
- widget/gtk2/nsDragService.cpp             |    2 +-
- widget/gtk2/nsWindow.cpp                  |    2 +-
- widget/nsIDragService.idl                 |    4 +--
- widget/nsPIDragService.idl                |   48 +++++++++++++++++++++++++++++
- widget/qt/nsDragService.h                 |    2 +
- widget/windows/Makefile.in                |    4 ++
- widget/windows/nsDragService.cpp          |   13 +++++---
- widget/windows/nsDragService.h            |   12 +++---
- widget/windows/nsNativeDragSource.cpp     |    7 ++--
- widget/windows/nsNativeDragTarget.cpp     |   28 ++++++++++------
- widget/windows/nsPIDragServiceWindows.idl |   46 +++++++++++++++++++++++++++
- widget/xpwidgets/nsBaseDragService.cpp    |   16 +++++++++-
- widget/xpwidgets/nsBaseDragService.h      |    9 ++---
- 15 files changed, 180 insertions(+), 46 deletions(-)
- create mode 100644 widget/nsPIDragService.idl
- create mode 100644 widget/windows/nsPIDragServiceWindows.idl
-
-diff --git a/widget/Makefile.in b/widget/Makefile.in
-index 4a3405b..4c105a4 100644
---- a/widget/Makefile.in
-+++ b/widget/Makefile.in
-@@ -138,6 +138,7 @@ XPIDLSRCS	= \
- 		nsIClipboardDragDropHooks.idl \
- 		nsIClipboardDragDropHookList.idl \
- 		nsIDragSession.idl \
-+		nsPIDragService.idl \
- 		nsIDragService.idl \
- 		nsIFormatConverter.idl \
- 		nsIClipboard.idl \
-diff --git a/widget/cocoa/nsChildView.mm b/widget/cocoa/nsChildView.mm
-index 0db6b1c..e88302b 100644
---- a/widget/cocoa/nsChildView.mm
-+++ b/widget/cocoa/nsChildView.mm
-@@ -4555,11 +4555,12 @@ NSEvent* gLastDragMouseDownEvent = nil;
-   if (!dragService) {
-     dragService = do_GetService(kDragServiceContractID);
-   }
-+  nsCOMPtr<nsPIDragService> dragServicePriv = do_QueryInterface(dragService);
- 
-   if (dragService) {
-     NSPoint pnt = [NSEvent mouseLocation];
-     FlipCocoaScreenCoordinate(pnt);
--    dragService->DragMoved(NSToIntRound(pnt.x), NSToIntRound(pnt.y));
-+    dragServicePriv->DragMoved(NSToIntRound(pnt.x), NSToIntRound(pnt.y));
-   }
- }
- 
-@@ -4580,11 +4581,13 @@ NSEvent* gLastDragMouseDownEvent = nil;
-   }
- 
-   if (mDragService) {
--    // set the dragend point from the current mouse location
--    nsDragService* dragService = static_cast<nsDragService *>(mDragService);
--    NSPoint pnt = [NSEvent mouseLocation];
--    FlipCocoaScreenCoordinate(pnt);
--    dragService->SetDragEndPoint(nsIntPoint(NSToIntRound(pnt.x), NSToIntRound(pnt.y)));
-+    nsCOMPtr<nsPIDragService> dragServicePriv = do_QueryInterface(mDragService);
-+    if (dragServicePriv) {
-+      // set the dragend point from the current mouse location
-+      NSPoint pnt = [NSEvent mouseLocation];
-+      FlipCocoaScreenCoordinate(pnt);
-+      dragServicePriv->SetDragEndPoint(NSToIntRound(pnt.x), NSToIntRound(pnt.y));
-+    }
- 
-     // XXX: dropEffect should be updated per |operation|. 
-     // As things stand though, |operation| isn't well handled within "our"
-@@ -4595,10 +4598,19 @@ NSEvent* gLastDragMouseDownEvent = nil;
-     // value for NSDragOperationGeneric that is passed by other applications.
-     // All that said, NSDragOperationNone is still reliable.
-     if (operation == NSDragOperationNone) {
--      nsCOMPtr<nsIDOMDataTransfer> dataTransfer;
--      dragService->GetDataTransfer(getter_AddRefs(dataTransfer));
--      if (dataTransfer)
--        dataTransfer->SetDropEffectInt(nsIDragService::DRAGDROP_ACTION_NONE);
-+      nsCOMPtr<nsIDragSession> dragSession;
-+      mDragService->GetCurrentSession(getter_AddRefs(dragSession));
-+      if (dragSession) {
-+        nsCOMPtr<nsIDOMDataTransfer> dataTransfer;
-+        dragSession->GetDataTransfer(getter_AddRefs(dataTransfer));
-+        if (dataTransfer) {
-+          nsCOMPtr<nsIDOMNSDataTransfer> dataTransferNS =
-+                do_QueryInterface(dataTransfer);
-+          if (dataTransferNS) {
-+            dataTransferNS->SetDropEffectInt(nsIDragService::DRAGDROP_ACTION_NONE);
-+          }
-+        }
-+      }
-     }
- 
-     mDragService->EndDragSession(true);
-diff --git a/widget/gtk2/nsDragService.cpp b/widget/gtk2/nsDragService.cpp
-index be8f388..99d3878 100644
---- a/widget/gtk2/nsDragService.cpp
-+++ b/widget/gtk2/nsDragService.cpp
-@@ -1332,7 +1332,7 @@ nsDragService::SourceEndDragSession(GdkDragContext *aContext,
-     GdkDisplay* display = gdk_display_get_default();
-     if (display) {
-       gdk_display_get_pointer(display, NULL, &x, &y, NULL);
--      SetDragEndPoint(nsIntPoint(x, y));
-+      SetDragEndPoint(x, y);
-     }
- 
-     // Either the drag was aborted or the drop occurred outside the app.
-diff --git a/widget/gtk2/nsWindow.cpp b/widget/gtk2/nsWindow.cpp
-index 9de734e..81fe553 100644
---- a/widget/gtk2/nsWindow.cpp
-+++ b/widget/gtk2/nsWindow.cpp
-@@ -3517,7 +3517,7 @@ nsWindow::OnDragDropEvent(GtkWidget *aWidget,
-     if (display) {
-       // get the current cursor position
-       gdk_display_get_pointer(display, NULL, &x, &y, NULL);
--      ((nsDragService *)dragService.get())->SetDragEndPoint(nsIntPoint(x, y));
-+      ((nsDragService *)dragService.get())->SetDragEndPoint(x, y);
-     }
-     dragService->EndDragSession(true);
- 
-diff --git a/widget/nsIDragService.idl b/widget/nsIDragService.idl
-index e42c578..ef8c46f 100644
---- a/widget/nsIDragService.idl
-+++ b/widget/nsIDragService.idl
-@@ -48,7 +48,7 @@ interface nsIDOMDragEvent;
- interface nsIDOMDataTransfer;
- interface nsISelection;
- 
--[scriptable, uuid(82B58ADA-F490-4C3D-B737-1057C4F1D052), builtinclass]
-+[scriptable, uuid(82B58ADA-F490-4C3D-B737-1057C4F1D052)]
- interface nsIDragService : nsISupports
- {
-   const long DRAGDROP_ACTION_NONE = 0;
-@@ -145,8 +145,6 @@ interface nsIDragService : nsISupports
-    */
-   void suppress();
-   void unsuppress();
--
--  [noscript] void dragMoved(in long aX, in long aY);
- };
- 
- 
-diff --git a/widget/nsPIDragService.idl b/widget/nsPIDragService.idl
-new file mode 100644
-index 0000000..93a144d
---- /dev/null
-+++ b/widget/nsPIDragService.idl
-@@ -0,0 +1,48 @@
-+/* ***** BEGIN LICENSE BLOCK *****
-+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
-+ *
-+ * The contents of this file are subject to the Mozilla Public License Version
-+ * 1.1 (the "License"); you may not use this file except in compliance with
-+ * the License. You may obtain a copy of the License at
-+ * http://www.mozilla.org/MPL/
-+ *
-+ * Software distributed under the License is distributed on an "AS IS" basis,
-+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
-+ * for the specific language governing rights and limitations under the
-+ * License.
-+ *
-+ * The Original Code is mozilla.org code.
-+ *
-+ * The Initial Developer of the Original Code is
-+ * The Mozilla Foundation.
-+ * Portions created by the Initial Developer are Copyright (C) 2012
-+ * the Initial Developer. All Rights Reserved.
-+ *
-+ * Contributor(s):
-+ *   Steven Michaud <smichaud at pobox.com>
-+ *
-+ * Alternatively, the contents of this file may be used under the terms of
-+ * either the GNU General Public License Version 2 or later (the "GPL"), or
-+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
-+ * in which case the provisions of the GPL or the LGPL are applicable instead
-+ * of those above. If you wish to allow use of your version of this file only
-+ * under the terms of either the GPL or the LGPL, and not to allow others to
-+ * use your version of this file under the terms of the MPL, indicate your
-+ * decision by deleting the provisions above and replace them with the notice
-+ * and other provisions required by the GPL or the LGPL. If you do not delete
-+ * the provisions above, a recipient may use your version of this file under
-+ * the terms of any one of the MPL, the GPL or the LGPL.
-+ *
-+ * ***** END LICENSE BLOCK ***** */
-+
-+#include "nsISupports.idl"
-+
-+[scriptable, uuid(FAD8C90B-8E1D-446A-9B6C-241486A85CBD)]
-+interface nsPIDragService : nsISupports
-+{
-+  void dragMoved(in long aX, in long aY);
-+
-+  PRUint16 getInputSource();
-+
-+  void setDragEndPoint(in long aX, in long aY);
-+};
-diff --git a/widget/qt/nsDragService.h b/widget/qt/nsDragService.h
-index 5a3e5bb..50dcfac 100644
---- a/widget/qt/nsDragService.h
-+++ b/widget/qt/nsDragService.h
-@@ -50,6 +50,8 @@ public:
-     NS_DECL_ISUPPORTS
-     NS_DECL_NSIDRAGSERVICE
- 
-+    NS_IMETHOD DragMoved(PRInt32 aX, PRInt32 aY);
-+
-     nsDragService();
- 
- private:
-diff --git a/widget/windows/Makefile.in b/widget/windows/Makefile.in
-index df811ac..8d5ea4b 100644
---- a/widget/windows/Makefile.in
-+++ b/widget/windows/Makefile.in
-@@ -120,6 +120,10 @@ ifdef MOZ_ENABLE_D3D10_LAYER
- DEFINES		+= -DMOZ_ENABLE_D3D10_LAYER
- endif
- 
-+XPIDLSRCS	+= \
-+		nsPIDragServiceWindows.idl \
-+		$(NULL)
-+
- SHARED_LIBRARY_LIBS = \
-   ../xpwidgets/$(LIB_PREFIX)xpwidgets_s.$(LIB_SUFFIX) \
-   $(NULL)
-diff --git a/widget/windows/nsDragService.cpp b/widget/windows/nsDragService.cpp
-index b6b5b62..9657263 100644
---- a/widget/windows/nsDragService.cpp
-+++ b/widget/windows/nsDragService.cpp
-@@ -97,6 +97,8 @@ nsDragService::~nsDragService()
-   NS_IF_RELEASE(mDataObject);
- }
- 
-+NS_IMPL_ISUPPORTS_INHERITED1(nsDragService, nsBaseDragService, nsPIDragServiceWindows)
-+
- bool
- nsDragService::CreateDragImage(nsIDOMNode *aDOMNode,
-                                nsIScriptableRegion *aRegion,
-@@ -347,7 +349,7 @@ nsDragService::StartInvokingDragSession(IDataObject * aDataObj,
-   POINT cpos;
-   cpos.x = GET_X_LPARAM(pos);
-   cpos.y = GET_Y_LPARAM(pos);
--  SetDragEndPoint(nsIntPoint(cpos.x, cpos.y));
-+  SetDragEndPoint(cpos.x, cpos.y);
-   EndDragSession(true);
- 
-   mDoingDrag = false;
-@@ -465,25 +467,26 @@ nsDragService::GetData(nsITransferable * aTransferable, PRUint32 anItem)
- 
- //---------------------------------------------------------
- NS_IMETHODIMP
--nsDragService::SetIDataObject(IDataObject * aDataObj)
-+nsDragService::SetIDataObject(nsISupports * aDataObj)
- {
-+  IDataObject *dataObj = (IDataObject*) aDataObj;
-   // When the native drag starts the DragService gets
-   // the IDataObject that is being dragged
-   NS_IF_RELEASE(mDataObject);
--  mDataObject = aDataObj;
-+  mDataObject = dataObj;
-   NS_IF_ADDREF(mDataObject);
- 
-   return NS_OK;
- }
- 
- //---------------------------------------------------------
--void
-+NS_IMETHODIMP
- nsDragService::SetDroppedLocal()
- {
-   // Sent from the native drag handler, letting us know
-   // a drop occurred within the application vs. outside of it.
-   mSentLocalDropEvent = true;
--  return;
-+  return NS_OK;
- }
- 
- //-------------------------------------------------------------------------
-diff --git a/widget/windows/nsDragService.h b/widget/windows/nsDragService.h
-index 87d6cc9..04c8746 100644
---- a/widget/windows/nsDragService.h
-+++ b/widget/windows/nsDragService.h
-@@ -39,6 +39,7 @@
- #define nsDragService_h__
- 
- #include "nsBaseDragService.h"
-+#include "nsPIDragServiceWindows.h"
- #include <windows.h>
- #include <shlobj.h>
- 
-@@ -52,12 +53,15 @@ class  nsString;
-  * Native Win32 DragService wrapper
-  */
- 
--class nsDragService : public nsBaseDragService
-+class nsDragService : public nsBaseDragService, public nsPIDragServiceWindows
- {
- public:
-   nsDragService();
-   virtual ~nsDragService();
--  
-+
-+  NS_DECL_ISUPPORTS_INHERITED
-+  NS_DECL_NSPIDRAGSERVICEWINDOWS
-+
-   // nsIDragService
-   NS_IMETHOD InvokeDragSession(nsIDOMNode *aDOMNode,
-                                nsISupportsArray *anArrayTransferables,
-@@ -71,13 +75,9 @@ public:
-   NS_IMETHOD EndDragSession(bool aDoneDrag);
- 
-   // native impl.
--  NS_IMETHOD SetIDataObject(IDataObject * aDataObj);
-   NS_IMETHOD StartInvokingDragSession(IDataObject * aDataObj,
-                                       PRUint32 aActionType);
- 
--  // A drop occurred within the application vs. outside of it.
--  void SetDroppedLocal();
--
- protected:
-   nsDataObjCollection* GetDataObjCollection(IDataObject * aDataObj);
- 
-diff --git a/widget/windows/nsNativeDragSource.cpp b/widget/windows/nsNativeDragSource.cpp
-index e51101e..0fe6ffe 100644
---- a/widget/windows/nsNativeDragSource.cpp
-+++ b/widget/windows/nsNativeDragSource.cpp
-@@ -42,7 +42,7 @@
- #include "nsIServiceManager.h"
- #include "nsToolkit.h"
- #include "nsWidgetsCID.h"
--#include "nsIDragService.h"
-+#include "nsDragService.h"
- 
- static NS_DEFINE_IID(kCDragServiceCID,  NS_DRAGSERVICE_CID);
- 
-@@ -101,9 +101,10 @@ STDMETHODIMP
- nsNativeDragSource::QueryContinueDrag(BOOL fEsc, DWORD grfKeyState)
- {
-   nsCOMPtr<nsIDragService> dragService = do_GetService(kCDragServiceCID);
--  if (dragService) {
-+  nsCOMPtr<nsPIDragService> dragServicePriv = do_QueryInterface(dragService);
-+  if (dragServicePriv) {
-     DWORD pos = ::GetMessagePos();
--    dragService->DragMoved(GET_X_LPARAM(pos), GET_Y_LPARAM(pos));
-+    dragServicePriv->DragMoved(GET_X_LPARAM(pos), GET_Y_LPARAM(pos));
-   }
- 
-   if (fEsc) {
-diff --git a/widget/windows/nsNativeDragTarget.cpp b/widget/windows/nsNativeDragTarget.cpp
-index 3362ca6..a69817c 100644
---- a/widget/windows/nsNativeDragTarget.cpp
-+++ b/widget/windows/nsNativeDragTarget.cpp
-@@ -205,7 +205,11 @@ nsNativeDragTarget::DispatchDragDropEvent(PRUint32 aEventType, POINTL aPT)
-   event.isControl = IsKeyDown(NS_VK_CONTROL);
-   event.isMeta    = false;
-   event.isAlt     = IsKeyDown(NS_VK_ALT);
--  event.inputSource = static_cast<nsBaseDragService*>(mDragService)->GetInputSource();
-+  event.inputSource = 0;
-+  nsCOMPtr<nsPIDragService> dragServicePriv = do_QueryInterface(mDragService);
-+  if (dragServicePriv) {
-+    dragServicePriv->GetInputSource(&event.inputSource);
-+  }
- 
-   mWindow->DispatchEvent(&event, status);
- }
-@@ -292,9 +296,8 @@ nsNativeDragTarget::DragEnter(LPDATAOBJECT pIDataSource,
-   // This cast is ok because in the constructor we created a
-   // the actual implementation we wanted, so we know this is
-   // a nsDragService. It should be a private interface, though.
--  nsDragService * winDragService =
--    static_cast<nsDragService *>(mDragService);
--  winDragService->SetIDataObject(pIDataSource);
-+  nsCOMPtr<nsPIDragServiceWindows> winDragService = do_QueryInterface(mDragService);
-+  winDragService->SetIDataObject((nsISupports*)pIDataSource);
- 
-   // Now process the native drag state and then dispatch the event
-   ProcessDrag(NS_DRAGDROP_ENTER, grfKeyState, ptl, pdwEffect);
-@@ -432,8 +435,8 @@ nsNativeDragTarget::Drop(LPDATAOBJECT pData,
-   // This cast is ok because in the constructor we created a
-   // the actual implementation we wanted, so we know this is
-   // a nsDragService (but it should still be a private interface)
--  nsDragService* winDragService = static_cast<nsDragService*>(mDragService);
--  winDragService->SetIDataObject(pData);
-+  nsCOMPtr<nsPIDragServiceWindows> winDragService = do_QueryInterface(mDragService);
-+  winDragService->SetIDataObject((nsISupports*)pData);
- 
-   // NOTE: ProcessDrag spins the event loop which may destroy arbitrary objects.
-   // We use strong refs to prevent it from destroying these:
-@@ -457,11 +460,14 @@ nsNativeDragTarget::Drop(LPDATAOBJECT pData,
-   // tell the drag service we're done with the session
-   // Use GetMessagePos to get the position of the mouse at the last message
-   // seen by the event loop. (Bug 489729)
--  DWORD pos = ::GetMessagePos();
--  POINT cpos;
--  cpos.x = GET_X_LPARAM(pos);
--  cpos.y = GET_Y_LPARAM(pos);
--  winDragService->SetDragEndPoint(nsIntPoint(cpos.x, cpos.y));
-+  nsCOMPtr<nsPIDragService> dragServicePriv = do_QueryInterface(mDragService);
-+  if (dragServicePriv) {
-+    DWORD pos = ::GetMessagePos();
-+    POINT cpos;
-+    cpos.x = GET_X_LPARAM(pos);
-+    cpos.y = GET_Y_LPARAM(pos);
-+    dragServicePriv->SetDragEndPoint(cpos.x, cpos.y);
-+  }
-   serv->EndDragSession(true);
- 
-   // release the ref that was taken in DragEnter
-diff --git a/widget/windows/nsPIDragServiceWindows.idl b/widget/windows/nsPIDragServiceWindows.idl
-new file mode 100644
-index 0000000..c8a46dd
---- /dev/null
-+++ b/widget/windows/nsPIDragServiceWindows.idl
-@@ -0,0 +1,46 @@
-+/* ***** BEGIN LICENSE BLOCK *****
-+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
-+ *
-+ * The contents of this file are subject to the Mozilla Public License Version
-+ * 1.1 (the "License"); you may not use this file except in compliance with
-+ * the License. You may obtain a copy of the License at
-+ * http://www.mozilla.org/MPL/
-+ *
-+ * Software distributed under the License is distributed on an "AS IS" basis,
-+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
-+ * for the specific language governing rights and limitations under the
-+ * License.
-+ *
-+ * The Original Code is mozilla.org code.
-+ *
-+ * The Initial Developer of the Original Code is
-+ * The Mozilla Foundation.
-+ * Portions created by the Initial Developer are Copyright (C) 2012
-+ * the Initial Developer. All Rights Reserved.
-+ *
-+ * Contributor(s):
-+ *   Steven Michaud <smichaud at pobox.com>
-+ *
-+ * Alternatively, the contents of this file may be used under the terms of
-+ * either the GNU General Public License Version 2 or later (the "GPL"), or
-+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
-+ * in which case the provisions of the GPL or the LGPL are applicable instead
-+ * of those above. If you wish to allow use of your version of this file only
-+ * under the terms of either the GPL or the LGPL, and not to allow others to
-+ * use your version of this file under the terms of the MPL, indicate your
-+ * decision by deleting the provisions above and replace them with the notice
-+ * and other provisions required by the GPL or the LGPL. If you do not delete
-+ * the provisions above, a recipient may use your version of this file under
-+ * the terms of any one of the MPL, the GPL or the LGPL.
-+ *
-+ * ***** END LICENSE BLOCK ***** */
-+
-+#include "nsISupports.idl"
-+
-+[scriptable, uuid(6FC2117D-5EB4-441A-9C12-62A783BEBC0C)]
-+interface nsPIDragServiceWindows : nsISupports
-+{
-+  void setIDataObject(in nsISupports aDataObj);
-+
-+  void setDroppedLocal();
-+};
-diff --git a/widget/xpwidgets/nsBaseDragService.cpp b/widget/xpwidgets/nsBaseDragService.cpp
-index 342a036..87e28f7 100644
---- a/widget/xpwidgets/nsBaseDragService.cpp
-+++ b/widget/xpwidgets/nsBaseDragService.cpp
-@@ -88,7 +88,7 @@ nsBaseDragService::~nsBaseDragService()
- {
- }
- 
--NS_IMPL_ISUPPORTS2(nsBaseDragService, nsIDragService, nsIDragSession)
-+NS_IMPL_ISUPPORTS3(nsBaseDragService, nsIDragService, nsPIDragService, nsIDragSession)
- 
- //---------------------------------------------------------
- NS_IMETHODIMP
-@@ -436,6 +436,20 @@ nsBaseDragService::DragMoved(PRInt32 aX, PRInt32 aY)
-   return NS_OK;
- }
- 
-+NS_IMETHODIMP
-+nsBaseDragService::SetDragEndPoint(PRInt32 aX, PRInt32 aY)
-+{
-+  mEndDragPoint = nsIntPoint(aX, aY);
-+  return NS_OK;
-+}
-+
-+NS_IMETHODIMP
-+nsBaseDragService::GetInputSource(PRUint16* aInputSource)
-+{
-+  *aInputSource = mInputSource;
-+  return NS_OK;
-+}
-+
- static nsIPresShell*
- GetPresShellForContent(nsIDOMNode* aDOMNode)
- {
-diff --git a/widget/xpwidgets/nsBaseDragService.h b/widget/xpwidgets/nsBaseDragService.h
-index 290c0cb..2ceac2b 100644
---- a/widget/xpwidgets/nsBaseDragService.h
-+++ b/widget/xpwidgets/nsBaseDragService.h
-@@ -39,6 +39,7 @@
- #define nsBaseDragService_h__
- 
- #include "nsIDragService.h"
-+#include "nsPIDragService.h"
- #include "nsIDragSession.h"
- #include "nsITransferable.h"
- #include "nsISupportsArray.h"
-@@ -64,6 +65,7 @@ class nsICanvasElementExternal;
-  */
- 
- class nsBaseDragService : public nsIDragService,
-+                          public nsPIDragService,
-                           public nsIDragSession
- {
- 
-@@ -74,14 +76,11 @@ public:
-   //nsISupports
-   NS_DECL_ISUPPORTS
- 
--  //nsIDragSession and nsIDragService
-+  //nsIDragSession, nsIDragService and nsPIDragService
-   NS_DECL_NSIDRAGSERVICE
-+  NS_DECL_NSPIDRAGSERVICE
-   NS_DECL_NSIDRAGSESSION
- 
--  void SetDragEndPoint(nsIntPoint aEndDragPoint) { mEndDragPoint = aEndDragPoint; }
--
--  PRUint16 GetInputSource() { return mInputSource; }
--
- protected:
- 
-   /**
--- 
-1.7.5.4
-
diff --git a/src/current-patches/firefox/alpha/0001-Block-Components.interfaces-lookupMethod-from-conten.patch b/src/current-patches/firefox/alpha/0001-Block-Components.interfaces-lookupMethod-from-conten.patch
new file mode 100644
index 0000000..5f8f4cc
--- /dev/null
+++ b/src/current-patches/firefox/alpha/0001-Block-Components.interfaces-lookupMethod-from-conten.patch
@@ -0,0 +1,50 @@
+From 801d2dcc512ca5e64b72d56faaab7d8ef0fadf39 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/19] 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.
+
+These two interfaces seem to be exposed to content script only to make our
+lives difficult. Components.lookupMethod can undo our JS hooks, and
+Components.interfaces is useful for fingerprinting the platform, OS, and
+Firebox version.
+
+They appear to have no other legitimate use. See also:
+https://bugzilla.mozilla.org/show_bug.cgi?id=429070
+https://trac.torproject.org/projects/tor/ticket/2873
+https://trac.torproject.org/projects/tor/ticket/2874
+---
+ js/xpconnect/src/XPCComponents.cpp |    8 ++++++--
+ 1 files changed, 6 insertions(+), 2 deletions(-)
+
+diff --git a/js/xpconnect/src/XPCComponents.cpp b/js/xpconnect/src/XPCComponents.cpp
+index a2a1102..49e4c7e 100644
+--- a/js/xpconnect/src/XPCComponents.cpp
++++ b/js/xpconnect/src/XPCComponents.cpp
+@@ -4287,7 +4287,9 @@ nsXPCComponents::CanCreateWrapper(const nsIID * iid, char **_retval)
+ NS_IMETHODIMP
+ nsXPCComponents::CanCallMethod(const nsIID * iid, const PRUnichar *methodName, char **_retval)
+ {
+-    static const char* allowed[] = { "isSuccessCode", "lookupMethod", nsnull };
++    // XXX: Pref observer? Also, is this what we want? Seems like a plan
++    //static const char* allowed[] = { "isSuccessCode", "lookupMethod", nsnull };
++    static const char* allowed[] = { "isSuccessCode", nsnull };
+     *_retval = xpc_CheckAccessList(methodName, allowed);
+     return NS_OK;
+ }
+@@ -4296,7 +4298,9 @@ nsXPCComponents::CanCallMethod(const nsIID * iid, const PRUnichar *methodName, c
+ NS_IMETHODIMP
+ nsXPCComponents::CanGetProperty(const nsIID * iid, const PRUnichar *propertyName, char **_retval)
+ {
+-    static const char* allowed[] = { "interfaces", "interfacesByID", "results", nsnull};
++    // XXX: Pref observer? Also, is this what we want? Seems like a plan
++    //    static const char* allowed[] = { "interfaces", "interfacesByID", "results", nsnull};
++    static const char* allowed[] = { "results", nsnull};
+     *_retval = xpc_CheckAccessList(propertyName, allowed);
+     return NS_OK;
+ }
+-- 
+1.7.5.4
+
diff --git a/src/current-patches/firefox/alpha/0002-Make-Permissions-Manager-memory-only.patch b/src/current-patches/firefox/alpha/0002-Make-Permissions-Manager-memory-only.patch
new file mode 100644
index 0000000..264e027
--- /dev/null
+++ b/src/current-patches/firefox/alpha/0002-Make-Permissions-Manager-memory-only.patch
@@ -0,0 +1,94 @@
+From 4c65de64fc28ca767009a0d0acfcefd8f2a73ad8 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/19] 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
+site permissions, as well as stored STS policy.
+
+The pref does successfully clear the permissions manager memory if toggled. It
+does not need to be set in prefs.js, and can be handled by Torbutton.
+
+https://trac.torproject.org/projects/tor/ticket/2950
+---
+ extensions/cookie/nsPermissionManager.cpp |   34 ++++++++++++++++++++++++++--
+ 1 files changed, 31 insertions(+), 3 deletions(-)
+
+diff --git a/extensions/cookie/nsPermissionManager.cpp b/extensions/cookie/nsPermissionManager.cpp
+index cdfe21b..a7a0efb 100644
+--- a/extensions/cookie/nsPermissionManager.cpp
++++ b/extensions/cookie/nsPermissionManager.cpp
+@@ -58,6 +58,10 @@
+ #include "mozStorageHelper.h"
+ #include "mozStorageCID.h"
+ #include "nsXULAppAPI.h"
++#include "nsCOMPtr.h"
++#include "nsIPrefService.h"
++#include "nsIPrefBranch.h"
++#include "nsIPrefBranch2.h"
+ 
+ static nsPermissionManager *gPermissionManager = nsnull;
+ 
+@@ -203,6 +207,11 @@ nsPermissionManager::Init()
+     mObserverService->AddObserver(this, "profile-do-change", true);
+   }
+ 
++  nsCOMPtr<nsIPrefBranch2> pbi = do_GetService(NS_PREFSERVICE_CONTRACTID);
++  if (pbi) {
++    pbi->AddObserver("permissions.", this, PR_FALSE);
++  }
++
+   if (IsChildProcess()) {
+     // Get the permissions from the parent process
+     InfallibleTArray<IPC::Permission> perms;
+@@ -251,8 +260,18 @@ nsPermissionManager::InitDB(bool aRemoveFile)
+   if (!storage)
+     return NS_ERROR_UNEXPECTED;
+ 
++  bool memory_db = false;
++  nsCOMPtr<nsIPrefBranch> prefs = do_GetService(NS_PREFSERVICE_CONTRACTID);
++  if (prefs) {
++    prefs->GetBoolPref("permissions.memory_only", &memory_db); 
++  }
++
+   // cache a connection to the hosts database
+-  rv = storage->OpenDatabase(permissionsFile, getter_AddRefs(mDBConn));
++  if (memory_db) {
++    rv = storage->OpenSpecialDatabase("memory", getter_AddRefs(mDBConn));
++  } else {
++    rv = storage->OpenDatabase(permissionsFile, getter_AddRefs(mDBConn));
++  }
+   NS_ENSURE_SUCCESS(rv, rv);
+ 
+   bool ready;
+@@ -262,7 +281,11 @@ nsPermissionManager::InitDB(bool aRemoveFile)
+     rv = permissionsFile->Remove(false);
+     NS_ENSURE_SUCCESS(rv, rv);
+ 
+-    rv = storage->OpenDatabase(permissionsFile, getter_AddRefs(mDBConn));
++    if (memory_db) {
++      rv = storage->OpenSpecialDatabase("memory", getter_AddRefs(mDBConn));
++    } else {
++      rv = storage->OpenDatabase(permissionsFile, getter_AddRefs(mDBConn));
++    }
+     NS_ENSURE_SUCCESS(rv, rv);
+ 
+     mDBConn->GetConnectionReady(&ready);
+@@ -794,7 +817,12 @@ NS_IMETHODIMP nsPermissionManager::Observe(nsISupports *aSubject, const char *aT
+ {
+   ENSURE_NOT_CHILD_PROCESS;
+ 
+-  if (!nsCRT::strcmp(aTopic, "profile-before-change")) {
++  if (nsCRT::strcmp(aTopic, NS_PREFBRANCH_PREFCHANGE_TOPIC_ID) == 0) {
++    if (!nsCRT::strcmp(someData, NS_LITERAL_STRING("permissions.memory_only").get())) {
++      // XXX: Should we remove the file? Probably not..
++      InitDB(PR_FALSE);
++    }
++  } else if (!nsCRT::strcmp(aTopic, "profile-before-change")) {
+     // The profile is about to change,
+     // or is going away because the application is shutting down.
+     if (!nsCRT::strcmp(someData, NS_LITERAL_STRING("shutdown-cleanse").get())) {
+-- 
+1.7.5.4
+
diff --git a/src/current-patches/firefox/alpha/0003-Make-Intermediate-Cert-Store-memory-only.patch b/src/current-patches/firefox/alpha/0003-Make-Intermediate-Cert-Store-memory-only.patch
new file mode 100644
index 0000000..eff5169
--- /dev/null
+++ b/src/current-patches/firefox/alpha/0003-Make-Intermediate-Cert-Store-memory-only.patch
@@ -0,0 +1,43 @@
+From 6b5b4816ffff9875f8fd3364841fde872a2af7a4 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/19] Make Intermediate Cert Store memory-only.
+
+This patch makes the intermediate SSL cert store exist in memory only.
+
+The pref must be set before startup in prefs.js.
+https://trac.torproject.org/projects/tor/ticket/2949
+---
+ security/manager/ssl/src/nsNSSComponent.cpp |   15 ++++++++++++++-
+ 1 files changed, 14 insertions(+), 1 deletions(-)
+
+diff --git a/security/manager/ssl/src/nsNSSComponent.cpp b/security/manager/ssl/src/nsNSSComponent.cpp
+index 89ad70e..783d0d2 100644
+--- a/security/manager/ssl/src/nsNSSComponent.cpp
++++ b/security/manager/ssl/src/nsNSSComponent.cpp
+@@ -1755,8 +1755,21 @@ nsNSSComponent::InitializeNSS(bool showWarningBox)
+     // Ubuntu 8.04, which loads any nonexistent "<configdir>/libnssckbi.so" as
+     // "/usr/lib/nss/libnssckbi.so".
+     PRUint32 init_flags = NSS_INIT_NOROOTINIT | NSS_INIT_OPTIMIZESPACE;
+-    SECStatus init_rv = ::NSS_Initialize(profileStr.get(), "", "",
++    bool nocertdb = false;
++    mPrefBranch->GetBoolPref("security.nocertdb", &nocertdb);
++
++    // XXX: We can also do the the following to only disable the certdb.
++    // Leaving this codepath in as a fallback in case InitNODB fails
++    if (nocertdb)
++      init_flags |= NSS_INIT_NOCERTDB;
++
++    SECStatus init_rv;
++    if (nocertdb) {
++        init_rv = ::NSS_NoDB_Init(NULL);
++    } else {
++        init_rv = ::NSS_Initialize(profileStr.get(), "", "",
+                                          SECMOD_DB, init_flags);
++    }
+ 
+     if (init_rv != SECSuccess) {
+       PR_LOG(gPIPNSSLog, PR_LOG_DEBUG, ("can not init NSS r/w in %s\n", profileStr.get()));
+-- 
+1.7.5.4
+
diff --git a/src/current-patches/firefox/alpha/0004-Add-a-string-based-cacheKey.patch b/src/current-patches/firefox/alpha/0004-Add-a-string-based-cacheKey.patch
new file mode 100644
index 0000000..0f509a6
--- /dev/null
+++ b/src/current-patches/firefox/alpha/0004-Add-a-string-based-cacheKey.patch
@@ -0,0 +1,85 @@
+From b2dfbf250bc83592e73abf932c5301f1688a277b 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/19] 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 34291f4..92f2d7d 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=");
+     }
+@@ -4784,6 +4790,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 f8e59fe..a5b7d1e 100644
+--- a/netwerk/protocol/http/nsHttpChannel.h
++++ b/netwerk/protocol/http/nsHttpChannel.h
+@@ -306,6 +306,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/alpha/0005-Block-all-plugins-except-flash.patch b/src/current-patches/firefox/alpha/0005-Block-all-plugins-except-flash.patch
new file mode 100644
index 0000000..d0b1104
--- /dev/null
+++ b/src/current-patches/firefox/alpha/0005-Block-all-plugins-except-flash.patch
@@ -0,0 +1,85 @@
+From 47235106c9e1257c66bab774aab330be4dabcfb0 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/19] 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 0c3efa0..e607e68 100644
+--- a/dom/plugins/base/nsPluginHost.cpp
++++ b/dom/plugins/base/nsPluginHost.cpp
+@@ -2002,6 +2002,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,
+@@ -2135,6 +2164,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 1b46957..4f1e890 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/alpha/0006-Make-content-pref-service-memory-only-clearable.patch b/src/current-patches/firefox/alpha/0006-Make-content-pref-service-memory-only-clearable.patch
new file mode 100644
index 0000000..643351d
--- /dev/null
+++ b/src/current-patches/firefox/alpha/0006-Make-content-pref-service-memory-only-clearable.patch
@@ -0,0 +1,37 @@
+From bd560666419266a862d5b0387c7941c8ef7bb624 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/19] 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 68a5561..effc33c 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/alpha/0007-Disable-SSL-Session-ID-tracking.patch b/src/current-patches/firefox/alpha/0007-Disable-SSL-Session-ID-tracking.patch
new file mode 100644
index 0000000..f1985cf
--- /dev/null
+++ b/src/current-patches/firefox/alpha/0007-Disable-SSL-Session-ID-tracking.patch
@@ -0,0 +1,28 @@
+From 3eebe3b7e2882de39e2c686a38e7084cccfa4c60 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 07/19] 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 28e6210..fa48ecd 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/alpha/0008-Provide-an-observer-event-to-close-persistent-connec.patch b/src/current-patches/firefox/alpha/0008-Provide-an-observer-event-to-close-persistent-connec.patch
new file mode 100644
index 0000000..13f16eb
--- /dev/null
+++ b/src/current-patches/firefox/alpha/0008-Provide-an-observer-event-to-close-persistent-connec.patch
@@ -0,0 +1,40 @@
+From 9594d3f2df4f20308406deea30aaccd577587438 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 08/19] 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 dcdf729..672d436 100644
+--- a/netwerk/protocol/http/nsHttpHandler.cpp
++++ b/netwerk/protocol/http/nsHttpHandler.cpp
+@@ -338,6 +338,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;
+@@ -1587,6 +1588,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/alpha/0009-Provide-client-values-only-to-CSS-Media-Queries.patch b/src/current-patches/firefox/alpha/0009-Provide-client-values-only-to-CSS-Media-Queries.patch
new file mode 100644
index 0000000..a520df9
--- /dev/null
+++ b/src/current-patches/firefox/alpha/0009-Provide-client-values-only-to-CSS-Media-Queries.patch
@@ -0,0 +1,72 @@
+From 4c247867a8aa7401fb91e332cfd1dce10ab5a972 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 09/19] 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/alpha/0010-Rebrand-Firefox-to-TorBrowser.patch b/src/current-patches/firefox/alpha/0010-Rebrand-Firefox-to-TorBrowser.patch
new file mode 100644
index 0000000..3df8c83
--- /dev/null
+++ b/src/current-patches/firefox/alpha/0010-Rebrand-Firefox-to-TorBrowser.patch
@@ -0,0 +1,50 @@
+From 8a4f6f4a67a7f2fce746aaaeb9b80ce18da88d73 Mon Sep 17 00:00:00 2001
+From: Erinn Clark <erinn at torproject.org>
+Date: Wed, 25 Apr 2012 09:14:00 -0300
+Subject: [PATCH 10/19] Rebrand Firefox to TorBrowser
+
+This patch does some basic renaming of Firefox to TorBrowser. The rest of the
+branding is done by images and icons.
+---
+ browser/branding/official/configure.sh             |    2 +-
+ browser/branding/official/locales/en-US/brand.dtd  |    6 +++---
+ .../official/locales/en-US/brand.properties        |    6 +++---
+ 3 files changed, 7 insertions(+), 7 deletions(-)
+
+diff --git a/browser/branding/official/configure.sh b/browser/branding/official/configure.sh
+index 4d3d297..e9b3738 100644
+--- a/browser/branding/official/configure.sh
++++ b/browser/branding/official/configure.sh
+@@ -1,2 +1,2 @@
+-MOZ_APP_DISPLAYNAME=Firefox
++MOZ_APP_DISPLAYNAME=TorBrowser
+ MOZ_UA_BUILDID=20100101
+diff --git a/browser/branding/official/locales/en-US/brand.dtd b/browser/branding/official/locales/en-US/brand.dtd
+index 142d79b..c137e04 100644
+--- a/browser/branding/official/locales/en-US/brand.dtd
++++ b/browser/branding/official/locales/en-US/brand.dtd
+@@ -1,4 +1,4 @@
+-<!ENTITY  brandShortName        "Firefox">
+-<!ENTITY  brandFullName         "Mozilla Firefox">
+-<!ENTITY  vendorShortName       "Mozilla">
++<!ENTITY  brandShortName        "TorBrowser">
++<!ENTITY  brandFullName         "Tor Browser">
++<!ENTITY  vendorShortName       "Tor Project">
+ <!ENTITY  trademarkInfo.part1   "Firefox and the Firefox logos are trademarks of the Mozilla Foundation.">
+diff --git a/browser/branding/official/locales/en-US/brand.properties b/browser/branding/official/locales/en-US/brand.properties
+index 5f3ad54..62ac2fd 100644
+--- a/browser/branding/official/locales/en-US/brand.properties
++++ b/browser/branding/official/locales/en-US/brand.properties
+@@ -1,6 +1,6 @@
+-brandShortName=Firefox
+-brandFullName=Mozilla Firefox
+-vendorShortName=Mozilla
++brandShortName=TorBrowser
++brandFullName=Tor Browser
++vendorShortName=Tor Project
+ 
+ homePageSingleStartMain=Firefox Start, a fast home page with built-in search
+ homePageImport=Import your home page from %S
+-- 
+1.7.5.4
+
diff --git a/src/current-patches/firefox/alpha/0011-Make-Download-manager-memory-only.patch b/src/current-patches/firefox/alpha/0011-Make-Download-manager-memory-only.patch
new file mode 100644
index 0000000..d9e1b3e
--- /dev/null
+++ b/src/current-patches/firefox/alpha/0011-Make-Download-manager-memory-only.patch
@@ -0,0 +1,57 @@
+From 5cffe3a9aaadfc2e86779d9e050153ad747c5548 Mon Sep 17 00:00:00 2001
+From: Mike Perry <mikeperry-git at torproject.org>
+Date: Wed, 25 Apr 2012 13:39:35 -0700
+Subject: [PATCH 11/19] Make Download manager memory only.
+
+Solves https://trac.torproject.org/projects/tor/ticket/4017.
+
+Yes, this is an ugly hack. We *could* send the observer notification from
+Torbutton to tell the download manager to switch to memory, but then we have
+to dance around and tell it again if the user switches in and out of private
+browsing mode..
+
+The right way to do this is with a pref. Maybe I'll get to that someday, if
+this breaks enough times in conflict.
+---
+ toolkit/components/downloads/nsDownloadManager.cpp |    4 ++--
+ toolkit/components/downloads/nsDownloadManager.h   |    2 +-
+ 2 files changed, 3 insertions(+), 3 deletions(-)
+
+diff --git a/toolkit/components/downloads/nsDownloadManager.cpp b/toolkit/components/downloads/nsDownloadManager.cpp
+index cb1f1f6..1de653b 100644
+--- a/toolkit/components/downloads/nsDownloadManager.cpp
++++ b/toolkit/components/downloads/nsDownloadManager.cpp
+@@ -1999,7 +1999,7 @@ nsDownloadManager::Observe(nsISupports *aSubject,
+     if (NS_LITERAL_STRING("memory").Equals(aData))
+       return SwitchDatabaseTypeTo(DATABASE_MEMORY);
+     else if (NS_LITERAL_STRING("disk").Equals(aData))
+-      return SwitchDatabaseTypeTo(DATABASE_DISK);
++      return SwitchDatabaseTypeTo(DATABASE_MEMORY);
+   }
+   else if (strcmp(aTopic, "alertclickcallback") == 0) {
+     nsCOMPtr<nsIDownloadManagerUI> dmui =
+@@ -2076,7 +2076,7 @@ nsDownloadManager::OnLeavePrivateBrowsingMode()
+   (void)ResumeAllDownloads(false);
+ 
+   // Switch back to the on-disk DB again
+-  (void)SwitchDatabaseTypeTo(DATABASE_DISK);
++  //(void)SwitchDatabaseTypeTo(DATABASE_DISK);
+ 
+   mInPrivateBrowsing = false;
+ }
+diff --git a/toolkit/components/downloads/nsDownloadManager.h b/toolkit/components/downloads/nsDownloadManager.h
+index 16a861e..e729cbf 100644
+--- a/toolkit/components/downloads/nsDownloadManager.h
++++ b/toolkit/components/downloads/nsDownloadManager.h
+@@ -92,7 +92,7 @@ public:
+ 
+   virtual ~nsDownloadManager();
+   nsDownloadManager() :
+-      mDBType(DATABASE_DISK)
++      mDBType(DATABASE_MEMORY)
+     , mInPrivateBrowsing(false)
+ #ifdef DOWNLOAD_SCANNER
+     , mScanner(nsnull)
+-- 
+1.7.5.4
+
diff --git a/src/current-patches/firefox/alpha/0012-Add-DDG-and-StartPage-to-Omnibox.patch b/src/current-patches/firefox/alpha/0012-Add-DDG-and-StartPage-to-Omnibox.patch
new file mode 100644
index 0000000..f3ebe5b
--- /dev/null
+++ b/src/current-patches/firefox/alpha/0012-Add-DDG-and-StartPage-to-Omnibox.patch
@@ -0,0 +1,84 @@
+From 96a520c56fd58f4ffaf89f26094de35425fa0ad4 Mon Sep 17 00:00:00 2001
+From: Mike Perry <mikeperry-git at torproject.org>
+Date: Wed, 25 Apr 2012 15:03:46 -0700
+Subject: [PATCH 12/19] Add DDG and StartPage to Omnibox.
+
+You mean there are search engines that don't require captchas if you don't
+have a cookie? Holy crap. Get those in there now.
+---
+ browser/locales/en-US/searchplugins/duckduckgo.xml |   29 ++++++++++++++++++++
+ browser/locales/en-US/searchplugins/list.txt       |    2 +
+ browser/locales/en-US/searchplugins/startpage.xml  |   11 +++++++
+ 3 files changed, 42 insertions(+), 0 deletions(-)
+ create mode 100644 browser/locales/en-US/searchplugins/duckduckgo.xml
+ create mode 100644 browser/locales/en-US/searchplugins/startpage.xml
+
+diff --git a/browser/locales/en-US/searchplugins/duckduckgo.xml b/browser/locales/en-US/searchplugins/duckduckgo.xml
+new file mode 100644
+index 0000000..4f00b4d
+--- /dev/null
++++ b/browser/locales/en-US/searchplugins/duckduckgo.xml
+@@ -0,0 +1,29 @@
++<SearchPlugin xmlns="http://www.mozilla.org/2006/browser/search/">
++<ShortName>DuckDuckGo</ShortName>
++<Description>Duck Duck Go</Description>
++<InputEncoding>UTF-8</InputEncoding>
++<Image width="16" height="16">data:image/png;base64,AAABAAEAEBAAAAEAIABoBAAAFgAAACgAAAAQAAAAIAAAAAEAIAAAAAAAAAAAANcNAADXDQAAAAAA
++AAAAAAAAAAAAAAAAAAAAAAAAAAAAJyDsJmlk8pf6+v3s/v7+++zr/fcnIOyzJyDsgCcg7CYAAAAA
++AAAAAAAAAAAAAAAAAAAAAAAAAAAnIOwBJyDscCcg7PZttJ7/7Pfs//////++xO7/S5GA/ycg7P8n
++IOz2JyDscCcg7AEAAAAAAAAAAAAAAAAnIOwBJyDstScg7P8nIOz/Y8p5/2fHZf9Yv0z/YcF2/1rB
++Uv8nIOz/JyDs/ycg7P8nIOy1JyDsAQAAAAAAAAAAJyDscCcg7P8nIOz/JyDs/4jQoP/p9+n/////
++/05X3v9LkYD/JyDs/ycg7P8nIOz/JyDs/ycg7HAAAAAAJyDsJicg7PYnIOz/JyDs/zUu7f/+/v//
++//////////89N+7/JyDs/yUo7f8nIOz/JyDs/ycg7P8nIOz2JyDsJicg7IAnIOz/JyDs/ycg7P9h
++XPH////////////t/P//GIr2/wfD+/8Gyfz/DKv5/yM57/8nIOz/JyDs/ycg7H8nIOyzJyDs/ycg
++7P8nIOz/jov1////////////Otz9/w3G/P8cWfH/JSvt/ycg7P8nIOz/JyDs/ycg7P8nIOyzJyDs
++5icg7P8nIOz/JyDs/7u5+f///////////27l/v8E0v3/BNL9/wTQ/f8Oofn/IT7v/ycg7P8nIOz/
++JyDs5icg7OYnIOz/JyDs/ycg7P/p6P3/uWsC////////////5fr//6Po/f8Thfb/DKv5/w6f+f8n IOz/JyDs/ycg7OYnIOyzJyDs/ycg7P8nIOz/9/b+/////////////////7lrAv/V1Pv/JyDs/ycg
++7P8nIOz/JyDs/ycg7P8nIOyzJyDsgCcg7P8nIOz/JyDs/8/N+///////////////////////iIX1
++/ycg7P8nIOz/JyDs/ycg7P8nIOz/JyDsfycg7CYnIOz2JyDs/ycg7P9FP+7/q6n4/+7u/f/n5v3/
++fXn0/yoj7P8nIOz/JyDs/ycg7P8nIOz/JyDs9icg7CYAAAAAJyDscCcg7P8nIOz/wsD6/+no/f/Y
++1/z/eHTz/ycg7P8nIOz/JyDs/ycg7P8nIOz/JyDs/ycg7HAAAAAAAAAAACcg7AEnIOy1JyDs/ycg
++7P8nIOz/JyDs/ycg7P8nIOz/JyDs/ycg7P8nIOz/JyDs/ycg7LUnIOwBAAAAAAAAAAAAAAAAJyDs
++AScg7HAnIOz2JyDs/ycg7P8nIOz/JyDs/ycg7P8nIOz/JyDs9icg7HAnIOwBAAAAAAAAAAAAAAAA
++AAAAAAAAAAAAAAAAJyDsJicg7IAnIOyzJyDs5icg7OYnIOyzJyDsgCcg7CYAAAAAAAAAAAAAAAAA
++AAAA+B8AAPAPAADAAwAAwAMAAIABAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAABAACAAQAAwAMAAMAD
++AADwDwAA+B8AAA==</Image>
++<Url type="text/html" method="POST" template="https://duckduckgo.com/html/">
++  <Param name="q" value="{searchTerms}"/>
++</Url>
++<SearchForm>https://duckduckgo.com/html/</SearchForm>
++</SearchPlugin>
+diff --git a/browser/locales/en-US/searchplugins/list.txt b/browser/locales/en-US/searchplugins/list.txt
+index 2a1141a..0466f4e 100644
+--- a/browser/locales/en-US/searchplugins/list.txt
++++ b/browser/locales/en-US/searchplugins/list.txt
+@@ -1,7 +1,9 @@
+ amazondotcom
+ bing
++duckduckgo
+ eBay
+ google
++startpage
+ twitter
+ wikipedia
+ yahoo
+diff --git a/browser/locales/en-US/searchplugins/startpage.xml b/browser/locales/en-US/searchplugins/startpage.xml
+new file mode 100644
+index 0000000..1a310b1
+--- /dev/null
++++ b/browser/locales/en-US/searchplugins/startpage.xml
+@@ -0,0 +1,11 @@
++<SearchPlugin xmlns="http://www.mozilla.org/2006/browser/search/">
++<ShortName>Startpage</ShortName>
++<Description>Start Page</Description>
++<InputEncoding>UTF-8</InputEncoding>
++<Image width="16" height="16">data:image/png;base64,AAABAAEAEBAAAAEAIABoBAAAFgAAACgAAAAQAAAAIAAAAAEAIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD2jkj+9YtD/vWLQ/71i0P+9otD/vaLRP72i0T+9YtE/vWLRP72i0T+9otD/vaNRP72jUT+9otF/vaLRf73kkv+9Yc///WJP//1iT//9Yk///rAmf/94Mz/+sCa//aRTv/1iUH/9ok///aJP//2i0H/9otB//aJQv/2iUL/9otC//aNRP/2jUT/9o1E//aNRP/6wpv////////////96dr/95dQ//aNRP/2kET/9pBG//aQRv/2kEb/9pBG//aRR//3lEz/95BH//mueP/7xJ3/959g//efYf/4p23//vDm//3p2//3kEr/95FJ//aRSf/niFH/95FK//aRSv/2mE//95hS/vq4iP/////////////////81bj/95xZ//q4iP//////+bF+//eZT//njFT/PSqi/2xGjv/2mVD/951V/vedVv783cX///////vQrf/++PP///////748//+8uj///////m3gf/olFr/PSuj/w8Pt/9sSJD/951V//eeWf73oVv++8ul///////5sXf/+KRi//vRsf////////////3r3v/olF//Piyk/w8Pt/9sSJH/+J5Z//ieWv/3oV/++KZf/vihXP/97N7//vn0//zTs//6wJP/+bBy//q6iP/onW//Piyl/w8Pt/8fGbH/m2iB/+icY//4pGD/96hl/viqZf74pmD/+Kxr//3iy/////////n1//ivbP/onGj/Pi2m/w8Pt/8uJKz/fFeQ/x8Zsf8+Lqb/6J9r//ivbP74rm3++Klm//mpZv/5q2f/+bR9//m0e//poW7/Pi6n/w8Pt/9sTZj/+Ktp//ira/+rd4P/Dw+3/4xijv/5snH+
 +LN1/vmvbf/5r23/+a5t//mvb//4r2//TTuk/w8Pt/8fGrL/6ah1//ivcP/4r3P/q3yI/w8Pt/+MZpP/+bN5/vm4ev75t3X/+bV1//m1df/5t3X/+Ld3/8qUhP98XZn/Hxqz/+mse//5t3f/2p+B/x8as/8PD7f/u4qK//m7fv76u4D++bl7//m3fP/5uXz/+bl8//m5fP/5t3z/+bl//x8as/9NPKf/fWCb/x8as/8PD7f/bVOh//q5f//6v4X++sGI/vm9g//5voX/+b6F//m9hf/6vYX/+r6F//nCh/+bepr/Hxu0/w8Pt/8PD7f/fWOh//q+hf/6wof/+saN/vrGjf75xIv/+ceL//nEi//5xIv/+sSL//rHi//6x43/+ceN/+m7kP+7lpj/6ruQ//rHkP/6x43/+seQ//rLlf76ypT++seR//rJkf/6yZH/+seR//rJkf/6yZH/+8mR//vJlP/7yZT/+smU//rJlP/6yZT/+8yV//rJlf/6zpn+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA==</Image>
++
++<Url type="text/html" method="POST" template="https://startpage.com/do/search">
++  <Param name="q" value="{searchTerms}"/>
++</Url>
++<SearchForm>https://startpage.com/do/search/</SearchForm>
++</SearchPlugin>
+-- 
+1.7.5.4
+
diff --git a/src/current-patches/firefox/alpha/0013-Make-nsICacheService.EvictEntries-synchronous.patch b/src/current-patches/firefox/alpha/0013-Make-nsICacheService.EvictEntries-synchronous.patch
new file mode 100644
index 0000000..cbc5bc7
--- /dev/null
+++ b/src/current-patches/firefox/alpha/0013-Make-nsICacheService.EvictEntries-synchronous.patch
@@ -0,0 +1,44 @@
+From 1cf939b8ba9e04b33969546436633d263c939000 Mon Sep 17 00:00:00 2001
+From: Mike Perry <mikeperry-git at torproject.org>
+Date: Tue, 1 May 2012 15:02:03 -0700
+Subject: [PATCH 13/19] Make nsICacheService.EvictEntries synchronous
+
+This fixes a race condition that allows cache-based EverCookies to persist for
+a brief time (on the order of minutes?) after cache clearing/"New Identity".
+
+https://trac.torproject.org/projects/tor/ticket/5715
+---
+ netwerk/cache/nsCacheService.cpp |   15 +++++++++++++--
+ 1 files changed, 13 insertions(+), 2 deletions(-)
+
+diff --git a/netwerk/cache/nsCacheService.cpp b/netwerk/cache/nsCacheService.cpp
+index 8c85b68..d43f121 100644
+--- a/netwerk/cache/nsCacheService.cpp
++++ b/netwerk/cache/nsCacheService.cpp
+@@ -1414,10 +1414,21 @@ NS_IMETHODIMP nsCacheService::VisitEntries(nsICacheVisitor *visitor)
+     return NS_OK;
+ }
+ 
+-
+ NS_IMETHODIMP nsCacheService::EvictEntries(nsCacheStoragePolicy storagePolicy)
+ {
+-    return  EvictEntriesForClient(nsnull, storagePolicy);
++    NS_IMETHODIMP r;
++    r = EvictEntriesForClient(nsnull, storagePolicy);
++
++    // XXX: Bloody hack until we get this notifier in FF14.0:
++    // https://developer.mozilla.org/en/XPCOM_Interface_Reference/nsICacheListener#onCacheEntryDoomed%28%29
++    if (storagePolicy == nsICache::STORE_ANYWHERE &&
++            NS_IsMainThread() && gService && gService->mInitialized) {
++        nsCacheServiceAutoLock lock;
++        gService->DoomActiveEntries();
++        gService->ClearDoomList();
++        (void) SyncWithCacheIOThread();
++    }
++    return r; 
+ }
+ 
+ NS_IMETHODIMP nsCacheService::GetCacheIOTarget(nsIEventTarget * *aCacheIOTarget)
+-- 
+1.7.5.4
+
diff --git a/src/current-patches/firefox/alpha/0014-Prevent-WebSocket-DNS-leak.patch b/src/current-patches/firefox/alpha/0014-Prevent-WebSocket-DNS-leak.patch
new file mode 100644
index 0000000..667d9c8
--- /dev/null
+++ b/src/current-patches/firefox/alpha/0014-Prevent-WebSocket-DNS-leak.patch
@@ -0,0 +1,132 @@
+From b2f620bbb866f556dc3791bca5478f47a2255376 Mon Sep 17 00:00:00 2001
+From: Mike Perry <mikeperry-git at torproject.org>
+Date: Wed, 2 May 2012 17:44:39 -0700
+Subject: [PATCH 14/19] Prevent WebSocket DNS leak.
+
+This is due to an improper implementation of the WebSocket spec by Mozilla.
+
+"There MUST be no more than one connection in a CONNECTING state.  If multiple
+connections to the same IP address are attempted simultaneously, the client
+MUST serialize them so that there is no more than one connection at a time
+running through the following steps.
+
+If the client cannot determine the IP address of the remote host (for
+example, because all communication is being done through a proxy server that
+performs DNS queries itself), then the client MUST assume for the purposes of
+this step that each host name refers to a distinct remote host,"
+
+https://tools.ietf.org/html/rfc6455#page-15
+
+They implmented the first paragraph, but not the second...
+
+While we're at it, we also prevent the DNS service from being used to look up
+anything other than IP addresses if socks_remote_dns is set to true, so this
+bug can't turn up in other components or due to 3rd party addons.
+---
+ netwerk/dns/nsDNSService2.cpp                   |   24 ++++++++++++++++++++++-
+ netwerk/dns/nsDNSService2.h                     |    1 +
+ netwerk/protocol/websocket/WebSocketChannel.cpp |    8 +++++-
+ 3 files changed, 30 insertions(+), 3 deletions(-)
+
+diff --git a/netwerk/dns/nsDNSService2.cpp b/netwerk/dns/nsDNSService2.cpp
+index 7458729..40fbaba 100644
+--- a/netwerk/dns/nsDNSService2.cpp
++++ b/netwerk/dns/nsDNSService2.cpp
+@@ -403,6 +403,7 @@ nsDNSService::Init()
+     bool     enableIDN        = true;
+     bool     disableIPv6      = false;
+     bool     disablePrefetch  = false;
++    bool     disableDNS       = false;
+     int      proxyType        = nsIProtocolProxyService::PROXYCONFIG_DIRECT;
+     
+     nsAdoptingCString ipv4OnlyDomains;
+@@ -426,6 +427,10 @@ nsDNSService::Init()
+ 
+         // If a manual proxy is in use, disable prefetch implicitly
+         prefs->GetIntPref("network.proxy.type", &proxyType);
++
++        // If the user wants remote DNS, we should fail any lookups that still
++        // make it here.
++        prefs->GetBoolPref("network.proxy.socks_remote_dns", &disableDNS);
+     }
+ 
+     if (mFirstTime) {
+@@ -443,7 +448,7 @@ nsDNSService::Init()
+ 
+             // Monitor these to see if there is a change in proxy configuration
+             // If a manual proxy is in use, disable prefetch implicitly
+-            prefs->AddObserver("network.proxy.type", this, false);
++            prefs->AddObserver("network.proxy.", this, false);
+         }
+     }
+ 
+@@ -472,6 +477,7 @@ nsDNSService::Init()
+         mIDN = idn;
+         mIPv4OnlyDomains = ipv4OnlyDomains; // exchanges buffer ownership
+         mDisableIPv6 = disableIPv6;
++        mDisableDNS = disableDNS;
+ 
+         // Disable prefetching either by explicit preference or if a manual proxy is configured 
+         mDisablePrefetch = disablePrefetch || (proxyType == nsIProtocolProxyService::PROXYCONFIG_MANUAL);
+@@ -583,6 +589,14 @@ nsDNSService::AsyncResolve(const nsACString  &hostname,
+         if (mDisablePrefetch && (flags & RESOLVE_SPECULATE))
+             return NS_ERROR_DNS_LOOKUP_QUEUE_FULL;
+ 
++        PRNetAddr tempAddr;
++        if (mDisableDNS) {
++            // Allow IP lookups through, but nothing else.
++            if (PR_StringToNetAddr(hostname.BeginReading(), &tempAddr) != PR_SUCCESS) {
++                return NS_ERROR_UNKNOWN_PROXY_HOST; // XXX: NS_ERROR_NOT_IMPLEMENTED?
++            }
++        }
++
+         res = mResolver;
+         idn = mIDN;
+     }
+@@ -669,6 +683,14 @@ nsDNSService::Resolve(const nsACString &hostname,
+         MutexAutoLock lock(mLock);
+         res = mResolver;
+         idn = mIDN;
++
++        PRNetAddr tempAddr;
++        if (mDisableDNS) {
++            // Allow IP lookups through, but nothing else.
++            if (PR_StringToNetAddr(hostname.BeginReading(), &tempAddr) != PR_SUCCESS) {
++                return NS_ERROR_UNKNOWN_PROXY_HOST; // XXX: NS_ERROR_NOT_IMPLEMENTED?
++            }
++        }
+     }
+     NS_ENSURE_TRUE(res, NS_ERROR_OFFLINE);
+ 
+diff --git a/netwerk/dns/nsDNSService2.h b/netwerk/dns/nsDNSService2.h
+index 1749b41..3ec8eba 100644
+--- a/netwerk/dns/nsDNSService2.h
++++ b/netwerk/dns/nsDNSService2.h
+@@ -70,4 +70,5 @@ private:
+     bool                      mDisableIPv6;
+     bool                      mDisablePrefetch;
+     bool                      mFirstTime;
++    bool                      mDisableDNS;
+ };
+diff --git a/netwerk/protocol/websocket/WebSocketChannel.cpp b/netwerk/protocol/websocket/WebSocketChannel.cpp
+index 3578866..b1aaec2 100644
+--- a/netwerk/protocol/websocket/WebSocketChannel.cpp
++++ b/netwerk/protocol/websocket/WebSocketChannel.cpp
+@@ -1884,8 +1884,12 @@ WebSocketChannel::ApplyForAdmission()
+   LOG(("WebSocketChannel::ApplyForAdmission: checking for concurrent open\n"));
+   nsCOMPtr<nsIThread> mainThread;
+   NS_GetMainThread(getter_AddRefs(mainThread));
+-  dns->AsyncResolve(hostName, 0, this, mainThread, getter_AddRefs(mDNSRequest));
+-  NS_ENSURE_SUCCESS(rv, rv);
++  rv = dns->AsyncResolve(hostName, 0, this, mainThread, getter_AddRefs(mDNSRequest));
++  if (NS_FAILED(rv)) {
++      // Fall back to hostname on dispatch failure
++      mDNSRequest = nsnull;
++      OnLookupComplete(nsnull, nsnull, rv);
++  }
+ 
+   return NS_OK;
+ }
+-- 
+1.7.5.4
+
diff --git a/src/current-patches/firefox/alpha/0015-Make-Tor-Browser-exit-when-not-launched-from-Vidalia.patch b/src/current-patches/firefox/alpha/0015-Make-Tor-Browser-exit-when-not-launched-from-Vidalia.patch
new file mode 100644
index 0000000..bc27267
--- /dev/null
+++ b/src/current-patches/firefox/alpha/0015-Make-Tor-Browser-exit-when-not-launched-from-Vidalia.patch
@@ -0,0 +1,45 @@
+From 57c38c109e0dd06eff36104570c40feefb03bb39 Mon Sep 17 00:00:00 2001
+From: Mike Perry <mikeperry-git at torproject.org>
+Date: Thu, 7 Jun 2012 14:45:26 -0700
+Subject: [PATCH 15/19] 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 |   14 ++++++++++++++
+ 1 files changed, 14 insertions(+), 0 deletions(-)
+
+diff --git a/browser/base/content/browser.js b/browser/base/content/browser.js
+index 6e254ca..57ca373 100644
+--- a/browser/base/content/browser.js
++++ b/browser/base/content/browser.js
+@@ -1234,6 +1234,20 @@ 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 && uriToLoad != "about:blank") {
+     if (uriToLoad instanceof Ci.nsISupportsArray) {
+       let count = uriToLoad.Count();
+-- 
+1.7.5.4
+
diff --git a/src/current-patches/firefox/alpha/0016-Limit-the-number-of-fonts-per-document.patch b/src/current-patches/firefox/alpha/0016-Limit-the-number-of-fonts-per-document.patch
new file mode 100644
index 0000000..5053dea
--- /dev/null
+++ b/src/current-patches/firefox/alpha/0016-Limit-the-number-of-fonts-per-document.patch
@@ -0,0 +1,225 @@
+From 1fda7ee08947f2df08709afed325a14e6a82f64d Mon Sep 17 00:00:00 2001
+From: Mike Perry <mikeperry-git at torproject.org>
+Date: Thu, 7 Jun 2012 15:09:59 -0700
+Subject: [PATCH 16/19] 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 f3815fb..1ab210e 100644
+--- a/layout/base/nsPresContext.cpp
++++ b/layout/base/nsPresContext.cpp
+@@ -97,6 +97,8 @@
+ #include "FrameLayerBuilder.h"
+ #include "nsDOMMediaQueryList.h"
+ #include "nsSMILAnimationController.h"
++#include "nsString.h"
++#include "nsUnicharUtils.h"
+ 
+ #ifdef IBMBIDI
+ #include "nsBidiPresUtils.h"
+@@ -772,6 +774,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 =
+@@ -1381,6 +1387,100 @@ nsPresContext::GetDefaultFont(PRUint8 aFontID, nsIAtom *aLanguage) 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 e367c5f..3d979f1 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);
++
+   /**
+    * Get the minimum font size for the specified language. If aLanguage
+    * is nsnull, then the document's language is used.
+@@ -1188,6 +1195,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 4b134b2..82b1dd7 100644
+--- a/layout/style/nsRuleNode.cpp
++++ b/layout/style/nsRuleNode.cpp
+@@ -3102,14 +3102,15 @@ nsRuleNode::ComputeFontData(void* aStartStruct,
+ 
+   bool useDocumentFonts =
+     mPresContext->GetCachedBoolPref(kPresContext_UseDocumentFonts);
++  bool isXUL = PR_FALSE;
+ 
+   // See if we are in the chrome
+   // We only need to know this to determine if we have to use the
+   // document fonts (overriding the useDocumentFonts flag).
+-  if (!useDocumentFonts && 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 = true;
+   }
+ 
+   // Figure out if we are a generic font
+@@ -3123,9 +3124,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)) {
+@@ -3161,6 +3166,8 @@ nsRuleNode::ComputeFontData(void* aStartStruct,
+                                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/alpha/0017-Randomize-HTTP-request-order-and-pipeline-depth.patch b/src/current-patches/firefox/alpha/0017-Randomize-HTTP-request-order-and-pipeline-depth.patch
new file mode 100644
index 0000000..67c40df
--- /dev/null
+++ b/src/current-patches/firefox/alpha/0017-Randomize-HTTP-request-order-and-pipeline-depth.patch
@@ -0,0 +1,251 @@
+From a14811fde3ebdf0073daafb570a733f601411e21 Mon Sep 17 00:00:00 2001
+From: Mike Perry <mikeperry-git at torproject.org>
+Date: Thu, 7 Jun 2012 15:13:45 -0700
+Subject: [PATCH 17/19] 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 |  136 ++++++++++++++++++++++++-
+ netwerk/protocol/http/nsHttpConnectionMgr.h   |    5 +
+ 2 files changed, 136 insertions(+), 5 deletions(-)
+
+diff --git a/netwerk/protocol/http/nsHttpConnectionMgr.cpp b/netwerk/protocol/http/nsHttpConnectionMgr.cpp
+index 463584f..e05669c 100644
+--- a/netwerk/protocol/http/nsHttpConnectionMgr.cpp
++++ b/netwerk/protocol/http/nsHttpConnectionMgr.cpp
+@@ -101,6 +101,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()
+@@ -380,8 +386,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 = new PRInt32[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);
+@@ -392,6 +402,8 @@ nsHttpConnectionMgr::AddTransactionToPipeline(nsHttpPipeline *pipeline)
+                     break;
+                 }
+             }
++
++            delete [] ind;
+         }
+     }
+ }
+@@ -922,12 +934,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 = new PRUint32[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
+@@ -951,6 +968,7 @@ nsHttpConnectionMgr::ProcessPendingQForEntry(nsConnectionEntry *ent)
+                               "something mutated pending queue from "
+                               "GetConnection()");
+         }
++        delete [] ind;
+         if (conn) {
+             LOG(("  dispatching pending transaction...\n"));
+ 
+@@ -1035,6 +1053,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) );
+@@ -1274,7 +1305,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;
+     }
+ 
+@@ -1349,6 +1380,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 6b4398b..c33870f 100644
+--- a/netwerk/protocol/http/nsHttpConnectionMgr.h
++++ b/netwerk/protocol/http/nsHttpConnectionMgr.h
+@@ -53,6 +53,7 @@
+ #include "nsIObserver.h"
+ #include "nsITimer.h"
+ #include "nsIX509Cert3.h"
++#include "nsIRandomGenerator.h"
+ 
+ class nsHttpPipeline;
+ 
+@@ -320,6 +321,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);
+@@ -412,6 +415,8 @@ private:
+     PRUint64 mTimeOfNextWakeUp;
+     // Timer for next pruning of dead connections.
+     nsCOMPtr<nsITimer> mTimer;
++    // Random number generator for reordering HTTP pipeline
++    nsCOMPtr<nsIRandomGenerator>             mRandomGenerator;
+ 
+     // A 1s tick to call nsHttpConnection::ReadTimeoutTick on
+     // active http/1 connections. Disabled when there are no
+-- 
+1.7.5.4
+
diff --git a/src/current-patches/firefox/alpha/0018-Adapt-Steven-Michaud-s-Mac-crashfix-patch.patch b/src/current-patches/firefox/alpha/0018-Adapt-Steven-Michaud-s-Mac-crashfix-patch.patch
new file mode 100644
index 0000000..311b44c
--- /dev/null
+++ b/src/current-patches/firefox/alpha/0018-Adapt-Steven-Michaud-s-Mac-crashfix-patch.patch
@@ -0,0 +1,541 @@
+From f427cb05b95348ed98ece917d8578e69e291b0f1 Mon Sep 17 00:00:00 2001
+From: Mike Perry <mikeperry-git at torproject.org>
+Date: Thu, 7 Jun 2012 15:26:13 -0700
+Subject: [PATCH 18/19] Adapt Steven Michaud's Mac crashfix patch
+
+Source is: https://bugzilla.mozilla.org/show_bug.cgi?id=715885#c35
+
+Some minor tweaks were needed to get it to apply and to compile on
+MacOS.
+---
+ widget/Makefile.in                        |    1 +
+ widget/cocoa/nsChildView.mm               |   32 +++++++++++++------
+ widget/gtk2/nsDragService.cpp             |    2 +-
+ widget/gtk2/nsWindow.cpp                  |    2 +-
+ widget/nsIDragService.idl                 |    4 +--
+ widget/nsPIDragService.idl                |   48 +++++++++++++++++++++++++++++
+ widget/qt/nsDragService.h                 |    2 +
+ widget/windows/Makefile.in                |    4 ++
+ widget/windows/nsDragService.cpp          |   13 +++++---
+ widget/windows/nsDragService.h            |   12 +++---
+ widget/windows/nsNativeDragSource.cpp     |    7 ++--
+ widget/windows/nsNativeDragTarget.cpp     |   28 ++++++++++------
+ widget/windows/nsPIDragServiceWindows.idl |   46 +++++++++++++++++++++++++++
+ widget/xpwidgets/nsBaseDragService.cpp    |   16 +++++++++-
+ widget/xpwidgets/nsBaseDragService.h      |    9 ++---
+ 15 files changed, 180 insertions(+), 46 deletions(-)
+ create mode 100644 widget/nsPIDragService.idl
+ create mode 100644 widget/windows/nsPIDragServiceWindows.idl
+
+diff --git a/widget/Makefile.in b/widget/Makefile.in
+index 4a3405b..4c105a4 100644
+--- a/widget/Makefile.in
++++ b/widget/Makefile.in
+@@ -138,6 +138,7 @@ XPIDLSRCS	= \
+ 		nsIClipboardDragDropHooks.idl \
+ 		nsIClipboardDragDropHookList.idl \
+ 		nsIDragSession.idl \
++		nsPIDragService.idl \
+ 		nsIDragService.idl \
+ 		nsIFormatConverter.idl \
+ 		nsIClipboard.idl \
+diff --git a/widget/cocoa/nsChildView.mm b/widget/cocoa/nsChildView.mm
+index 0db6b1c..e88302b 100644
+--- a/widget/cocoa/nsChildView.mm
++++ b/widget/cocoa/nsChildView.mm
+@@ -4555,11 +4555,12 @@ NSEvent* gLastDragMouseDownEvent = nil;
+   if (!dragService) {
+     dragService = do_GetService(kDragServiceContractID);
+   }
++  nsCOMPtr<nsPIDragService> dragServicePriv = do_QueryInterface(dragService);
+ 
+   if (dragService) {
+     NSPoint pnt = [NSEvent mouseLocation];
+     FlipCocoaScreenCoordinate(pnt);
+-    dragService->DragMoved(NSToIntRound(pnt.x), NSToIntRound(pnt.y));
++    dragServicePriv->DragMoved(NSToIntRound(pnt.x), NSToIntRound(pnt.y));
+   }
+ }
+ 
+@@ -4580,11 +4581,13 @@ NSEvent* gLastDragMouseDownEvent = nil;
+   }
+ 
+   if (mDragService) {
+-    // set the dragend point from the current mouse location
+-    nsDragService* dragService = static_cast<nsDragService *>(mDragService);
+-    NSPoint pnt = [NSEvent mouseLocation];
+-    FlipCocoaScreenCoordinate(pnt);
+-    dragService->SetDragEndPoint(nsIntPoint(NSToIntRound(pnt.x), NSToIntRound(pnt.y)));
++    nsCOMPtr<nsPIDragService> dragServicePriv = do_QueryInterface(mDragService);
++    if (dragServicePriv) {
++      // set the dragend point from the current mouse location
++      NSPoint pnt = [NSEvent mouseLocation];
++      FlipCocoaScreenCoordinate(pnt);
++      dragServicePriv->SetDragEndPoint(NSToIntRound(pnt.x), NSToIntRound(pnt.y));
++    }
+ 
+     // XXX: dropEffect should be updated per |operation|. 
+     // As things stand though, |operation| isn't well handled within "our"
+@@ -4595,10 +4598,19 @@ NSEvent* gLastDragMouseDownEvent = nil;
+     // value for NSDragOperationGeneric that is passed by other applications.
+     // All that said, NSDragOperationNone is still reliable.
+     if (operation == NSDragOperationNone) {
+-      nsCOMPtr<nsIDOMDataTransfer> dataTransfer;
+-      dragService->GetDataTransfer(getter_AddRefs(dataTransfer));
+-      if (dataTransfer)
+-        dataTransfer->SetDropEffectInt(nsIDragService::DRAGDROP_ACTION_NONE);
++      nsCOMPtr<nsIDragSession> dragSession;
++      mDragService->GetCurrentSession(getter_AddRefs(dragSession));
++      if (dragSession) {
++        nsCOMPtr<nsIDOMDataTransfer> dataTransfer;
++        dragSession->GetDataTransfer(getter_AddRefs(dataTransfer));
++        if (dataTransfer) {
++          nsCOMPtr<nsIDOMNSDataTransfer> dataTransferNS =
++                do_QueryInterface(dataTransfer);
++          if (dataTransferNS) {
++            dataTransferNS->SetDropEffectInt(nsIDragService::DRAGDROP_ACTION_NONE);
++          }
++        }
++      }
+     }
+ 
+     mDragService->EndDragSession(true);
+diff --git a/widget/gtk2/nsDragService.cpp b/widget/gtk2/nsDragService.cpp
+index be8f388..99d3878 100644
+--- a/widget/gtk2/nsDragService.cpp
++++ b/widget/gtk2/nsDragService.cpp
+@@ -1332,7 +1332,7 @@ nsDragService::SourceEndDragSession(GdkDragContext *aContext,
+     GdkDisplay* display = gdk_display_get_default();
+     if (display) {
+       gdk_display_get_pointer(display, NULL, &x, &y, NULL);
+-      SetDragEndPoint(nsIntPoint(x, y));
++      SetDragEndPoint(x, y);
+     }
+ 
+     // Either the drag was aborted or the drop occurred outside the app.
+diff --git a/widget/gtk2/nsWindow.cpp b/widget/gtk2/nsWindow.cpp
+index 9de734e..81fe553 100644
+--- a/widget/gtk2/nsWindow.cpp
++++ b/widget/gtk2/nsWindow.cpp
+@@ -3517,7 +3517,7 @@ nsWindow::OnDragDropEvent(GtkWidget *aWidget,
+     if (display) {
+       // get the current cursor position
+       gdk_display_get_pointer(display, NULL, &x, &y, NULL);
+-      ((nsDragService *)dragService.get())->SetDragEndPoint(nsIntPoint(x, y));
++      ((nsDragService *)dragService.get())->SetDragEndPoint(x, y);
+     }
+     dragService->EndDragSession(true);
+ 
+diff --git a/widget/nsIDragService.idl b/widget/nsIDragService.idl
+index e42c578..ef8c46f 100644
+--- a/widget/nsIDragService.idl
++++ b/widget/nsIDragService.idl
+@@ -48,7 +48,7 @@ interface nsIDOMDragEvent;
+ interface nsIDOMDataTransfer;
+ interface nsISelection;
+ 
+-[scriptable, uuid(82B58ADA-F490-4C3D-B737-1057C4F1D052), builtinclass]
++[scriptable, uuid(82B58ADA-F490-4C3D-B737-1057C4F1D052)]
+ interface nsIDragService : nsISupports
+ {
+   const long DRAGDROP_ACTION_NONE = 0;
+@@ -145,8 +145,6 @@ interface nsIDragService : nsISupports
+    */
+   void suppress();
+   void unsuppress();
+-
+-  [noscript] void dragMoved(in long aX, in long aY);
+ };
+ 
+ 
+diff --git a/widget/nsPIDragService.idl b/widget/nsPIDragService.idl
+new file mode 100644
+index 0000000..93a144d
+--- /dev/null
++++ b/widget/nsPIDragService.idl
+@@ -0,0 +1,48 @@
++/* ***** BEGIN LICENSE BLOCK *****
++ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
++ *
++ * The contents of this file are subject to the Mozilla Public License Version
++ * 1.1 (the "License"); you may not use this file except in compliance with
++ * the License. You may obtain a copy of the License at
++ * http://www.mozilla.org/MPL/
++ *
++ * Software distributed under the License is distributed on an "AS IS" basis,
++ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
++ * for the specific language governing rights and limitations under the
++ * License.
++ *
++ * The Original Code is mozilla.org code.
++ *
++ * The Initial Developer of the Original Code is
++ * The Mozilla Foundation.
++ * Portions created by the Initial Developer are Copyright (C) 2012
++ * the Initial Developer. All Rights Reserved.
++ *
++ * Contributor(s):
++ *   Steven Michaud <smichaud at pobox.com>
++ *
++ * Alternatively, the contents of this file may be used under the terms of
++ * either the GNU General Public License Version 2 or later (the "GPL"), or
++ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
++ * in which case the provisions of the GPL or the LGPL are applicable instead
++ * of those above. If you wish to allow use of your version of this file only
++ * under the terms of either the GPL or the LGPL, and not to allow others to
++ * use your version of this file under the terms of the MPL, indicate your
++ * decision by deleting the provisions above and replace them with the notice
++ * and other provisions required by the GPL or the LGPL. If you do not delete
++ * the provisions above, a recipient may use your version of this file under
++ * the terms of any one of the MPL, the GPL or the LGPL.
++ *
++ * ***** END LICENSE BLOCK ***** */
++
++#include "nsISupports.idl"
++
++[scriptable, uuid(FAD8C90B-8E1D-446A-9B6C-241486A85CBD)]
++interface nsPIDragService : nsISupports
++{
++  void dragMoved(in long aX, in long aY);
++
++  PRUint16 getInputSource();
++
++  void setDragEndPoint(in long aX, in long aY);
++};
+diff --git a/widget/qt/nsDragService.h b/widget/qt/nsDragService.h
+index 5a3e5bb..50dcfac 100644
+--- a/widget/qt/nsDragService.h
++++ b/widget/qt/nsDragService.h
+@@ -50,6 +50,8 @@ public:
+     NS_DECL_ISUPPORTS
+     NS_DECL_NSIDRAGSERVICE
+ 
++    NS_IMETHOD DragMoved(PRInt32 aX, PRInt32 aY);
++
+     nsDragService();
+ 
+ private:
+diff --git a/widget/windows/Makefile.in b/widget/windows/Makefile.in
+index df811ac..8d5ea4b 100644
+--- a/widget/windows/Makefile.in
++++ b/widget/windows/Makefile.in
+@@ -120,6 +120,10 @@ ifdef MOZ_ENABLE_D3D10_LAYER
+ DEFINES		+= -DMOZ_ENABLE_D3D10_LAYER
+ endif
+ 
++XPIDLSRCS	+= \
++		nsPIDragServiceWindows.idl \
++		$(NULL)
++
+ SHARED_LIBRARY_LIBS = \
+   ../xpwidgets/$(LIB_PREFIX)xpwidgets_s.$(LIB_SUFFIX) \
+   $(NULL)
+diff --git a/widget/windows/nsDragService.cpp b/widget/windows/nsDragService.cpp
+index b6b5b62..9657263 100644
+--- a/widget/windows/nsDragService.cpp
++++ b/widget/windows/nsDragService.cpp
+@@ -97,6 +97,8 @@ nsDragService::~nsDragService()
+   NS_IF_RELEASE(mDataObject);
+ }
+ 
++NS_IMPL_ISUPPORTS_INHERITED1(nsDragService, nsBaseDragService, nsPIDragServiceWindows)
++
+ bool
+ nsDragService::CreateDragImage(nsIDOMNode *aDOMNode,
+                                nsIScriptableRegion *aRegion,
+@@ -347,7 +349,7 @@ nsDragService::StartInvokingDragSession(IDataObject * aDataObj,
+   POINT cpos;
+   cpos.x = GET_X_LPARAM(pos);
+   cpos.y = GET_Y_LPARAM(pos);
+-  SetDragEndPoint(nsIntPoint(cpos.x, cpos.y));
++  SetDragEndPoint(cpos.x, cpos.y);
+   EndDragSession(true);
+ 
+   mDoingDrag = false;
+@@ -465,25 +467,26 @@ nsDragService::GetData(nsITransferable * aTransferable, PRUint32 anItem)
+ 
+ //---------------------------------------------------------
+ NS_IMETHODIMP
+-nsDragService::SetIDataObject(IDataObject * aDataObj)
++nsDragService::SetIDataObject(nsISupports * aDataObj)
+ {
++  IDataObject *dataObj = (IDataObject*) aDataObj;
+   // When the native drag starts the DragService gets
+   // the IDataObject that is being dragged
+   NS_IF_RELEASE(mDataObject);
+-  mDataObject = aDataObj;
++  mDataObject = dataObj;
+   NS_IF_ADDREF(mDataObject);
+ 
+   return NS_OK;
+ }
+ 
+ //---------------------------------------------------------
+-void
++NS_IMETHODIMP
+ nsDragService::SetDroppedLocal()
+ {
+   // Sent from the native drag handler, letting us know
+   // a drop occurred within the application vs. outside of it.
+   mSentLocalDropEvent = true;
+-  return;
++  return NS_OK;
+ }
+ 
+ //-------------------------------------------------------------------------
+diff --git a/widget/windows/nsDragService.h b/widget/windows/nsDragService.h
+index 87d6cc9..04c8746 100644
+--- a/widget/windows/nsDragService.h
++++ b/widget/windows/nsDragService.h
+@@ -39,6 +39,7 @@
+ #define nsDragService_h__
+ 
+ #include "nsBaseDragService.h"
++#include "nsPIDragServiceWindows.h"
+ #include <windows.h>
+ #include <shlobj.h>
+ 
+@@ -52,12 +53,15 @@ class  nsString;
+  * Native Win32 DragService wrapper
+  */
+ 
+-class nsDragService : public nsBaseDragService
++class nsDragService : public nsBaseDragService, public nsPIDragServiceWindows
+ {
+ public:
+   nsDragService();
+   virtual ~nsDragService();
+-  
++
++  NS_DECL_ISUPPORTS_INHERITED
++  NS_DECL_NSPIDRAGSERVICEWINDOWS
++
+   // nsIDragService
+   NS_IMETHOD InvokeDragSession(nsIDOMNode *aDOMNode,
+                                nsISupportsArray *anArrayTransferables,
+@@ -71,13 +75,9 @@ public:
+   NS_IMETHOD EndDragSession(bool aDoneDrag);
+ 
+   // native impl.
+-  NS_IMETHOD SetIDataObject(IDataObject * aDataObj);
+   NS_IMETHOD StartInvokingDragSession(IDataObject * aDataObj,
+                                       PRUint32 aActionType);
+ 
+-  // A drop occurred within the application vs. outside of it.
+-  void SetDroppedLocal();
+-
+ protected:
+   nsDataObjCollection* GetDataObjCollection(IDataObject * aDataObj);
+ 
+diff --git a/widget/windows/nsNativeDragSource.cpp b/widget/windows/nsNativeDragSource.cpp
+index e51101e..0fe6ffe 100644
+--- a/widget/windows/nsNativeDragSource.cpp
++++ b/widget/windows/nsNativeDragSource.cpp
+@@ -42,7 +42,7 @@
+ #include "nsIServiceManager.h"
+ #include "nsToolkit.h"
+ #include "nsWidgetsCID.h"
+-#include "nsIDragService.h"
++#include "nsDragService.h"
+ 
+ static NS_DEFINE_IID(kCDragServiceCID,  NS_DRAGSERVICE_CID);
+ 
+@@ -101,9 +101,10 @@ STDMETHODIMP
+ nsNativeDragSource::QueryContinueDrag(BOOL fEsc, DWORD grfKeyState)
+ {
+   nsCOMPtr<nsIDragService> dragService = do_GetService(kCDragServiceCID);
+-  if (dragService) {
++  nsCOMPtr<nsPIDragService> dragServicePriv = do_QueryInterface(dragService);
++  if (dragServicePriv) {
+     DWORD pos = ::GetMessagePos();
+-    dragService->DragMoved(GET_X_LPARAM(pos), GET_Y_LPARAM(pos));
++    dragServicePriv->DragMoved(GET_X_LPARAM(pos), GET_Y_LPARAM(pos));
+   }
+ 
+   if (fEsc) {
+diff --git a/widget/windows/nsNativeDragTarget.cpp b/widget/windows/nsNativeDragTarget.cpp
+index 3362ca6..a69817c 100644
+--- a/widget/windows/nsNativeDragTarget.cpp
++++ b/widget/windows/nsNativeDragTarget.cpp
+@@ -205,7 +205,11 @@ nsNativeDragTarget::DispatchDragDropEvent(PRUint32 aEventType, POINTL aPT)
+   event.isControl = IsKeyDown(NS_VK_CONTROL);
+   event.isMeta    = false;
+   event.isAlt     = IsKeyDown(NS_VK_ALT);
+-  event.inputSource = static_cast<nsBaseDragService*>(mDragService)->GetInputSource();
++  event.inputSource = 0;
++  nsCOMPtr<nsPIDragService> dragServicePriv = do_QueryInterface(mDragService);
++  if (dragServicePriv) {
++    dragServicePriv->GetInputSource(&event.inputSource);
++  }
+ 
+   mWindow->DispatchEvent(&event, status);
+ }
+@@ -292,9 +296,8 @@ nsNativeDragTarget::DragEnter(LPDATAOBJECT pIDataSource,
+   // This cast is ok because in the constructor we created a
+   // the actual implementation we wanted, so we know this is
+   // a nsDragService. It should be a private interface, though.
+-  nsDragService * winDragService =
+-    static_cast<nsDragService *>(mDragService);
+-  winDragService->SetIDataObject(pIDataSource);
++  nsCOMPtr<nsPIDragServiceWindows> winDragService = do_QueryInterface(mDragService);
++  winDragService->SetIDataObject((nsISupports*)pIDataSource);
+ 
+   // Now process the native drag state and then dispatch the event
+   ProcessDrag(NS_DRAGDROP_ENTER, grfKeyState, ptl, pdwEffect);
+@@ -432,8 +435,8 @@ nsNativeDragTarget::Drop(LPDATAOBJECT pData,
+   // This cast is ok because in the constructor we created a
+   // the actual implementation we wanted, so we know this is
+   // a nsDragService (but it should still be a private interface)
+-  nsDragService* winDragService = static_cast<nsDragService*>(mDragService);
+-  winDragService->SetIDataObject(pData);
++  nsCOMPtr<nsPIDragServiceWindows> winDragService = do_QueryInterface(mDragService);
++  winDragService->SetIDataObject((nsISupports*)pData);
+ 
+   // NOTE: ProcessDrag spins the event loop which may destroy arbitrary objects.
+   // We use strong refs to prevent it from destroying these:
+@@ -457,11 +460,14 @@ nsNativeDragTarget::Drop(LPDATAOBJECT pData,
+   // tell the drag service we're done with the session
+   // Use GetMessagePos to get the position of the mouse at the last message
+   // seen by the event loop. (Bug 489729)
+-  DWORD pos = ::GetMessagePos();
+-  POINT cpos;
+-  cpos.x = GET_X_LPARAM(pos);
+-  cpos.y = GET_Y_LPARAM(pos);
+-  winDragService->SetDragEndPoint(nsIntPoint(cpos.x, cpos.y));
++  nsCOMPtr<nsPIDragService> dragServicePriv = do_QueryInterface(mDragService);
++  if (dragServicePriv) {
++    DWORD pos = ::GetMessagePos();
++    POINT cpos;
++    cpos.x = GET_X_LPARAM(pos);
++    cpos.y = GET_Y_LPARAM(pos);
++    dragServicePriv->SetDragEndPoint(cpos.x, cpos.y);
++  }
+   serv->EndDragSession(true);
+ 
+   // release the ref that was taken in DragEnter
+diff --git a/widget/windows/nsPIDragServiceWindows.idl b/widget/windows/nsPIDragServiceWindows.idl
+new file mode 100644
+index 0000000..c8a46dd
+--- /dev/null
++++ b/widget/windows/nsPIDragServiceWindows.idl
+@@ -0,0 +1,46 @@
++/* ***** BEGIN LICENSE BLOCK *****
++ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
++ *
++ * The contents of this file are subject to the Mozilla Public License Version
++ * 1.1 (the "License"); you may not use this file except in compliance with
++ * the License. You may obtain a copy of the License at
++ * http://www.mozilla.org/MPL/
++ *
++ * Software distributed under the License is distributed on an "AS IS" basis,
++ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
++ * for the specific language governing rights and limitations under the
++ * License.
++ *
++ * The Original Code is mozilla.org code.
++ *
++ * The Initial Developer of the Original Code is
++ * The Mozilla Foundation.
++ * Portions created by the Initial Developer are Copyright (C) 2012
++ * the Initial Developer. All Rights Reserved.
++ *
++ * Contributor(s):
++ *   Steven Michaud <smichaud at pobox.com>
++ *
++ * Alternatively, the contents of this file may be used under the terms of
++ * either the GNU General Public License Version 2 or later (the "GPL"), or
++ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
++ * in which case the provisions of the GPL or the LGPL are applicable instead
++ * of those above. If you wish to allow use of your version of this file only
++ * under the terms of either the GPL or the LGPL, and not to allow others to
++ * use your version of this file under the terms of the MPL, indicate your
++ * decision by deleting the provisions above and replace them with the notice
++ * and other provisions required by the GPL or the LGPL. If you do not delete
++ * the provisions above, a recipient may use your version of this file under
++ * the terms of any one of the MPL, the GPL or the LGPL.
++ *
++ * ***** END LICENSE BLOCK ***** */
++
++#include "nsISupports.idl"
++
++[scriptable, uuid(6FC2117D-5EB4-441A-9C12-62A783BEBC0C)]
++interface nsPIDragServiceWindows : nsISupports
++{
++  void setIDataObject(in nsISupports aDataObj);
++
++  void setDroppedLocal();
++};
+diff --git a/widget/xpwidgets/nsBaseDragService.cpp b/widget/xpwidgets/nsBaseDragService.cpp
+index 342a036..87e28f7 100644
+--- a/widget/xpwidgets/nsBaseDragService.cpp
++++ b/widget/xpwidgets/nsBaseDragService.cpp
+@@ -88,7 +88,7 @@ nsBaseDragService::~nsBaseDragService()
+ {
+ }
+ 
+-NS_IMPL_ISUPPORTS2(nsBaseDragService, nsIDragService, nsIDragSession)
++NS_IMPL_ISUPPORTS3(nsBaseDragService, nsIDragService, nsPIDragService, nsIDragSession)
+ 
+ //---------------------------------------------------------
+ NS_IMETHODIMP
+@@ -436,6 +436,20 @@ nsBaseDragService::DragMoved(PRInt32 aX, PRInt32 aY)
+   return NS_OK;
+ }
+ 
++NS_IMETHODIMP
++nsBaseDragService::SetDragEndPoint(PRInt32 aX, PRInt32 aY)
++{
++  mEndDragPoint = nsIntPoint(aX, aY);
++  return NS_OK;
++}
++
++NS_IMETHODIMP
++nsBaseDragService::GetInputSource(PRUint16* aInputSource)
++{
++  *aInputSource = mInputSource;
++  return NS_OK;
++}
++
+ static nsIPresShell*
+ GetPresShellForContent(nsIDOMNode* aDOMNode)
+ {
+diff --git a/widget/xpwidgets/nsBaseDragService.h b/widget/xpwidgets/nsBaseDragService.h
+index 290c0cb..2ceac2b 100644
+--- a/widget/xpwidgets/nsBaseDragService.h
++++ b/widget/xpwidgets/nsBaseDragService.h
+@@ -39,6 +39,7 @@
+ #define nsBaseDragService_h__
+ 
+ #include "nsIDragService.h"
++#include "nsPIDragService.h"
+ #include "nsIDragSession.h"
+ #include "nsITransferable.h"
+ #include "nsISupportsArray.h"
+@@ -64,6 +65,7 @@ class nsICanvasElementExternal;
+  */
+ 
+ class nsBaseDragService : public nsIDragService,
++                          public nsPIDragService,
+                           public nsIDragSession
+ {
+ 
+@@ -74,14 +76,11 @@ public:
+   //nsISupports
+   NS_DECL_ISUPPORTS
+ 
+-  //nsIDragSession and nsIDragService
++  //nsIDragSession, nsIDragService and nsPIDragService
+   NS_DECL_NSIDRAGSERVICE
++  NS_DECL_NSPIDRAGSERVICE
+   NS_DECL_NSIDRAGSESSION
+ 
+-  void SetDragEndPoint(nsIntPoint aEndDragPoint) { mEndDragPoint = aEndDragPoint; }
+-
+-  PRUint16 GetInputSource() { return mInputSource; }
+-
+ protected:
+ 
+   /**
+-- 
+1.7.5.4
+





More information about the tor-commits mailing list