[tor-commits] [torbrowser/maint-2.3] Update patches for FF15.

erinn at torproject.org erinn at torproject.org
Fri Sep 7 11:59:12 UTC 2012


commit 659a8abeee6615868dda1ea359982c50babad84f
Author: Mike Perry <mikeperry-git at fscked.org>
Date:   Tue Aug 28 23:06:34 2012 -0700

    Update patches for FF15.
---
 ...nents.interfaces-lookupMethod-from-conten.patch |   10 +-
 ...0002-Make-Permissions-Manager-memory-only.patch |   16 +-
 ...-Make-Intermediate-Cert-Store-memory-only.patch |    8 +-
 .../alpha/0004-Add-a-string-based-cacheKey.patch   |   26 +-
 .../0005-Block-all-plugins-except-flash.patch      |   14 +-
 ...ontent-pref-service-memory-only-clearable.patch |   10 +-
 .../0007-Disable-SSL-Session-ID-tracking.patch     |    4 +-
 ...ice-and-system-specific-CSS-Media-Queries.patch |  116 +++
 ...observer-event-to-close-persistent-connec.patch |   40 -
 ...ice-and-system-specific-CSS-Media-Queries.patch |  116 ---
 .../0009-Make-Download-manager-memory-only.patch   |   57 ++
 .../0010-Add-DDG-and-StartPage-to-Omnibox.patch    |   84 ++
 .../alpha/0010-Rebrand-Firefox-to-TorBrowser.patch |   50 --
 .../0011-Make-Download-manager-memory-only.patch   |   57 --
 ...-nsICacheService.EvictEntries-synchronous.patch |   44 +
 .../0012-Add-DDG-and-StartPage-to-Omnibox.patch    |   84 --
 ...owser-exit-when-not-launched-from-Vidalia.patch |   45 +
 ...13-Limit-the-number-of-fonts-per-document.patch |  225 +++++
 ...-nsICacheService.EvictEntries-synchronous.patch |   44 -
 .../alpha/0014-Prevent-WebSocket-DNS-leak.patch    |  132 ---
 ...observer-event-to-close-persistent-connec.patch |   40 +
 ...owser-exit-when-not-launched-from-Vidalia.patch |   45 -
 .../alpha/0015-Rebrand-Firefox-to-TorBrowser.patch |   59 ++
 ...16-Limit-the-number-of-fonts-per-document.patch |  225 -----
 .../alpha/0016-Prevent-WebSocket-DNS-leak.patch    |  133 +++
 ...ize-HTTP-request-order-and-pipeline-depth.patch |   26 +-
 ...Adapt-Steven-Michaud-s-Mac-crashfix-patch.patch |  271 ++----
 ...9-Add-a-redirect-API-for-HTTPS-Everywhere.patch |  345 ++++++++
 .../alpha/0019-Fix-Firefox-build-process.patch     |  267 ------
 ...0-Add-a-redirect-API-for-HTTPS-Everywhere.patch |  346 --------
 ...solate-the-Image-Cache-per-url-bar-domain.patch |  910 ++++++++++++++++++++
 31 files changed, 2194 insertions(+), 1655 deletions(-)

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
index 31805de..41da39d 100644
--- 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
@@ -1,7 +1,7 @@
-From 497c96e0d9be60c3c4d61edf6162aff22ee9f4fc Mon Sep 17 00:00:00 2001
+From d4c3ef2aadb70643bf0a3784cd5d9e9bb72481e1 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
+Subject: [PATCH 01/20] Block Components.interfaces,lookupMethod from content
 
 This patch removes the ability of content script to access
 Components.interfaces.* as well as call or access Components.lookupMethod.
@@ -20,10 +20,10 @@ https://trac.torproject.org/projects/tor/ticket/2874
  1 files changed, 6 insertions(+), 2 deletions(-)
 
 diff --git a/js/xpconnect/src/XPCComponents.cpp b/js/xpconnect/src/XPCComponents.cpp
-index ad39de5..cf11c20 100644
+index ed7ab0a..609b73f 100644
 --- a/js/xpconnect/src/XPCComponents.cpp
 +++ b/js/xpconnect/src/XPCComponents.cpp
-@@ -4636,7 +4636,9 @@ nsXPCComponents::CanCreateWrapper(const nsIID * iid, char **_retval)
+@@ -4621,7 +4621,9 @@ nsXPCComponents::CanCreateWrapper(const nsIID * iid, char **_retval)
  NS_IMETHODIMP
  nsXPCComponents::CanCallMethod(const nsIID * iid, const PRUnichar *methodName, char **_retval)
  {
@@ -34,7 +34,7 @@ index ad39de5..cf11c20 100644
      *_retval = xpc_CheckAccessList(methodName, allowed);
      return NS_OK;
  }
-@@ -4645,7 +4647,9 @@ nsXPCComponents::CanCallMethod(const nsIID * iid, const PRUnichar *methodName, c
+@@ -4630,7 +4632,9 @@ nsXPCComponents::CanCallMethod(const nsIID * iid, const PRUnichar *methodName, c
  NS_IMETHODIMP
  nsXPCComponents::CanGetProperty(const nsIID * iid, const PRUnichar *propertyName, char **_retval)
  {
diff --git a/src/current-patches/firefox/alpha/0002-Make-Permissions-Manager-memory-only.patch b/src/current-patches/firefox/alpha/0002-Make-Permissions-Manager-memory-only.patch
index 682aa52..3dfb09b 100644
--- 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
@@ -1,7 +1,7 @@
-From 167d0ac069fa5d50f679636d690171b4fd4ac5a2 Mon Sep 17 00:00:00 2001
+From 59d440e340d37c95fe71396f420db13908df80d2 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
+Subject: [PATCH 02/20] Make Permissions Manager memory-only
 
 This patch exposes a pref 'permissions.memory_only' that properly isolates the
 permissions manager to memory, which is responsible for all user specified
@@ -16,10 +16,10 @@ https://trac.torproject.org/projects/tor/ticket/2950
  1 files changed, 31 insertions(+), 3 deletions(-)
 
 diff --git a/extensions/cookie/nsPermissionManager.cpp b/extensions/cookie/nsPermissionManager.cpp
-index cdfe21b..a7a0efb 100644
+index 94791ca..1f7bcbd 100644
 --- a/extensions/cookie/nsPermissionManager.cpp
 +++ b/extensions/cookie/nsPermissionManager.cpp
-@@ -58,6 +58,10 @@
+@@ -24,6 +24,10 @@
  #include "mozStorageHelper.h"
  #include "mozStorageCID.h"
  #include "nsXULAppAPI.h"
@@ -30,7 +30,7 @@ index cdfe21b..a7a0efb 100644
  
  static nsPermissionManager *gPermissionManager = nsnull;
  
-@@ -203,6 +207,11 @@ nsPermissionManager::Init()
+@@ -167,6 +171,11 @@ nsPermissionManager::Init()
      mObserverService->AddObserver(this, "profile-do-change", true);
    }
  
@@ -42,7 +42,7 @@ index cdfe21b..a7a0efb 100644
    if (IsChildProcess()) {
      // Get the permissions from the parent process
      InfallibleTArray<IPC::Permission> perms;
-@@ -251,8 +260,18 @@ nsPermissionManager::InitDB(bool aRemoveFile)
+@@ -215,8 +224,18 @@ nsPermissionManager::InitDB(bool aRemoveFile)
    if (!storage)
      return NS_ERROR_UNEXPECTED;
  
@@ -62,7 +62,7 @@ index cdfe21b..a7a0efb 100644
    NS_ENSURE_SUCCESS(rv, rv);
  
    bool ready;
-@@ -262,7 +281,11 @@ nsPermissionManager::InitDB(bool aRemoveFile)
+@@ -226,7 +245,11 @@ nsPermissionManager::InitDB(bool aRemoveFile)
      rv = permissionsFile->Remove(false);
      NS_ENSURE_SUCCESS(rv, rv);
  
@@ -75,7 +75,7 @@ index cdfe21b..a7a0efb 100644
      NS_ENSURE_SUCCESS(rv, rv);
  
      mDBConn->GetConnectionReady(&ready);
-@@ -794,7 +817,12 @@ NS_IMETHODIMP nsPermissionManager::Observe(nsISupports *aSubject, const char *aT
+@@ -758,7 +781,12 @@ NS_IMETHODIMP nsPermissionManager::Observe(nsISupports *aSubject, const char *aT
  {
    ENSURE_NOT_CHILD_PROCESS;
  
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
index cbcefc3..6873aee 100644
--- 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
@@ -1,7 +1,7 @@
-From 157823ac6088b718c12267593ae99003c71a29df Mon Sep 17 00:00:00 2001
+From 128b9ac61b08961bd606290c5a24231d4bf5622c 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.
+Subject: [PATCH 03/20] Make Intermediate Cert Store memory-only.
 
 This patch makes the intermediate SSL cert store exist in memory only.
 
@@ -12,10 +12,10 @@ https://trac.torproject.org/projects/tor/ticket/2949
  1 files changed, 14 insertions(+), 1 deletions(-)
 
 diff --git a/security/manager/ssl/src/nsNSSComponent.cpp b/security/manager/ssl/src/nsNSSComponent.cpp
-index 5204d75..60c0eb7 100644
+index bc49de9..0f66320 100644
 --- a/security/manager/ssl/src/nsNSSComponent.cpp
 +++ b/security/manager/ssl/src/nsNSSComponent.cpp
-@@ -1781,8 +1781,21 @@ nsNSSComponent::InitializeNSS(bool showWarningBox)
+@@ -1743,8 +1743,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;
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
index 9ee780b..3f01281 100644
--- 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
@@ -1,7 +1,7 @@
-From 0abaf15bf59d5d742511642c1f05127058c557b9 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.
+From edf66166ab881d3cafc73ffcc8d2ec4b78ef42ed Mon Sep 17 00:00:00 2001
+From: Mike Perry <mikeperry-git at torproject.org>
+Date: Tue, 28 Aug 2012 17:03:57 -0700
+Subject: [PATCH 04/20] Add a string-based cacheKey.
 
 Used for isolating cache according to same-origin policy.
 ---
@@ -11,10 +11,10 @@ Used for isolating cache according to same-origin policy.
  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
+index 96a8aef..b1c6f05 100644
 --- a/netwerk/base/public/nsICachingChannel.idl
 +++ b/netwerk/base/public/nsICachingChannel.idl
-@@ -98,6 +98,13 @@ interface nsICachingChannel : nsICacheInfoChannel
+@@ -66,6 +66,13 @@ interface nsICachingChannel : nsICacheInfoChannel
      attribute nsISupports cacheKey;
  
      /**
@@ -29,10 +29,10 @@ index 2da46d6..4ee5774 100644
       * 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 3f63c27..23edc3c 100644
+index 0c8b530..529857b 100644
 --- a/netwerk/protocol/http/nsHttpChannel.cpp
 +++ b/netwerk/protocol/http/nsHttpChannel.cpp
-@@ -2540,6 +2540,12 @@ nsHttpChannel::AssembleCacheKey(const char *spec, PRUint32 postID,
+@@ -2543,6 +2543,12 @@ nsHttpChannel::AssembleCacheKey(const char *spec, PRUint32 postID,
          cacheKey.Append(buf);
      }
  
@@ -45,7 +45,7 @@ index 3f63c27..23edc3c 100644
      if (!cacheKey.IsEmpty()) {
          cacheKey.AppendLiteral("uri=");
      }
-@@ -4910,6 +4916,22 @@ nsHttpChannel::SetCacheForOfflineUse(bool value)
+@@ -4881,6 +4887,22 @@ nsHttpChannel::SetCacheForOfflineUse(bool value)
  }
  
  NS_IMETHODIMP
@@ -69,17 +69,17 @@ index 3f63c27..23edc3c 100644
  {
      value = mOfflineCacheClientID;
 diff --git a/netwerk/protocol/http/nsHttpChannel.h b/netwerk/protocol/http/nsHttpChannel.h
-index c3935f5..5a61e21 100644
+index 333e884..3d06ffd 100644
 --- a/netwerk/protocol/http/nsHttpChannel.h
 +++ b/netwerk/protocol/http/nsHttpChannel.h
-@@ -311,6 +311,7 @@ private:
+@@ -302,6 +302,7 @@ private:
      nsCOMPtr<nsICacheEntryDescriptor> mOfflineCacheEntry;
      nsCacheAccessMode                 mOfflineCacheAccess;
      nsCString                         mOfflineCacheClientID;
 +    nsCString                         mCacheDomain;
  
-     // auth specific data
-     nsCOMPtr<nsIHttpChannelAuthProvider> mAuthProvider;
+     nsCOMPtr<nsILocalFile>            mProfileDirectory;
+ 
 -- 
 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
index cbfee28..bc7afbb 100644
--- 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
@@ -1,7 +1,7 @@
-From eb378defcebed631d488d2e20d1c3a063f9efce3 Mon Sep 17 00:00:00 2001
+From 20068bdda01cb2a1cd0f890fe2172887318ec20c 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.
+Subject: [PATCH 05/20] 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
@@ -17,10 +17,10 @@ on a better way. Until then, it is delta-darwinism for us.
  2 files changed, 35 insertions(+), 0 deletions(-)
 
 diff --git a/dom/plugins/base/nsPluginHost.cpp b/dom/plugins/base/nsPluginHost.cpp
-index a4e5982..9f63789 100644
+index 2877669..901fbb9 100644
 --- a/dom/plugins/base/nsPluginHost.cpp
 +++ b/dom/plugins/base/nsPluginHost.cpp
-@@ -1944,6 +1944,35 @@ bool nsPluginHost::IsDuplicatePlugin(nsPluginTag * aPluginTag)
+@@ -1876,6 +1876,35 @@ bool nsPluginHost::IsDuplicatePlugin(nsPluginTag * aPluginTag)
    return false;
  }
  
@@ -56,7 +56,7 @@ index a4e5982..9f63789 100644
  typedef NS_NPAPIPLUGIN_CALLBACK(char *, NP_GETMIMEDESCRIPTION)(void);
  
  nsresult nsPluginHost::ScanPluginsDirectory(nsIFile *pluginsDir,
-@@ -2077,6 +2106,10 @@ nsresult nsPluginHost::ScanPluginsDirectory(nsIFile *pluginsDir,
+@@ -2009,6 +2038,10 @@ nsresult nsPluginHost::ScanPluginsDirectory(nsIFile *pluginsDir,
        continue;
      }
  
@@ -68,10 +68,10 @@ index a4e5982..9f63789 100644
      if (!pluginTag) {
        nsPluginFile pluginFile(localfile);
 diff --git a/dom/plugins/base/nsPluginHost.h b/dom/plugins/base/nsPluginHost.h
-index e8b4ad5..cc783ce 100644
+index 036a102..1f7bd14 100644
 --- a/dom/plugins/base/nsPluginHost.h
 +++ b/dom/plugins/base/nsPluginHost.h
-@@ -284,6 +284,8 @@ private:
+@@ -247,6 +247,8 @@ private:
    // Loads all cached plugins info into mCachedPlugins
    nsresult ReadPluginInfo();
  
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
index 31c49e6..f2bd23d 100644
--- 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
@@ -1,7 +1,7 @@
-From 85b0de664cde83b0a0dff2ba973ace3f9aa6221b Mon Sep 17 00:00:00 2001
+From b967a0bf9803f887876635cb0c40c66e900dec35 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
+Subject: [PATCH 06/20] 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
@@ -11,10 +11,10 @@ other site prefs?).
  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
+index 81f974d..31597ac 100644
 --- a/toolkit/components/contentprefs/nsContentPrefService.js
 +++ b/toolkit/components/contentprefs/nsContentPrefService.js
-@@ -1242,7 +1242,7 @@ ContentPrefService.prototype = {
+@@ -1208,7 +1208,7 @@ ContentPrefService.prototype = {
  
      var dbConnection;
  
@@ -23,7 +23,7 @@ index 68a5561..effc33c 100644
        dbConnection = this._dbCreate(dbService, dbFile);
      else {
        try {
-@@ -1290,7 +1290,7 @@ ContentPrefService.prototype = {
+@@ -1256,7 +1256,7 @@ ContentPrefService.prototype = {
    },
  
    _dbCreate: function ContentPrefService__dbCreate(aDBService, aDBFile) {
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
index 4aa36dc..befce4a 100644
--- 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
@@ -1,7 +1,7 @@
-From fdc588cee6af4192360775caa4d2f0d25c8727bd Mon Sep 17 00:00:00 2001
+From a143df8693d811bde257a748ffc914aca38acb21 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.
+Subject: [PATCH 07/20] 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
diff --git a/src/current-patches/firefox/alpha/0008-Limit-device-and-system-specific-CSS-Media-Queries.patch b/src/current-patches/firefox/alpha/0008-Limit-device-and-system-specific-CSS-Media-Queries.patch
new file mode 100644
index 0000000..7276a46
--- /dev/null
+++ b/src/current-patches/firefox/alpha/0008-Limit-device-and-system-specific-CSS-Media-Queries.patch
@@ -0,0 +1,116 @@
+From 1bed42f67d1dd1a10693199448e495b155c44034 Mon Sep 17 00:00:00 2001
+From: Shondoit Walker <shondoit at gmail.com>
+Date: Mon, 4 Jun 2012 19:15:31 +0200
+Subject: [PATCH 08/20] Limit device- and system-specific CSS Media Queries
+
+This is done to address
+https://www.torproject.org/projects/torbrowser/design/#fingerprinting-linkability
+
+This also fixes bug #4795 by making queries still available for chrome windows,
+whilst returning nothing or non-device-specific values for web pages or extensions.
+---
+ layout/style/nsMediaFeatures.cpp |   42 ++++++++++++++++++++++++-------------
+ 1 files changed, 27 insertions(+), 15 deletions(-)
+
+diff --git a/layout/style/nsMediaFeatures.cpp b/layout/style/nsMediaFeatures.cpp
+index a814f30..c9785b9 100644
+--- a/layout/style/nsMediaFeatures.cpp
++++ b/layout/style/nsMediaFeatures.cpp
+@@ -98,6 +98,9 @@ GetDeviceContextFor(nsPresContext* aPresContext)
+ static nsSize
+ GetDeviceSize(nsPresContext* aPresContext)
+ {
++  if (!aPresContext->IsChrome()) {
++    return GetSize(aPresContext);
++  } else {
+     nsSize size;
+     if (aPresContext->IsRootPaginatedDocument())
+         // We want the page size, including unprintable areas and margins.
+@@ -108,6 +111,7 @@ GetDeviceSize(nsPresContext* aPresContext)
+         GetDeviceContextFor(aPresContext)->
+             GetDeviceSurfaceDimensions(size.width, size.height);
+     return size;
++  }
+ }
+ 
+ static nsresult
+@@ -151,17 +155,17 @@ static nsresult
+ GetDeviceOrientation(nsPresContext* aPresContext, const nsMediaFeature*,
+                      nsCSSValue& aResult)
+ {
+-    nsSize size = GetDeviceSize(aPresContext);
+-    PRInt32 orientation;
+-    if (size.width > size.height) {
+-        orientation = NS_STYLE_ORIENTATION_LANDSCAPE;
+-    } else {
+-        // Per spec, square viewports should be 'portrait'
+-        orientation = NS_STYLE_ORIENTATION_PORTRAIT;
+-    }
+-
+-    aResult.SetIntValue(orientation, eCSSUnit_Enumerated);
+-    return NS_OK;
++  nsSize size = GetDeviceSize(aPresContext);
++  PRInt32 orientation;
++  if (size.width > size.height) {
++      orientation = NS_STYLE_ORIENTATION_LANDSCAPE;
++  } else {
++      // Per spec, square viewports should be 'portrait'
++      orientation = NS_STYLE_ORIENTATION_PORTRAIT;
++  }
++
++  aResult.SetIntValue(orientation, eCSSUnit_Enumerated);
++  return NS_OK;
+ }
+ 
+ static nsresult
+@@ -279,8 +283,12 @@ static nsresult
+ GetDevicePixelRatio(nsPresContext* aPresContext, const nsMediaFeature*,
+                     nsCSSValue& aResult)
+ {
+-  float ratio = aPresContext->CSSPixelsToDevPixels(1.0f);
+-  aResult.SetFloatValue(ratio, eCSSUnit_Number);
++  if (aPresContext->IsChrome()) {
++    float ratio = aPresContext->CSSPixelsToDevPixels(1.0f);
++    aResult.SetFloatValue(ratio, eCSSUnit_Number);
++  } else {
++    aResult.SetFloatValue(1.0, eCSSUnit_Number);
++  }
+   return NS_OK;
+ }
+ 
+@@ -288,18 +296,21 @@ static nsresult
+ GetSystemMetric(nsPresContext* aPresContext, const nsMediaFeature* aFeature,
+                 nsCSSValue& aResult)
+ {
++  if (aPresContext->IsChrome()) {
+     NS_ABORT_IF_FALSE(aFeature->mValueType == nsMediaFeature::eBoolInteger,
+                       "unexpected type");
+     nsIAtom *metricAtom = *aFeature->mData.mMetric;
+     bool hasMetric = nsCSSRuleProcessor::HasSystemMetric(metricAtom);
+     aResult.SetIntValue(hasMetric ? 1 : 0, eCSSUnit_Integer);
+-    return NS_OK;
++  }
++  return NS_OK;
+ }
+ 
+ static nsresult
+ GetWindowsTheme(nsPresContext* aPresContext, const nsMediaFeature* aFeature,
+                 nsCSSValue& aResult)
+ {
++  if (aPresContext->IsChrome()) {
+     aResult.Reset();
+ #ifdef XP_WIN
+     PRUint8 windowsThemeId =
+@@ -318,7 +329,8 @@ GetWindowsTheme(nsPresContext* aPresContext, const nsMediaFeature* aFeature,
+         }
+     }
+ #endif
+-    return NS_OK;
++  }
++  return NS_OK;
+ }
+ 
+ /*
+-- 
+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
deleted file mode 100644
index 2eb308e..0000000
--- a/src/current-patches/firefox/alpha/0008-Provide-an-observer-event-to-close-persistent-connec.patch
+++ /dev/null
@@ -1,40 +0,0 @@
-From 1b4b8d3e22bf6d344b92953ad6e46d2d0577988b Mon Sep 17 00:00:00 2001
-From: Mike Perry <mikeperry-git at torproject.org>
-Date: Thu, 19 Jul 2012 19:02:39 -0700
-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 56bca0e..2d8afa0 100644
---- a/netwerk/protocol/http/nsHttpHandler.cpp
-+++ b/netwerk/protocol/http/nsHttpHandler.cpp
-@@ -344,6 +344,7 @@ nsHttpHandler::Init()
-         mObserverService->AddObserver(this, NS_XPCOM_SHUTDOWN_OBSERVER_ID, true);
-         mObserverService->AddObserver(this, "net:clear-active-logins", true);
-         mObserverService->AddObserver(this, NS_PRIVATE_BROWSING_SWITCH_TOPIC, true);
-+        mObserverService->AddObserver(this, "net:prune-all-connections", true);
-         mObserverService->AddObserver(this, "net:prune-dead-connections", true);
-         mObserverService->AddObserver(this, "net:failed-to-process-uri-content", true);
-     }
-@@ -1665,6 +1666,12 @@ nsHttpHandler::Observe(nsISupports *subject,
-         if (uri && mConnMgr)
-             mConnMgr->ReportFailedToProcess(uri);
-     }
-+    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-Limit-device-and-system-specific-CSS-Media-Queries.patch b/src/current-patches/firefox/alpha/0009-Limit-device-and-system-specific-CSS-Media-Queries.patch
deleted file mode 100644
index f92cc80..0000000
--- a/src/current-patches/firefox/alpha/0009-Limit-device-and-system-specific-CSS-Media-Queries.patch
+++ /dev/null
@@ -1,116 +0,0 @@
-From c4fbcc6ea2af3d7a97e0ab7687aa8921a02f243f Mon Sep 17 00:00:00 2001
-From: Shondoit Walker <shondoit at gmail.com>
-Date: Mon, 4 Jun 2012 19:15:31 +0200
-Subject: [PATCH 09/19] Limit device- and system-specific CSS Media Queries
-
-This is done to address
-https://www.torproject.org/projects/torbrowser/design/#fingerprinting-linkability
-
-This also fixes bug #4795 by making queries still available for chrome windows,
-whilst returning nothing or non-device-specific values for web pages or extensions.
----
- layout/style/nsMediaFeatures.cpp |   42 ++++++++++++++++++++++++-------------
- 1 files changed, 27 insertions(+), 15 deletions(-)
-
-diff --git a/layout/style/nsMediaFeatures.cpp b/layout/style/nsMediaFeatures.cpp
-index 6eca06e..25735e8 100644
---- a/layout/style/nsMediaFeatures.cpp
-+++ b/layout/style/nsMediaFeatures.cpp
-@@ -130,6 +130,9 @@ GetDeviceContextFor(nsPresContext* aPresContext)
- static nsSize
- GetDeviceSize(nsPresContext* aPresContext)
- {
-+  if (!aPresContext->IsChrome()) {
-+    return GetSize(aPresContext);
-+  } else {
-     nsSize size;
-     if (aPresContext->IsRootPaginatedDocument())
-         // We want the page size, including unprintable areas and margins.
-@@ -140,6 +143,7 @@ GetDeviceSize(nsPresContext* aPresContext)
-         GetDeviceContextFor(aPresContext)->
-             GetDeviceSurfaceDimensions(size.width, size.height);
-     return size;
-+  }
- }
- 
- static nsresult
-@@ -183,17 +187,17 @@ static nsresult
- GetDeviceOrientation(nsPresContext* aPresContext, const nsMediaFeature*,
-                      nsCSSValue& aResult)
- {
--    nsSize size = GetDeviceSize(aPresContext);
--    PRInt32 orientation;
--    if (size.width > size.height) {
--        orientation = NS_STYLE_ORIENTATION_LANDSCAPE;
--    } else {
--        // Per spec, square viewports should be 'portrait'
--        orientation = NS_STYLE_ORIENTATION_PORTRAIT;
--    }
--
--    aResult.SetIntValue(orientation, eCSSUnit_Enumerated);
--    return NS_OK;
-+  nsSize size = GetDeviceSize(aPresContext);
-+  PRInt32 orientation;
-+  if (size.width > size.height) {
-+      orientation = NS_STYLE_ORIENTATION_LANDSCAPE;
-+  } else {
-+      // Per spec, square viewports should be 'portrait'
-+      orientation = NS_STYLE_ORIENTATION_PORTRAIT;
-+  }
-+
-+  aResult.SetIntValue(orientation, eCSSUnit_Enumerated);
-+  return NS_OK;
- }
- 
- static nsresult
-@@ -311,8 +315,12 @@ static nsresult
- GetDevicePixelRatio(nsPresContext* aPresContext, const nsMediaFeature*,
-                     nsCSSValue& aResult)
- {
--  float ratio = aPresContext->CSSPixelsToDevPixels(1.0f);
--  aResult.SetFloatValue(ratio, eCSSUnit_Number);
-+  if (aPresContext->IsChrome()) {
-+    float ratio = aPresContext->CSSPixelsToDevPixels(1.0f);
-+    aResult.SetFloatValue(ratio, eCSSUnit_Number);
-+  } else {
-+    aResult.SetFloatValue(1.0, eCSSUnit_Number);
-+  }
-   return NS_OK;
- }
- 
-@@ -320,18 +328,21 @@ static nsresult
- GetSystemMetric(nsPresContext* aPresContext, const nsMediaFeature* aFeature,
-                 nsCSSValue& aResult)
- {
-+  if (aPresContext->IsChrome()) {
-     NS_ABORT_IF_FALSE(aFeature->mValueType == nsMediaFeature::eBoolInteger,
-                       "unexpected type");
-     nsIAtom *metricAtom = *aFeature->mData.mMetric;
-     bool hasMetric = nsCSSRuleProcessor::HasSystemMetric(metricAtom);
-     aResult.SetIntValue(hasMetric ? 1 : 0, eCSSUnit_Integer);
--    return NS_OK;
-+  }
-+  return NS_OK;
- }
- 
- static nsresult
- GetWindowsTheme(nsPresContext* aPresContext, const nsMediaFeature* aFeature,
-                 nsCSSValue& aResult)
- {
-+  if (aPresContext->IsChrome()) {
-     aResult.Reset();
- #ifdef XP_WIN
-     PRUint8 windowsThemeId =
-@@ -350,7 +361,8 @@ GetWindowsTheme(nsPresContext* aPresContext, const nsMediaFeature* aFeature,
-         }
-     }
- #endif
--    return NS_OK;
-+  }
-+  return NS_OK;
- }
- 
- /*
--- 
-1.7.5.4
-
diff --git a/src/current-patches/firefox/alpha/0009-Make-Download-manager-memory-only.patch b/src/current-patches/firefox/alpha/0009-Make-Download-manager-memory-only.patch
new file mode 100644
index 0000000..dfc54fd
--- /dev/null
+++ b/src/current-patches/firefox/alpha/0009-Make-Download-manager-memory-only.patch
@@ -0,0 +1,57 @@
+From 3788af0e0eee6639870de19a48178d9718542dc6 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 09/20] 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 0e846a0..42ca743 100644
+--- a/toolkit/components/downloads/nsDownloadManager.cpp
++++ b/toolkit/components/downloads/nsDownloadManager.cpp
+@@ -2005,7 +2005,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 =
+@@ -2082,7 +2082,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 5649eeb..1e7912b 100644
+--- a/toolkit/components/downloads/nsDownloadManager.h
++++ b/toolkit/components/downloads/nsDownloadManager.h
+@@ -54,7 +54,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/0010-Add-DDG-and-StartPage-to-Omnibox.patch b/src/current-patches/firefox/alpha/0010-Add-DDG-and-StartPage-to-Omnibox.patch
new file mode 100644
index 0000000..50feb06
--- /dev/null
+++ b/src/current-patches/firefox/alpha/0010-Add-DDG-and-StartPage-to-Omnibox.patch
@@ -0,0 +1,84 @@
+From 78271fc762f49a74b762afa62b69d62f55bc5ab9 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 10/20] 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/0010-Rebrand-Firefox-to-TorBrowser.patch b/src/current-patches/firefox/alpha/0010-Rebrand-Firefox-to-TorBrowser.patch
deleted file mode 100644
index b55d18d..0000000
--- a/src/current-patches/firefox/alpha/0010-Rebrand-Firefox-to-TorBrowser.patch
+++ /dev/null
@@ -1,50 +0,0 @@
-From 60d3c7f15f7be3a49b3f0301146c46a1c640d24a 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
deleted file mode 100644
index e8680ba..0000000
--- a/src/current-patches/firefox/alpha/0011-Make-Download-manager-memory-only.patch
+++ /dev/null
@@ -1,57 +0,0 @@
-From d4810f02097dd7a3cf2ba597ca9c0e0358bb74ad 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 1cdc022..71d89a1 100644
---- a/toolkit/components/downloads/nsDownloadManager.cpp
-+++ b/toolkit/components/downloads/nsDownloadManager.cpp
-@@ -2037,7 +2037,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 =
-@@ -2114,7 +2114,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 f3df6f7..7946973 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/0011-Make-nsICacheService.EvictEntries-synchronous.patch b/src/current-patches/firefox/alpha/0011-Make-nsICacheService.EvictEntries-synchronous.patch
new file mode 100644
index 0000000..9db46a6
--- /dev/null
+++ b/src/current-patches/firefox/alpha/0011-Make-nsICacheService.EvictEntries-synchronous.patch
@@ -0,0 +1,44 @@
+From fe734b407d4dca7e83cd08b918418b73af15fa8a 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 11/20] 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 709705e..d3af3fc 100644
+--- a/netwerk/cache/nsCacheService.cpp
++++ b/netwerk/cache/nsCacheService.cpp
+@@ -1460,10 +1460,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(nsnull);
++        gService->ClearDoomList();
++        (void) SyncWithCacheIOThread();
++    }
++    return r; 
+ }
+ 
+ NS_IMETHODIMP nsCacheService::GetCacheIOTarget(nsIEventTarget * *aCacheIOTarget)
+-- 
+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
deleted file mode 100644
index 890c6fc..0000000
--- a/src/current-patches/firefox/alpha/0012-Add-DDG-and-StartPage-to-Omnibox.patch
+++ /dev/null
@@ -1,84 +0,0 @@
-From 3bb5867bd77a042b867d890e72c8dfbc236de1a8 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/0012-Make-Tor-Browser-exit-when-not-launched-from-Vidalia.patch b/src/current-patches/firefox/alpha/0012-Make-Tor-Browser-exit-when-not-launched-from-Vidalia.patch
new file mode 100644
index 0000000..a3d06cc
--- /dev/null
+++ b/src/current-patches/firefox/alpha/0012-Make-Tor-Browser-exit-when-not-launched-from-Vidalia.patch
@@ -0,0 +1,45 @@
+From 4d49aed78e8185f590060be473ab7e2013e6a792 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 12/20] 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 79ab155..84f747c 100644
+--- a/browser/base/content/browser.js
++++ b/browser/base/content/browser.js
+@@ -995,6 +995,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/0013-Limit-the-number-of-fonts-per-document.patch b/src/current-patches/firefox/alpha/0013-Limit-the-number-of-fonts-per-document.patch
new file mode 100644
index 0000000..cf7aac9
--- /dev/null
+++ b/src/current-patches/firefox/alpha/0013-Limit-the-number-of-fonts-per-document.patch
@@ -0,0 +1,225 @@
+From a7917e7ceb3aebfc20f56fa64ec9780dd32f78e3 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 13/20] 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 f49d9f3..53f0b12 100644
+--- a/layout/base/nsPresContext.cpp
++++ b/layout/base/nsPresContext.cpp
+@@ -63,6 +63,8 @@
+ #include "FrameLayerBuilder.h"
+ #include "nsDOMMediaQueryList.h"
+ #include "nsSMILAnimationController.h"
++#include "nsString.h"
++#include "nsUnicharUtils.h"
+ 
+ #ifdef IBMBIDI
+ #include "nsBidiPresUtils.h"
+@@ -740,6 +742,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 =
+@@ -1363,6 +1369,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 0c42c6b..f37c7a2 100644
+--- a/layout/base/nsPresContext.h
++++ b/layout/base/nsPresContext.h
+@@ -514,6 +514,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.
+@@ -1174,6 +1181,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 01613b8..fb19eba 100644
+--- a/layout/style/nsRuleNode.cpp
++++ b/layout/style/nsRuleNode.cpp
+@@ -3387,14 +3387,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
+@@ -3408,9 +3409,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)) {
+@@ -3446,6 +3451,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/0013-Make-nsICacheService.EvictEntries-synchronous.patch b/src/current-patches/firefox/alpha/0013-Make-nsICacheService.EvictEntries-synchronous.patch
deleted file mode 100644
index 6ae486c..0000000
--- a/src/current-patches/firefox/alpha/0013-Make-nsICacheService.EvictEntries-synchronous.patch
+++ /dev/null
@@ -1,44 +0,0 @@
-From 94a5a512ea1a66ea1c1a9a3b57c25b13ae19aea6 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 801507e..c37bd7c 100644
---- a/netwerk/cache/nsCacheService.cpp
-+++ b/netwerk/cache/nsCacheService.cpp
-@@ -1530,10 +1530,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
deleted file mode 100644
index f085502..0000000
--- a/src/current-patches/firefox/alpha/0014-Prevent-WebSocket-DNS-leak.patch
+++ /dev/null
@@ -1,132 +0,0 @@
-From 5c680fadbae54ff9f0d1817823679cd961049ceb 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 7a5ee7b..7f68798 100644
---- a/netwerk/protocol/websocket/WebSocketChannel.cpp
-+++ b/netwerk/protocol/websocket/WebSocketChannel.cpp
-@@ -1897,8 +1897,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/0014-Provide-an-observer-event-to-close-persistent-connec.patch b/src/current-patches/firefox/alpha/0014-Provide-an-observer-event-to-close-persistent-connec.patch
new file mode 100644
index 0000000..9d50822
--- /dev/null
+++ b/src/current-patches/firefox/alpha/0014-Provide-an-observer-event-to-close-persistent-connec.patch
@@ -0,0 +1,40 @@
+From f67aed29f53ef17aad69cba6d008df4f2d09d231 Mon Sep 17 00:00:00 2001
+From: Mike Perry <mikeperry-git at torproject.org>
+Date: Tue, 28 Aug 2012 18:03:22 -0700
+Subject: [PATCH 14/20] 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 8b5533f..3647edc 100644
+--- a/netwerk/protocol/http/nsHttpHandler.cpp
++++ b/netwerk/protocol/http/nsHttpHandler.cpp
+@@ -307,6 +307,7 @@ nsHttpHandler::Init()
+         mObserverService->AddObserver(this, NS_XPCOM_SHUTDOWN_OBSERVER_ID, true);
+         mObserverService->AddObserver(this, "net:clear-active-logins", true);
+         mObserverService->AddObserver(this, "net:prune-dead-connections", true);
++        mObserverService->AddObserver(this, "net:prune-all-connections", true);
+         mObserverService->AddObserver(this, "net:failed-to-process-uri-content", true);
+     }
+  
+@@ -1625,6 +1626,12 @@ nsHttpHandler::Observe(nsISupports *subject,
+         if (uri && mConnMgr)
+             mConnMgr->ReportFailedToProcess(uri);
+     }
++    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/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
deleted file mode 100644
index 472bab2..0000000
--- a/src/current-patches/firefox/alpha/0015-Make-Tor-Browser-exit-when-not-launched-from-Vidalia.patch
+++ /dev/null
@@ -1,45 +0,0 @@
-From 6c15c52f930e7c7bccca0270219d87433c6d4dc8 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 fa89e20..e504b88 100644
---- a/browser/base/content/browser.js
-+++ b/browser/base/content/browser.js
-@@ -1243,6 +1243,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/0015-Rebrand-Firefox-to-TorBrowser.patch b/src/current-patches/firefox/alpha/0015-Rebrand-Firefox-to-TorBrowser.patch
new file mode 100644
index 0000000..2829fa2
--- /dev/null
+++ b/src/current-patches/firefox/alpha/0015-Rebrand-Firefox-to-TorBrowser.patch
@@ -0,0 +1,59 @@
+From 883793ca836ce271f65ea6c31d27f41c7240ca59 Mon Sep 17 00:00:00 2001
+From: Mike Perry <mikeperry-git at torproject.org>
+Date: Tue, 28 Aug 2012 18:05:11 -0700
+Subject: [PATCH 15/20] 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 55f3f18..33102b0 100644
+--- a/browser/branding/official/configure.sh
++++ b/browser/branding/official/configure.sh
+@@ -2,5 +2,5 @@
+ # License, v. 2.0. If a copy of the MPL was not distributed with this
+ # file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ 
+-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 8e7f6c9..76e405d 100644
+--- a/browser/branding/official/locales/en-US/brand.dtd
++++ b/browser/branding/official/locales/en-US/brand.dtd
+@@ -2,7 +2,7 @@
+    - License, v. 2.0. If a copy of the MPL was not distributed with this
+    - file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
+ 
+-<!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 4a67c55..9ae168e 100644
+--- a/browser/branding/official/locales/en-US/brand.properties
++++ b/browser/branding/official/locales/en-US/brand.properties
+@@ -2,9 +2,9 @@
+ # License, v. 2.0. If a copy of the MPL was not distributed with this
+ # file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ 
+-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/0016-Limit-the-number-of-fonts-per-document.patch b/src/current-patches/firefox/alpha/0016-Limit-the-number-of-fonts-per-document.patch
deleted file mode 100644
index 295a832..0000000
--- a/src/current-patches/firefox/alpha/0016-Limit-the-number-of-fonts-per-document.patch
+++ /dev/null
@@ -1,225 +0,0 @@
-From 56f0543f8bc32d5f22b84d6bd4f59a0f93ef815a 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 5c8b974..c567111 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"
-@@ -774,6 +776,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 =
-@@ -1383,6 +1389,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 9d58bcf..08b7766 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.
-@@ -1195,6 +1202,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 294a41c..c9313bc 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/0016-Prevent-WebSocket-DNS-leak.patch b/src/current-patches/firefox/alpha/0016-Prevent-WebSocket-DNS-leak.patch
new file mode 100644
index 0000000..bde4e62
--- /dev/null
+++ b/src/current-patches/firefox/alpha/0016-Prevent-WebSocket-DNS-leak.patch
@@ -0,0 +1,133 @@
+From 2bf15d1165f2d7aad286ab1591db318682ef4df2 Mon Sep 17 00:00:00 2001
+From: Mike Perry <mikeperry-git at torproject.org>
+Date: Tue, 28 Aug 2012 18:07:37 -0700
+Subject: [PATCH 16/20] 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 a59b6e3..d54ebf3 100644
+--- a/netwerk/dns/nsDNSService2.cpp
++++ b/netwerk/dns/nsDNSService2.cpp
+@@ -373,6 +373,7 @@ nsDNSService::Init()
+     bool     enableIDN        = true;
+     bool     disableIPv6      = false;
+     bool     disablePrefetch  = false;
++    bool     disableDNS       = false;
+     int      proxyType        = nsIProtocolProxyService::PROXYCONFIG_DIRECT;
+     
+     nsAdoptingCString ipv4OnlyDomains;
+@@ -398,6 +399,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) {
+@@ -418,7 +423,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);
+         }
+     }
+ 
+@@ -447,6 +452,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);
+@@ -572,6 +578,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;
+         localDomain = mLocalDomains.GetEntry(hostname);
+@@ -668,6 +682,14 @@ nsDNSService::Resolve(const nsACString &hostname,
+     }
+     NS_ENSURE_TRUE(res, NS_ERROR_OFFLINE);
+ 
++    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?
++        }
++    }
++
+     const nsACString *hostPtr = &hostname;
+ 
+     if (localDomain) {
+diff --git a/netwerk/dns/nsDNSService2.h b/netwerk/dns/nsDNSService2.h
+index b60572c..3cf00e9 100644
+--- a/netwerk/dns/nsDNSService2.h
++++ b/netwerk/dns/nsDNSService2.h
+@@ -40,5 +40,6 @@ private:
+     bool                      mDisableIPv6;
+     bool                      mDisablePrefetch;
+     bool                      mFirstTime;
++    bool                      mDisableDNS;
+     nsTHashtable<nsCStringHashKey> mLocalDomains;
+ };
+diff --git a/netwerk/protocol/websocket/WebSocketChannel.cpp b/netwerk/protocol/websocket/WebSocketChannel.cpp
+index a87e1e0..4bee667 100644
+--- a/netwerk/protocol/websocket/WebSocketChannel.cpp
++++ b/netwerk/protocol/websocket/WebSocketChannel.cpp
+@@ -1897,8 +1897,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/0017-Randomize-HTTP-request-order-and-pipeline-depth.patch b/src/current-patches/firefox/alpha/0017-Randomize-HTTP-request-order-and-pipeline-depth.patch
index 96df3f7..8550cdd 100644
--- 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
@@ -1,7 +1,7 @@
-From 1777a19229cf111156aeae078344a27f34c953c3 Mon Sep 17 00:00:00 2001
+From fc8110586a4777dfd3cb93eb5544535f6bd7b0f3 Mon Sep 17 00:00:00 2001
 From: Mike Perry <mikeperry-git at torproject.org>
-Date: Fri, 20 Jul 2012 18:13:44 -0700
-Subject: [PATCH 17/21] Randomize HTTP request order and pipeline depth.
+Date: Tue, 28 Aug 2012 18:08:27 -0700
+Subject: [PATCH 17/20] Randomize HTTP request order and pipeline depth.
 
 This is an experimental defense against
 http://lorre.uni.lu/~andriy/papers/acmccs-wpes11-fingerprinting.pdf
@@ -24,19 +24,19 @@ request order (though SPDY is still disabled by default in TBB).
  2 files changed, 57 insertions(+), 4 deletions(-)
 
 diff --git a/netwerk/protocol/http/nsHttpConnectionMgr.cpp b/netwerk/protocol/http/nsHttpConnectionMgr.cpp
-index 5336c7d..b94ee31 100644
+index 60a6807..334c5fb 100644
 --- a/netwerk/protocol/http/nsHttpConnectionMgr.cpp
 +++ b/netwerk/protocol/http/nsHttpConnectionMgr.cpp
-@@ -52,6 +52,8 @@
+@@ -20,6 +20,8 @@
  #include "prnetdb.h"
  #include "mozilla/Telemetry.h"
  
 +#include <stdlib.h>
 +
  using namespace mozilla;
+ using namespace mozilla::net;
  
- // defined by the socket transport service while active
-@@ -70,15 +72,39 @@ InsertTransactionSorted(nsTArray<nsHttpTransaction*> &pendingQ, nsHttpTransactio
+@@ -39,15 +41,39 @@ InsertTransactionSorted(nsTArray<nsHttpTransaction*> &pendingQ, nsHttpTransactio
      // insert into queue with smallest valued number first.  search in reverse
      // order under the assumption that many of the existing transactions will
      // have the same priority (usually 0).
@@ -80,7 +80,7 @@ index 5336c7d..b94ee31 100644
  }
  
  //-----------------------------------------------------------------------------
-@@ -101,6 +127,12 @@ nsHttpConnectionMgr::nsHttpConnectionMgr()
+@@ -70,6 +96,12 @@ nsHttpConnectionMgr::nsHttpConnectionMgr()
      mCT.Init();
      mAlternateProtocolHash.Init(16);
      mSpdyPreferredHash.Init();
@@ -93,7 +93,7 @@ index 5336c7d..b94ee31 100644
  }
  
  nsHttpConnectionMgr::~nsHttpConnectionMgr()
-@@ -1115,6 +1147,19 @@ nsHttpConnectionMgr::AtActiveConnectionLimit(nsConnectionEntry *ent, PRUint8 cap
+@@ -1153,6 +1185,19 @@ nsHttpConnectionMgr::AtActiveConnectionLimit(nsConnectionEntry *ent, PRUint8 cap
          maxPersistConns = mMaxPersistConnsPerHost;
      }
  
@@ -113,7 +113,7 @@ index 5336c7d..b94ee31 100644
      // use >= just to be safe
      bool result = (totalCount >= maxConns) || ( (caps & NS_HTTP_ALLOW_KEEPALIVE) &&
                                                (persistCount >= maxPersistConns) );
-@@ -1250,6 +1295,11 @@ nsHttpConnectionMgr::AddToShortestPipeline(nsConnectionEntry *ent,
+@@ -1319,6 +1364,11 @@ nsHttpConnectionMgr::AddToShortestPipeline(nsConnectionEntry *ent,
  
      maxdepth = PR_MIN(maxdepth, depthLimit);
  
@@ -126,10 +126,10 @@ index 5336c7d..b94ee31 100644
          return false;
  
 diff --git a/netwerk/protocol/http/nsHttpConnectionMgr.h b/netwerk/protocol/http/nsHttpConnectionMgr.h
-index 9f36345..6e12015 100644
+index 9e65da0..07c93b1 100644
 --- a/netwerk/protocol/http/nsHttpConnectionMgr.h
 +++ b/netwerk/protocol/http/nsHttpConnectionMgr.h
-@@ -54,6 +54,7 @@
+@@ -22,6 +22,7 @@
  #include "nsIObserver.h"
  #include "nsITimer.h"
  #include "nsIX509Cert3.h"
@@ -137,7 +137,7 @@ index 9f36345..6e12015 100644
  
  class nsHttpPipeline;
  
-@@ -562,6 +563,8 @@ private:
+@@ -579,6 +580,8 @@ private:
      PRUint64 mTimeOfNextWakeUp;
      // Timer for next pruning of dead connections.
      nsCOMPtr<nsITimer> mTimer;
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
index 0ef12a9..e09a3bf 100644
--- 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
@@ -1,37 +1,32 @@
-From 0beb4d8440fd7ff415ac3207d010947c9bfceaf2 Mon Sep 17 00:00:00 2001
+From c60d40f3ead79d91128f28682dc94fc626c45110 Mon Sep 17 00:00:00 2001
 From: Mike Perry <mikeperry-git at torproject.org>
-Date: Fri, 20 Jul 2012 18:29:08 -0700
-Subject: [PATCH 18/19] Adapt Steven Michaud's Mac crashfix patch
+Date: Tue, 28 Aug 2012 18:22:32 -0700
+Subject: [PATCH 18/20] 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               |   28 +++++++++++------
- widget/gtk2/nsDragService.cpp             |    4 +-
- widget/gtk2/nsWindow.cpp                  |    3 +-
- 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, 178 insertions(+), 47 deletions(-)
- create mode 100644 widget/nsPIDragService.idl
- create mode 100644 widget/windows/nsPIDragServiceWindows.idl
+ widget/Makefile.in                     |    1 +
+ widget/cocoa/nsChildView.mm            |   28 ++++++++++++++++++----------
+ widget/gtk2/nsDragService.cpp          |    9 +++++----
+ widget/nsIDragService.idl              |    4 +---
+ 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/xpwidgets/nsBaseDragService.cpp |   16 +++++++++++++++-
+ widget/xpwidgets/nsBaseDragService.h   |    9 ++++-----
+ 12 files changed, 85 insertions(+), 48 deletions(-)
 
 diff --git a/widget/Makefile.in b/widget/Makefile.in
-index 4a3405b..4c105a4 100644
+index f1df966..eb6eec2 100644
 --- a/widget/Makefile.in
 +++ b/widget/Makefile.in
-@@ -138,6 +138,7 @@ XPIDLSRCS	= \
+@@ -105,6 +105,7 @@ XPIDLSRCS	= \
  		nsIClipboardDragDropHooks.idl \
  		nsIClipboardDragDropHookList.idl \
  		nsIDragSession.idl \
@@ -40,10 +35,10 @@ index 4a3405b..4c105a4 100644
  		nsIFormatConverter.idl \
  		nsIClipboard.idl \
 diff --git a/widget/cocoa/nsChildView.mm b/widget/cocoa/nsChildView.mm
-index 6f89719..33c16ff 100644
+index 9cbc1e3..92b93cb 100644
 --- a/widget/cocoa/nsChildView.mm
 +++ b/widget/cocoa/nsChildView.mm
-@@ -4555,11 +4555,12 @@ NSEvent* gLastDragMouseDownEvent = nil;
+@@ -4513,11 +4513,12 @@ NSEvent* gLastDragMouseDownEvent = nil;
    if (!dragService) {
      dragService = do_GetService(kDragServiceContractID);
    }
@@ -57,7 +52,7 @@ index 6f89719..33c16ff 100644
    }
  }
  
-@@ -4580,11 +4581,13 @@ NSEvent* gLastDragMouseDownEvent = nil;
+@@ -4538,11 +4539,13 @@ NSEvent* gLastDragMouseDownEvent = nil;
    }
  
    if (mDragService) {
@@ -76,7 +71,7 @@ index 6f89719..33c16ff 100644
  
      // XXX: dropEffect should be updated per |operation|. 
      // As things stand though, |operation| isn't well handled within "our"
-@@ -4595,10 +4598,15 @@ NSEvent* gLastDragMouseDownEvent = nil;
+@@ -4553,10 +4556,15 @@ NSEvent* gLastDragMouseDownEvent = nil;
      // value for NSDragOperationGeneric that is passed by other applications.
      // All that said, NSDragOperationNone is still reliable.
      if (operation == NSDragOperationNone) {
@@ -97,19 +92,21 @@ index 6f89719..33c16ff 100644
  
      mDragService->EndDragSession(true);
 diff --git a/widget/gtk2/nsDragService.cpp b/widget/gtk2/nsDragService.cpp
-index 16f9764..0f078b6 100644
+index e0ff5d6..2c10c10 100644
 --- a/widget/gtk2/nsDragService.cpp
 +++ b/widget/gtk2/nsDragService.cpp
-@@ -285,7 +285,7 @@ OnSourceGrabEventAfter(GtkWidget *widget, GdkEvent *event, gpointer user_data)
-     // the NS_DRAGDROP_END event.
-     nsDragService *dragService = static_cast<nsDragService*>(user_data);
-     dragService->
--        SetDragEndPoint(nsIntPoint(event->motion.x_root, event->motion.y_root));
-+        SetDragEndPoint(event->motion.x_root, event->motion.y_root);
- 
-     MotionEventData *data = new MotionEventData(widget, event);
- 
-@@ -1404,7 +1404,7 @@ nsDragService::SourceEndDragSession(GdkDragContext *aContext,
+@@ -239,8 +239,8 @@ OnSourceGrabEventAfter(GtkWidget *widget, GdkEvent *event, gpointer user_data)
+         // Update the cursor position.  The last of these recorded gets used for
+         // the NS_DRAGDROP_END event.
+         nsDragService *dragService = static_cast<nsDragService*>(user_data);
+-        dragService->SetDragEndPoint(nsIntPoint(event->motion.x_root,
+-                                                event->motion.y_root));
++        dragService->SetDragEndPoint(event->motion.x_root,
++                                     event->motion.y_root);
+     } else if (sMotionEvent && (event->type != GDK_KEY_PRESS ||
+                                 event->type != GDK_KEY_RELEASE)) {
+         // Update modifier state from keypress events.
+@@ -1348,7 +1348,7 @@ nsDragService::SourceEndDragSession(GdkDragContext *aContext,
          GdkDisplay* display = gdk_display_get_default();
          if (display) {
              gdk_display_get_pointer(display, NULL, &x, &y, NULL);
@@ -118,26 +115,22 @@ index 16f9764..0f078b6 100644
          }
      }
  
-diff --git a/widget/gtk2/nsWindow.cpp b/widget/gtk2/nsWindow.cpp
-index 07a1ae2..664293d 100644
---- a/widget/gtk2/nsWindow.cpp
-+++ b/widget/gtk2/nsWindow.cpp
-@@ -3447,8 +3447,9 @@ nsWindow::OnDragDropEvent(GtkWidget *aWidget,
-     // get our drag context
-     nsCOMPtr<nsIDragService> dragService = do_GetService(kCDragServiceCID);
-     nsDragService *dragServiceGTK = static_cast<nsDragService*>(dragService.get());
-+    nsIntPoint end = nsIntPoint(aX, aY) + WidgetToScreenOffset();
- 
--    dragServiceGTK->SetDragEndPoint(nsIntPoint(aX, aY) + WidgetToScreenOffset());
-+    dragServiceGTK->SetDragEndPoint(end.x, end.y);
- 
-     nscoord retx = 0;
-     nscoord rety = 0;
+@@ -1765,8 +1765,9 @@ nsDragService::ScheduleDropEvent(nsWindow *aWindow,
+         NS_WARNING("Additional drag drop ignored");
+         return FALSE;        
+     }
++    nsIntPoint pt = aWindowPoint + aWindow->WidgetToScreenOffset();
+ 
+-    SetDragEndPoint(aWindowPoint + aWindow->WidgetToScreenOffset());
++    SetDragEndPoint(pt.x, pt.y);
+ 
+     // We'll reply with gtk_drag_finish().
+     return TRUE;
 diff --git a/widget/nsIDragService.idl b/widget/nsIDragService.idl
-index e42c578..ef8c46f 100644
+index 196761e..c0565bb 100644
 --- a/widget/nsIDragService.idl
 +++ b/widget/nsIDragService.idl
-@@ -48,7 +48,7 @@ interface nsIDOMDragEvent;
+@@ -15,7 +15,7 @@ interface nsIDOMDragEvent;
  interface nsIDOMDataTransfer;
  interface nsISelection;
  
@@ -146,7 +139,7 @@ index e42c578..ef8c46f 100644
  interface nsIDragService : nsISupports
  {
    const long DRAGDROP_ACTION_NONE = 0;
-@@ -145,8 +145,6 @@ interface nsIDragService : nsISupports
+@@ -112,8 +112,6 @@ interface nsIDragService : nsISupports
     */
    void suppress();
    void unsuppress();
@@ -155,65 +148,11 @@ index e42c578..ef8c46f 100644
  };
  
  
-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
+index 393be99..56d0312 100644
 --- a/widget/qt/nsDragService.h
 +++ b/widget/qt/nsDragService.h
-@@ -50,6 +50,8 @@ public:
+@@ -17,6 +17,8 @@ public:
      NS_DECL_ISUPPORTS
      NS_DECL_NSIDRAGSERVICE
  
@@ -223,10 +162,10 @@ index 5a3e5bb..50dcfac 100644
  
  private:
 diff --git a/widget/windows/Makefile.in b/widget/windows/Makefile.in
-index df811ac..8d5ea4b 100644
+index 160c941..12f6dc7 100644
 --- a/widget/windows/Makefile.in
 +++ b/widget/windows/Makefile.in
-@@ -120,6 +120,10 @@ ifdef MOZ_ENABLE_D3D10_LAYER
+@@ -88,6 +88,10 @@ ifdef MOZ_ENABLE_D3D10_LAYER
  DEFINES		+= -DMOZ_ENABLE_D3D10_LAYER
  endif
  
@@ -238,10 +177,10 @@ index df811ac..8d5ea4b 100644
    ../xpwidgets/$(LIB_PREFIX)xpwidgets_s.$(LIB_SUFFIX) \
    $(NULL)
 diff --git a/widget/windows/nsDragService.cpp b/widget/windows/nsDragService.cpp
-index ec4b16e..bbae112 100644
+index efe8ce1..62e7d97 100644
 --- a/widget/windows/nsDragService.cpp
 +++ b/widget/windows/nsDragService.cpp
-@@ -97,6 +97,8 @@ nsDragService::~nsDragService()
+@@ -60,6 +60,8 @@ nsDragService::~nsDragService()
    NS_IF_RELEASE(mDataObject);
  }
  
@@ -250,7 +189,7 @@ index ec4b16e..bbae112 100644
  bool
  nsDragService::CreateDragImage(nsIDOMNode *aDOMNode,
                                 nsIScriptableRegion *aRegion,
-@@ -347,7 +349,7 @@ nsDragService::StartInvokingDragSession(IDataObject * aDataObj,
+@@ -305,7 +307,7 @@ nsDragService::StartInvokingDragSession(IDataObject * aDataObj,
    POINT cpos;
    cpos.x = GET_X_LPARAM(pos);
    cpos.y = GET_Y_LPARAM(pos);
@@ -259,7 +198,7 @@ index ec4b16e..bbae112 100644
    EndDragSession(true);
  
    mDoingDrag = false;
-@@ -465,25 +467,26 @@ nsDragService::GetData(nsITransferable * aTransferable, PRUint32 anItem)
+@@ -423,25 +425,26 @@ nsDragService::GetData(nsITransferable * aTransferable, PRUint32 anItem)
  
  //---------------------------------------------------------
  NS_IMETHODIMP
@@ -291,10 +230,10 @@ index ec4b16e..bbae112 100644
  
  //-------------------------------------------------------------------------
 diff --git a/widget/windows/nsDragService.h b/widget/windows/nsDragService.h
-index 87d6cc9..04c8746 100644
+index 93b5480..bd2125b 100644
 --- a/widget/windows/nsDragService.h
 +++ b/widget/windows/nsDragService.h
-@@ -39,6 +39,7 @@
+@@ -7,6 +7,7 @@
  #define nsDragService_h__
  
  #include "nsBaseDragService.h"
@@ -302,7 +241,7 @@ index 87d6cc9..04c8746 100644
  #include <windows.h>
  #include <shlobj.h>
  
-@@ -52,12 +53,15 @@ class  nsString;
+@@ -20,12 +21,15 @@ class  nsString;
   * Native Win32 DragService wrapper
   */
  
@@ -320,7 +259,7 @@ index 87d6cc9..04c8746 100644
    // nsIDragService
    NS_IMETHOD InvokeDragSession(nsIDOMNode *aDOMNode,
                                 nsISupportsArray *anArrayTransferables,
-@@ -71,13 +75,9 @@ public:
+@@ -39,13 +43,9 @@ public:
    NS_IMETHOD EndDragSession(bool aDoneDrag);
  
    // native impl.
@@ -335,10 +274,10 @@ index 87d6cc9..04c8746 100644
    nsDataObjCollection* GetDataObjCollection(IDataObject * aDataObj);
  
 diff --git a/widget/windows/nsNativeDragSource.cpp b/widget/windows/nsNativeDragSource.cpp
-index e51101e..0fe6ffe 100644
+index e981ff9..e34613f 100644
 --- a/widget/windows/nsNativeDragSource.cpp
 +++ b/widget/windows/nsNativeDragSource.cpp
-@@ -42,7 +42,7 @@
+@@ -10,7 +10,7 @@
  #include "nsIServiceManager.h"
  #include "nsToolkit.h"
  #include "nsWidgetsCID.h"
@@ -347,7 +286,7 @@ index e51101e..0fe6ffe 100644
  
  static NS_DEFINE_IID(kCDragServiceCID,  NS_DRAGSERVICE_CID);
  
-@@ -101,9 +101,10 @@ STDMETHODIMP
+@@ -69,9 +69,10 @@ STDMETHODIMP
  nsNativeDragSource::QueryContinueDrag(BOOL fEsc, DWORD grfKeyState)
  {
    nsCOMPtr<nsIDragService> dragService = do_GetService(kCDragServiceCID);
@@ -361,13 +300,13 @@ index e51101e..0fe6ffe 100644
  
    if (fEsc) {
 diff --git a/widget/windows/nsNativeDragTarget.cpp b/widget/windows/nsNativeDragTarget.cpp
-index 3362ca6..a69817c 100644
+index da1cd1f..96303c3 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);
+@@ -172,7 +172,11 @@ nsNativeDragTarget::DispatchDragDropEvent(PRUint32 aEventType, POINTL aPT)
+   nsModifierKeyState modifierKeyState;
+   modifierKeyState.InitInputEvent(event);
+ 
 -  event.inputSource = static_cast<nsBaseDragService*>(mDragService)->GetInputSource();
 +  event.inputSource = 0;
 +  nsCOMPtr<nsPIDragService> dragServicePriv = do_QueryInterface(mDragService);
@@ -377,7 +316,7 @@ index 3362ca6..a69817c 100644
  
    mWindow->DispatchEvent(&event, status);
  }
-@@ -292,9 +296,8 @@ nsNativeDragTarget::DragEnter(LPDATAOBJECT pIDataSource,
+@@ -259,9 +263,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.
@@ -389,7 +328,7 @@ index 3362ca6..a69817c 100644
  
    // 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,
+@@ -399,8 +402,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)
@@ -400,7 +339,7 @@ index 3362ca6..a69817c 100644
  
    // 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,
+@@ -424,11 +427,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)
@@ -420,63 +359,11 @@ index 3362ca6..a69817c 100644
    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
+index 1b2ef0d..627ebd2 100644
 --- a/widget/xpwidgets/nsBaseDragService.cpp
 +++ b/widget/xpwidgets/nsBaseDragService.cpp
-@@ -88,7 +88,7 @@ nsBaseDragService::~nsBaseDragService()
+@@ -55,7 +55,7 @@ nsBaseDragService::~nsBaseDragService()
  {
  }
  
@@ -485,7 +372,7 @@ index 342a036..87e28f7 100644
  
  //---------------------------------------------------------
  NS_IMETHODIMP
-@@ -436,6 +436,20 @@ nsBaseDragService::DragMoved(PRInt32 aX, PRInt32 aY)
+@@ -403,6 +403,20 @@ nsBaseDragService::DragMoved(PRInt32 aX, PRInt32 aY)
    return NS_OK;
  }
  
@@ -507,10 +394,10 @@ index 342a036..87e28f7 100644
  GetPresShellForContent(nsIDOMNode* aDOMNode)
  {
 diff --git a/widget/xpwidgets/nsBaseDragService.h b/widget/xpwidgets/nsBaseDragService.h
-index 290c0cb..2ceac2b 100644
+index 006747f..d825b53 100644
 --- a/widget/xpwidgets/nsBaseDragService.h
 +++ b/widget/xpwidgets/nsBaseDragService.h
-@@ -39,6 +39,7 @@
+@@ -7,6 +7,7 @@
  #define nsBaseDragService_h__
  
  #include "nsIDragService.h"
@@ -518,7 +405,7 @@ index 290c0cb..2ceac2b 100644
  #include "nsIDragSession.h"
  #include "nsITransferable.h"
  #include "nsISupportsArray.h"
-@@ -64,6 +65,7 @@ class nsICanvasElementExternal;
+@@ -32,6 +33,7 @@ class nsICanvasElementExternal;
   */
  
  class nsBaseDragService : public nsIDragService,
@@ -526,7 +413,7 @@ index 290c0cb..2ceac2b 100644
                            public nsIDragSession
  {
  
-@@ -74,14 +76,11 @@ public:
+@@ -42,14 +44,11 @@ public:
    //nsISupports
    NS_DECL_ISUPPORTS
  
diff --git a/src/current-patches/firefox/alpha/0019-Add-a-redirect-API-for-HTTPS-Everywhere.patch b/src/current-patches/firefox/alpha/0019-Add-a-redirect-API-for-HTTPS-Everywhere.patch
new file mode 100644
index 0000000..693d372
--- /dev/null
+++ b/src/current-patches/firefox/alpha/0019-Add-a-redirect-API-for-HTTPS-Everywhere.patch
@@ -0,0 +1,345 @@
+From c63f5efde7280d3167a3ba6bdd1140235817b518 Mon Sep 17 00:00:00 2001
+From: Mike Perry <mikeperry-git at torproject.org>
+Date: Tue, 28 Aug 2012 18:30:22 -0700
+Subject: [PATCH 19/20] Add a redirect API for HTTPS-Everywhere.
+
+---
+ netwerk/protocol/http/HttpChannelChild.cpp         |   15 ++++-
+ netwerk/protocol/http/HttpChannelChild.h           |    4 +
+ netwerk/protocol/http/HttpChannelParent.cpp        |    4 +
+ netwerk/protocol/http/HttpChannelParent.h          |    1 +
+ netwerk/protocol/http/PHttpChannel.ipdl            |    1 +
+ netwerk/protocol/http/nsHttpChannel.cpp            |   67 +++++++++++++++++---
+ netwerk/protocol/http/nsHttpChannel.h              |   12 +++-
+ netwerk/protocol/http/nsIHttpChannel.idl           |   12 ++++
+ .../protocol/viewsource/nsViewSourceChannel.cpp    |   13 ++++-
+ 9 files changed, 117 insertions(+), 12 deletions(-)
+
+diff --git a/netwerk/protocol/http/HttpChannelChild.cpp b/netwerk/protocol/http/HttpChannelChild.cpp
+index 691fee0..f22fa40 100644
+--- a/netwerk/protocol/http/HttpChannelChild.cpp
++++ b/netwerk/protocol/http/HttpChannelChild.cpp
+@@ -1035,7 +1035,8 @@ HttpChannelChild::AsyncOpen(nsIStreamListener *listener, nsISupports *aContext)
+   gNeckoChild->SendPHttpChannelConstructor(this, tabChild);
+ 
+   SendAsyncOpen(IPC::URI(mURI), IPC::URI(mOriginalURI),
+-                IPC::URI(mDocumentURI), IPC::URI(mReferrer), mLoadFlags,
++                IPC::URI(mDocumentURI), IPC::URI(mReferrer),
++                IPC::URI(mInternalRedirectURI), mLoadFlags,
+                 mClientSetRequestHeaders, mRequestHead.Method(),
+                 IPC::InputStream(mUploadStream), mUploadStreamHasHeaders,
+                 mPriority, mRedirectionLimit, mAllowPipelining,
+@@ -1079,6 +1080,18 @@ HttpChannelChild::SetupFallbackChannel(const char *aFallbackKey)
+   DROP_DEAD();
+ }
+ 
++NS_IMETHODIMP
++HttpChannelChild::RedirectTo(nsIURI *uri)
++{
++  // We can only redirect unopened channels
++  NS_ENSURE_TRUE(!mIPCOpen, NS_ERROR_ALREADY_OPENED);
++
++  // The redirect is stored internally for use in AsyncOpen
++  mInternalRedirectURI = uri;
++
++  return NS_OK;
++}
++
+ // The next four _should_ be implemented, but we need to figure out how
+ // to transfer the data from the chrome process first.
+ 
+diff --git a/netwerk/protocol/http/HttpChannelChild.h b/netwerk/protocol/http/HttpChannelChild.h
+index 6b699c7..b29a4a7 100644
+--- a/netwerk/protocol/http/HttpChannelChild.h
++++ b/netwerk/protocol/http/HttpChannelChild.h
+@@ -75,6 +75,9 @@ public:
+   NS_IMETHOD GetLocalPort(PRInt32* port);
+   NS_IMETHOD GetRemoteAddress(nsACString& addr);
+   NS_IMETHOD GetRemotePort(PRInt32* port);
++
++  NS_IMETHOD RedirectTo(nsIURI *uri);
++
+   // nsISupportsPriority
+   NS_IMETHOD SetPriority(PRInt32 value);
+   // nsIResumableChannel
+@@ -125,6 +128,7 @@ private:
+   RequestHeaderTuples mClientSetRequestHeaders;
+   nsCOMPtr<nsIChildChannel> mRedirectChannelChild;
+   nsCOMPtr<nsISupports> mSecurityInfo;
++  nsCOMPtr<nsIURI>      mInternalRedirectURI;
+ 
+   bool mIsFromCache;
+   bool mCacheEntryAvailable;
+diff --git a/netwerk/protocol/http/HttpChannelParent.cpp b/netwerk/protocol/http/HttpChannelParent.cpp
+index 31aa582..25568bd 100644
+--- a/netwerk/protocol/http/HttpChannelParent.cpp
++++ b/netwerk/protocol/http/HttpChannelParent.cpp
+@@ -97,6 +97,7 @@ HttpChannelParent::RecvAsyncOpen(const IPC::URI&            aURI,
+                                  const IPC::URI&            aOriginalURI,
+                                  const IPC::URI&            aDocURI,
+                                  const IPC::URI&            aReferrerURI,
++                                 const IPC::URI&            aInternalRedirectURI,
+                                  const PRUint32&            loadFlags,
+                                  const RequestHeaderTuples& requestHeaders,
+                                  const nsHttpAtom&          requestMethod,
+@@ -118,6 +119,7 @@ HttpChannelParent::RecvAsyncOpen(const IPC::URI&            aURI,
+   nsCOMPtr<nsIURI> originalUri(aOriginalURI);
+   nsCOMPtr<nsIURI> docUri(aDocURI);
+   nsCOMPtr<nsIURI> referrerUri(aReferrerURI);
++  nsCOMPtr<nsIURI> internalRedirectUri(aInternalRedirectURI);
+ 
+   nsCString uriSpec;
+   uri->GetSpec(uriSpec);
+@@ -145,6 +147,8 @@ HttpChannelParent::RecvAsyncOpen(const IPC::URI&            aURI,
+     httpChan->SetDocumentURI(docUri);
+   if (referrerUri)
+     httpChan->SetReferrerInternal(referrerUri);
++  if (internalRedirectUri)
++    httpChan->SetInternalRedirectURI(internalRedirectUri);
+   if (loadFlags != nsIRequest::LOAD_NORMAL)
+     httpChan->SetLoadFlags(loadFlags);
+ 
+diff --git a/netwerk/protocol/http/HttpChannelParent.h b/netwerk/protocol/http/HttpChannelParent.h
+index 97eea07..e254589 100644
+--- a/netwerk/protocol/http/HttpChannelParent.h
++++ b/netwerk/protocol/http/HttpChannelParent.h
+@@ -49,6 +49,7 @@ protected:
+                              const IPC::URI&            originalUri,
+                              const IPC::URI&            docUri,
+                              const IPC::URI&            referrerUri,
++                             const IPC::URI&            internalRedirectUri,
+                              const PRUint32&            loadFlags,
+                              const RequestHeaderTuples& requestHeaders,
+                              const nsHttpAtom&          requestMethod,
+diff --git a/netwerk/protocol/http/PHttpChannel.ipdl b/netwerk/protocol/http/PHttpChannel.ipdl
+index b67e2c1..2b919cc 100644
+--- a/netwerk/protocol/http/PHttpChannel.ipdl
++++ b/netwerk/protocol/http/PHttpChannel.ipdl
+@@ -35,6 +35,7 @@ parent:
+             URI                 original,
+             URI                 doc,
+             URI                 referrer,
++            URI                 internalRedirect,
+             PRUint32            loadFlags,
+             RequestHeaderTuples requestHeaders,
+             nsHttpAtom          requestMethod,
+diff --git a/netwerk/protocol/http/nsHttpChannel.cpp b/netwerk/protocol/http/nsHttpChannel.cpp
+index 529857b..73b54ce 100644
+--- a/netwerk/protocol/http/nsHttpChannel.cpp
++++ b/netwerk/protocol/http/nsHttpChannel.cpp
+@@ -1398,18 +1398,17 @@ nsHttpChannel::HandleAsyncRedirectChannelToHttps()
+         return;
+     }
+ 
+-    nsresult rv = AsyncRedirectChannelToHttps();
++    nsresult rv = InternalRedirectChannelToHttps();
+     if (NS_FAILED(rv))
+-        ContinueAsyncRedirectChannelToHttps(rv);
++        ContinueInternalRedirectChannelToURI(rv);
+ }
+ 
+ nsresult
+-nsHttpChannel::AsyncRedirectChannelToHttps()
++nsHttpChannel::InternalRedirectChannelToHttps()
+ {
+     nsresult rv = NS_OK;
+     LOG(("nsHttpChannel::HandleAsyncRedirectChannelToHttps() [STS]\n"));
+ 
+-    nsCOMPtr<nsIChannel> newChannel;
+     nsCOMPtr<nsIURI> upgradedURI;
+ 
+     rv = mURI->Clone(getter_AddRefs(upgradedURI));
+@@ -1431,6 +1430,48 @@ nsHttpChannel::AsyncRedirectChannelToHttps()
+     else
+         upgradedURI->SetPort(oldPort);
+ 
++    return InternalRedirectChannelToURI(upgradedURI);
++}
++
++NS_IMETHODIMP
++nsHttpChannel::RedirectTo(nsIURI *newURI)
++{
++    // We can only redirect unopened channels
++    NS_ENSURE_TRUE(!mWasOpened, NS_ERROR_ALREADY_OPENED);
++
++    // The redirect is stored internally for use in AsyncOpen
++    mInternalRedirectURI = newURI;
++
++    return NS_OK;
++}
++
++void
++nsHttpChannel::HandleAsyncInternalRedirect()
++{
++    NS_PRECONDITION(!mCallOnResume, "How did that happen?");
++    NS_PRECONDITION(mInternalRedirectURI, "How did that happen?");
++
++    if (mSuspendCount) {
++        LOG(("Waiting until resume to do async API redirect [this=%p]\n", this));
++        mCallOnResume = &nsHttpChannel::HandleAsyncInternalRedirect;
++        return;
++    }
++
++    nsresult rv = InternalRedirectChannelToURI(mInternalRedirectURI);
++    if (NS_FAILED(rv))
++        ContinueInternalRedirectChannelToURI(rv);
++
++    return;
++}
++
++nsresult
++nsHttpChannel::InternalRedirectChannelToURI(nsIURI *upgradedURI)
++{
++    nsresult rv = NS_OK;
++    LOG(("nsHttpChannel::InternalRedirectChannelToURI()\n"));
++
++    nsCOMPtr<nsIChannel> newChannel;
++
+     nsCOMPtr<nsIIOService> ioService;
+     rv = gHttpHandler->GetIOService(getter_AddRefs(ioService));
+     NS_ENSURE_SUCCESS(rv, rv);
+@@ -1446,7 +1487,7 @@ nsHttpChannel::AsyncRedirectChannelToHttps()
+     PRUint32 flags = nsIChannelEventSink::REDIRECT_PERMANENT;
+ 
+     PushRedirectAsyncFunc(
+-        &nsHttpChannel::ContinueAsyncRedirectChannelToHttps);
++        &nsHttpChannel::ContinueInternalRedirectChannelToURI);
+     rv = gHttpHandler->AsyncOnChannelRedirect(this, newChannel, flags);
+ 
+     if (NS_SUCCEEDED(rv))
+@@ -1455,14 +1496,18 @@ nsHttpChannel::AsyncRedirectChannelToHttps()
+     if (NS_FAILED(rv)) {
+         AutoRedirectVetoNotifier notifier(this);
+         PopRedirectAsyncFunc(
+-            &nsHttpChannel::ContinueAsyncRedirectChannelToHttps);
++            &nsHttpChannel::ContinueInternalRedirectChannelToURI);
++
++        // If we've failed so far, cancel the current channel, too,
++        // as both HSTS and the redirectTo codepaths prefer
++        // request failure to insecurity.
++        Cancel(rv);
+     }
+ 
+     return rv;
+ }
+-
+ nsresult
+-nsHttpChannel::ContinueAsyncRedirectChannelToHttps(nsresult rv)
++nsHttpChannel::ContinueInternalRedirectChannelToURI(nsresult rv)
+ {
+     AutoRedirectVetoNotifier notifier(this);
+ 
+@@ -3910,6 +3955,12 @@ nsHttpChannel::AsyncOpen(nsIStreamListener *listener, nsISupports *context)
+     if (mLoadGroup)
+         mLoadGroup->AddRequest(this, nsnull);
+ 
++    // Check to see if we should redirect this channel elsewhere by 
++    // nsIHttpChannel.redirectTo API request
++    if (mInternalRedirectURI) {
++        return AsyncCall(&nsHttpChannel::HandleAsyncInternalRedirect);
++    }
++
+     // Collect mAsyncOpenTime after we have called all obsrevers like
+     // "http-on-modify-request" and load group observers that may set
+     // mTimingEnabled flag.
+diff --git a/netwerk/protocol/http/nsHttpChannel.h b/netwerk/protocol/http/nsHttpChannel.h
+index 3d06ffd..60f52dd 100644
+--- a/netwerk/protocol/http/nsHttpChannel.h
++++ b/netwerk/protocol/http/nsHttpChannel.h
+@@ -103,6 +103,8 @@ public:
+     // nsIChannel
+     NS_IMETHOD GetSecurityInfo(nsISupports **aSecurityInfo);
+     NS_IMETHOD AsyncOpen(nsIStreamListener *listener, nsISupports *aContext);
++    // nsIHttpChannel
++    NS_IMETHOD RedirectTo(nsIURI *newURI);
+     // nsIHttpChannelInternal
+     NS_IMETHOD SetupFallbackChannel(const char *aFallbackKey);
+     // nsISupportsPriority
+@@ -117,6 +119,9 @@ public: /* internal necko use only */
+     void SetUploadStreamHasHeaders(bool hasHeaders) 
+       { mUploadStreamHasHeaders = hasHeaders; }
+ 
++    void SetInternalRedirectURI(nsIURI *redirectTo) 
++      { mInternalRedirectURI = redirectTo; }
++
+     nsresult SetReferrerInternal(nsIURI *referrer) {
+         nsCAutoString spec;
+         nsresult rv = referrer->GetAsciiSpec(spec);
+@@ -183,11 +188,13 @@ private:
+ 
+     // redirection specific methods
+     void     HandleAsyncRedirect();
++    void     HandleAsyncInternalRedirect();
+     nsresult ContinueHandleAsyncRedirect(nsresult);
+     void     HandleAsyncNotModified();
+     void     HandleAsyncFallback();
+     nsresult ContinueHandleAsyncFallback(nsresult);
+     nsresult PromptTempRedirect();
++    nsresult InternalRedirectChannelToURI(nsIURI *);
+     virtual nsresult SetupReplacementChannel(nsIURI *, nsIChannel *, bool preserveMethod);
+ 
+     // proxy specific methods
+@@ -247,8 +254,8 @@ private:
+     bool     MustValidateBasedOnQueryUrl();
+ 
+     void     HandleAsyncRedirectChannelToHttps();
+-    nsresult AsyncRedirectChannelToHttps();
+-    nsresult ContinueAsyncRedirectChannelToHttps(nsresult rv);
++    nsresult InternalRedirectChannelToHttps();
++    nsresult ContinueInternalRedirectChannelToURI(nsresult rv);
+ 
+     /**
+      * A function that takes care of reading STS headers and enforcing STS 
+@@ -320,6 +327,7 @@ private:
+     friend class AutoRedirectVetoNotifier;
+     friend class HttpAsyncAborter<nsHttpChannel>;
+     nsCOMPtr<nsIURI>                  mRedirectURI;
++    nsCOMPtr<nsIURI>                  mInternalRedirectURI;
+     nsCOMPtr<nsIChannel>              mRedirectChannel;
+     PRUint32                          mRedirectType;
+ 
+diff --git a/netwerk/protocol/http/nsIHttpChannel.idl b/netwerk/protocol/http/nsIHttpChannel.idl
+index c541df1..2ee3cbc 100644
+--- a/netwerk/protocol/http/nsIHttpChannel.idl
++++ b/netwerk/protocol/http/nsIHttpChannel.idl
+@@ -257,4 +257,16 @@ interface nsIHttpChannel : nsIChannel
+      *         has been received (before onStartRequest).
+      */
+     boolean isNoCacheResponse();
++    
++    /**
++     * Instructs the channel to immediately redirect to a new destination.
++     * Can only be called on channels not yet opened.
++     * 
++     * This method provides no explicit conflict resolution. The last
++     * caller to call it wins.
++     *
++     * @throws NS_ERROR_ALREADY_OPENED if called after the channel
++     *         has been opened.
++     */ 
++    void redirectTo(in nsIURI aNewURI);
+ };
+diff --git a/netwerk/protocol/viewsource/nsViewSourceChannel.cpp b/netwerk/protocol/viewsource/nsViewSourceChannel.cpp
+index 8f6d159..d1ca639 100644
+--- a/netwerk/protocol/viewsource/nsViewSourceChannel.cpp
++++ b/netwerk/protocol/viewsource/nsViewSourceChannel.cpp
+@@ -671,4 +671,15 @@ nsViewSourceChannel::IsNoCacheResponse(bool *_retval)
+ {
+     return !mHttpChannel ? NS_ERROR_NULL_POINTER :
+         mHttpChannel->IsNoCacheResponse(_retval);
+-} 
++}
++
++// XXX: Is this the right thing to do here? Or should we have
++// made an nsIHTTPChannelRedirect that only nsHttpChannel implements?
++// Also, will this mean that some ViewSource requests may be non-https?
++// Or will the mHttpChannel take care of that for us?
++NS_IMETHODIMP
++nsViewSourceChannel::RedirectTo(nsIURI *uri)
++{
++    return NS_ERROR_NOT_IMPLEMENTED;
++}
++
+-- 
+1.7.5.4
+
diff --git a/src/current-patches/firefox/alpha/0019-Fix-Firefox-build-process.patch b/src/current-patches/firefox/alpha/0019-Fix-Firefox-build-process.patch
deleted file mode 100644
index 5415a03..0000000
--- a/src/current-patches/firefox/alpha/0019-Fix-Firefox-build-process.patch
+++ /dev/null
@@ -1,267 +0,0 @@
-From dc89146d7f45dc1b0d0050d1714118b4968a8339 Mon Sep 17 00:00:00 2001
-From: Mike Perry <mikeperry-git at torproject.org>
-Date: Mon, 23 Jul 2012 15:01:01 -0700
-Subject: [PATCH 19/19] Fix Firefox build process.
-
-Patch is from https://bugzilla.mozilla.org/show_bug.cgi?id=736961 and
-https://bugzilla.mozilla.org/show_bug.cgi?id=754625.
----
- config/rules.mk                           |   12 ++++-----
- js/src/config/rules.mk                    |   12 ++++-----
- js/xpconnect/src/Makefile.in              |   35 ++++++++++++----------------
- js/xpconnect/src/dictionary_helper_gen.py |    2 +-
- toolkit/mozapps/installer/packager.mk     |    2 +
- xpcom/idl-parser/Makefile.in              |    7 ++---
- xpcom/idl-parser/header.py                |    7 ++---
- 7 files changed, 34 insertions(+), 43 deletions(-)
-
-diff --git a/config/rules.mk b/config/rules.mk
-index c522235..653ac9e 100644
---- a/config/rules.mk
-+++ b/config/rules.mk
-@@ -1437,9 +1437,9 @@ endif
- # warn against overriding existing .h file.
- 
- XPIDL_DEPS = \
--  $(topsrcdir)/xpcom/idl-parser/header.py \
--  $(topsrcdir)/xpcom/idl-parser/typelib.py \
--  $(topsrcdir)/xpcom/idl-parser/xpidl.py \
-+  $(LIBXUL_DIST)/sdk/bin/header.py \
-+  $(LIBXUL_DIST)/sdk/bin/typelib.py \
-+  $(LIBXUL_DIST)/sdk/bin/xpidl.py \
-   $(NULL)
- 
- xpidl-preqs = \
-@@ -1451,8 +1451,7 @@ $(XPIDL_GEN_DIR)/%.h: %.idl $(XPIDL_DEPS) $(xpidl-preqs)
- 	$(REPORT_BUILD)
- 	$(PYTHON_PATH) \
- 	  $(PLY_INCLUDE) \
--	  -I$(topsrcdir)/xpcom/idl-parser \
--	  $(topsrcdir)/xpcom/idl-parser/header.py --cachedir=$(DEPTH)/xpcom/idl-parser $(XPIDL_FLAGS) $(_VPATH_SRCS) -d $(MDDEPDIR)/$(@F).pp -o $@
-+	  $(LIBXUL_DIST)/sdk/bin/header.py $(XPIDL_FLAGS) $(_VPATH_SRCS) -d $(MDDEPDIR)/$(@F).pp -o $@
- 	@if test -n "$(findstring $*.h, $(EXPORTS))"; \
- 	  then echo "*** WARNING: file $*.h generated from $*.idl overrides $(srcdir)/$*.h"; else true; fi
- 
-@@ -1463,9 +1462,8 @@ $(XPIDL_GEN_DIR)/%.xpt: %.idl $(XPIDL_DEPS) $(xpidl-preqs)
- 	$(REPORT_BUILD)
- 	$(PYTHON_PATH) \
- 	  $(PLY_INCLUDE) \
--	  -I$(topsrcdir)/xpcom/idl-parser \
- 	  -I$(topsrcdir)/xpcom/typelib/xpt/tools \
--	  $(topsrcdir)/xpcom/idl-parser/typelib.py --cachedir=$(DEPTH)/xpcom/idl-parser $(XPIDL_FLAGS) $(_VPATH_SRCS) -d $(MDDEPDIR)/$(@F).pp -o $@
-+	  $(LIBXUL_DIST)/sdk/bin/typelib.py $(XPIDL_FLAGS) $(_VPATH_SRCS) -d $(MDDEPDIR)/$(@F).pp -o $@
- 
- # no need to link together if XPIDLSRCS contains only XPIDL_MODULE
- ifneq ($(XPIDL_MODULE).idl,$(strip $(XPIDLSRCS)))
-diff --git a/js/src/config/rules.mk b/js/src/config/rules.mk
-index c522235..653ac9e 100644
---- a/js/src/config/rules.mk
-+++ b/js/src/config/rules.mk
-@@ -1437,9 +1437,9 @@ endif
- # warn against overriding existing .h file.
- 
- XPIDL_DEPS = \
--  $(topsrcdir)/xpcom/idl-parser/header.py \
--  $(topsrcdir)/xpcom/idl-parser/typelib.py \
--  $(topsrcdir)/xpcom/idl-parser/xpidl.py \
-+  $(LIBXUL_DIST)/sdk/bin/header.py \
-+  $(LIBXUL_DIST)/sdk/bin/typelib.py \
-+  $(LIBXUL_DIST)/sdk/bin/xpidl.py \
-   $(NULL)
- 
- xpidl-preqs = \
-@@ -1451,8 +1451,7 @@ $(XPIDL_GEN_DIR)/%.h: %.idl $(XPIDL_DEPS) $(xpidl-preqs)
- 	$(REPORT_BUILD)
- 	$(PYTHON_PATH) \
- 	  $(PLY_INCLUDE) \
--	  -I$(topsrcdir)/xpcom/idl-parser \
--	  $(topsrcdir)/xpcom/idl-parser/header.py --cachedir=$(DEPTH)/xpcom/idl-parser $(XPIDL_FLAGS) $(_VPATH_SRCS) -d $(MDDEPDIR)/$(@F).pp -o $@
-+	  $(LIBXUL_DIST)/sdk/bin/header.py $(XPIDL_FLAGS) $(_VPATH_SRCS) -d $(MDDEPDIR)/$(@F).pp -o $@
- 	@if test -n "$(findstring $*.h, $(EXPORTS))"; \
- 	  then echo "*** WARNING: file $*.h generated from $*.idl overrides $(srcdir)/$*.h"; else true; fi
- 
-@@ -1463,9 +1462,8 @@ $(XPIDL_GEN_DIR)/%.xpt: %.idl $(XPIDL_DEPS) $(xpidl-preqs)
- 	$(REPORT_BUILD)
- 	$(PYTHON_PATH) \
- 	  $(PLY_INCLUDE) \
--	  -I$(topsrcdir)/xpcom/idl-parser \
- 	  -I$(topsrcdir)/xpcom/typelib/xpt/tools \
--	  $(topsrcdir)/xpcom/idl-parser/typelib.py --cachedir=$(DEPTH)/xpcom/idl-parser $(XPIDL_FLAGS) $(_VPATH_SRCS) -d $(MDDEPDIR)/$(@F).pp -o $@
-+	  $(LIBXUL_DIST)/sdk/bin/typelib.py $(XPIDL_FLAGS) $(_VPATH_SRCS) -d $(MDDEPDIR)/$(@F).pp -o $@
- 
- # no need to link together if XPIDLSRCS contains only XPIDL_MODULE
- ifneq ($(XPIDL_MODULE).idl,$(strip $(XPIDLSRCS)))
-diff --git a/js/xpconnect/src/Makefile.in b/js/xpconnect/src/Makefile.in
-index 35dfa68..0587acf 100644
---- a/js/xpconnect/src/Makefile.in
-+++ b/js/xpconnect/src/Makefile.in
-@@ -147,15 +147,14 @@ dom_quickstubs.h: dom_quickstubs.cpp
- 
- dom_quickstubs.cpp: $(srcdir)/dom_quickstubs.qsconf \
-                     $(srcdir)/qsgen.py \
--                    $(topsrcdir)/xpcom/idl-parser/header.py \
--                    $(topsrcdir)/xpcom/idl-parser/xpidl.py \
-+                    $(LIBXUL_DIST)/sdk/bin/header.py \
-+                    $(LIBXUL_DIST)/sdk/bin/xpidl.py \
-                     $(DEPTH)/js/src/js-confdefs.h
- 	$(PYTHON) $(topsrcdir)/config/pythonpath.py \
- 	  $(PLY_INCLUDE) \
--	  -I$(topsrcdir)/xpcom/idl-parser \
-+	  -I$(LIBXUL_DIST)/sdk/bin \
- 	  $(srcdir)/qsgen.py \
- 	  --idlpath=$(DEPTH)/dist/idl \
--	  --cachedir=$(DEPTH)/xpcom/idl-parser \
- 	  --header-output dom_quickstubs.h \
- 	  --stub-output dom_quickstubs.cpp \
- 	  --makedepend-output $(MDDEPDIR)/dom_qsgen.pp \
-@@ -168,15 +167,14 @@ dombindings.$(OBJ_SUFFIX): dombindings_gen.h \
- dombindings_gen.h: $(srcdir)/dombindings.conf \
-                    $(srcdir)/dombindingsgen.py \
-                    $(srcdir)/codegen.py \
--                   $(topsrcdir)/xpcom/idl-parser/header.py \
--                   $(topsrcdir)/xpcom/idl-parser/xpidl.py \
-+                   $(LIBXUL_DIST)/sdk/bin/header.py \
-+                   $(LIBXUL_DIST)/sdk/bin/xpidl.py \
-                    $(DEPTH)/js/src/js-confdefs.h
- 	$(PYTHON) $(topsrcdir)/config/pythonpath.py \
- 	  $(PLY_INCLUDE) \
--	  -I$(topsrcdir)/xpcom/idl-parser \
-+	  -I$(LIBXUL_DIST)/sdk/bin \
- 	  $(srcdir)/dombindingsgen.py \
- 	  --idlpath=$(DEPTH)/dist/idl \
--	  --cachedir=$(DEPTH)/xpcom/idl-parser \
- 	  --header-output dombindings_gen.h \
- 	  $(srcdir)/dombindings.conf
- 
-@@ -185,15 +183,14 @@ exports:: dombindings_gen.h
- dombindings_gen.cpp: $(srcdir)/dombindings.conf \
-                      $(srcdir)/dombindingsgen.py \
-                      $(srcdir)/codegen.py \
--                     $(topsrcdir)/xpcom/idl-parser/header.py \
--                     $(topsrcdir)/xpcom/idl-parser/xpidl.py \
-+                     $(LIBXUL_DIST)/sdk/bin/header.py \
-+                     $(LIBXUL_DIST)/sdk/bin/xpidl.py \
-                      $(DEPTH)/js/src/js-confdefs.h
- 	$(PYTHON) $(topsrcdir)/config/pythonpath.py \
- 	  $(PLY_INCLUDE) \
--	  -I$(topsrcdir)/xpcom/idl-parser \
-+	  -I$(LIBXUL_DIST)/sdk/bin \
- 	  $(srcdir)/dombindingsgen.py \
- 	  --idlpath=$(DEPTH)/dist/idl \
--	  --cachedir=$(DEPTH)/xpcom/idl-parser \
- 	  --stub-output dombindings_gen.cpp \
- 	  --makedepend-output $(MDDEPDIR)/dombindingsgen.pp \
- 	  $(srcdir)/dombindings.conf
-@@ -204,30 +201,28 @@ DictionaryHelpers.$(OBJ_SUFFIX): DictionaryHelpers.h \
- DictionaryHelpers.h: $(srcdir)/dictionary_helper_gen.conf \
-                      $(srcdir)/dictionary_helper_gen.py \
-                      $(srcdir)/codegen.py \
--                     $(topsrcdir)/xpcom/idl-parser/header.py \
--                     $(topsrcdir)/xpcom/idl-parser/xpidl.py \
-+                     $(LIBXUL_DIST)/sdk/bin/header.py \
-+                     $(LIBXUL_DIST)/sdk/bin/xpidl.py \
-                      $(DEPTH)/js/src/js-confdefs.h
- 	$(PYTHON) $(topsrcdir)/config/pythonpath.py \
- 	  $(PLY_INCLUDE) \
--	  -I$(topsrcdir)/xpcom/idl-parser \
-+	  -I$(LIBXUL_DIST)/sdk/bin \
- 	  $(srcdir)/dictionary_helper_gen.py \
- 	  -I $(DEPTH)/dist/idl \
--	  --cachedir=$(DEPTH)/xpcom/idl-parser \
- 	  --header-output DictionaryHelpers.h \
- 	  $(srcdir)/dictionary_helper_gen.conf
- 
- DictionaryHelpers.cpp: $(srcdir)/dictionary_helper_gen.conf \
-                        $(srcdir)/dictionary_helper_gen.py \
-                        $(srcdir)/codegen.py \
--                       $(topsrcdir)/xpcom/idl-parser/header.py \
--                       $(topsrcdir)/xpcom/idl-parser/xpidl.py \
-+                       $(LIBXUL_DIST)/sdk/bin/header.py \
-+                       $(LIBXUL_DIST)/sdk/bin/xpidl.py \
-                        $(DEPTH)/js/src/js-confdefs.h
- 	$(PYTHON) $(topsrcdir)/config/pythonpath.py \
- 	  $(PLY_INCLUDE) \
--	  -I$(topsrcdir)/xpcom/idl-parser \
-+	  -I$(LIBXUL_DIST)/sdk/bin \
- 	  $(srcdir)/dictionary_helper_gen.py \
- 	  -I $(DEPTH)/dist/idl \
--	  --cachedir=$(DEPTH)/xpcom/idl-parser \
- 	  --header-output DictionaryHelpers.h \
- 	  --stub-output DictionaryHelpers.cpp \
- 	  --makedepend-output $(MDDEPDIR)/dictionary_helper_gen.pp \
-diff --git a/js/xpconnect/src/dictionary_helper_gen.py b/js/xpconnect/src/dictionary_helper_gen.py
-index aaf4da7..5eaa07a 100644
---- a/js/xpconnect/src/dictionary_helper_gen.py
-+++ b/js/xpconnect/src/dictionary_helper_gen.py
-@@ -460,7 +460,7 @@ if __name__ == '__main__':
-                  help="Quick stub header output file", metavar="FILE")
-     o.add_option('--makedepend-output', type='string', default=None,
-                  help="gnumake dependencies output file", metavar="FILE")
--    o.add_option('--cachedir', dest='cachedir', default='',
-+    o.add_option('--cachedir', dest='cachedir', default=None,
-                  help="Directory in which to cache lex/parse tables.")
-     (options, filenames) = o.parse_args()
-     if len(filenames) != 1:
-diff --git a/toolkit/mozapps/installer/packager.mk b/toolkit/mozapps/installer/packager.mk
-index e217d7f..e7e2b86 100644
---- a/toolkit/mozapps/installer/packager.mk
-+++ b/toolkit/mozapps/installer/packager.mk
-@@ -947,6 +947,7 @@ ifdef INSTALL_SDK # Here comes the hard part
- 	if test -f $(DIST)/include/xpcom-config.h; then \
- 	  $(SYSINSTALL) $(IFLAGS1) $(DIST)/include/xpcom-config.h $(DESTDIR)$(sdkdir); \
- 	fi
-+	find $(DIST)/sdk -name "*.pyc" | xargs rm
- 	(cd $(DIST)/sdk/lib && tar $(TAR_CREATE_FLAGS) - .) | (cd $(DESTDIR)$(sdkdir)/sdk/lib && tar -xf -)
- 	(cd $(DIST)/sdk/bin && tar $(TAR_CREATE_FLAGS) - .) | (cd $(DESTDIR)$(sdkdir)/sdk/bin && tar -xf -)
- 	$(RM) -f $(DESTDIR)$(sdkdir)/lib $(DESTDIR)$(sdkdir)/bin $(DESTDIR)$(sdkdir)/include $(DESTDIR)$(sdkdir)/include $(DESTDIR)$(sdkdir)/sdk/idl $(DESTDIR)$(sdkdir)/idl
-@@ -967,6 +968,7 @@ make-sdk:
- 	(cd $(DIST)/host/bin && tar $(TAR_CREATE_FLAGS) - .) | \
- 	  (cd $(DIST)/$(MOZ_APP_NAME)-sdk/host/bin && tar -xf -)
- 	$(NSINSTALL) -D $(DIST)/$(MOZ_APP_NAME)-sdk/sdk
-+	find $(DIST)/sdk -name "*.pyc" | xargs rm
- 	(cd $(DIST)/sdk && tar $(TAR_CREATE_FLAGS) - .) | \
- 	  (cd $(DIST)/$(MOZ_APP_NAME)-sdk/sdk && tar -xf -)
- 	$(NSINSTALL) -D $(DIST)/$(MOZ_APP_NAME)-sdk/include
-diff --git a/xpcom/idl-parser/Makefile.in b/xpcom/idl-parser/Makefile.in
-index 4f578a1..e696666 100644
---- a/xpcom/idl-parser/Makefile.in
-+++ b/xpcom/idl-parser/Makefile.in
-@@ -60,14 +60,13 @@ include $(topsrcdir)/config/rules.mk
- export:: $(PARSER_SRCS) $(PLY_PROGS)
- 	$(PYTHON_PATH) \
- 	  $(PLY_INCLUDE) \
--	  -I$(topsrcdir)/xpcom/idl-parser \
--	  $(topsrcdir)/xpcom/idl-parser/header.py --cachedir=. --regen
-+	  $(srcdir)/header.py --cachedir=. --regen
- 
- check::
- 	$(PYTHON_PATH) \
- 	  $(PLY_INCLUDE) \
--	  -I$(topsrcdir)/xpcom/idl-parser \
--	  $(topsrcdir)/xpcom/idl-parser/runtests.py
-+	  -I. \
-+	  $(srcdir)/runtests.py
- 
- GARBAGE += \
-   xpidllex.py \
-diff --git a/xpcom/idl-parser/header.py b/xpcom/idl-parser/header.py
-index b8d6940..8ee8765 100644
---- a/xpcom/idl-parser/header.py
-+++ b/xpcom/idl-parser/header.py
-@@ -505,10 +505,9 @@ if __name__ == '__main__':
-             print >>sys.stderr, "--regen useless without --cachedir"
-         # Delete the lex/yacc files.  Ply is too stupid to regenerate them
-         # properly
--        deadfiles = os.path.join(options.cachedir, "*.py*")
--        for filename in glob.glob(deadfiles):
--            print filename
--            os.remove(filename)
-+        for fileglobs in [os.path.join(options.cachedir, f) for f in ["xpidllex.py*", "xpidlyacc.py*"]]:
-+            for filename in glob.glob(fileglobs):
-+                os.remove(filename)
- 
-     # Instantiate the parser.
-     p = xpidl.IDLParser(outputdir=options.cachedir)
--- 
-1.7.5.4
-
diff --git a/src/current-patches/firefox/alpha/0020-Add-a-redirect-API-for-HTTPS-Everywhere.patch b/src/current-patches/firefox/alpha/0020-Add-a-redirect-API-for-HTTPS-Everywhere.patch
deleted file mode 100644
index dd15f05..0000000
--- a/src/current-patches/firefox/alpha/0020-Add-a-redirect-API-for-HTTPS-Everywhere.patch
+++ /dev/null
@@ -1,346 +0,0 @@
-From 046d49340c963f140c618866a4ddd47cc75f576f Mon Sep 17 00:00:00 2001
-From: Mike Perry <mikeperry-git at torproject.org>
-Date: Thu, 26 Jul 2012 15:13:44 -0700
-Subject: [PATCH 20/21] Add a redirect API for HTTPS-Everywhere.
-
----
- netwerk/protocol/http/HttpChannelChild.cpp         |   15 ++++-
- netwerk/protocol/http/HttpChannelChild.h           |    4 +
- netwerk/protocol/http/HttpChannelParent.cpp        |    4 +
- netwerk/protocol/http/HttpChannelParent.h          |    1 +
- netwerk/protocol/http/PHttpChannel.ipdl            |    1 +
- netwerk/protocol/http/nsHttpChannel.cpp            |   67 +++++++++++++++++---
- netwerk/protocol/http/nsHttpChannel.h              |   13 +++-
- netwerk/protocol/http/nsIHttpChannel.idl           |   12 ++++
- .../protocol/viewsource/nsViewSourceChannel.cpp    |   13 ++++-
- 9 files changed, 118 insertions(+), 12 deletions(-)
-
-diff --git a/netwerk/protocol/http/HttpChannelChild.cpp b/netwerk/protocol/http/HttpChannelChild.cpp
-index 777dfb6..a563438 100644
---- a/netwerk/protocol/http/HttpChannelChild.cpp
-+++ b/netwerk/protocol/http/HttpChannelChild.cpp
-@@ -1070,7 +1070,8 @@ HttpChannelChild::AsyncOpen(nsIStreamListener *listener, nsISupports *aContext)
-   gNeckoChild->SendPHttpChannelConstructor(this, tabChild);
- 
-   SendAsyncOpen(IPC::URI(mURI), IPC::URI(mOriginalURI),
--                IPC::URI(mDocumentURI), IPC::URI(mReferrer), mLoadFlags,
-+                IPC::URI(mDocumentURI), IPC::URI(mReferrer),
-+                IPC::URI(mInternalRedirectURI), mLoadFlags,
-                 mClientSetRequestHeaders, mRequestHead.Method(),
-                 IPC::InputStream(mUploadStream), mUploadStreamHasHeaders,
-                 mPriority, mRedirectionLimit, mAllowPipelining,
-@@ -1114,6 +1115,18 @@ HttpChannelChild::SetupFallbackChannel(const char *aFallbackKey)
-   DROP_DEAD();
- }
- 
-+NS_IMETHODIMP
-+HttpChannelChild::RedirectTo(nsIURI *uri)
-+{
-+  // We can only redirect unopened channels
-+  NS_ENSURE_TRUE(!mIPCOpen, NS_ERROR_ALREADY_OPENED);
-+
-+  // The redirect is stored internally for use in AsyncOpen
-+  mInternalRedirectURI = uri;
-+
-+  return NS_OK;
-+}
-+
- // The next four _should_ be implemented, but we need to figure out how
- // to transfer the data from the chrome process first.
- 
-diff --git a/netwerk/protocol/http/HttpChannelChild.h b/netwerk/protocol/http/HttpChannelChild.h
-index 43617ef..f595c4d 100644
---- a/netwerk/protocol/http/HttpChannelChild.h
-+++ b/netwerk/protocol/http/HttpChannelChild.h
-@@ -110,6 +110,9 @@ public:
-   NS_IMETHOD GetLocalPort(PRInt32* port);
-   NS_IMETHOD GetRemoteAddress(nsACString& addr);
-   NS_IMETHOD GetRemotePort(PRInt32* port);
-+
-+  NS_IMETHOD RedirectTo(nsIURI *uri);
-+
-   // nsISupportsPriority
-   NS_IMETHOD SetPriority(PRInt32 value);
-   // nsIResumableChannel
-@@ -160,6 +163,7 @@ private:
-   RequestHeaderTuples mClientSetRequestHeaders;
-   nsCOMPtr<nsIChildChannel> mRedirectChannelChild;
-   nsCOMPtr<nsISupports> mSecurityInfo;
-+  nsCOMPtr<nsIURI>      mInternalRedirectURI;
- 
-   bool mIsFromCache;
-   bool mCacheEntryAvailable;
-diff --git a/netwerk/protocol/http/HttpChannelParent.cpp b/netwerk/protocol/http/HttpChannelParent.cpp
-index 464cbe7..3ce94b8 100644
---- a/netwerk/protocol/http/HttpChannelParent.cpp
-+++ b/netwerk/protocol/http/HttpChannelParent.cpp
-@@ -132,6 +132,7 @@ HttpChannelParent::RecvAsyncOpen(const IPC::URI&            aURI,
-                                  const IPC::URI&            aOriginalURI,
-                                  const IPC::URI&            aDocURI,
-                                  const IPC::URI&            aReferrerURI,
-+                                 const IPC::URI&            aInternalRedirectURI,
-                                  const PRUint32&            loadFlags,
-                                  const RequestHeaderTuples& requestHeaders,
-                                  const nsHttpAtom&          requestMethod,
-@@ -152,6 +153,7 @@ HttpChannelParent::RecvAsyncOpen(const IPC::URI&            aURI,
-   nsCOMPtr<nsIURI> originalUri(aOriginalURI);
-   nsCOMPtr<nsIURI> docUri(aDocURI);
-   nsCOMPtr<nsIURI> referrerUri(aReferrerURI);
-+  nsCOMPtr<nsIURI> internalRedirectUri(aInternalRedirectURI);
- 
-   nsCString uriSpec;
-   uri->GetSpec(uriSpec);
-@@ -179,6 +181,8 @@ HttpChannelParent::RecvAsyncOpen(const IPC::URI&            aURI,
-     httpChan->SetDocumentURI(docUri);
-   if (referrerUri)
-     httpChan->SetReferrerInternal(referrerUri);
-+  if (internalRedirectUri)
-+    httpChan->SetInternalRedirectURI(internalRedirectUri);
-   if (loadFlags != nsIRequest::LOAD_NORMAL)
-     httpChan->SetLoadFlags(loadFlags);
- 
-diff --git a/netwerk/protocol/http/HttpChannelParent.h b/netwerk/protocol/http/HttpChannelParent.h
-index 6cfc3a6..a4b410a 100644
---- a/netwerk/protocol/http/HttpChannelParent.h
-+++ b/netwerk/protocol/http/HttpChannelParent.h
-@@ -82,6 +82,7 @@ protected:
-                              const IPC::URI&            originalUri,
-                              const IPC::URI&            docUri,
-                              const IPC::URI&            referrerUri,
-+                             const IPC::URI&            internalRedirectUri,
-                              const PRUint32&            loadFlags,
-                              const RequestHeaderTuples& requestHeaders,
-                              const nsHttpAtom&          requestMethod,
-diff --git a/netwerk/protocol/http/PHttpChannel.ipdl b/netwerk/protocol/http/PHttpChannel.ipdl
-index 252a6ee..23a912e 100644
---- a/netwerk/protocol/http/PHttpChannel.ipdl
-+++ b/netwerk/protocol/http/PHttpChannel.ipdl
-@@ -69,6 +69,7 @@ parent:
-             URI                 original,
-             URI                 doc,
-             URI                 referrer,
-+            URI                 internalRedirect,
-             PRUint32            loadFlags,
-             RequestHeaderTuples requestHeaders,
-             nsHttpAtom          requestMethod,
-diff --git a/netwerk/protocol/http/nsHttpChannel.cpp b/netwerk/protocol/http/nsHttpChannel.cpp
-index 23edc3c..c55fe4d 100644
---- a/netwerk/protocol/http/nsHttpChannel.cpp
-+++ b/netwerk/protocol/http/nsHttpChannel.cpp
-@@ -1403,18 +1403,17 @@ nsHttpChannel::HandleAsyncRedirectChannelToHttps()
-         return;
-     }
- 
--    nsresult rv = AsyncRedirectChannelToHttps();
-+    nsresult rv = InternalRedirectChannelToHttps();
-     if (NS_FAILED(rv))
--        ContinueAsyncRedirectChannelToHttps(rv);
-+        ContinueInternalRedirectChannelToURI(rv);
- }
- 
- nsresult
--nsHttpChannel::AsyncRedirectChannelToHttps()
-+nsHttpChannel::InternalRedirectChannelToHttps()
- {
-     nsresult rv = NS_OK;
-     LOG(("nsHttpChannel::HandleAsyncRedirectChannelToHttps() [STS]\n"));
- 
--    nsCOMPtr<nsIChannel> newChannel;
-     nsCOMPtr<nsIURI> upgradedURI;
- 
-     rv = mURI->Clone(getter_AddRefs(upgradedURI));
-@@ -1436,6 +1435,48 @@ nsHttpChannel::AsyncRedirectChannelToHttps()
-     else
-         upgradedURI->SetPort(oldPort);
- 
-+    return InternalRedirectChannelToURI(upgradedURI);
-+}
-+
-+NS_IMETHODIMP
-+nsHttpChannel::RedirectTo(nsIURI *newURI)
-+{
-+    // We can only redirect unopened channels
-+    NS_ENSURE_TRUE(!mWasOpened, NS_ERROR_ALREADY_OPENED);
-+
-+    // The redirect is stored internally for use in AsyncOpen
-+    mInternalRedirectURI = newURI;
-+
-+    return NS_OK;
-+}
-+
-+void
-+nsHttpChannel::HandleAsyncInternalRedirect()
-+{
-+    NS_PRECONDITION(!mCallOnResume, "How did that happen?");
-+    NS_PRECONDITION(mInternalRedirectURI, "How did that happen?");
-+
-+    if (mSuspendCount) {
-+        LOG(("Waiting until resume to do async API redirect [this=%p]\n", this));
-+        mCallOnResume = &nsHttpChannel::HandleAsyncInternalRedirect;
-+        return;
-+    }
-+
-+    nsresult rv = InternalRedirectChannelToURI(mInternalRedirectURI);
-+    if (NS_FAILED(rv))
-+        ContinueInternalRedirectChannelToURI(rv);
-+
-+    return;
-+}
-+
-+nsresult
-+nsHttpChannel::InternalRedirectChannelToURI(nsIURI *upgradedURI)
-+{
-+    nsresult rv = NS_OK;
-+    LOG(("nsHttpChannel::InternalRedirectChannelToURI()\n"));
-+
-+    nsCOMPtr<nsIChannel> newChannel;
-+
-     nsCOMPtr<nsIIOService> ioService;
-     rv = gHttpHandler->GetIOService(getter_AddRefs(ioService));
-     NS_ENSURE_SUCCESS(rv, rv);
-@@ -1451,7 +1492,7 @@ nsHttpChannel::AsyncRedirectChannelToHttps()
-     PRUint32 flags = nsIChannelEventSink::REDIRECT_PERMANENT;
- 
-     PushRedirectAsyncFunc(
--        &nsHttpChannel::ContinueAsyncRedirectChannelToHttps);
-+        &nsHttpChannel::ContinueInternalRedirectChannelToURI);
-     rv = gHttpHandler->AsyncOnChannelRedirect(this, newChannel, flags);
- 
-     if (NS_SUCCEEDED(rv))
-@@ -1460,14 +1501,18 @@ nsHttpChannel::AsyncRedirectChannelToHttps()
-     if (NS_FAILED(rv)) {
-         AutoRedirectVetoNotifier notifier(this);
-         PopRedirectAsyncFunc(
--            &nsHttpChannel::ContinueAsyncRedirectChannelToHttps);
-+            &nsHttpChannel::ContinueInternalRedirectChannelToURI);
-+
-+        // If we've failed so far, cancel the current channel, too,
-+        // as both HSTS and the redirectTo codepaths prefer
-+        // request failure to insecurity.
-+        Cancel(rv);
-     }
- 
-     return rv;
- }
--
- nsresult
--nsHttpChannel::ContinueAsyncRedirectChannelToHttps(nsresult rv)
-+nsHttpChannel::ContinueInternalRedirectChannelToURI(nsresult rv)
- {
-     AutoRedirectVetoNotifier notifier(this);
- 
-@@ -3929,6 +3974,12 @@ nsHttpChannel::AsyncOpen(nsIStreamListener *listener, nsISupports *context)
-     if (mLoadGroup)
-         mLoadGroup->AddRequest(this, nsnull);
- 
-+    // Check to see if we should redirect this channel elsewhere by 
-+    // nsIHttpChannel.redirectTo API request
-+    if (mInternalRedirectURI) {
-+        return AsyncCall(&nsHttpChannel::HandleAsyncInternalRedirect);
-+    }
-+
-     // Collect mAsyncOpenTime after we have called all obsrevers like
-     // "http-on-modify-request" and load group observers that may set
-     // mTimingEnabled flag.
-diff --git a/netwerk/protocol/http/nsHttpChannel.h b/netwerk/protocol/http/nsHttpChannel.h
-index 5a61e21..d156c28 100644
---- a/netwerk/protocol/http/nsHttpChannel.h
-+++ b/netwerk/protocol/http/nsHttpChannel.h
-@@ -138,6 +138,8 @@ public:
-     // nsIChannel
-     NS_IMETHOD GetSecurityInfo(nsISupports **aSecurityInfo);
-     NS_IMETHOD AsyncOpen(nsIStreamListener *listener, nsISupports *aContext);
-+    // nsIHttpChannel
-+    NS_IMETHOD RedirectTo(nsIURI *newURI);
-     // nsIHttpChannelInternal
-     NS_IMETHOD SetupFallbackChannel(const char *aFallbackKey);
-     // nsISupportsPriority
-@@ -152,6 +154,9 @@ public: /* internal necko use only */
-     void SetUploadStreamHasHeaders(bool hasHeaders) 
-       { mUploadStreamHasHeaders = hasHeaders; }
- 
-+    void SetInternalRedirectURI(nsIURI *redirectTo) 
-+      { mInternalRedirectURI = redirectTo; }
-+
-     nsresult SetReferrerInternal(nsIURI *referrer) {
-         nsCAutoString spec;
-         nsresult rv = referrer->GetAsciiSpec(spec);
-@@ -190,11 +195,14 @@ private:
- 
-     // redirection specific methods
-     void     HandleAsyncRedirect();
-+    void     HandleAsyncInternalRedirect();
-     nsresult ContinueHandleAsyncRedirect(nsresult);
-     void     HandleAsyncNotModified();
-     void     HandleAsyncFallback();
-     nsresult ContinueHandleAsyncFallback(nsresult);
-     nsresult PromptTempRedirect();
-+    nsresult InternalRedirectChannelToURI(nsIURI *);
-+
-     virtual nsresult SetupReplacementChannel(nsIURI *, nsIChannel *,
-                                              bool preserveMethod,
-                                              bool forProxy);
-@@ -256,8 +264,8 @@ private:
-     bool     MustValidateBasedOnQueryUrl();
- 
-     void     HandleAsyncRedirectChannelToHttps();
--    nsresult AsyncRedirectChannelToHttps();
--    nsresult ContinueAsyncRedirectChannelToHttps(nsresult rv);
-+    nsresult InternalRedirectChannelToHttps();
-+    nsresult ContinueInternalRedirectChannelToURI(nsresult rv);
- 
-     /**
-      * A function that takes care of reading STS headers and enforcing STS 
-@@ -327,6 +335,7 @@ private:
-     friend class AutoRedirectVetoNotifier;
-     friend class HttpAsyncAborter<nsHttpChannel>;
-     nsCOMPtr<nsIURI>                  mRedirectURI;
-+    nsCOMPtr<nsIURI>                  mInternalRedirectURI;
-     nsCOMPtr<nsIChannel>              mRedirectChannel;
-     PRUint32                          mRedirectType;
- 
-diff --git a/netwerk/protocol/http/nsIHttpChannel.idl b/netwerk/protocol/http/nsIHttpChannel.idl
-index 2d3f01a..39b2ee5 100644
---- a/netwerk/protocol/http/nsIHttpChannel.idl
-+++ b/netwerk/protocol/http/nsIHttpChannel.idl
-@@ -291,4 +291,16 @@ interface nsIHttpChannel : nsIChannel
-      *         has been received (before onStartRequest).
-      */
-     boolean isNoCacheResponse();
-+    
-+    /**
-+     * Instructs the channel to immediately redirect to a new destination.
-+     * Can only be called on channels not yet opened.
-+     * 
-+     * This method provides no explicit conflict resolution. The last
-+     * caller to call it wins.
-+     *
-+     * @throws NS_ERROR_ALREADY_OPENED if called after the channel
-+     *         has been opened.
-+     */ 
-+    void redirectTo(in nsIURI aNewURI);
- };
-diff --git a/netwerk/protocol/viewsource/nsViewSourceChannel.cpp b/netwerk/protocol/viewsource/nsViewSourceChannel.cpp
-index 919c3f7..e286b8f 100644
---- a/netwerk/protocol/viewsource/nsViewSourceChannel.cpp
-+++ b/netwerk/protocol/viewsource/nsViewSourceChannel.cpp
-@@ -703,4 +703,15 @@ nsViewSourceChannel::IsNoCacheResponse(bool *_retval)
- {
-     return !mHttpChannel ? NS_ERROR_NULL_POINTER :
-         mHttpChannel->IsNoCacheResponse(_retval);
--} 
-+}
-+
-+// XXX: Is this the right thing to do here? Or should we have
-+// made an nsIHTTPChannelRedirect that only nsHttpChannel implements?
-+// Also, will this mean that some ViewSource requests may be non-https?
-+// Or will the mHttpChannel take care of that for us?
-+NS_IMETHODIMP
-+nsViewSourceChannel::RedirectTo(nsIURI *uri)
-+{
-+    return NS_ERROR_NOT_IMPLEMENTED;
-+}
-+
--- 
-1.7.5.4
-
diff --git a/src/current-patches/firefox/alpha/0020-Isolate-the-Image-Cache-per-url-bar-domain.patch b/src/current-patches/firefox/alpha/0020-Isolate-the-Image-Cache-per-url-bar-domain.patch
new file mode 100644
index 0000000..e82086b
--- /dev/null
+++ b/src/current-patches/firefox/alpha/0020-Isolate-the-Image-Cache-per-url-bar-domain.patch
@@ -0,0 +1,910 @@
+From ec223865a42088ab02009d8f91387d56c1a5c0cf Mon Sep 17 00:00:00 2001
+From: Mike Perry <mikeperry-git at torproject.org>
+Date: Tue, 28 Aug 2012 18:35:33 -0700
+Subject: [PATCH 20/20] Isolate the Image Cache per url bar domain.
+
+Also adds a new API to mozIThirdPartyUtil to allow you to get the url bar URI
+for a channel or nsIDocument.
+---
+ content/base/src/ThirdPartyUtil.cpp                |   52 +++++
+ content/base/src/ThirdPartyUtil.h                  |    2 +
+ content/base/src/nsContentUtils.cpp                |   13 +-
+ embedding/browser/webBrowser/nsContextMenuInfo.cpp |   29 ++-
+ extensions/cookie/nsCookiePermission.cpp           |    3 +
+ image/public/imgILoader.idl                        |    4 +-
+ image/src/imgLoader.cpp                            |  200 ++++++++++++--------
+ image/src/imgLoader.h                              |   13 +-
+ image/src/imgRequest.cpp                           |    9 +-
+ image/src/imgRequest.h                             |    3 +
+ layout/generic/nsImageFrame.cpp                    |   11 +-
+ netwerk/base/public/mozIThirdPartyUtil.idl         |   21 ++
+ netwerk/cookie/nsICookiePermission.idl             |    1 +
+ toolkit/system/gnome/nsAlertsIconListener.cpp      |    3 +-
+ widget/cocoa/nsMenuItemIconX.mm                    |    9 +-
+ 15 files changed, 272 insertions(+), 101 deletions(-)
+
+diff --git a/content/base/src/ThirdPartyUtil.cpp b/content/base/src/ThirdPartyUtil.cpp
+index 97a000e..87ffc8a 100644
+--- a/content/base/src/ThirdPartyUtil.cpp
++++ b/content/base/src/ThirdPartyUtil.cpp
+@@ -7,6 +7,9 @@
+ #include "nsIServiceManager.h"
+ #include "nsIHttpChannelInternal.h"
+ #include "nsIDOMWindow.h"
++#include "nsICookiePermission.h"
++#include "nsIDOMDocument.h"
++#include "nsIDocument.h"
+ #include "nsILoadContext.h"
+ #include "nsIPrincipal.h"
+ #include "nsIScriptObjectPrincipal.h"
+@@ -21,6 +24,7 @@ ThirdPartyUtil::Init()
+ 
+   nsresult rv;
+   mTLDService = do_GetService(NS_EFFECTIVETLDSERVICE_CONTRACTID, &rv);
++  mCookiePermissions = do_GetService(NS_COOKIEPERMISSION_CONTRACTID);
+   return rv;
+ }
+ 
+@@ -282,3 +286,51 @@ ThirdPartyUtil::GetBaseDomain(nsIURI* aHostURI,
+ 
+   return NS_OK;
+ }
++
++NS_IMETHODIMP
++ThirdPartyUtil::GetFirstPartyURI(nsIChannel *aChannel,
++                                 nsIDocument *aDoc,
++                                 nsIURI **aOutput)
++{
++  nsresult rv = NS_ERROR_NULL_POINTER;
++
++  if (!aChannel && aDoc) {
++    aChannel = aDoc->GetChannel();
++  }
++
++  // If aChannel is specified or available, use the official route
++  // for sure
++  if (aChannel) {
++    rv = mCookiePermissions->GetOriginatingURI(aChannel, aOutput);
++  }
++
++  // If the channel was missing, closed or broken, try the
++  // window hierarchy directly. 
++  //
++  // This might fail to work for first-party loads themselves, but 
++  // we don't need this codepath for that case.
++  if (NS_FAILED(rv) && aDoc) {
++    nsCOMPtr<nsIDOMWindow> top;
++    nsCOMPtr<nsIDOMDocument> topDDoc;
++    
++    aDoc->GetWindow()->GetTop(getter_AddRefs(top));
++    top->GetDocument(getter_AddRefs(topDDoc));
++
++    nsCOMPtr<nsIDocument> topDoc(do_QueryInterface(topDDoc));
++    *aOutput = topDoc->GetOriginalURI();
++
++    if (*aOutput)
++      rv = NS_OK;
++  }
++
++  // TODO: We could provide a route through the loadgroup + notification
++  // callbacks too, but either channel or document was always available
++  // in the cases where this function was originally needed (the image cache).
++  // The notification callbacks also appear to suffers from the same limitation
++  // as the document path. See nsICookiePermissions.GetOriginatingURI() for
++  // details.
++
++  return rv;
++}
++
++
+diff --git a/content/base/src/ThirdPartyUtil.h b/content/base/src/ThirdPartyUtil.h
+index 269069b..37c30e8 100644
+--- a/content/base/src/ThirdPartyUtil.h
++++ b/content/base/src/ThirdPartyUtil.h
+@@ -9,6 +9,7 @@
+ #include "nsString.h"
+ #include "mozIThirdPartyUtil.h"
+ #include "nsIEffectiveTLDService.h"
++#include "nsICookiePermission.h"
+ 
+ class nsIURI;
+ class nsIChannel;
+@@ -28,6 +29,7 @@ private:
+   static already_AddRefed<nsIURI> GetURIFromWindow(nsIDOMWindow* aWin);
+ 
+   nsCOMPtr<nsIEffectiveTLDService> mTLDService;
++  nsCOMPtr<nsICookiePermission> mCookiePermissions;
+ };
+ 
+ #endif
+diff --git a/content/base/src/nsContentUtils.cpp b/content/base/src/nsContentUtils.cpp
+index 73cb024..951ba80 100644
+--- a/content/base/src/nsContentUtils.cpp
++++ b/content/base/src/nsContentUtils.cpp
+@@ -143,6 +143,7 @@ static NS_DEFINE_CID(kXTFServiceCID, NS_XTFSERVICE_CID);
+ #include "nsIDOMHTMLInputElement.h"
+ #include "nsParserConstants.h"
+ #include "nsIWebNavigation.h"
++#include "mozIThirdPartyUtil.h"
+ 
+ #ifdef IBMBIDI
+ #include "nsIBidiKeyboard.h"
+@@ -2647,8 +2648,6 @@ nsContentUtils::LoadImage(nsIURI* aURI, nsIDocument* aLoadingDocument,
+   nsCOMPtr<nsILoadGroup> loadGroup = aLoadingDocument->GetDocumentLoadGroup();
+   NS_ASSERTION(loadGroup, "Could not get loadgroup; onload may fire too early");
+ 
+-  nsIURI *documentURI = aLoadingDocument->GetDocumentURI();
+-
+   // check for a Content Security Policy to pass down to the channel that
+   // will get created to load the image
+   nsCOMPtr<nsIChannelPolicy> channelPolicy;
+@@ -2665,11 +2664,15 @@ nsContentUtils::LoadImage(nsIURI* aURI, nsIDocument* aLoadingDocument,
+     
+   // Make the URI immutable so people won't change it under us
+   NS_TryToSetImmutable(aURI);
++ 
++  nsCOMPtr<nsIURI> firstPartyURI;
++  nsCOMPtr<mozIThirdPartyUtil> thirdPartySvc
++                               = do_GetService(THIRDPARTYUTIL_CONTRACTID);
++  thirdPartySvc->GetFirstPartyURI(nsnull, aLoadingDocument,
++                                  getter_AddRefs(firstPartyURI));
+ 
+-  // XXXbz using "documentURI" for the initialDocumentURI is not quite
+-  // right, but the best we can do here...
+   return imgLoader->LoadImage(aURI,                 /* uri to load */
+-                              documentURI,          /* initialDocumentURI */
++                              firstPartyURI,        /* firstPartyURI */
+                               aReferrer,            /* referrer */
+                               aLoadingPrincipal,    /* loading principal */
+                               loadGroup,            /* loadgroup */
+diff --git a/embedding/browser/webBrowser/nsContextMenuInfo.cpp b/embedding/browser/webBrowser/nsContextMenuInfo.cpp
+index 4db0d9f..8b57b55 100644
+--- a/embedding/browser/webBrowser/nsContextMenuInfo.cpp
++++ b/embedding/browser/webBrowser/nsContextMenuInfo.cpp
+@@ -26,6 +26,7 @@
+ #include "nsIChannelPolicy.h"
+ #include "nsIContentSecurityPolicy.h"
+ #include "nsIContentPolicy.h"
++#include "mozIThirdPartyUtil.h"
+ 
+ //*****************************************************************************
+ // class nsContextMenuInfo
+@@ -269,15 +270,15 @@ nsContextMenuInfo::GetBackgroundImageRequestInternal(nsIDOMNode *aDOMNode, imgIR
+   nsCOMPtr<nsIPrincipal> principal;
+   nsCOMPtr<nsIChannelPolicy> channelPolicy;
+   nsCOMPtr<nsIContentSecurityPolicy> csp;
+-  if (doc) {
+-    principal = doc->NodePrincipal();
+-    nsresult rv = principal->GetCsp(getter_AddRefs(csp));
+-    NS_ENSURE_SUCCESS(rv, rv);
+-    if (csp) {
+-      channelPolicy = do_CreateInstance("@mozilla.org/nschannelpolicy;1");
+-      channelPolicy->SetContentSecurityPolicy(csp);
+-      channelPolicy->SetLoadType(nsIContentPolicy::TYPE_IMAGE);
+-    }
++  NS_ENSURE_TRUE(doc, NS_ERROR_FAILURE);
++
++  principal = doc->NodePrincipal();
++  nsresult rv = principal->GetCsp(getter_AddRefs(csp));
++  NS_ENSURE_SUCCESS(rv, rv);
++  if (csp) {
++    channelPolicy = do_CreateInstance("@mozilla.org/nschannelpolicy;1");
++    channelPolicy->SetContentSecurityPolicy(csp);
++    channelPolicy->SetLoadType(nsIContentPolicy::TYPE_IMAGE);
+   }
+   
+   while (true) {
+@@ -304,8 +305,14 @@ nsContextMenuInfo::GetBackgroundImageRequestInternal(nsIDOMNode *aDOMNode, imgIR
+           nsCOMPtr<imgILoader> il(do_GetService(
+                                     "@mozilla.org/image/loader;1"));
+           NS_ENSURE_TRUE(il, NS_ERROR_FAILURE);
+-
+-          return il->LoadImage(bgUri, nsnull, nsnull, principal, nsnull,
++          
++          nsCOMPtr<nsIURI> firstPartyURI;
++          nsCOMPtr<mozIThirdPartyUtil> thirdPartySvc
++              = do_GetService(THIRDPARTYUTIL_CONTRACTID);
++          thirdPartySvc->GetFirstPartyURI(nsnull, doc,
++                                          getter_AddRefs(firstPartyURI));
++
++          return il->LoadImage(bgUri, firstPartyURI, nsnull, principal, nsnull,
+                                nsnull, nsnull, nsIRequest::LOAD_NORMAL, nsnull,
+                                nsnull, channelPolicy, aRequest);
+         }
+diff --git a/extensions/cookie/nsCookiePermission.cpp b/extensions/cookie/nsCookiePermission.cpp
+index 4d3cdc5..cbc0240 100644
+--- a/extensions/cookie/nsCookiePermission.cpp
++++ b/extensions/cookie/nsCookiePermission.cpp
+@@ -408,6 +408,9 @@ nsCookiePermission::GetOriginatingURI(nsIChannel  *aChannel,
+ 
+       return NS_OK;
+     }
++
++    // TODO: Why don't we just use this here:
++    // httpChannelInternal->GetDocumentURI(aURI);
+   }
+ 
+   // find the associated window and its top window
+diff --git a/image/public/imgILoader.idl b/image/public/imgILoader.idl
+index da26463..ecff309 100644
+--- a/image/public/imgILoader.idl
++++ b/image/public/imgILoader.idl
+@@ -38,7 +38,7 @@ interface imgILoader : nsISupports
+   /**
+    * Start the load and decode of an image.
+    * @param aURI the URI to load
+-   * @param aInitialDocumentURI the URI that 'initiated' the load -- used for 3rd party cookie blocking
++   * @param aFirstPartyURI the urlbar URI that 'initiated' the load -- used for 3rd party blocking
+    * @param aReferrerURI the 'referring' URI
+    * @param aLoadingPrincipal the principal of the loading document
+    * @param aLoadGroup Loadgroup to put the image load into
+@@ -57,7 +57,7 @@ interface imgILoader : nsISupports
+    * goes away.
+    */
+   imgIRequest loadImage(in nsIURI aURI,
+-                        in nsIURI aInitialDocumentURL,
++                        in nsIURI aFirstPartyURI,
+                         in nsIURI aReferrerURI,
+                         in nsIPrincipal aLoadingPrincipal,
+                         in nsILoadGroup aLoadGroup,
+diff --git a/image/src/imgLoader.cpp b/image/src/imgLoader.cpp
+index 6cf52dd..3b28acb 100644
+--- a/image/src/imgLoader.cpp
++++ b/image/src/imgLoader.cpp
+@@ -58,6 +58,7 @@
+ #include "nsIHttpChannelInternal.h"  
+ #include "nsIContentSecurityPolicy.h"
+ #include "nsIChannelPolicy.h"
++#include "mozIThirdPartyUtil.h"
+ 
+ #include "nsContentUtils.h"
+ 
+@@ -470,7 +471,7 @@ static nsresult NewImageChannel(nsIChannel **aResult,
+                                 // aLoadingPrincipal and false otherwise.
+                                 bool *aForcePrincipalCheckForCacheEntry,
+                                 nsIURI *aURI,
+-                                nsIURI *aInitialDocumentURI,
++                                nsIURI *aFirstPartyURI,
+                                 nsIURI *aReferringURI,
+                                 nsILoadGroup *aLoadGroup,
+                                 const nsCString& aAcceptHeader,
+@@ -522,7 +523,7 @@ static nsresult NewImageChannel(nsIChannel **aResult,
+ 
+     nsCOMPtr<nsIHttpChannelInternal> httpChannelInternal = do_QueryInterface(newHttpChannel);
+     NS_ENSURE_TRUE(httpChannelInternal, NS_ERROR_UNEXPECTED);
+-    httpChannelInternal->SetDocumentURI(aInitialDocumentURI);
++    httpChannelInternal->SetDocumentURI(aFirstPartyURI);
+     newHttpChannel->SetReferrer(aReferringURI);
+   }
+ 
+@@ -963,34 +964,61 @@ NS_IMETHODIMP imgLoader::ClearCache(bool chrome)
+ /* void removeEntry(in nsIURI uri); */
+ NS_IMETHODIMP imgLoader::RemoveEntry(nsIURI *uri)
+ {
+-  if (RemoveFromCache(uri))
++  if (RemoveMatchingUrlsFromCache(uri))
+     return NS_OK;
+ 
+   return NS_ERROR_NOT_AVAILABLE;
+ }
+ 
++static PLDHashOperator EnumAllEntries(const nsACString&, 
++                                        nsRefPtr<imgCacheEntry> &aData,
++                                        void *data)
++{
++  nsTArray<nsRefPtr<imgCacheEntry> > *entries = 
++    reinterpret_cast<nsTArray<nsRefPtr<imgCacheEntry> > *>(data);
++
++  entries->AppendElement(aData);
++
++  return PL_DHASH_NEXT;
++}
++
+ /* imgIRequest findEntry(in nsIURI uri); */
+ NS_IMETHODIMP imgLoader::FindEntryProperties(nsIURI *uri, nsIProperties **_retval)
+ {
+   nsRefPtr<imgCacheEntry> entry;
+-  nsCAutoString spec;
+   imgCacheTable &cache = GetCache(uri);
+-
+-  uri->GetSpec(spec);
+   *_retval = nsnull;
+ 
+-  if (cache.Get(spec, getter_AddRefs(entry)) && entry) {
+-    if (gCacheTracker && entry->HasNoProxies())
+-      gCacheTracker->MarkUsed(entry);
++  // We must traverse the whole cache in O(N) looking for the first
++  // matching URI.
++  //
++  // TODO: For now, it's ok to pick at random here. The images should be
++  // identical unless there is a cache-tracking attack. And even if they
++  // are not identical due to attack, this code is only used for save
++  // dialogs at this point, so no differentiating info is leaked to
++  // content.
++  nsTArray<nsRefPtr<imgCacheEntry> > entries;
++  cache.Enumerate(EnumAllEntries, &entries);
++
++  for (PRUint32 i = 0; i < entries.Length(); ++i) {
++    bool isEqual = false;
+ 
+-    nsRefPtr<imgRequest> request = getter_AddRefs(entry->GetRequest());
++    nsRefPtr<imgRequest> request = getter_AddRefs(entries[i]->GetRequest());
+     if (request) {
+-      *_retval = request->Properties();
+-      NS_ADDREF(*_retval);
++      request->mURI->Equals(uri, &isEqual);
++      if (isEqual) {
++        if (gCacheTracker && entries[i]->HasNoProxies())
++          gCacheTracker->MarkUsed(entries[i]);
++
++        *_retval = request->Properties();
++      }
+     }
+   }
+ 
+-  return NS_OK;
++  if (*_retval)
++    return NS_OK;
++  
++  return NS_ERROR_NOT_AVAILABLE;
+ }
+ 
+ void imgLoader::Shutdown()
+@@ -1018,20 +1046,18 @@ void imgLoader::MinimizeCaches()
+   EvictEntries(sChromeCacheQueue);
+ }
+ 
+-bool imgLoader::PutIntoCache(nsIURI *key, imgCacheEntry *entry)
++bool imgLoader::PutIntoCache(nsCAutoString key, 
++                             imgCacheEntry *entry)
+ {
+-  imgCacheTable &cache = GetCache(key);
+-
+-  nsCAutoString spec;
+-  key->GetSpec(spec);
+-
+-  LOG_STATIC_FUNC_WITH_PARAM(gImgLog, "imgLoader::PutIntoCache", "uri", spec.get());
++  LOG_STATIC_FUNC_WITH_PARAM(gImgLog, "imgLoader::PutIntoCache", "uri", key.get());
++  imgCacheTable &cache = GetCache(entry->mRequest->mURI);
++  imgCacheQueue &queue = GetCacheQueue(entry->mRequest->mURI);
+ 
+   // Check to see if this request already exists in the cache and is being
+   // loaded on a different thread. If so, don't allow this entry to be added to
+   // the cache.
+   nsRefPtr<imgCacheEntry> tmpCacheEntry;
+-  if (cache.Get(spec, getter_AddRefs(tmpCacheEntry)) && tmpCacheEntry) {
++  if (cache.Get(key, getter_AddRefs(tmpCacheEntry)) && tmpCacheEntry) {
+     PR_LOG(gImgLog, PR_LOG_DEBUG,
+            ("[this=%p] imgLoader::PutIntoCache -- Element already in the cache", nsnull));
+     nsRefPtr<imgRequest> tmpRequest = getter_AddRefs(tmpCacheEntry->GetRequest());
+@@ -1041,13 +1067,13 @@ bool imgLoader::PutIntoCache(nsIURI *key, imgCacheEntry *entry)
+     PR_LOG(gImgLog, PR_LOG_DEBUG,
+            ("[this=%p] imgLoader::PutIntoCache -- Replacing cached element", nsnull));
+ 
+-    RemoveFromCache(key);
++    RemoveKeyFromCache(cache, queue, key);
+   } else {
+     PR_LOG(gImgLog, PR_LOG_DEBUG,
+            ("[this=%p] imgLoader::PutIntoCache -- Element NOT already in the cache", nsnull));
+   }
+ 
+-  cache.Put(spec, entry);
++  cache.Put(key, entry);
+ 
+   // We can be called to resurrect an evicted entry.
+   if (entry->Evicted())
+@@ -1062,7 +1088,6 @@ bool imgLoader::PutIntoCache(nsIURI *key, imgCacheEntry *entry)
+       addrv = gCacheTracker->AddObject(entry);
+ 
+     if (NS_SUCCEEDED(addrv)) {
+-      imgCacheQueue &queue = GetCacheQueue(key);
+       queue.Push(entry);
+     }
+   }
+@@ -1168,7 +1193,7 @@ void imgLoader::CheckCacheLimits(imgCacheTable &cache, imgCacheQueue &queue)
+ 
+ bool imgLoader::ValidateRequestWithNewChannel(imgRequest *request,
+                                                 nsIURI *aURI,
+-                                                nsIURI *aInitialDocumentURI,
++                                                nsIURI *aFirstPartyURI,
+                                                 nsIURI *aReferrerURI,
+                                                 nsILoadGroup *aLoadGroup,
+                                                 imgIDecoderObserver *aObserver,
+@@ -1220,7 +1245,7 @@ bool imgLoader::ValidateRequestWithNewChannel(imgRequest *request,
+     rv = NewImageChannel(getter_AddRefs(newChannel),
+                          &forcePrincipalCheck,
+                          aURI,
+-                         aInitialDocumentURI,
++                         aFirstPartyURI,
+                          aReferrerURI,
+                          aLoadGroup,
+                          mAcceptHeader,
+@@ -1289,7 +1314,7 @@ bool imgLoader::ValidateRequestWithNewChannel(imgRequest *request,
+ 
+ bool imgLoader::ValidateEntry(imgCacheEntry *aEntry,
+                                 nsIURI *aURI,
+-                                nsIURI *aInitialDocumentURI,
++                                nsIURI *aFirstPartyURI,
+                                 nsIURI *aReferrerURI,
+                                 nsILoadGroup *aLoadGroup,
+                                 imgIDecoderObserver *aObserver,
+@@ -1395,7 +1420,7 @@ bool imgLoader::ValidateEntry(imgCacheEntry *aEntry,
+   if (validateRequest && aCanMakeNewChannel) {
+     LOG_SCOPE(gImgLog, "imgLoader::ValidateRequest |cache hit| must validate");
+ 
+-    return ValidateRequestWithNewChannel(request, aURI, aInitialDocumentURI,
++    return ValidateRequestWithNewChannel(request, aURI, aFirstPartyURI,
+                                          aReferrerURI, aLoadGroup, aObserver,
+                                          aCX, aLoadFlags, aExistingRequest,
+                                          aProxyRequest, aPolicy,
+@@ -1405,16 +1430,32 @@ bool imgLoader::ValidateEntry(imgCacheEntry *aEntry,
+   return !validateRequest;
+ }
+ 
+-
+-bool imgLoader::RemoveFromCache(nsIURI *aKey)
++bool imgLoader::RemoveMatchingUrlsFromCache(nsIURI *aKey)
+ {
+-  if (!aKey) return false;
+-
++  bool rv = true;
+   imgCacheTable &cache = GetCache(aKey);
+-  imgCacheQueue &queue = GetCacheQueue(aKey);
+ 
+-  nsCAutoString spec;
+-  aKey->GetSpec(spec);
++  // We have to make a temporary, since RemoveFromCache removes the element
++  // from the queue, invalidating iterators.
++  nsTArray<nsRefPtr<imgCacheEntry> > entries;
++  cache.Enumerate(EnumAllEntries, &entries);
++
++  for (PRUint32 i = 0; i < entries.Length(); ++i) {
++    bool isEqual = false;
++
++    entries[i]->mRequest->mURI->Equals(aKey, &isEqual);
++    if (isEqual && !RemoveFromCache(entries[i]))
++      rv = false;
++  }
++
++  return rv;
++}
++
++bool imgLoader::RemoveKeyFromCache(imgCacheTable &cache, 
++                                   imgCacheQueue &queue,
++                                   nsCAutoString spec)
++{
++  if (spec.IsEmpty()) return false;
+ 
+   LOG_STATIC_FUNC_WITH_PARAM(gImgLog, "imgLoader::RemoveFromCache", "uri", spec.get());
+ 
+@@ -1448,12 +1489,13 @@ bool imgLoader::RemoveFromCache(imgCacheEntry *entry)
+ 
+   nsRefPtr<imgRequest> request(getter_AddRefs(entry->GetRequest()));
+   if (request) {
+-    nsCOMPtr<nsIURI> key;
+-    if (NS_SUCCEEDED(request->GetURI(getter_AddRefs(key))) && key) {
+-      imgCacheTable &cache = GetCache(key);
+-      imgCacheQueue &queue = GetCacheQueue(key);
+-      nsCAutoString spec;
+-      key->GetSpec(spec);
++    nsCOMPtr<nsIURI> imgURI = request->mURI;
++    nsCOMPtr<nsIURI> firstPartyURI = request->mFirstPartyURI;
++
++    if (imgURI && firstPartyURI) {
++      imgCacheTable &cache = GetCache(imgURI);
++      imgCacheQueue &queue = GetCacheQueue(imgURI);
++      nsCAutoString spec = GetCacheKey(firstPartyURI, imgURI);
+ 
+       LOG_STATIC_FUNC_WITH_PARAM(gImgLog, "imgLoader::RemoveFromCache", "entry's uri", spec.get());
+ 
+@@ -1476,18 +1518,6 @@ bool imgLoader::RemoveFromCache(imgCacheEntry *entry)
+   return false;
+ }
+ 
+-static PLDHashOperator EnumEvictEntries(const nsACString&, 
+-                                        nsRefPtr<imgCacheEntry> &aData,
+-                                        void *data)
+-{
+-  nsTArray<nsRefPtr<imgCacheEntry> > *entries = 
+-    reinterpret_cast<nsTArray<nsRefPtr<imgCacheEntry> > *>(data);
+-
+-  entries->AppendElement(aData);
+-
+-  return PL_DHASH_NEXT;
+-}
+-
+ nsresult imgLoader::EvictEntries(imgCacheTable &aCacheToClear)
+ {
+   LOG_STATIC_FUNC(gImgLog, "imgLoader::EvictEntries table");
+@@ -1495,7 +1525,7 @@ nsresult imgLoader::EvictEntries(imgCacheTable &aCacheToClear)
+   // We have to make a temporary, since RemoveFromCache removes the element
+   // from the queue, invalidating iterators.
+   nsTArray<nsRefPtr<imgCacheEntry> > entries;
+-  aCacheToClear.Enumerate(EnumEvictEntries, &entries);
++  aCacheToClear.Enumerate(EnumAllEntries, &entries);
+ 
+   for (PRUint32 i = 0; i < entries.Length(); ++i)
+     if (!RemoveFromCache(entries[i]))
+@@ -1528,11 +1558,10 @@ nsresult imgLoader::EvictEntries(imgCacheQueue &aQueueToClear)
+                                   nsIRequest::VALIDATE_NEVER |    \
+                                   nsIRequest::VALIDATE_ONCE_PER_SESSION)
+ 
+-
+-/* imgIRequest loadImage (in nsIURI aURI, in nsIURI initialDocumentURI, in nsIPrincipal loadingPrincipal, in nsILoadGroup aLoadGroup, in imgIDecoderObserver aObserver, in nsISupports aCX, in nsLoadFlags aLoadFlags, in nsISupports cacheKey, in imgIRequest aRequest); */
++/* imgIRequest loadImage (in nsIURI aURI, in nsIURI aUrlBarURI, in nsIPrincipal loadingPrincipal, in nsILoadGroup aLoadGroup, in imgIDecoderObserver aObserver, in nsISupports aCX, in nsLoadFlags aLoadFlags, in nsISupports cacheKey, in imgIRequest aRequest); */
+ 
+ NS_IMETHODIMP imgLoader::LoadImage(nsIURI *aURI, 
+-                                   nsIURI *aInitialDocumentURI,
++                                   nsIURI *aFirstPartyURI,
+                                    nsIURI *aReferrerURI,
+                                    nsIPrincipal* aLoadingPrincipal,
+                                    nsILoadGroup *aLoadGroup,
+@@ -1551,8 +1580,8 @@ NS_IMETHODIMP imgLoader::LoadImage(nsIURI *aURI,
+   if (!aURI)
+     return NS_ERROR_NULL_POINTER;
+ 
+-  nsCAutoString spec;
+-  aURI->GetSpec(spec);
++  nsCAutoString spec = GetCacheKey(aFirstPartyURI, aURI);
++
+   LOG_SCOPE_WITH_PARAM(gImgLog, "imgLoader::LoadImage", "aURI", spec.get());
+ 
+   *_retval = nsnull;
+@@ -1604,7 +1633,7 @@ NS_IMETHODIMP imgLoader::LoadImage(nsIURI *aURI,
+   imgCacheTable &cache = GetCache(aURI);
+ 
+   if (cache.Get(spec, getter_AddRefs(entry)) && entry) {
+-    if (ValidateEntry(entry, aURI, aInitialDocumentURI, aReferrerURI,
++    if (ValidateEntry(entry, aURI, aFirstPartyURI, aReferrerURI,
+                       aLoadGroup, aObserver, aCX, requestFlags, true,
+                       aRequest, _retval, aPolicy, aLoadingPrincipal, corsmode)) {
+       request = getter_AddRefs(entry->GetRequest());
+@@ -1643,7 +1672,7 @@ NS_IMETHODIMP imgLoader::LoadImage(nsIURI *aURI,
+     rv = NewImageChannel(getter_AddRefs(newChannel),
+                          &forcePrincipalCheck,
+                          aURI,
+-                         aInitialDocumentURI,
++                         aFirstPartyURI,
+                          aReferrerURI,
+                          aLoadGroup,
+                          mAcceptHeader,
+@@ -1665,8 +1694,8 @@ NS_IMETHODIMP imgLoader::LoadImage(nsIURI *aURI,
+         do_CreateInstance(NS_LOADGROUP_CONTRACTID);
+     newChannel->SetLoadGroup(loadGroup);
+ 
+-    request->Init(aURI, aURI, loadGroup, newChannel, entry, aCX,
+-                  aLoadingPrincipal, corsmode);
++    request->Init(aURI, aURI, aFirstPartyURI, loadGroup, newChannel, entry,
++                  aCX, aLoadingPrincipal, corsmode);
+ 
+     // Pass the inner window ID of the loading document, if possible.
+     nsCOMPtr<nsIDocument> doc = do_QueryInterface(aCX);
+@@ -1714,7 +1743,7 @@ NS_IMETHODIMP imgLoader::LoadImage(nsIURI *aURI,
+     }
+ 
+     // Try to add the new request into the cache.
+-    PutIntoCache(aURI, entry);
++    PutIntoCache(spec, entry);
+   } else {
+     LOG_MSG_WITH_PARAM(gImgLog, 
+                        "imgLoader::LoadImage |cache hit|", "request", request);
+@@ -1774,6 +1803,21 @@ NS_IMETHODIMP imgLoader::LoadImage(nsIURI *aURI,
+   return NS_OK;
+ }
+ 
++nsCAutoString imgLoader::GetCacheKey(nsIURI *firstPartyURI, nsIURI *imgURI)
++{
++  nsCAutoString spec, hostKey;
++  imgURI->GetSpec(spec);
++
++  // FIXME: Should we use mozIThirdPartyUtil to get a domain from this?
++  firstPartyURI->GetHost(hostKey);
++
++  // Make a new key using host
++  // FIXME: This might involve a couple more copies than necessary.. 
++  // But man, 18 string types? Who knows which one I need to use to do
++  // this cheaply..
++  return hostKey + nsCAutoString("&") + spec;
++}
++
+ /* imgIRequest loadImageWithChannel(in nsIChannel channel, in imgIDecoderObserver aObserver, in nsISupports cx, out nsIStreamListener); */
+ NS_IMETHODIMP imgLoader::LoadImageWithChannel(nsIChannel *channel, imgIDecoderObserver *aObserver, nsISupports *aCX, nsIStreamListener **listener, imgIRequest **_retval)
+ {
+@@ -1784,22 +1828,27 @@ NS_IMETHODIMP imgLoader::LoadImageWithChannel(nsIChannel *channel, imgIDecoderOb
+   nsCOMPtr<nsIURI> uri;
+   channel->GetURI(getter_AddRefs(uri));
+ 
++  nsCOMPtr<nsIURI> firstPartyURI;
++  nsCOMPtr<mozIThirdPartyUtil> thirdPartySvc
++                               = do_GetService(THIRDPARTYUTIL_CONTRACTID);
++  thirdPartySvc->GetFirstPartyURI(channel, nsnull,
++                                  getter_AddRefs(firstPartyURI));
++
+   nsLoadFlags requestFlags = nsIRequest::LOAD_NORMAL;
+   channel->GetLoadFlags(&requestFlags);
+ 
+   nsRefPtr<imgCacheEntry> entry;
++  imgCacheTable &cache = GetCache(uri);
++  nsCAutoString spec = GetCacheKey(firstPartyURI, uri);
+ 
+   if (requestFlags & nsIRequest::LOAD_BYPASS_CACHE) {
+-    RemoveFromCache(uri);
++    imgCacheQueue &queue = GetCacheQueue(uri);
++    RemoveKeyFromCache(cache, queue, spec);
+   } else {
+     // Look in the cache for our URI, and then validate it.
+     // XXX For now ignore aCacheKey. We will need it in the future
+     // for correctly dealing with image load requests that are a result
+     // of post data.
+-    imgCacheTable &cache = GetCache(uri);
+-    nsCAutoString spec;
+-
+-    uri->GetSpec(spec);
+ 
+     if (cache.Get(spec, getter_AddRefs(entry)) && entry) {
+       // We don't want to kick off another network load. So we ask
+@@ -1871,7 +1920,7 @@ NS_IMETHODIMP imgLoader::LoadImageWithChannel(nsIChannel *channel, imgIDecoderOb
+     channel->GetOriginalURI(getter_AddRefs(originalURI));
+ 
+     // No principal specified here, because we're not passed one.
+-    request->Init(originalURI, uri, channel, channel, entry,
++    request->Init(originalURI, uri, firstPartyURI, channel, channel, entry,
+                   aCX, nsnull, imgIRequest::CORS_NONE);
+ 
+     ProxyListener *pl = new ProxyListener(static_cast<nsIStreamListener *>(request.get()));
+@@ -1883,7 +1932,7 @@ NS_IMETHODIMP imgLoader::LoadImageWithChannel(nsIChannel *channel, imgIDecoderOb
+     NS_RELEASE(pl);
+ 
+     // Try to add the new request into the cache.
+-    PutIntoCache(originalURI, entry);
++    PutIntoCache(GetCacheKey(originalURI, firstPartyURI), entry);
+ 
+     rv = CreateNewProxyForRequest(request, loadGroup, aObserver,
+                                   requestFlags, nsnull, _retval);
+@@ -2170,6 +2219,7 @@ NS_IMETHODIMP imgCacheValidator::OnStartRequest(nsIRequest *aRequest, nsISupport
+ 
+   PRInt32 corsmode = mRequest->GetCORSMode();
+   nsCOMPtr<nsIPrincipal> loadingPrincipal = mRequest->GetLoadingPrincipal();
++  nsCOMPtr<nsIURI> firstPartyURI = mRequest->mFirstPartyURI;
+ 
+   // Doom the old request's cache entry
+   mRequest->RemoveFromCache();
+@@ -2180,16 +2230,16 @@ NS_IMETHODIMP imgCacheValidator::OnStartRequest(nsIRequest *aRequest, nsISupport
+   // We use originalURI here to fulfil the imgIRequest contract on GetURI.
+   nsCOMPtr<nsIURI> originalURI;
+   channel->GetOriginalURI(getter_AddRefs(originalURI));
+-  mNewRequest->Init(originalURI, uri, aRequest, channel, mNewEntry,
+-                    mContext, loadingPrincipal,
+-                    corsmode);
++  mNewRequest->Init(originalURI, uri, firstPartyURI, aRequest, channel,
++                    mNewEntry, mContext, loadingPrincipal, corsmode);
+ 
+   mDestListener = new ProxyListener(mNewRequest);
+ 
+   // Try to add the new request into the cache. Note that the entry must be in
+   // the cache before the proxies' ownership changes, because adding a proxy
+   // changes the caching behaviour for imgRequests.
+-  sImgLoader.PutIntoCache(originalURI, mNewEntry);
++  sImgLoader.PutIntoCache(imgLoader::GetCacheKey(firstPartyURI, originalURI),
++                          mNewEntry);
+ 
+   PRUint32 count = mProxies.Count();
+   for (PRInt32 i = count-1; i>=0; i--) {
+diff --git a/image/src/imgLoader.h b/image/src/imgLoader.h
+index 9911a85..0451ae7 100644
+--- a/image/src/imgLoader.h
++++ b/image/src/imgLoader.h
+@@ -227,10 +227,11 @@ public:
+ 
+   static nsresult InitCache();
+ 
+-  static bool RemoveFromCache(nsIURI *aKey);
++  static nsCAutoString GetCacheKey(nsIURI *firstPartyURI,
++                                   nsIURI *imgURI);
+   static bool RemoveFromCache(imgCacheEntry *entry);
+-
+-  static bool PutIntoCache(nsIURI *key, imgCacheEntry *entry);
++  static bool PutIntoCache(nsCAutoString key, imgCacheEntry *entry);
++  static bool RemoveMatchingUrlsFromCache(nsIURI *aKey);
+ 
+   // Returns true if we should prefer evicting cache entry |two| over cache
+   // entry |one|.
+@@ -315,9 +316,15 @@ private: // methods
+   static void CacheEntriesChanged(nsIURI *aURI, PRInt32 sizediff = 0);
+   static void CheckCacheLimits(imgCacheTable &cache, imgCacheQueue &queue);
+ 
++  static bool RemoveKeyFromCache(imgCacheTable &cache, 
++                                 imgCacheQueue &queue,
++                                 nsCAutoString key);
++
++
+ private: // data
+   friend class imgCacheEntry;
+   friend class imgMemoryReporter;
++  friend class imgRequest;
+ 
+   static imgCacheTable sCache;
+   static imgCacheQueue sCacheQueue;
+diff --git a/image/src/imgRequest.cpp b/image/src/imgRequest.cpp
+index 81e108a..28ff837 100644
+--- a/image/src/imgRequest.cpp
++++ b/image/src/imgRequest.cpp
+@@ -103,6 +103,7 @@ imgRequest::~imgRequest()
+ 
+ nsresult imgRequest::Init(nsIURI *aURI,
+                           nsIURI *aCurrentURI,
++                          nsIURI *aFirstPartyURI,
+                           nsIRequest *aRequest,
+                           nsIChannel *aChannel,
+                           imgCacheEntry *aCacheEntry,
+@@ -124,6 +125,7 @@ nsresult imgRequest::Init(nsIURI *aURI,
+ 
+   mURI = aURI;
+   mCurrentURI = aCurrentURI;
++  mFirstPartyURI = aFirstPartyURI;
+   mRequest = aRequest;
+   mChannel = aChannel;
+   mTimedChannel = do_QueryInterface(mChannel);
+@@ -317,8 +319,11 @@ void imgRequest::RemoveFromCache()
+     // mCacheEntry is nulled out when we have no more observers.
+     if (mCacheEntry)
+       imgLoader::RemoveFromCache(mCacheEntry);
+-    else
+-      imgLoader::RemoveFromCache(mURI);
++    else {
++      imgLoader::RemoveKeyFromCache(imgLoader::GetCache(mURI),
++                                    imgLoader::GetCacheQueue(mURI),
++                                    imgLoader::GetCacheKey(mFirstPartyURI, mURI));
++    }
+   }
+ 
+   mCacheEntry = nsnull;
+diff --git a/image/src/imgRequest.h b/image/src/imgRequest.h
+index 3c2d1bc..f4399b2 100644
+--- a/image/src/imgRequest.h
++++ b/image/src/imgRequest.h
+@@ -57,6 +57,7 @@ public:
+ 
+   nsresult Init(nsIURI *aURI,
+                 nsIURI *aCurrentURI,
++                nsIURI *aFirstPartyURI,
+                 nsIRequest *aRequest,
+                 nsIChannel *aChannel,
+                 imgCacheEntry *aCacheEntry,
+@@ -189,6 +190,8 @@ private:
+   nsCOMPtr<nsIURI> mURI;
+   // The URI of the resource we ended up loading after all redirects, etc.
+   nsCOMPtr<nsIURI> mCurrentURI;
++  // The first party that triggered the load -- for cookie + cache isolation
++  nsCOMPtr<nsIURI> mFirstPartyURI;
+   // The principal of the document which loaded this image. Used when validating for CORS.
+   nsCOMPtr<nsIPrincipal> mLoadingPrincipal;
+   // The principal of this image.
+diff --git a/layout/generic/nsImageFrame.cpp b/layout/generic/nsImageFrame.cpp
+index d0ed1c4..7d1e8a0 100644
+--- a/layout/generic/nsImageFrame.cpp
++++ b/layout/generic/nsImageFrame.cpp
+@@ -63,6 +63,7 @@
+ #include "nsLayoutErrors.h"
+ #include "nsBidiUtils.h"
+ #include "nsBidiPresUtils.h"
++#include "mozIThirdPartyUtil.h"
+ 
+ #include "gfxRect.h"
+ #include "ImageLayers.h"
+@@ -1794,9 +1795,17 @@ nsImageFrame::LoadIcon(const nsAString& aSpec,
+ 
+   // For icon loads, we don't need to merge with the loadgroup flags
+   nsLoadFlags loadFlags = nsIRequest::LOAD_NORMAL;
++  
++  nsCOMPtr<nsIURI> firstPartyURI;
++  nsCOMPtr<mozIThirdPartyUtil> thirdPartySvc
++      = do_GetService(THIRDPARTYUTIL_CONTRACTID);
++  // XXX: Should we pass the loadgroup, too? Is document ever likely
++  // to be unset?
++  thirdPartySvc->GetFirstPartyURI(nsnull, aPresContext->Document(),
++                                 getter_AddRefs(firstPartyURI));
+ 
+   return il->LoadImage(realURI,     /* icon URI */
+-                       nsnull,      /* initial document URI; this is only
++                       firstPartyURI,      /* initial document URI; this is only
+                                        relevant for cookies, so does not
+                                        apply to icons. */
+                        nsnull,      /* referrer (not relevant for icons) */
+diff --git a/netwerk/base/public/mozIThirdPartyUtil.idl b/netwerk/base/public/mozIThirdPartyUtil.idl
+index 578d8db..1869d14 100644
+--- a/netwerk/base/public/mozIThirdPartyUtil.idl
++++ b/netwerk/base/public/mozIThirdPartyUtil.idl
+@@ -7,6 +7,7 @@
+ interface nsIURI;
+ interface nsIDOMWindow;
+ interface nsIChannel;
++interface nsIDocument;
+ 
+ /**
+  * Utility functions for determining whether a given URI, channel, or window
+@@ -140,6 +141,26 @@ interface mozIThirdPartyUtil : nsISupports
+    * @return the base domain.
+    */
+   AUTF8String getBaseDomain(in nsIURI aHostURI);
++
++
++  /**
++   * getFirstPartyURI
++   *
++   * Obtain the top-level url bar URI for either a channel or a document.
++   * Either parameter may be null (but not both).
++   * 
++   * @param aChannel
++   *        An arbitrary channel for some content element of a first party
++   *        load. Can be null.
++   *
++   * @param aDoc
++   *        An arbitrary third party document. Can be null.
++   *
++   * @return the first party url bar URI for the load.
++   */ 
++  nsIURI getFirstPartyURI(in nsIChannel aChannel,
++                          in nsIDocument aDoc);
++
+ };
+ 
+ %{ C++
+diff --git a/netwerk/cookie/nsICookiePermission.idl b/netwerk/cookie/nsICookiePermission.idl
+index c576a46..5a753f3 100644
+--- a/netwerk/cookie/nsICookiePermission.idl
++++ b/netwerk/cookie/nsICookiePermission.idl
+@@ -7,6 +7,7 @@
+ interface nsICookie2;
+ interface nsIURI;
+ interface nsIChannel;
++interface nsIDocument;
+ 
+ typedef long nsCookieAccess;
+ 
+diff --git a/toolkit/system/gnome/nsAlertsIconListener.cpp b/toolkit/system/gnome/nsAlertsIconListener.cpp
+index e6f4068..61927af 100644
+--- a/toolkit/system/gnome/nsAlertsIconListener.cpp
++++ b/toolkit/system/gnome/nsAlertsIconListener.cpp
+@@ -239,7 +239,8 @@ nsAlertsIconListener::StartRequest(const nsAString & aImageUrl)
+   if (!il)
+     return ShowAlert(NULL);
+ 
+-  return il->LoadImage(imageUri, nsnull, nsnull, nsnull, nsnull, this,
++  // XXX: Hrmm.... Bypass cache, or isolate to imageUrl?
++  return il->LoadImage(imageUri, imageUri, nsnull, nsnull, nsnull, this,
+                        nsnull, nsIRequest::LOAD_NORMAL, nsnull, nsnull,
+                        nsnull, getter_AddRefs(mIconRequest));
+ }
+diff --git a/widget/cocoa/nsMenuItemIconX.mm b/widget/cocoa/nsMenuItemIconX.mm
+index 9b40850..1a267d1 100644
+--- a/widget/cocoa/nsMenuItemIconX.mm
++++ b/widget/cocoa/nsMenuItemIconX.mm
+@@ -29,6 +29,7 @@
+ #include "gfxImageSurface.h"
+ #include "imgIContainer.h"
+ #include "nsCocoaUtils.h"
++#include "mozIThirdPartyUtil.h"
+ 
+ static const PRUint32 kIconWidth = 16;
+ static const PRUint32 kIconHeight = 16;
+@@ -304,9 +305,15 @@ nsMenuItemIconX::LoadIcon(nsIURI* aIconURI)
+       [mNativeMenuItem setImage:sPlaceholderIconImage];
+   }
+ 
++  nsCOMPtr<nsIURI> firstPartyURI;
++  nsCOMPtr<mozIThirdPartyUtil> thirdPartySvc
++                               = do_GetService(THIRDPARTYUTIL_CONTRACTID);
++  thirdPartySvc->GetFirstPartyURI(nsnull, document,
++                                  getter_AddRefs(firstPartyURI));
++
+   // Passing in null for channelPolicy here since nsMenuItemIconX::LoadIcon is
+   // not exposed to web content
+-  rv = loader->LoadImage(aIconURI, nsnull, nsnull, nsnull, loadGroup, this,
++  rv = loader->LoadImage(aIconURI, firstPartyURI, nsnull, nsnull, loadGroup, this,
+                          nsnull, nsIRequest::LOAD_NORMAL, nsnull, nsnull,
+                          nsnull, getter_AddRefs(mIconRequest));
+   if (NS_FAILED(rv)) return rv;
+-- 
+1.7.5.4
+





More information about the tor-commits mailing list