[tor-commits] [torbrowser/master] Update Firefox patches for 17.0.10ESR.

mikeperry at torproject.org mikeperry at torproject.org
Wed Oct 30 02:02:53 UTC 2013


commit d35038d0a6af7e6033cd8a9f8a5853f116c40319
Author: Mike Perry <mikeperry-git at torproject.org>
Date:   Tue Oct 29 18:53:04 2013 -0700

    Update Firefox patches for 17.0.10ESR.
    
    This is the subset from TBB 3.0beta1 that are relevant to TBB 2.x.
---
 ...-Block-Components.interfaces-from-content.patch |   14 +-
 ...0002-Make-Permissions-Manager-memory-only.patch |   10 +-
 ...-Make-Intermediate-Cert-Store-memory-only.patch |   10 +-
 .../firefox/0004-Add-a-string-based-cacheKey.patch |   14 +-
 .../0005-Block-all-plugins-except-flash.patch      |   14 +-
 ...ontent-pref-service-memory-only-clearable.patch |   10 +-
 ...owser-exit-when-not-launched-from-Vidalia.patch |   45 -
 .../0008-Disable-SSL-Session-ID-tracking.patch     |   28 -
 ...observer-event-to-close-persistent-connec.patch |   40 -
 ...ice-and-system-specific-CSS-Media-Queries.patch |  147 ----
 ...11-Limit-the-number-of-fonts-per-document.patch |  451 ----------
 .../0012-Rebrand-Firefox-to-TorBrowser.patch       |   59 --
 .../0013-Make-Download-manager-memory-only.patch   |   57 --
 .../0014-Add-DDG-and-StartPage-to-Omnibox.patch    |  103 ---
 ...-nsICacheService.EvictEntries-synchronous.patch |   43 -
 .../firefox/0016-Prevent-WebSocket-DNS-leak.patch  |  133 ---
 ...ize-HTTP-request-order-and-pipeline-depth.patch |  791 -----------------
 ...er-event-to-filter-the-Drag-Drop-url-list.patch |   74 --
 ...d-mozIThirdPartyUtil.getFirstPartyURI-API.patch |  164 ----
 .../0020-Add-canvas-image-extraction-prompt.patch  |  548 ------------
 ...nt-window-coordinates-for-mouse-event-scr.patch |   77 --
 ...se-physical-screen-info.-via-window-and-w.patch |  310 -------
 ...not-expose-system-colors-to-CSS-or-canvas.patch |  631 --------------
 ...solate-the-Image-Cache-per-url-bar-domain.patch |  922 --------------------
 .../0025-nsIHTTPChannel.redirectTo-API.patch       |  474 ----------
 ...26-Isolate-DOM-storage-to-first-party-URI.patch |  776 ----------------
 ...27-Remove-This-plugin-is-disabled-barrier.patch |   46 -
 .../0028-Use-Optimistic-Data-SOCKS-variant.patch   |   82 --
 .../0029-Disable-library-timestamping.patch        |   27 -
 29 files changed, 36 insertions(+), 6064 deletions(-)

diff --git a/src/current-patches/firefox/0001-Block-Components.interfaces-from-content.patch b/src/current-patches/firefox/0001-Block-Components.interfaces-from-content.patch
index a1ed5a8..035bfcd 100644
--- a/src/current-patches/firefox/0001-Block-Components.interfaces-from-content.patch
+++ b/src/current-patches/firefox/0001-Block-Components.interfaces-from-content.patch
@@ -1,7 +1,7 @@
-From 26ab2cbf5b925a3f1251bd536728a7e222b4f9e4 Mon Sep 17 00:00:00 2001
+From b3ea41baf4c3ff455ab9c40ab090f8f77e34924d Mon Sep 17 00:00:00 2001
 From: Mike Perry <mikeperry-git at torproject.org>
 Date: Tue, 4 Dec 2012 15:41:09 -0800
-Subject: [PATCH 01/27] Block Components.interfaces from content
+Subject: [PATCH 01/41] Block Components.interfaces from content
 
 This patch removes the ability of content script to access
 Components.interfaces.*.
@@ -16,14 +16,14 @@ https://trac.torproject.org/projects/tor/ticket/2874
 Note: We no longer block Components.lookupMethod, because we no longer rely on
 JS hooks for fingerprinting defenses.
 ---
- js/xpconnect/src/XPCComponents.cpp |    2 +-
- 1 files changed, 1 insertions(+), 1 deletions(-)
+ js/xpconnect/src/XPCComponents.cpp | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
 
 diff --git a/js/xpconnect/src/XPCComponents.cpp b/js/xpconnect/src/XPCComponents.cpp
-index 3a14254..4040349 100644
+index e0b03fc..aa83318 100644
 --- a/js/xpconnect/src/XPCComponents.cpp
 +++ b/js/xpconnect/src/XPCComponents.cpp
-@@ -4838,7 +4838,7 @@ nsXPCComponents::CanCallMethod(const nsIID * iid, const PRUnichar *methodName, c
+@@ -4837,7 +4837,7 @@ nsXPCComponents::CanCallMethod(const nsIID * iid, const PRUnichar *methodName, c
  NS_IMETHODIMP
  nsXPCComponents::CanGetProperty(const nsIID * iid, const PRUnichar *propertyName, char **_retval)
  {
@@ -33,5 +33,5 @@ index 3a14254..4040349 100644
      return NS_OK;
  }
 -- 
-1.7.5.4
+1.8.1.2
 
diff --git a/src/current-patches/firefox/0002-Make-Permissions-Manager-memory-only.patch b/src/current-patches/firefox/0002-Make-Permissions-Manager-memory-only.patch
index 4a2b515..bf38d04 100644
--- a/src/current-patches/firefox/0002-Make-Permissions-Manager-memory-only.patch
+++ b/src/current-patches/firefox/0002-Make-Permissions-Manager-memory-only.patch
@@ -1,7 +1,7 @@
-From 2391ce37afd5da908fc986cec6018795cb06fa63 Mon Sep 17 00:00:00 2001
+From c3c1d5555672c8348feb8f545aad7241a2f81a0a Mon Sep 17 00:00:00 2001
 From: Mike Perry <mikeperry-git at torproject.org>
 Date: Tue, 4 Dec 2012 15:45:59 -0800
-Subject: [PATCH 02/27] Make Permissions Manager memory-only
+Subject: [PATCH 02/41] 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
@@ -12,8 +12,8 @@ does not need to be set in prefs.js, and can be handled by Torbutton.
 
 https://trac.torproject.org/projects/tor/ticket/2950
 ---
- extensions/cookie/nsPermissionManager.cpp |   34 ++++++++++++++++++++++++++--
- 1 files changed, 31 insertions(+), 3 deletions(-)
+ extensions/cookie/nsPermissionManager.cpp | 34 ++++++++++++++++++++++++++++---
+ 1 file changed, 31 insertions(+), 3 deletions(-)
 
 diff --git a/extensions/cookie/nsPermissionManager.cpp b/extensions/cookie/nsPermissionManager.cpp
 index 9c50080..4102408 100644
@@ -90,5 +90,5 @@ index 9c50080..4102408 100644
      // or is going away because the application is shutting down.
      mIsShuttingDown = true;
 -- 
-1.7.5.4
+1.8.1.2
 
diff --git a/src/current-patches/firefox/0003-Make-Intermediate-Cert-Store-memory-only.patch b/src/current-patches/firefox/0003-Make-Intermediate-Cert-Store-memory-only.patch
index 37daf66..23c99f7 100644
--- a/src/current-patches/firefox/0003-Make-Intermediate-Cert-Store-memory-only.patch
+++ b/src/current-patches/firefox/0003-Make-Intermediate-Cert-Store-memory-only.patch
@@ -1,15 +1,15 @@
-From 5130a82dcc2dd7385d7d1cd2b15daa1dc4577f5b Mon Sep 17 00:00:00 2001
+From e10d253e44e4541a0030b041bdc430f416defcb3 Mon Sep 17 00:00:00 2001
 From: Mike Perry <mikeperry-git at torproject.org>
 Date: Tue, 4 Dec 2012 15:51:07 -0800
-Subject: [PATCH 03/27] Make Intermediate Cert Store memory-only.
+Subject: [PATCH 03/41] Make Intermediate Cert Store memory-only.
 
 This patch makes the intermediate SSL cert store exist in memory only.
 
 The pref must be set before startup in prefs.js.
 https://trac.torproject.org/projects/tor/ticket/2949
 ---
- security/manager/ssl/src/nsNSSComponent.cpp |   17 +++++++++++++++--
- 1 files changed, 15 insertions(+), 2 deletions(-)
+ security/manager/ssl/src/nsNSSComponent.cpp | 17 +++++++++++++++--
+ 1 file changed, 15 insertions(+), 2 deletions(-)
 
 diff --git a/security/manager/ssl/src/nsNSSComponent.cpp b/security/manager/ssl/src/nsNSSComponent.cpp
 index c9205bc..159985c 100644
@@ -40,5 +40,5 @@ index c9205bc..159985c 100644
      if (init_rv != SECSuccess) {
        PR_LOG(gPIPNSSLog, PR_LOG_DEBUG, ("can not init NSS r/w in %s\n", profileStr.get()));
 -- 
-1.7.5.4
+1.8.1.2
 
diff --git a/src/current-patches/firefox/0004-Add-a-string-based-cacheKey.patch b/src/current-patches/firefox/0004-Add-a-string-based-cacheKey.patch
index b9f4572..c8c3bea 100644
--- a/src/current-patches/firefox/0004-Add-a-string-based-cacheKey.patch
+++ b/src/current-patches/firefox/0004-Add-a-string-based-cacheKey.patch
@@ -1,14 +1,14 @@
-From 0d1a840e58117d83d910d3eb09e9f7deaaeabbff Mon Sep 17 00:00:00 2001
+From 7cdd6f0ac4b4b236ca5177e0fc5e7621fd012878 Mon Sep 17 00:00:00 2001
 From: Mike Perry <mikeperry-git at torproject.org>
 Date: Tue, 4 Dec 2012 16:01:42 -0800
-Subject: [PATCH 04/27] Add a string-based cacheKey.
+Subject: [PATCH 04/41] Add a string-based cacheKey.
 
 Used for isolating cache according to same-origin policy.
 ---
- netwerk/base/public/nsICachingChannel.idl |    7 +++++++
- netwerk/protocol/http/nsHttpChannel.cpp   |   22 ++++++++++++++++++++++
- netwerk/protocol/http/nsHttpChannel.h     |    1 +
- 3 files changed, 30 insertions(+), 0 deletions(-)
+ netwerk/base/public/nsICachingChannel.idl |  7 +++++++
+ netwerk/protocol/http/nsHttpChannel.cpp   | 22 ++++++++++++++++++++++
+ netwerk/protocol/http/nsHttpChannel.h     |  1 +
+ 3 files changed, 30 insertions(+)
 
 diff --git a/netwerk/base/public/nsICachingChannel.idl b/netwerk/base/public/nsICachingChannel.idl
 index 3119dd9..fd2ec89 100644
@@ -81,5 +81,5 @@ index d66415f..b1f0848 100644
      // auth specific data
      nsCOMPtr<nsIHttpChannelAuthProvider> mAuthProvider;
 -- 
-1.7.5.4
+1.8.1.2
 
diff --git a/src/current-patches/firefox/0005-Block-all-plugins-except-flash.patch b/src/current-patches/firefox/0005-Block-all-plugins-except-flash.patch
index 6f70b29..976c707 100644
--- a/src/current-patches/firefox/0005-Block-all-plugins-except-flash.patch
+++ b/src/current-patches/firefox/0005-Block-all-plugins-except-flash.patch
@@ -1,7 +1,7 @@
-From 7c95e69c73f64e45f9a1f5821a1e96457f9ae83a Mon Sep 17 00:00:00 2001
+From df78c79c083df8116e4312806ca3a875295e35bd Mon Sep 17 00:00:00 2001
 From: Mike Perry <mikeperry-git at torproject.org>
 Date: Tue, 4 Dec 2012 16:03:13 -0800
-Subject: [PATCH 05/27] Block all plugins except flash.
+Subject: [PATCH 05/41] 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
@@ -12,12 +12,12 @@ ruin our day, and censorship filters). Hence we rolled our own.
 See https://trac.torproject.org/projects/tor/ticket/3547#comment:6 for musings
 on a better way. Until then, it is delta-darwinism for us.
 ---
- dom/plugins/base/nsPluginHost.cpp |   33 +++++++++++++++++++++++++++++++++
- dom/plugins/base/nsPluginHost.h   |    2 ++
- 2 files changed, 35 insertions(+), 0 deletions(-)
+ dom/plugins/base/nsPluginHost.cpp | 33 +++++++++++++++++++++++++++++++++
+ dom/plugins/base/nsPluginHost.h   |  2 ++
+ 2 files changed, 35 insertions(+)
 
 diff --git a/dom/plugins/base/nsPluginHost.cpp b/dom/plugins/base/nsPluginHost.cpp
-index 858b428..c7ae680 100644
+index 858b4284..c7ae680 100644
 --- a/dom/plugins/base/nsPluginHost.cpp
 +++ b/dom/plugins/base/nsPluginHost.cpp
 @@ -2052,6 +2052,35 @@ struct CompareFilesByTime
@@ -81,5 +81,5 @@ index 3c48eec..2cba11d 100644
    // and removes it from the cache.
    void RemoveCachedPluginsInfo(const char *filePath,
 -- 
-1.7.5.4
+1.8.1.2
 
diff --git a/src/current-patches/firefox/0006-Make-content-pref-service-memory-only-clearable.patch b/src/current-patches/firefox/0006-Make-content-pref-service-memory-only-clearable.patch
index ac514c1..81d8bea 100644
--- a/src/current-patches/firefox/0006-Make-content-pref-service-memory-only-clearable.patch
+++ b/src/current-patches/firefox/0006-Make-content-pref-service-memory-only-clearable.patch
@@ -1,14 +1,14 @@
-From 50293cf7c107df2d76492890b945d17f63536f90 Mon Sep 17 00:00:00 2001
+From 98fb4263ec8b9f530336cbdf961323bf3380a386 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/27] Make content pref service memory-only + clearable
+Subject: [PATCH 06/41] Make content pref service memory-only + clearable
 
 This prevents random urls from being inserted into content-prefs.sqllite in
 the profile directory as content prefs change (includes site-zoom and perhaps
 other site prefs?).
 ---
- .../contentprefs/nsContentPrefService.js           |    4 ++--
- 1 files changed, 2 insertions(+), 2 deletions(-)
+ toolkit/components/contentprefs/nsContentPrefService.js | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
 
 diff --git a/toolkit/components/contentprefs/nsContentPrefService.js b/toolkit/components/contentprefs/nsContentPrefService.js
 index ed8ad2e..794c9f3 100644
@@ -33,5 +33,5 @@ index ed8ad2e..794c9f3 100644
      try {
        this._dbCreateSchema(dbConnection);
 -- 
-1.7.5.4
+1.8.1.2
 
diff --git a/src/current-patches/firefox/0007-Make-Tor-Browser-exit-when-not-launched-from-Vidalia.patch b/src/current-patches/firefox/0007-Make-Tor-Browser-exit-when-not-launched-from-Vidalia.patch
deleted file mode 100644
index 5304a1a..0000000
--- a/src/current-patches/firefox/0007-Make-Tor-Browser-exit-when-not-launched-from-Vidalia.patch
+++ /dev/null
@@ -1,45 +0,0 @@
-From b2c1cd58fda04daa92b6f69253fd2ff8bc7ce8f4 Mon Sep 17 00:00:00 2001
-From: Mike Perry <mikeperry-git at torproject.org>
-Date: Tue, 4 Dec 2012 16:29:24 -0800
-Subject: [PATCH 07/27] 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 35664ec..bd2feed 100644
---- a/browser/base/content/browser.js
-+++ b/browser/base/content/browser.js
-@@ -1093,6 +1093,20 @@ var gBrowserInit = {
-     // setup simple gestures support
-     gGestureSupport.init(true);
- 
-+    // If this is not a TBB profile, exit. 
-+    // Solves https://trac.torproject.org/projects/tor/ticket/4192
-+    var foundPref = false;
-+    try {
-+      var ignored = gPrefService.getCharPref("torbrowser.version");
-+      foundPref = true;
-+    } 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) {
--- 
-1.7.5.4
-
diff --git a/src/current-patches/firefox/0008-Disable-SSL-Session-ID-tracking.patch b/src/current-patches/firefox/0008-Disable-SSL-Session-ID-tracking.patch
deleted file mode 100644
index 494c765..0000000
--- a/src/current-patches/firefox/0008-Disable-SSL-Session-ID-tracking.patch
+++ /dev/null
@@ -1,28 +0,0 @@
-From e700063f5d18e86077af8ecf7fb3f4d92f2d0ef4 Mon Sep 17 00:00:00 2001
-From: Mike Perry <mikeperry-git at torproject.org>
-Date: Sun, 31 Mar 2013 22:48:00 -0700
-Subject: [PATCH 08/27] Disable SSL Session ID tracking.
-
-We can't easily bind SSL Session ID tracking to url bar domain,
-so we have to disable them to satisfy
-https://www.torproject.org/projects/torbrowser/design/#identifier-linkability.
----
- security/nss/lib/ssl/sslsock.c |    2 +-
- 1 file changed, 1 insertion(+), 1 deletion(-)
-
-diff --git a/security/nss/lib/ssl/sslsock.c b/security/nss/lib/ssl/sslsock.c
-index 4f4b034..6ce5d11 100644
---- a/security/nss/lib/ssl/sslsock.c
-+++ b/security/nss/lib/ssl/sslsock.c
-@@ -141,7 +141,7 @@ static sslOptions ssl_defaults = {
-     PR_FALSE,	/* enableSSL2         */ /* now defaults to off in NSS 3.13 */
-     PR_FALSE,	/* unusedBit9         */
-     PR_FALSE, 	/* unusedBit10        */
--    PR_FALSE,	/* noCache            */
-+    PR_TRUE,	/* noCache            */
-     PR_FALSE,	/* fdx                */
-     PR_FALSE,	/* v2CompatibleHello  */ /* now defaults to off in NSS 3.13 */
-     PR_TRUE,	/* detectRollBack     */
--- 
-1.7.9.5
-
diff --git a/src/current-patches/firefox/0009-Provide-an-observer-event-to-close-persistent-connec.patch b/src/current-patches/firefox/0009-Provide-an-observer-event-to-close-persistent-connec.patch
deleted file mode 100644
index 1457815..0000000
--- a/src/current-patches/firefox/0009-Provide-an-observer-event-to-close-persistent-connec.patch
+++ /dev/null
@@ -1,40 +0,0 @@
-From 41c163c0497ef16faaf103debf5bf7ef8244849a Mon Sep 17 00:00:00 2001
-From: Mike Perry <mikeperry-git at torproject.org>
-Date: Fri, 7 Sep 2012 16:18:26 -0700
-Subject: [PATCH 09/27] 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 d897a2c..e33ff08 100644
---- a/netwerk/protocol/http/nsHttpHandler.cpp
-+++ b/netwerk/protocol/http/nsHttpHandler.cpp
-@@ -312,6 +312,7 @@ nsHttpHandler::Init()
-         mObserverService->AddObserver(this, "net:clear-active-logins", true);
-         mObserverService->AddObserver(this, NS_PRIVATE_BROWSING_SWITCH_TOPIC, true);
-         mObserverService->AddObserver(this, "net:prune-dead-connections", true);
-+        mObserverService->AddObserver(this, "net:prune-all-connections", true);
-         mObserverService->AddObserver(this, "net:failed-to-process-uri-content", true);
-     }
-  
-@@ -1576,6 +1577,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/0010-Limit-device-and-system-specific-CSS-Media-Queries.patch b/src/current-patches/firefox/0010-Limit-device-and-system-specific-CSS-Media-Queries.patch
deleted file mode 100644
index e2876b3..0000000
--- a/src/current-patches/firefox/0010-Limit-device-and-system-specific-CSS-Media-Queries.patch
+++ /dev/null
@@ -1,147 +0,0 @@
-From 0c006870b9d96a8093ca66751e9738b4237c9251 Mon Sep 17 00:00:00 2001
-From: Kathleen Brade <brade at pearlcrescent.com>
-Date: Wed, 28 Nov 2012 09:49:40 -0500
-Subject: [PATCH 10/27] Limit device and system specific CSS Media Queries.
-
----
- layout/style/nsMediaFeatures.cpp |   68 +++++++++++++++++++++++++-------------
- 1 files changed, 45 insertions(+), 23 deletions(-)
-
-diff --git a/layout/style/nsMediaFeatures.cpp b/layout/style/nsMediaFeatures.cpp
-index d5741ea..5f2e6dd 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
-@@ -204,13 +208,17 @@ static nsresult
- GetColor(nsPresContext* aPresContext, const nsMediaFeature*,
-          nsCSSValue& aResult)
- {
--    // FIXME:  This implementation is bogus.  nsDeviceContext
--    // doesn't provide reliable information (should be fixed in bug
--    // 424386).
--    // FIXME: On a monochrome device, return 0!
--    nsDeviceContext *dx = GetDeviceContextFor(aPresContext);
--    uint32_t depth;
--    dx->GetDepth(depth);
-+    uint32_t depth = 24; // Always return 24 to non-chrome callers.
-+
-+    if (aPresContext->IsChrome()) {
-+        // FIXME:  This implementation is bogus.  nsDeviceContext
-+        // doesn't provide reliable information (should be fixed in bug
-+        // 424386).
-+        // FIXME: On a monochrome device, return 0!
-+        nsDeviceContext *dx = GetDeviceContextFor(aPresContext);
-+        dx->GetDepth(depth);
-+    }
-+
-     // The spec says to use bits *per color component*, so divide by 3,
-     // and round down, since the spec says to use the smallest when the
-     // color components differ.
-@@ -248,18 +256,23 @@ static nsresult
- GetResolution(nsPresContext* aPresContext, const nsMediaFeature*,
-               nsCSSValue& aResult)
- {
--    // Resolution measures device pixels per CSS (inch/cm/pixel).  We
--    // return it in device pixels per CSS inches.
--    //
--    // However, on platforms where the CSS viewport is not fixed to the
--    // screen viewport, use the device resolution instead (bug 779527).
--    nsIPresShell *shell = aPresContext->PresShell();
--    float appUnitsPerInch = shell->GetIsViewportOverridden() ?
--            GetDeviceContextFor(aPresContext)->AppUnitsPerPhysicalInch() :
--            nsPresContext::AppUnitsPerCSSInch();
--
--    float dpi = appUnitsPerInch /
-+    float dpi = 96; // Always return 96 to non-chrome callers.
-+
-+    if (aPresContext->IsChrome()) {
-+        // Resolution measures device pixels per CSS (inch/cm/pixel).  We
-+        // return it in device pixels per CSS inches.
-+        //
-+        // However, on platforms where the CSS viewport is not fixed to the
-+        // screen viewport, use the device resolution instead (bug 779527).
-+        nsIPresShell *shell = aPresContext->PresShell();
-+        float appUnitsPerInch = shell->GetIsViewportOverridden() ?
-+                GetDeviceContextFor(aPresContext)->AppUnitsPerPhysicalInch() :
-+                nsPresContext::AppUnitsPerCSSInch();
-+
-+        dpi = appUnitsPerInch /
-                 float(aPresContext->AppUnitsPerDevPixel());
-+    }
-+
-     aResult.SetFloatValue(dpi, eCSSUnit_Inch);
-     return NS_OK;
- }
-@@ -288,8 +301,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;
- }
- 
-@@ -297,20 +314,24 @@ static nsresult
- GetSystemMetric(nsPresContext* aPresContext, const nsMediaFeature* aFeature,
-                 nsCSSValue& aResult)
- {
-+  aResult.Reset();
-+  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)
- {
--    aResult.Reset();
-+  aResult.Reset();
- #ifdef XP_WIN
-+  if (aPresContext->IsChrome()) {
-     uint8_t windowsThemeId =
-         nsCSSRuleProcessor::GetWindowsThemeIdentifier();
- 
-@@ -326,8 +347,9 @@ GetWindowsTheme(nsPresContext* aPresContext, const nsMediaFeature* aFeature,
-             break;
-         }
-     }
-+  }
- #endif
--    return NS_OK;
-+  return NS_OK;
- }
- 
- /*
--- 
-1.7.5.4
-
diff --git a/src/current-patches/firefox/0011-Limit-the-number-of-fonts-per-document.patch b/src/current-patches/firefox/0011-Limit-the-number-of-fonts-per-document.patch
deleted file mode 100644
index 163968a..0000000
--- a/src/current-patches/firefox/0011-Limit-the-number-of-fonts-per-document.patch
+++ /dev/null
@@ -1,451 +0,0 @@
-From 81fde0b8f4af7bae20c49ac0ce0ea4df046a6701 Mon Sep 17 00:00:00 2001
-From: Mike Perry <mikeperry-git at torproject.org>
-Date: Wed, 5 Dec 2012 12:25:21 -0800
-Subject: [PATCH 11/28] 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.
-
-The use of "User Fonts" (aka WebFonts, aka @font-face fonts) are exempt from
-both of these limits. The patch also makes such fonts take precedence over
-local fonts. This vastly improves typography on many sites that would
-otherwise hit these limits.
-
-This is done to address:
-https://www.torproject.org/projects/torbrowser/design/#fingerprinting-linkability
----
- gfx/thebes/gfxFont.cpp            |    2 +
- gfx/thebes/gfxPangoFonts.cpp      |    1 +
- gfx/thebes/gfxUserFontSet.cpp     |   28 ++++++++++-
- gfx/thebes/gfxUserFontSet.h       |    3 ++
- layout/base/nsPresContext.cpp     |  100 +++++++++++++++++++++++++++++++++++++
- layout/base/nsPresContext.h       |    9 ++++
- layout/style/nsCSSParser.cpp      |    1 +
- layout/style/nsFontFaceLoader.cpp |    4 +-
- layout/style/nsFontFaceLoader.h   |    2 +-
- layout/style/nsRuleNode.cpp       |   56 +++++++++++++++++++--
- 10 files changed, 198 insertions(+), 8 deletions(-)
-
-diff --git a/gfx/thebes/gfxFont.cpp b/gfx/thebes/gfxFont.cpp
-index e8392e0..af5c1c8 100644
---- a/gfx/thebes/gfxFont.cpp
-+++ b/gfx/thebes/gfxFont.cpp
-@@ -3045,6 +3045,7 @@ gfxFontGroup::FindPlatformFont(const nsAString& aName,
-     }
- 
-     // Not known in the user font set ==> check system fonts
-+    // XXX: Fallback is bad..
-     if (!foundFamily) {
-         fe = gfxPlatformFontList::PlatformFontList()->
-             FindFontForFamily(aName, fontStyle, needsBold);
-@@ -3260,6 +3261,7 @@ gfxFontGroup::ForEachFontInternal(const nsAString& aFamilies,
-                     }
-                     if (!foundFamily) {
-                         gfxPlatform *pf = gfxPlatform::GetPlatform();
-+                        // XXX: Fallback is bad
-                         rv = pf->ResolveFontName(family,
-                                                  gfxFontGroup::FontResolverProc,
-                                                  &data, aborted);
-diff --git a/gfx/thebes/gfxPangoFonts.cpp b/gfx/thebes/gfxPangoFonts.cpp
-index c94a299..88c8b8e 100644
---- a/gfx/thebes/gfxPangoFonts.cpp
-+++ b/gfx/thebes/gfxPangoFonts.cpp
-@@ -1408,6 +1408,7 @@ gfxFcFontSet::SortPreferredFonts(bool &aWaitForUserFont)
-         const nsTArray< nsCountedRef<FcPattern> > *familyFonts = nullptr;
- 
-         // Is this an @font-face family?
-+        // XXX: Make use of this + pass to nsFont??
-         bool isUserFont = false;
-         if (mUserFontSet) {
-             // Have some @font-face definitions
-diff --git a/gfx/thebes/gfxUserFontSet.cpp b/gfx/thebes/gfxUserFontSet.cpp
-index 020c35a..161b52f 100644
---- a/gfx/thebes/gfxUserFontSet.cpp
-+++ b/gfx/thebes/gfxUserFontSet.cpp
-@@ -15,6 +15,7 @@
- #include "prlong.h"
- #include "nsNetUtil.h"
- #include "nsIProtocolHandler.h"
-+#include "nsFont.h"
- 
- #include "woff.h"
- 
-@@ -517,18 +518,41 @@ gfxUserFontSet::LoadNext(gfxProxyFontEntry *aProxyEntry)
-         aProxyEntry->mSrcIndex++;
-     }
- 
-+    /* If there are any urls, prefer them to local */
-+    bool listHasURL = false; 
-+    for (uint32_t i = aProxyEntry->mSrcIndex; i < numSrc; i++) {
-+        const gfxFontFaceSrc& currSrc = aProxyEntry->mSrcList[i];
-+        if (!currSrc.mIsLocal) {
-+           listHasURL = true;
-+           break;
-+        }
-+    }
-+    nsPresContext *pres = GetPresContext();
-+    /* If we have no pres context, simply fail this load */
-+    if (!pres) listHasURL = true;
-+
-     // load each src entry in turn, until a local face is found
-     // or a download begins successfully
-     while (aProxyEntry->mSrcIndex < numSrc) {
-         const gfxFontFaceSrc& currSrc = aProxyEntry->mSrcList[aProxyEntry->mSrcIndex];
- 
-         // src local ==> lookup and load immediately
--
--        if (currSrc.mIsLocal) {
-+        if (!listHasURL && currSrc.mIsLocal) {
-+            nsFont font;
-+            font.name = currSrc.mLocalName;
-             gfxFontEntry *fe =
-                 gfxPlatform::GetPlatform()->LookupLocalFont(aProxyEntry,
-                                                             currSrc.mLocalName);
-+            pres->AddFontAttempt(font);
-+
-+            /* No more fonts for you */
-+            if (pres->FontAttemptCountReached(font) || 
-+                pres->FontUseCountReached(font)) {
-+                break;
-+            }
-+
-             if (fe) {
-+                pres->AddFontUse(font);
-                 LOG(("userfonts (%p) [src %d] loaded local: (%s) for (%s) gen: %8.8x\n",
-                      this, aProxyEntry->mSrcIndex,
-                      NS_ConvertUTF16toUTF8(currSrc.mLocalName).get(),
-diff --git a/gfx/thebes/gfxUserFontSet.h b/gfx/thebes/gfxUserFontSet.h
-index 1781a37..d6f7292 100644
---- a/gfx/thebes/gfxUserFontSet.h
-+++ b/gfx/thebes/gfxUserFontSet.h
-@@ -9,6 +9,7 @@
- #include "gfxTypes.h"
- #include "gfxFont.h"
- #include "gfxFontUtils.h"
-+#include "nsPresContext.h"
- #include "nsRefPtrHashtable.h"
- #include "nsAutoPtr.h"
- #include "nsCOMPtr.h"
-@@ -230,6 +231,8 @@ public:
- 
-     // increment the generation on font load
-     void IncrementGeneration();
-+  
-+    virtual nsPresContext *GetPresContext() { return NULL; }
- 
- protected:
-     // for a given proxy font entry, attempt to load the next resource
-diff --git a/layout/base/nsPresContext.cpp b/layout/base/nsPresContext.cpp
-index d47460a..8064fb4 100644
---- a/layout/base/nsPresContext.cpp
-+++ b/layout/base/nsPresContext.cpp
-@@ -63,6 +63,8 @@
- #include "nsDOMMediaQueryList.h"
- #include "nsSMILAnimationController.h"
- #include "mozilla/css/ImageLoader.h"
-+#include "nsString.h"
-+#include "nsUnicharUtils.h"
- 
- #ifdef IBMBIDI
- #include "nsBidiPresUtils.h"
-@@ -712,6 +714,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 =
-@@ -1328,6 +1334,100 @@ nsPresContext::GetDefaultFont(uint8_t 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 5f0f528..ffe4766 100644
---- a/layout/base/nsPresContext.h
-+++ b/layout/base/nsPresContext.h
-@@ -467,6 +467,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 nullptr, then the document's language is used.
-@@ -1104,6 +1111,8 @@ protected:
-   uint32_t              mInterruptChecksToSkip;
- 
-   mozilla::TimeStamp    mReflowStartTime;
-+  PRInt32               mMaxFontAttempts;
-+  PRInt32               mMaxFonts;
- 
-   unsigned              mHasPendingInterrupt : 1;
-   unsigned              mInterruptsEnabled : 1;
-diff --git a/layout/style/nsCSSParser.cpp b/layout/style/nsCSSParser.cpp
-index 37a19c4..30fd021 100644
---- a/layout/style/nsCSSParser.cpp
-+++ b/layout/style/nsCSSParser.cpp
-@@ -8719,6 +8719,7 @@ CSSParserImpl::ParseFontSrc(nsCSSValue& aValue)
-         return false;
-       }
- 
-+      // XXX: Getting closer...
-       // the style parameters to the nsFont constructor are ignored,
-       // because it's only being used to call EnumerateFamilies
-       nsFont font(family, 0, 0, 0, 0, 0, 0);
-diff --git a/layout/style/nsFontFaceLoader.cpp b/layout/style/nsFontFaceLoader.cpp
-index 26c8a8d..2a803ae 100644
---- a/layout/style/nsFontFaceLoader.cpp
-+++ b/layout/style/nsFontFaceLoader.cpp
-@@ -86,9 +86,9 @@ nsFontFaceLoader::StartedLoading(nsIStreamLoader *aStreamLoader)
-                                        loadTimeout,
-                                        nsITimer::TYPE_ONE_SHOT);
-     }
--  } else {
-+  } else if (loadTimeout == 0) {
-     mFontEntry->mLoadingState = gfxProxyFontEntry::LOADING_SLOWLY;
--  }
-+  } // -1 disables fallback
-   mStreamLoader = aStreamLoader;
- }
- 
-diff --git a/layout/style/nsFontFaceLoader.h b/layout/style/nsFontFaceLoader.h
-index 9cd218d..0c7473d 100644
---- a/layout/style/nsFontFaceLoader.h
-+++ b/layout/style/nsFontFaceLoader.h
-@@ -48,7 +48,7 @@ public:
- 
-   bool UpdateRules(const nsTArray<nsFontFaceRuleContainer>& aRules);
- 
--  nsPresContext *GetPresContext() { return mPresContext; }
-+  virtual nsPresContext *GetPresContext() { return mPresContext; }
- 
-   virtual void ReplaceFontEntry(gfxProxyFontEntry *aProxy,
-                                 gfxFontEntry *aFontEntry);
-diff --git a/layout/style/nsRuleNode.cpp b/layout/style/nsRuleNode.cpp
-index 64504fb..86eff1f 100644
---- a/layout/style/nsRuleNode.cpp
-+++ b/layout/style/nsRuleNode.cpp
-@@ -42,6 +42,7 @@
- #include "mozilla/dom/Element.h"
- #include "mozilla/LookAndFeel.h"
- #include "mozilla/Util.h"
-+#include "gfxUserFontSet.h"
- 
- #if defined(_MSC_VER) || defined(__MINGW32__)
- #include <malloc.h>
-@@ -2954,6 +2955,7 @@ nsRuleNode::SetFont(nsPresContext* aPresContext, nsStyleContext* aContext,
-     aPresContext->GetDefaultFont(kPresContext_DefaultVariableFont_ID,
-                                  aFont->mLanguage);
- 
-+  // XXX: Bleh. Disable these somehow?
-   // -moz-system-font: enum (never inherit!)
-   MOZ_STATIC_ASSERT(
-     NS_STYLE_FONT_CAPTION        == LookAndFeel::eFont_Caption &&
-@@ -3416,6 +3418,31 @@ static bool ExtractGeneric(const nsString& aFamily, bool aGeneric,
-   return true;
- }
- 
-+struct smugglerStruct {
-+  nsStyleFont *font;
-+  gfxUserFontSet *userFonts;
-+};
-+
-+/* This function forces the use of the first @font-face font we find */
-+static bool ForceFirstWebFont(const nsString& aFamily, bool aGeneric,
-+                              void *smuggled)
-+{
-+  smugglerStruct *sm = static_cast<smugglerStruct*>(smuggled);
-+    
-+  if (aGeneric) {
-+    return true;
-+  }
-+
-+  if (sm->userFonts->HasFamily(aFamily)) {
-+    // Force use of this exact @font-face font since we have it.
-+    sm->font->mFont.name = aFamily;
-+
-+    return false; // Stop enumeration. 
-+  }
-+
-+  return true;
-+}
-+
- const void*
- nsRuleNode::ComputeFontData(void* aStartStruct,
-                             const nsRuleData* aRuleData,
-@@ -3439,14 +3466,16 @@ nsRuleNode::ComputeFontData(void* aStartStruct,
- 
-   bool useDocumentFonts =
-     mPresContext->GetCachedBoolPref(kPresContext_UseDocumentFonts);
-+  bool isXUL = PR_FALSE;
-+  bool forcedWebFont = 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
-@@ -3460,9 +3489,28 @@ nsRuleNode::ComputeFontData(void* aStartStruct,
-     // generic?
-     nsFont::GetGenericID(font->mFont.name, &generic);
- 
-+    if (!isXUL) {
-+      gfxUserFontSet *userFonts = mPresContext->GetUserFontSet();
-+      if (userFonts) {
-+        smugglerStruct sm;
-+        sm.userFonts = userFonts;
-+        sm.font = font;
-+
-+        if (!sm.font->mFont.EnumerateFamilies(ForceFirstWebFont, &sm)) {
-+          isXUL = true; // Always allow WebFont use.
-+          forcedWebFont = true;
-+        }
-+      }
-+    }
-+
-+    if (!forcedWebFont && generic == kGenericFont_NONE)
-+      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)) {
-@@ -3498,6 +3546,8 @@ nsRuleNode::ComputeFontData(void* aStartStruct,
-                                font);
-   }
- 
-+  if (!forcedWebFont && font->mGenericID == kGenericFont_NONE)
-+    mPresContext->AddFontUse(font->mFont);
-   COMPUTE_END_INHERITED(Font, font)
- }
- 
--- 
-1.7.9.5
-
diff --git a/src/current-patches/firefox/0012-Rebrand-Firefox-to-TorBrowser.patch b/src/current-patches/firefox/0012-Rebrand-Firefox-to-TorBrowser.patch
deleted file mode 100644
index 38097b2..0000000
--- a/src/current-patches/firefox/0012-Rebrand-Firefox-to-TorBrowser.patch
+++ /dev/null
@@ -1,59 +0,0 @@
-From e04a04b7d3837b12c728a04b48be3748248e8342 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 12/27] 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/0013-Make-Download-manager-memory-only.patch b/src/current-patches/firefox/0013-Make-Download-manager-memory-only.patch
deleted file mode 100644
index 4959935..0000000
--- a/src/current-patches/firefox/0013-Make-Download-manager-memory-only.patch
+++ /dev/null
@@ -1,57 +0,0 @@
-From 5f9d765db5e0f09fd64c710644dfed872cec3942 Mon Sep 17 00:00:00 2001
-From: Mike Perry <mikeperry-git at torproject.org>
-Date: Tue, 4 Dec 2012 16:05:55 -0800
-Subject: [PATCH 13/27] 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 024686f..7845544 100644
---- a/toolkit/components/downloads/nsDownloadManager.cpp
-+++ b/toolkit/components/downloads/nsDownloadManager.cpp
-@@ -2002,7 +2002,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 =
-@@ -2079,7 +2079,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 bbe7f39..6bdad89 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(nullptr)
--- 
-1.7.5.4
-
diff --git a/src/current-patches/firefox/0014-Add-DDG-and-StartPage-to-Omnibox.patch b/src/current-patches/firefox/0014-Add-DDG-and-StartPage-to-Omnibox.patch
deleted file mode 100644
index e97642e..0000000
--- a/src/current-patches/firefox/0014-Add-DDG-and-StartPage-to-Omnibox.patch
+++ /dev/null
@@ -1,103 +0,0 @@
-From 9e6ade2c9a98d97536cbda15be33432ca8ef8215 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 11/38] 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.
----
- .../en-US/chrome/browser-region/region.properties  |  8 +++---
- browser/locales/en-US/searchplugins/duckduckgo.xml | 29 ++++++++++++++++++++++
- browser/locales/en-US/searchplugins/list.txt       |  2 ++
- browser/locales/en-US/searchplugins/startpage.xml  | 11 ++++++++
- 4 files changed, 46 insertions(+), 4 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/chrome/browser-region/region.properties b/browser/locales/en-US/chrome/browser-region/region.properties
-index c3a980c..9c21f04 100644
---- a/browser/locales/en-US/chrome/browser-region/region.properties
-+++ b/browser/locales/en-US/chrome/browser-region/region.properties
-@@ -3,12 +3,12 @@
- # file, You can obtain one at http://mozilla.org/MPL/2.0/.
- 
- # Default search engine
--browser.search.defaultenginename=Google
-+browser.search.defaultenginename=Startpage
- 
- # Search engine order (order displayed in the search bar dropdown)s
--browser.search.order.1=Google
--browser.search.order.2=Yahoo
--browser.search.order.3=Bing
-+browser.search.order.1=Startpage
-+browser.search.order.2=DuckDuckGo
-+browser.search.order.3=Google
- 
- # This is the default set of web based feed handlers shown in the reader
- # selection UI
-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..a323fdf
---- /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/vmv
 bf/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/rto/search">
-+  <Param name="q" value="{searchTerms}"/>
-+</Url>
-+<SearchForm>https://startpage.com/rto/search/</SearchForm>
-+</SearchPlugin>
diff --git a/src/current-patches/firefox/0015-Make-nsICacheService.EvictEntries-synchronous.patch b/src/current-patches/firefox/0015-Make-nsICacheService.EvictEntries-synchronous.patch
deleted file mode 100644
index f16e57b..0000000
--- a/src/current-patches/firefox/0015-Make-nsICacheService.EvictEntries-synchronous.patch
+++ /dev/null
@@ -1,43 +0,0 @@
-From 865601ec4faab63762f896c39fac69ee133d8023 Mon Sep 17 00:00:00 2001
-From: Mike Perry <mikeperry-git at torproject.org>
-Date: Tue, 4 Dec 2012 16:25:52 -0800
-Subject: [PATCH 15/27] 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 |   16 +++++++++++++++-
- 1 files changed, 15 insertions(+), 1 deletions(-)
-
-diff --git a/netwerk/cache/nsCacheService.cpp b/netwerk/cache/nsCacheService.cpp
-index e88de40..5035f68 100644
---- a/netwerk/cache/nsCacheService.cpp
-+++ b/netwerk/cache/nsCacheService.cpp
-@@ -1555,7 +1555,21 @@ NS_IMETHODIMP nsCacheService::VisitEntries(nsICacheVisitor *visitor)
- 
- NS_IMETHODIMP nsCacheService::EvictEntries(nsCacheStoragePolicy storagePolicy)
- {
--    return  EvictEntriesForClient(nullptr, storagePolicy);
-+    NS_IMETHODIMP r;
-+    r = EvictEntriesForClient(nullptr, 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(LOCK_TELEM(NSCACHESERVICE_EVICTENTRIESFORCLIENT));
-+        gService->mClearingEntries = true;
-+        gService->DoomActiveEntries();
-+        gService->ClearDoomList();
-+        (void) SyncWithCacheIOThread();
-+        gService->mClearingEntries = false;
-+    }
-+    return r; 
- }
- 
- NS_IMETHODIMP nsCacheService::GetCacheIOTarget(nsIEventTarget * *aCacheIOTarget)
--- 
-1.7.5.4
-
diff --git a/src/current-patches/firefox/0016-Prevent-WebSocket-DNS-leak.patch b/src/current-patches/firefox/0016-Prevent-WebSocket-DNS-leak.patch
deleted file mode 100644
index 68cad05..0000000
--- a/src/current-patches/firefox/0016-Prevent-WebSocket-DNS-leak.patch
+++ /dev/null
@@ -1,133 +0,0 @@
-From 1c0ac4187521b5ee7f6de1a11df3bbc400fa1b53 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/27] 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 114af2e..4d66dc5 100644
---- a/netwerk/dns/nsDNSService2.cpp
-+++ b/netwerk/dns/nsDNSService2.cpp
-@@ -374,6 +374,7 @@ nsDNSService::Init()
-     bool     enableIDN        = true;
-     bool     disableIPv6      = false;
-     bool     disablePrefetch  = false;
-+    bool     disableDNS       = false;
-     int      proxyType        = nsIProtocolProxyService::PROXYCONFIG_DIRECT;
-     
-     nsAdoptingCString ipv4OnlyDomains;
-@@ -399,6 +400,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) {
-@@ -419,7 +424,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);
-         }
-     }
- 
-@@ -448,6 +453,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);
-@@ -573,6 +579,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);
-@@ -669,6 +683,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 26d0939..c62c9dd 100644
---- a/netwerk/dns/nsDNSService2.h
-+++ b/netwerk/dns/nsDNSService2.h
-@@ -41,5 +41,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 56a71ab..345df6e 100644
---- a/netwerk/protocol/websocket/WebSocketChannel.cpp
-+++ b/netwerk/protocol/websocket/WebSocketChannel.cpp
-@@ -2157,8 +2157,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 = nullptr;
-+      OnLookupComplete(nullptr, nullptr, rv);
-+  }
- 
-   return NS_OK;
- }
--- 
-1.7.5.4
-
diff --git a/src/current-patches/firefox/0017-Randomize-HTTP-request-order-and-pipeline-depth.patch b/src/current-patches/firefox/0017-Randomize-HTTP-request-order-and-pipeline-depth.patch
deleted file mode 100644
index 11d0e47..0000000
--- a/src/current-patches/firefox/0017-Randomize-HTTP-request-order-and-pipeline-depth.patch
+++ /dev/null
@@ -1,791 +0,0 @@
-From aa6534432718dae0e3810dc441fc797ecf809c6e Mon Sep 17 00:00:00 2001
-From: Mike Perry <mikeperry-git at torproject.org>
-Date: Tue, 4 Dec 2012 17:38:51 -0800
-Subject: [PATCH 17/28] Randomize HTTP request order and pipeline depth.
-
-This is an experimental defense against Website Traffic Fingerprinting:
-http://lorre.uni.lu/~andriy/papers/acmccs-wpes11-fingerprinting.pdf
-
-See:
-https://blog.torproject.org/blog/experimental-defense-website-traffic-fingerprinting
-
-This patch is different from the approach described in that post, as well as
-the 10.x ESR patch, as the pipelining code has changed significantly between
-the time of writing of that post and Firefox 17.
-
-The main control nob for this patch is now the about:config pref
-"network.http.pipelining.max-optimistic-requests". The value of that pref
-represents the minimum number of pipelined requests we will attempt to batch
-together.
-
-The total outstanding pipeline size is randomized between that value and
-"network.http.pipelining.maxrequests" on a per-host basis.
-
-Care must be taken when evaluating this defense, as pipeline behavior is
-extremely sensitive to browser performance. In fact, a debug build alone is
-enough to significantly impair request availability to the pipeline (due
-slower document parsing and rendering). For this reason, we provide two
-separate debug log defines. For most evaluation circumstances, you want to
-define only WTF_TEST in an optimized build to only log request order,
-combination behavior, and cases where the pipeline is forcibly disabled.
-
-This patch may also have some minor impact on SPDY request order, but the SPDY
-implementation has not been altered directly. It has several stream queues
-that may also benefit from reordering and batching, as well as a more compact
-request representation that will allow more requests to be packed inside Tor
-cells. If you have interest in evaluating SPDY in a study of Website Traffic
-Fingerprinting, please contact me.
----
- netwerk/protocol/http/nsHttpConnectionMgr.cpp |  351 +++++++++++++++++--------
- netwerk/protocol/http/nsHttpConnectionMgr.h   |   15 +-
- netwerk/protocol/http/nsHttpHandler.h         |    2 +
- netwerk/protocol/http/nsHttpPipeline.cpp      |   62 ++++-
- netwerk/protocol/http/nsHttpPipeline.h        |    3 +
- 5 files changed, 327 insertions(+), 106 deletions(-)
-
-diff --git a/netwerk/protocol/http/nsHttpConnectionMgr.cpp b/netwerk/protocol/http/nsHttpConnectionMgr.cpp
-index 133c301..c98894c 100644
---- a/netwerk/protocol/http/nsHttpConnectionMgr.cpp
-+++ b/netwerk/protocol/http/nsHttpConnectionMgr.cpp
-@@ -20,6 +20,8 @@
- #include "prnetdb.h"
- #include "mozilla/Telemetry.h"
- 
-+#include <stdlib.h>
-+
- using namespace mozilla;
- using namespace mozilla::net;
- 
-@@ -39,15 +41,26 @@ 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).
-+    uint32_t len = pendingQ.Length();
- 
--    for (int32_t i=pendingQ.Length()-1; i>=0; --i) {
--        nsHttpTransaction *t = pendingQ[i];
--        if (trans->Priority() >= t->Priority()) {
--            pendingQ.InsertElementAt(i+1, trans);
--            return;
--        }
-+    if (pendingQ.IsEmpty()) {
-+        pendingQ.InsertElementAt(0, trans);
-+        return;
-     }
-+
-     pendingQ.InsertElementAt(0, trans);
-+
-+    // FIXME: Refactor into standalone helper (for nsHttpPipeline)
-+    // Or at least simplify this function if this shuffle ends up
-+    // being an improvement.
-+    uint32_t i = 0;
-+    for (i=0; i < len; ++i) {
-+        uint32_t ridx = rand() % len;
-+
-+        nsHttpTransaction *tmp = pendingQ[i];
-+        pendingQ[i] = pendingQ[ridx];
-+        pendingQ[ridx] = tmp;
-+    }
- }
- 
- //-----------------------------------------------------------------------------
-@@ -919,22 +932,27 @@ nsHttpConnectionMgr::ProcessPendingQForEntry(nsConnectionEntry *ent)
-     nsHttpTransaction *trans;
-     nsresult rv;
-     bool dispatchedSuccessfully = false;
-+    int dispatchCount = 0;
-+    int total = count;
- 
-     // iterate the pending list until one is dispatched successfully. Keep
-     // iterating afterwards only until a transaction fails to dispatch.
-     for (uint32_t i = 0; i < count; ++i) {
-         trans = ent->mPendingQ[i];
- 
--        // When this transaction has already established a half-open
-+        // When this entry has already established a half-open
-         // connection, we want to prevent any duplicate half-open
-         // connections from being established and bound to this
--        // transaction. Allow only use of an idle persistent connection
--        // (if found) for transactions referred by a half-open connection.
-+        // transaction.
-         bool alreadyHalfOpen = false;
--        for (int32_t j = 0; j < ((int32_t) ent->mHalfOpens.Length()); ++j) {
--            if (ent->mHalfOpens[j]->Transaction() == trans) {
--                alreadyHalfOpen = true;
--                break;
-+        if (ent->SupportsPipelining()) {
-+            alreadyHalfOpen = (ent->UnconnectedHalfOpens() > 0);
-+        } else {
-+            for (int32_t j = 0; j < ((int32_t) ent->mHalfOpens.Length()); ++j) {
-+                if (ent->mHalfOpens[j]->Transaction() == trans) {
-+                    alreadyHalfOpen = true;
-+                    break;
-+                }
-             }
-         }
- 
-@@ -953,16 +971,29 @@ nsHttpConnectionMgr::ProcessPendingQForEntry(nsConnectionEntry *ent)
-             dispatchedSuccessfully = true;
-             count = ent->mPendingQ.Length();
-             --i;
-+            dispatchCount++;
-             continue;
-         }
- 
--        if (dispatchedSuccessfully)
--            return true;
-+        // We want to keep walking the dispatch table to ensure requests
-+        // get combined properly.
-+        //if (dispatchedSuccessfully) {
-+        //    return true;
-+        //}
- 
-         NS_ABORT_IF_FALSE(count == ((int32_t) ent->mPendingQ.Length()),
-                           "something mutated pending queue from "
-                           "GetConnection()");
-     }
-+
-+#ifdef WTF_DEBUG
-+    if (dispatchedSuccessfully) {
-+        fprintf(stderr, "WTF-queue: Dispatched %d/%d pending transactions for %s\n",
-+                dispatchCount, total, ent->mConnInfo->Host());
-+        return true;
-+    }
-+#endif
-+
-     return false;
- }
- 
-@@ -1247,6 +1278,10 @@ nsHttpConnectionMgr::MakeNewConnection(nsConnectionEntry *ent,
-     if (AtActiveConnectionLimit(ent, trans->Caps()))
-         return NS_ERROR_NOT_AVAILABLE;
- 
-+#ifdef WTF_DEBUG
-+        fprintf(stderr, "WTF: MakeNewConnection() is creating a transport (pipelines %d) for host %s\n",
-+                ent->SupportsPipelining(), ent->mConnInfo->Host());
-+#endif
-     nsresult rv = CreateTransport(ent, trans, trans->Caps(), false);
-     if (NS_FAILED(rv)) {
-         /* hard failure */
-@@ -1263,7 +1298,7 @@ nsHttpConnectionMgr::MakeNewConnection(nsConnectionEntry *ent,
- }
- 
- bool
--nsHttpConnectionMgr::AddToShortestPipeline(nsConnectionEntry *ent,
-+nsHttpConnectionMgr::AddToBestPipeline(nsConnectionEntry *ent,
-                                            nsHttpTransaction *trans,
-                                            nsHttpTransaction::Classifier classification,
-                                            uint16_t depthLimit)
-@@ -1300,40 +1335,100 @@ nsHttpConnectionMgr::AddToShortestPipeline(nsConnectionEntry *ent,
-     if (maxdepth < 2)
-         return false;
- 
--    nsAHttpTransaction *activeTrans;
-+    // Find out how many requests of this class we have
-+    uint32_t sameClass = 0;
-+    uint32_t allClasses = ent->mPendingQ.Length();
-+    for (uint32_t i = 0; i < allClasses; ++i) {
-+        if (trans != ent->mPendingQ[i] &&
-+            classification == ent->mPendingQ[i]->Classification()) {
-+            sameClass++;
-+        }
-+    }
- 
-+    nsAHttpTransaction *activeTrans;
-+    nsHttpPipeline *pipeline;
-     nsHttpConnection *bestConn = nullptr;
-     uint32_t activeCount = ent->mActiveConns.Length();
--    uint32_t bestConnLength = 0;
--    uint32_t connLength;
-+    uint32_t pipelineDepth;
-+    uint32_t requestLen;
-+    uint32_t totalDepth = 0;
-+
-+    // Now, try to find the best pipeline
-+    nsTArray<nsHttpConnection *> validConns;
-+    nsTArray<nsHttpConnection *> betterConns;
-+    nsTArray<nsHttpConnection *> bestConns;
-+    uint32_t numPipelines = 0;
- 
-     for (uint32_t i = 0; i < activeCount; ++i) {
-         nsHttpConnection *conn = ent->mActiveConns[i];
--        if (!conn->SupportsPipelining())
--            continue;
- 
--        if (conn->Classification() != classification)
-+        if (!conn->SupportsPipelining())
-             continue;
- 
-         activeTrans = conn->Transaction();
-+
-         if (!activeTrans ||
-             activeTrans->IsDone() ||
-             NS_FAILED(activeTrans->Status()))
-             continue;
- 
--        connLength = activeTrans->PipelineDepth();
-+        pipeline = activeTrans->QueryPipeline();
-+        if (!pipeline)
-+            continue;
-+
-+        numPipelines++;
- 
--        if (maxdepth <= connLength)
-+        pipelineDepth = activeTrans->PipelineDepth();
-+        requestLen = pipeline->RequestDepth();
-+
-+        totalDepth += pipelineDepth;
-+
-+        // If we're within striking distance of our pipeline
-+        // packaging goal, give a little slack on the depth
-+        // limit to allow us to try to get there. Don't give
-+        // too much slack, though, or we'll tend to have
-+        // request packages of the same size when we have
-+        // many content elements appear at once.
-+        if (maxdepth +
-+              PR_MIN(mMaxOptimisticPipelinedRequests,
-+                     requestLen + allClasses)
-+              <= pipelineDepth)
-             continue;
- 
--        if (!bestConn || (connLength < bestConnLength)) {
--            bestConn = conn;
--            bestConnLength = connLength;
--        }
--    }
-+        validConns.AppendElement(conn);
-+
-+        // Prefer a pipeline that either has at least two requests
-+        // queued already, or for which we can add multiple requests
-+        if (requestLen + allClasses < mMaxOptimisticPipelinedRequests)
-+            continue;
-+
-+        betterConns.AppendElement(conn);
-+
-+        // Prefer a pipeline with the same classification if 
-+        // our current classes will put it over the line
-+        if (conn->Classification() != classification)
-+            continue;
-+        if (requestLen + sameClass < mMaxOptimisticPipelinedRequests)
-+            continue;
- 
--    if (!bestConn)
-+        bestConns.AppendElement(conn);
-+    }
-+
-+    const char *type;
-+    if (bestConns.Length()) {
-+        type = "best";
-+        bestConn = bestConns[rand()%bestConns.Length()];
-+    } else if (betterConns.Length()) {
-+        type = "better";
-+        bestConn = betterConns[rand()%betterConns.Length()];
-+    } else if (validConns.Length() && totalDepth == 0) {
-+        // We only use valid conns if it's a last resort
-+        // (No other requests are pending or in flight)
-+        type = "valid";
-+        bestConn = validConns[rand()%validConns.Length()];
-+    } else {
-         return false;
-+    }
- 
-     activeTrans = bestConn->Transaction();
-     nsresult rv = activeTrans->AddTransaction(trans);
-@@ -1343,6 +1438,15 @@ nsHttpConnectionMgr::AddToShortestPipeline(nsConnectionEntry *ent,
-     LOG(("   scheduling trans %p on pipeline at position %d\n",
-          trans, trans->PipelinePosition()));
- 
-+#ifdef WTF_DEBUG
-+    pipeline = activeTrans->QueryPipeline();
-+    fprintf(stderr,
-+            "WTF-depth: Added trans to %s of %d/%d/%d/%d pipelines. Request len %d/%d/%d for %s\n",
-+            type, bestConns.Length(), betterConns.Length(), validConns.Length(),
-+            numPipelines, pipeline->RequestDepth(), activeTrans->PipelineDepth(),
-+            maxdepth, ent->mConnInfo->Host());
-+#endif
-+
-     if ((ent->PipelineState() == PS_YELLOW) && (trans->PipelinePosition() > 1))
-         ent->SetYellowConnection(bestConn);
-     return true;
-@@ -1403,26 +1507,12 @@ nsHttpConnectionMgr::TryDispatchTransaction(nsConnectionEntry *ent,
-     nsHttpTransaction::Classifier classification = trans->Classification();
-     uint8_t caps = trans->Caps();
- 
-+    bool allowNewPipelines = true;
-+
-     // no keep-alive means no pipelines either
-     if (!(caps & NS_HTTP_ALLOW_KEEPALIVE))
-         caps = caps & ~NS_HTTP_ALLOW_PIPELINING;
- 
--    // 0 - If this should use spdy then dispatch it post haste.
--    // 1 - If there is connection pressure then see if we can pipeline this on
--    //     a connection of a matching type instead of using a new conn
--    // 2 - If there is an idle connection, use it!
--    // 3 - if class == reval or script and there is an open conn of that type
--    //     then pipeline onto shortest pipeline of that class if limits allow
--    // 4 - If we aren't up against our connection limit,
--    //     then open a new one
--    // 5 - Try a pipeline if we haven't already - this will be unusual because
--    //     it implies a low connection pressure situation where
--    //     MakeNewConnection() failed.. that is possible, but unlikely, due to
--    //     global limits
--    // 6 - no connection is available - queue it
--
--    bool attemptedOptimisticPipeline = !(caps & NS_HTTP_ALLOW_PIPELINING);
--
-     // step 0
-     // look for existing spdy connection - that's always best because it is
-     // essentially pipelining without head of line blocking
-@@ -1436,20 +1526,27 @@ nsHttpConnectionMgr::TryDispatchTransaction(nsConnectionEntry *ent,
-         }
-     }
- 
--    // step 1
--    // If connection pressure, then we want to favor pipelining of any kind
--    if (IsUnderPressure(ent, classification) && !attemptedOptimisticPipeline) {
--        attemptedOptimisticPipeline = true;
--        if (AddToShortestPipeline(ent, trans,
--                                  classification,
--                                  mMaxOptimisticPipelinedRequests)) {
--            return NS_OK;
--        }
-+    // step 1: Try a pipeline
-+    if (caps & NS_HTTP_ALLOW_PIPELINING &&
-+        AddToBestPipeline(ent, trans, classification,
-+                          mMaxPipelinedRequests)) {
-+        return NS_OK;
-     }
- 
--    // step 2
--    // consider an idle persistent connection
--    if (caps & NS_HTTP_ALLOW_KEEPALIVE) {
-+    // Step 2: Decide if we should forbid new pipeline creation.
-+    //
-+    // FIXME: We repurposed mMaxOptimisticPipelinedRequests here to mean:
-+    // "Don't make a new pipeline until you have this many requests pending and 
-+    // no potential connections to put them on". It might be nice to give this
-+    // its own pref..
-+    if (HasPipelines(ent) &&
-+            ent->mPendingQ.Length() < mMaxOptimisticPipelinedRequests &&
-+            trans->Classification() != nsAHttpTransaction::CLASS_SOLO &&
-+            caps & NS_HTTP_ALLOW_PIPELINING)
-+        allowNewPipelines = false;
-+
-+    // step 3: consider an idle persistent connection
-+    if (allowNewPipelines && (caps & NS_HTTP_ALLOW_KEEPALIVE)) {
-         nsRefPtr<nsHttpConnection> conn;
-         while (!conn && (ent->mIdleConns.Length() > 0)) {
-             conn = ent->mIdleConns[0];
-@@ -1483,21 +1580,8 @@ nsHttpConnectionMgr::TryDispatchTransaction(nsConnectionEntry *ent,
-         }
-     }
- 
--    // step 3
--    // consider pipelining scripts and revalidations
--    if (!attemptedOptimisticPipeline &&
--        (classification == nsHttpTransaction::CLASS_REVALIDATION ||
--         classification == nsHttpTransaction::CLASS_SCRIPT)) {
--        attemptedOptimisticPipeline = true;
--        if (AddToShortestPipeline(ent, trans,
--                                  classification,
--                                  mMaxOptimisticPipelinedRequests)) {
--            return NS_OK;
--        }
--    }
--
--    // step 4
--    if (!onlyReusedConnection) {
-+    // step 4: Maybe make a connection? 
-+    if (!onlyReusedConnection && allowNewPipelines) {
-         nsresult rv = MakeNewConnection(ent, trans);
-         if (NS_SUCCEEDED(rv)) {
-             // this function returns NOT_AVAILABLE for asynchronous connects
-@@ -1510,17 +1594,16 @@ nsHttpConnectionMgr::TryDispatchTransaction(nsConnectionEntry *ent,
-             return rv;
-         }
-     }
-+
-+    // XXX: We dequeue and queue the same url here sometimes..
-+#ifdef WTF_DEBUG
-+    nsHttpRequestHead *head = trans->RequestHead();
-+    fprintf(stderr, "WTF: Queuing url %s%s\n",
-+            ent->mConnInfo->Host(),
-+            head ? head->RequestURI().BeginReading() : "<unknown?>");
-+#endif
-     
--    // step 5
--    if (caps & NS_HTTP_ALLOW_PIPELINING) {
--        if (AddToShortestPipeline(ent, trans,
--                                  classification,
--                                  mMaxPipelinedRequests)) {
--            return NS_OK;
--        }
--    }
--    
--    // step 6
-+    // step 5: Queue it
-     return NS_ERROR_NOT_AVAILABLE;                /* queue it */
- }
- 
-@@ -1590,10 +1673,28 @@ nsHttpConnectionMgr::DispatchAbstractTransaction(nsConnectionEntry *ent,
-         if (!NS_SUCCEEDED(rv))
-             return rv;
-         transaction = pipeline;
-+#ifdef WTF_DEBUG
-+        if (HasPipelines(ent) &&
-+                ent->mPendingQ.Length()+1 < mMaxOptimisticPipelinedRequests) {
-+            fprintf(stderr, "WTF-new-bug: New pipeline created from %d idle conns for host %s with %d/%d pending\n",
-+                    ent->mIdleConns.Length(), ent->mConnInfo->Host(), ent->mPendingQ.Length(),
-+                    mMaxOptimisticPipelinedRequests);
-+        } else {
-+            fprintf(stderr, "WTF-new: New pipeline created from %d idle conns for host %s with %d/%d pending\n",
-+                    ent->mIdleConns.Length(), ent->mConnInfo->Host(), ent->mPendingQ.Length(),
-+                    mMaxOptimisticPipelinedRequests);
-+        }
-+#endif
-     }
-     else {
-         LOG(("   not using pipeline datastructure due to class solo.\n"));
-         transaction = aTrans;
-+#ifdef WTF_TEST
-+        nsHttpRequestHead *head = transaction->RequestHead();
-+        fprintf(stderr, "WTF-order: Pipeline forbidden for url %s%s\n",
-+                ent->mConnInfo->Host(),
-+                head ? head->RequestURI().BeginReading() : "<unknown?>");
-+#endif
-     }
- 
-     nsRefPtr<nsConnectionHandle> handle = new nsConnectionHandle(conn);
-@@ -1691,28 +1792,20 @@ nsHttpConnectionMgr::ProcessNewTransaction(nsHttpTransaction *trans)
-         NS_ABORT_IF_FALSE(((int32_t)ent->mActiveConns.IndexOf(conn)) != -1,
-                           "Sticky Connection Not In Active List");
-         trans->SetConnection(nullptr);
-+#ifdef WTF_TEST
-+        fprintf(stderr, "WTF-bad: Sticky connection status on 1 transaction to host %s\n",
-+                ent->mConnInfo->Host());
-+#endif
-         rv = DispatchTransaction(ent, trans, conn);
--    }
--    else
--        rv = TryDispatchTransaction(ent, false, trans);
--
--    if (NS_SUCCEEDED(rv)) {
--        LOG(("  ProcessNewTransaction Dispatch Immediately trans=%p\n", trans));
-         return rv;
-     }
--    
--    if (rv == NS_ERROR_NOT_AVAILABLE) {
--        LOG(("  adding transaction to pending queue "
--             "[trans=%p pending-count=%u]\n",
--             trans, ent->mPendingQ.Length()+1));
--        // put this transaction on the pending queue...
-+    else {
-+        // XXX: maybe check the queue first and directly call TryDispatch?
-         InsertTransactionSorted(ent->mPendingQ, trans);
-         NS_ADDREF(trans);
-+        ProcessPendingQForEntry(ent);
-         return NS_OK;
-     }
--
--    LOG(("  ProcessNewTransaction Hard Error trans=%p rv=%x\n", trans, rv));
--    return rv;
- }
- 
- 
-@@ -2311,10 +2404,48 @@ nsHttpConnectionMgr::OnMsgSpeculativeConnect(int32_t, void *param)
-     if (preferredEntry)
-         ent = preferredEntry;
- 
--    if (!ent->mIdleConns.Length() && !RestrictConnections(ent) &&
--        !AtActiveConnectionLimit(ent, trans->Caps())) {
-+    if (ent->SupportsPipelining()) {
-+        /* Only speculative connect if we're not pipelining and have no other pending
-+         * unconnected half-opens.. */
-+        if (ent->UnconnectedHalfOpens() == 0 && ent->mIdleConns.Length() == 0
-+                && !RestrictConnections(ent) && !HasPipelines(ent)
-+                && !AtActiveConnectionLimit(ent, trans->Caps())) {
-+#ifdef WTF_DEBUG
-+            fprintf(stderr, "WTF: Creating speculative connection because we have no pipelines\n");
-+#endif
-+            CreateTransport(ent, trans, trans->Caps(), true);
-+        }
-+    } else if (!ent->mIdleConns.Length() && !RestrictConnections(ent) &&
-+            !AtActiveConnectionLimit(ent, trans->Caps())) {
-+#ifdef WTF_DEBUG
-+            fprintf(stderr, "WTF: Creating speculative connection because we can't pipeline\n");
-+#endif
-         CreateTransport(ent, trans, trans->Caps(), true);
-     }
-+
-+}
-+
-+bool
-+nsHttpConnectionMgr::HasPipelines(nsConnectionEntry *ent)
-+{
-+    uint32_t activeCount = ent->mActiveConns.Length();
-+
-+    if (!ent->SupportsPipelining()) {
-+        return false;
-+    }
-+
-+    for (uint32_t i = 0; i < activeCount; ++i) {
-+        nsHttpConnection *conn = ent->mActiveConns[i];
-+        if (!conn->SupportsPipelining())
-+            continue;
-+
-+        nsAHttpTransaction *activeTrans = conn->Transaction();
-+
-+        if (activeTrans && !activeTrans->IsDone() &&
-+            !NS_FAILED(activeTrans->Status()))
-+            return true;
-+    }
-+    return false;
- }
- 
- bool
-@@ -2661,6 +2792,10 @@ nsHalfOpenSocket::OnOutputStreamReady(nsIAsyncOutputStream *out)
-         nsRefPtr<nsHttpTransaction> temp = dont_AddRef(mEnt->mPendingQ[index]);
-         mEnt->mPendingQ.RemoveElementAt(index);
-         gHttpHandler->ConnMgr()->AddActiveConn(conn, mEnt);
-+#ifdef WTF_DEBUG
-+        fprintf(stderr, "WTF: Speculative half-opened connection is now ready for %s (pipelines %d)\n",
-+                mEnt->mConnInfo->Host(), mEnt->SupportsPipelining());
-+#endif
-         rv = gHttpHandler->ConnMgr()->DispatchTransaction(mEnt, temp, conn);
-     }
-     else {
-@@ -2852,9 +2987,13 @@ nsConnectionEntry::nsConnectionEntry(nsHttpConnectionInfo *ci)
- {
-     NS_ADDREF(mConnInfo);
-     if (gHttpHandler->GetPipelineAggressive()) {
--        mGreenDepth = kPipelineUnlimited;
-+        // Randomize the pipeline depth (3..12)
-+        mGreenDepth = gHttpHandler->GetMaxOptimisticPipelinedRequests()
-+                      + rand() % (gHttpHandler->GetMaxPipelinedRequests()
-+                                  - gHttpHandler->GetMaxOptimisticPipelinedRequests());
-         mPipelineState = PS_GREEN;
-     }
-+
-     mInitialGreenDepth = mGreenDepth;
-     memset(mPipeliningClassPenalty, 0, sizeof(int16_t) * nsAHttpTransaction::CLASS_MAX);
- }
-@@ -2892,8 +3031,9 @@ nsConnectionEntry::OnPipelineFeedbackInfo(
-         LOG(("Transaction completed at pipeline depth of %d. Host = %s\n",
-              depth, mConnInfo->Host()));
- 
--        if (depth >= 3)
--            mGreenDepth = kPipelineUnlimited;
-+        // Don't set this. We want to keep our initial random value..
-+        //if (depth >= 3)
-+        //    mGreenDepth = kPipelineUnlimited;
-     }
- 
-     nsAHttpTransaction::Classifier classification;
-@@ -2921,6 +3061,11 @@ nsConnectionEntry::OnPipelineFeedbackInfo(
-                  mPipelineState, mConnInfo->Host()));
-             mPipelineState = PS_RED;
-             mPipeliningPenalty = 0;
-+#ifdef WTF_TEST
-+            fprintf(stderr, "WTF-bad: Red pipeline status disabled host %s\n",
-+                    mConnInfo->Host());
-+#endif
-+
-         }
- 
-         if (mLastCreditTime.IsNull())
-diff --git a/netwerk/protocol/http/nsHttpConnectionMgr.h b/netwerk/protocol/http/nsHttpConnectionMgr.h
-index 580710a..7aecb68 100644
---- a/netwerk/protocol/http/nsHttpConnectionMgr.h
-+++ b/netwerk/protocol/http/nsHttpConnectionMgr.h
-@@ -23,11 +23,23 @@
- #include "nsIObserver.h"
- #include "nsITimer.h"
- #include "nsIX509Cert3.h"
-+#include "nsIRandomGenerator.h"
- 
- class nsHttpPipeline;
- 
- class nsIHttpUpgradeListener;
- 
-+// We need our own optional debug define because pipelining behavior
-+// is significantly altered by rendering speed (which is abysmal on
-+// debug builds)
-+#ifdef DEBUG
-+# define WTF_DEBUG
-+#endif
-+
-+#ifdef WTF_DEBUG
-+# define WTF_TEST
-+#endif
-+
- //-----------------------------------------------------------------------------
- 
- class nsHttpConnectionMgr : public nsIObserver
-@@ -478,6 +490,7 @@ private:
-     nsresult BuildPipeline(nsConnectionEntry *,
-                            nsAHttpTransaction *,
-                            nsHttpPipeline **);
-+    bool     HasPipelines(nsConnectionEntry *);
-     bool     RestrictConnections(nsConnectionEntry *);
-     nsresult ProcessNewTransaction(nsHttpTransaction *);
-     nsresult EnsureSocketThreadTargetIfOnline();
-@@ -492,7 +505,7 @@ private:
- 
-     nsresult MakeNewConnection(nsConnectionEntry *ent,
-                                nsHttpTransaction *trans);
--    bool     AddToShortestPipeline(nsConnectionEntry *ent,
-+    bool     AddToBestPipeline(nsConnectionEntry *ent,
-                                    nsHttpTransaction *trans,
-                                    nsHttpTransaction::Classifier classification,
-                                    uint16_t depthLimit);
-diff --git a/netwerk/protocol/http/nsHttpHandler.h b/netwerk/protocol/http/nsHttpHandler.h
-index 2963195..cd79069 100644
---- a/netwerk/protocol/http/nsHttpHandler.h
-+++ b/netwerk/protocol/http/nsHttpHandler.h
-@@ -215,6 +215,8 @@ public:
-                                      nsCString& hostLine);
- 
-     bool GetPipelineAggressive()     { return mPipelineAggressive; }
-+    uint32_t GetMaxPipelinedRequests()     { return mMaxPipelinedRequests; }
-+    uint32_t GetMaxOptimisticPipelinedRequests()     { return mMaxOptimisticPipelinedRequests; }
-     void GetMaxPipelineObjectSize(int64_t *outVal)
-     {
-         *outVal = mMaxPipelineObjectSize;
-diff --git a/netwerk/protocol/http/nsHttpPipeline.cpp b/netwerk/protocol/http/nsHttpPipeline.cpp
-index 9e59878..a9e9911 100644
---- a/netwerk/protocol/http/nsHttpPipeline.cpp
-+++ b/netwerk/protocol/http/nsHttpPipeline.cpp
-@@ -87,6 +87,32 @@ nsHttpPipeline::~nsHttpPipeline()
-         free(mPushBackBuf);
- }
- 
-+// Generate a shuffled request ordering sequence 
-+void
-+nsHttpPipeline::ShuffleTransOrder(uint32_t count)
-+{
-+   if (count < 2)
-+       return;
-+
-+   uint32_t pos = mRequestQ[0]->PipelinePosition();
-+   uint32_t i = 0;
-+
-+   for (i=0; i < count; ++i) {
-+       uint32_t ridx = rand() % count;
-+
-+       nsAHttpTransaction *tmp = mRequestQ[i];
-+       mRequestQ[i] = mRequestQ[ridx];
-+       mRequestQ[ridx] = tmp;
-+   }
-+
-+   for (i=0; i < count; ++i) {
-+       mRequestQ[i]->SetPipelinePosition(pos);
-+       pos++;
-+   }
-+
-+   LOG(("nsHttpPipeline::ShuffleTransOrder: Shuffled %d transactions.\n", count));
-+}
-+
- nsresult
- nsHttpPipeline::AddTransaction(nsAHttpTransaction *trans)
- {
-@@ -112,6 +138,8 @@ nsHttpPipeline::AddTransaction(nsAHttpTransaction *trans)
-     // the pipeline object.
-     trans->SetConnection(this);
- 
-+    ShuffleTransOrder(mRequestQ.Length());
-+
-     if (mConnection && !mClosed && mRequestQ.Length() == 1)
-         mConnection->ResumeSend();
- 
-@@ -760,8 +788,11 @@ nsHttpPipeline::CancelPipeline(nsresult originalReason)
-     if (respLen > 1)
-         mResponseQ.TruncateLength(1);
- 
--    DontReuse();
--    Classify(nsAHttpTransaction::CLASS_SOLO);
-+    /* Don't flag timed out connections as unreusable.. Tor is just slow :( */
-+    if (originalReason != NS_ERROR_NET_TIMEOUT) {
-+        DontReuse();
-+        Classify(nsAHttpTransaction::CLASS_SOLO);
-+    }
- 
-     return total;
- }
-@@ -842,8 +873,19 @@ nsHttpPipeline::FillSendBuf()
- 
-     uint32_t n;
-     uint64_t avail;
-+    uint64_t totalAvailable = Available();
-+    uint64_t totalSent = 0;
-+    uint64_t reqsSent = 0;
-+    uint64_t alreadyPending = 0;
-+
-+    mSendBufIn->Available(&alreadyPending);
-+
-     nsAHttpTransaction *trans;
-     nsITransport *transport = Transport();
-+#ifdef WTF_TEST
-+    nsRefPtr<nsHttpConnectionInfo> ci;
-+    GetConnectionInfo(getter_AddRefs(ci));
-+#endif
- 
-     while ((trans = Request(0)) != nullptr) {
-         avail = trans->Available();
-@@ -864,6 +906,7 @@ nsHttpPipeline::FillSendBuf()
-             }
- 
-             mSendingToProgress += n;
-+            totalSent += n;
-             if (!mSuppressSendEvents && transport) {
-                 // Simulate a SENDING_TO event
-                 trans->OnTransportStatus(transport,
-@@ -874,6 +917,14 @@ nsHttpPipeline::FillSendBuf()
- 
-         avail = trans->Available();
-         if (avail == 0) {
-+#ifdef WTF_TEST
-+            nsHttpRequestHead *head = trans->RequestHead();
-+            fprintf(stderr, "WTF-order: Pipelined req %d/%d (%dB). Url: %s%s\n",
-+                    trans->PipelinePosition(), PipelineDepth(), n,
-+                    ci->Host(), head ? head->RequestURI().BeginReading() : "<unknown?>");
-+#endif
-+            reqsSent++;
-+
-             // move transaction from request queue to response queue
-             mRequestQ.RemoveElementAt(0);
-             mResponseQ.AppendElement(trans);
-@@ -893,5 +944,12 @@ nsHttpPipeline::FillSendBuf()
-         else
-             mRequestIsPartial = true;
-     }
-+
-+#ifdef WTF_TEST
-+    if (totalSent)
-+      fprintf(stderr, "WTF-combine: Sent %d/%d bytes of %d combined pipelined requests for host %s\n",
-+              alreadyPending+totalSent, totalAvailable, reqsSent, ci->Host());
-+#endif
-+
-     return NS_OK;
- }
-diff --git a/netwerk/protocol/http/nsHttpPipeline.h b/netwerk/protocol/http/nsHttpPipeline.h
-index 746a196..4dc06c1 100644
---- a/netwerk/protocol/http/nsHttpPipeline.h
-+++ b/netwerk/protocol/http/nsHttpPipeline.h
-@@ -27,11 +27,14 @@ public:
-     nsHttpPipeline();
-     virtual ~nsHttpPipeline();
- 
-+    uint32_t RequestDepth() { return mRequestQ.Length(); }
-+
- private:
-     nsresult FillSendBuf();
-     
-     static NS_METHOD ReadFromPipe(nsIInputStream *, void *, const char *,
-                                   uint32_t, uint32_t, uint32_t *);
-+    void ShuffleTransOrder(uint32_t);
- 
-     // convenience functions
-     nsAHttpTransaction *Request(int32_t i)
--- 
-1.7.9.5
-
diff --git a/src/current-patches/firefox/0018-Emit-observer-event-to-filter-the-Drag-Drop-url-list.patch b/src/current-patches/firefox/0018-Emit-observer-event-to-filter-the-Drag-Drop-url-list.patch
deleted file mode 100644
index 437329b..0000000
--- a/src/current-patches/firefox/0018-Emit-observer-event-to-filter-the-Drag-Drop-url-list.patch
+++ /dev/null
@@ -1,74 +0,0 @@
-From 5e505dec0ee00899a1fa22e1759e856bb5381468 Mon Sep 17 00:00:00 2001
-From: Mike Perry <mikeperry-git at torproject.org>
-Date: Thu, 28 Feb 2013 18:10:16 -0800
-Subject: [PATCH 18/27] Emit observer event to filter the Drag+Drop url list
-
-This patch creates an "on-modify-drag-list" observer that addons can listen
-to. For us, it supports Torbutton code that filters out Drag+Drop mime types
-that the OS Desktop sniffs and attempts to load without Tor.
-
-Such proxy bypass behavior is immediate on Mac and Ubuntu: you don't even have
-to release the object for it to get sniffed and cause the OS to load it
-without Tor. In fact, accidentally clicking for too long on an image is enough
-to cause proxy bypass on those systems.
----
- widget/xpwidgets/nsBaseDragService.cpp |    8 ++++++++
- widget/xpwidgets/nsBaseDragService.h   |    2 ++
- 2 files changed, 10 insertions(+), 0 deletions(-)
-
-diff --git a/widget/xpwidgets/nsBaseDragService.cpp b/widget/xpwidgets/nsBaseDragService.cpp
-index 805d83f..4c99b9c 100644
---- a/widget/xpwidgets/nsBaseDragService.cpp
-+++ b/widget/xpwidgets/nsBaseDragService.cpp
-@@ -34,6 +34,7 @@
- #include "nsXULPopupManager.h"
- #include "nsMenuPopupFrame.h"
- #include "mozilla/Preferences.h"
-+#include "mozilla/Services.h"
- 
- #include "gfxContext.h"
- #include "gfxPlatform.h"
-@@ -49,6 +50,7 @@ nsBaseDragService::nsBaseDragService()
-     mImageX(0), mImageY(0), mScreenX(-1), mScreenY(-1), mSuppressLevel(0),
-     mInputSource(nsIDOMMouseEvent::MOZ_SOURCE_MOUSE)
- {
-+    mObserverService = mozilla::services::GetObserverService();
- }
- 
- nsBaseDragService::~nsBaseDragService()
-@@ -203,6 +205,12 @@ nsBaseDragService::InvokeDragSession(nsIDOMNode *aDOMNode,
-   NS_ENSURE_TRUE(aDOMNode, NS_ERROR_INVALID_ARG);
-   NS_ENSURE_TRUE(mSuppressLevel == 0, NS_ERROR_FAILURE);
- 
-+  // Emit observer event to allow addons to modify the transfer array.
-+  if (mObserverService)
-+    mObserverService->NotifyObservers(aTransferableArray,
-+                                      "on-modify-drag-list",
-+                                      nullptr);
-+
-   // stash the document of the dom node
-   aDOMNode->GetOwnerDocument(getter_AddRefs(mSourceDocument));
-   mSourceNode = aDOMNode;
-diff --git a/widget/xpwidgets/nsBaseDragService.h b/widget/xpwidgets/nsBaseDragService.h
-index cb00f8e..8b91899 100644
---- a/widget/xpwidgets/nsBaseDragService.h
-+++ b/widget/xpwidgets/nsBaseDragService.h
-@@ -6,6 +6,7 @@
- #ifndef nsBaseDragService_h__
- #define nsBaseDragService_h__
- 
-+#include "nsIObserverService.h"
- #include "nsIDragService.h"
- #include "nsIDragSession.h"
- #include "nsITransferable.h"
-@@ -113,6 +114,7 @@ protected:
- 
-   uint32_t mDragAction;
-   nsSize mTargetSize;
-+  nsCOMPtr<nsIObserverService> mObserverService;
-   nsCOMPtr<nsIDOMNode> mSourceNode;
-   nsCOMPtr<nsIDOMDocument> mSourceDocument;       // the document at the drag source. will be null
-                                                   //  if it came from outside the app.
--- 
-1.7.5.4
-
diff --git a/src/current-patches/firefox/0019-Add-mozIThirdPartyUtil.getFirstPartyURI-API.patch b/src/current-patches/firefox/0019-Add-mozIThirdPartyUtil.getFirstPartyURI-API.patch
deleted file mode 100644
index 4baf190..0000000
--- a/src/current-patches/firefox/0019-Add-mozIThirdPartyUtil.getFirstPartyURI-API.patch
+++ /dev/null
@@ -1,164 +0,0 @@
-From f98cbea138095a46570912a2f624b82dff109d55 Mon Sep 17 00:00:00 2001
-From: Mike Perry <mikeperry-git at torproject.org>
-Date: Wed, 28 Nov 2012 17:08:29 -0500
-Subject: [PATCH 19/27] Add mozIThirdPartyUtil.getFirstPartyURI API
-
-API allows you to get the url bar URI for a channel or nsIDocument.
----
- content/base/src/ThirdPartyUtil.cpp        |   68 ++++++++++++++++++++++++++++
- content/base/src/ThirdPartyUtil.h          |    2 +
- netwerk/base/public/mozIThirdPartyUtil.idl |   21 +++++++++
- 3 files changed, 91 insertions(+), 0 deletions(-)
-
-diff --git a/content/base/src/ThirdPartyUtil.cpp b/content/base/src/ThirdPartyUtil.cpp
-index 97a000e..ad1b0fa 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,67 @@ ThirdPartyUtil::GetBaseDomain(nsIURI* aHostURI,
- 
-   return NS_OK;
- }
-+
-+NS_IMETHODIMP
-+ThirdPartyUtil::GetFirstPartyURI(nsIChannel *aChannel,
-+                                 nsIDocument *aDoc,
-+                                 nsIURI **aOutput)
-+{
-+  nsresult rv = NS_ERROR_NULL_POINTER;
-+
-+  if (!aOutput)
-+    return rv;
-+
-+  *aOutput = nullptr;
-+
-+  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;
-+    nsIURI *docURI = nullptr;
-+
-+    if (aDoc->GetWindow()) {
-+      aDoc->GetWindow()->GetTop(getter_AddRefs(top));
-+      top->GetDocument(getter_AddRefs(topDDoc));
-+
-+      nsCOMPtr<nsIDocument> topDoc(do_QueryInterface(topDDoc));
-+      docURI = topDoc->GetOriginalURI();
-+      if (docURI) {
-+        // Give us a mutable URI and also addref
-+        rv = NS_EnsureSafeToReturn(docURI, aOutput);
-+      }
-+    } else {
-+      // XXX: Chrome callers (such as NoScript) can end up here
-+      // through getImageData/canvas usage with no document state
-+      // (no Window and a document URI of about:blank). Propogate
-+      // rv fail (by doing nothing), and hope caller recovers.
-+    }
-+
-+    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 3f50ac3..fe7b214 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"
- #include "mozilla/Attributes.h"
- 
- class nsIURI;
-@@ -29,6 +30,7 @@ private:
-   static already_AddRefed<nsIURI> GetURIFromWindow(nsIDOMWindow* aWin);
- 
-   nsCOMPtr<nsIEffectiveTLDService> mTLDService;
-+  nsCOMPtr<nsICookiePermission> mCookiePermissions;
- };
- 
- #endif
-diff --git a/netwerk/base/public/mozIThirdPartyUtil.idl b/netwerk/base/public/mozIThirdPartyUtil.idl
-index 578d8db..963385c 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++
--- 
-1.7.5.4
-
diff --git a/src/current-patches/firefox/0020-Add-canvas-image-extraction-prompt.patch b/src/current-patches/firefox/0020-Add-canvas-image-extraction-prompt.patch
deleted file mode 100644
index b5d2f93..0000000
--- a/src/current-patches/firefox/0020-Add-canvas-image-extraction-prompt.patch
+++ /dev/null
@@ -1,548 +0,0 @@
-From 43871b07e1ae9a55136f5a4d4454011eae5569f8 Mon Sep 17 00:00:00 2001
-From: Kathleen Brade <brade at pearlcrescent.com>
-Date: Tue, 27 Nov 2012 13:13:40 -0500
-Subject: [PATCH 20/27] Add canvas image extraction prompt.
-
----
- browser/base/content/browser.js                    |  102 ++++++++++++++++++++
- browser/base/content/browser.xul                   |    1 +
- .../en-US/chrome/browser/browser.properties        |    7 ++
- browser/themes/gnomestripe/browser.css             |    2 +
- browser/themes/pinstripe/browser.css               |    2 +
- browser/themes/winstripe/browser.css               |    2 +
- content/canvas/src/CanvasUtils.cpp                 |   65 +++++++++++++
- content/canvas/src/CanvasUtils.h                   |    2 +
- content/canvas/src/nsCanvasRenderingContext2D.cpp  |   16 +++
- .../canvas/src/nsCanvasRenderingContext2DAzure.cpp |   16 +++
- content/html/content/public/nsHTMLCanvasElement.h  |    3 +
- content/html/content/src/Makefile.in               |    1 +
- content/html/content/src/nsHTMLCanvasElement.cpp   |   40 ++++++--
- 13 files changed, 249 insertions(+), 10 deletions(-)
-
-diff --git a/browser/base/content/browser.js b/browser/base/content/browser.js
-index bd2feed..50054e7 100644
---- a/browser/base/content/browser.js
-+++ b/browser/base/content/browser.js
-@@ -1280,6 +1280,7 @@ var gBrowserInit = {
-     BrowserOffline.init();
-     OfflineApps.init();
-     IndexedDBPromptHelper.init();
-+    CanvasPermissionPromptHelper.init();
-     gFormSubmitObserver.init();
-     SocialUI.init();
-     AddonManager.addAddonListener(AddonsMgrListener);
-@@ -1637,6 +1638,7 @@ var gBrowserInit = {
-       BrowserOffline.uninit();
-       OfflineApps.uninit();
-       IndexedDBPromptHelper.uninit();
-+      CanvasPermissionPromptHelper.uninit();
-       AddonManager.removeAddonListener(AddonsMgrListener);
-       SocialUI.uninit();
-     }
-@@ -6127,6 +6129,106 @@ var IndexedDBPromptHelper = {
-   }
- };
- 
-+var CanvasPermissionPromptHelper = {
-+  _permissionsPrompt: "canvas-permissions-prompt",
-+  _notificationIcon: "canvas-notification-icon",
-+
-+  init:
-+  function CanvasPermissionPromptHelper_init() {
-+    Services.obs.addObserver(this, this._permissionsPrompt, false);
-+  },
-+
-+  uninit:
-+  function CanvasPermissionPromptHelper_uninit() {
-+    Services.obs.removeObserver(this, this._permissionsPrompt, false);
-+  },
-+
-+  // aSubject is an nsIDOMWindow.
-+  // aData is an URL string.
-+  observe:
-+  function CanvasPermissionPromptHelper_observe(aSubject, aTopic, aData) {
-+    if ((aTopic != this._permissionsPrompt) || !aData)
-+      throw new Error("Unexpected topic or missing URL");
-+
-+    var uri = makeURI(aData);
-+    var contentWindow = aSubject.QueryInterface(Ci.nsIDOMWindow);
-+    var contentDocument = contentWindow.document;
-+    var browserWindow =
-+      OfflineApps._getBrowserWindowForContentWindow(contentWindow);
-+
-+    if (browserWindow != window) {
-+      // Must belong to some other window.
-+      return;
-+    }
-+
-+    // If canvas prompt is already displayed, just return.  This is OK (and
-+    // more efficient) since this permission is associated with the top
-+    // browser's URL.
-+    if (PopupNotifications.getNotification(aTopic, browser))
-+      return;
-+
-+    var bundleSvc = Cc["@mozilla.org/intl/stringbundle;1"].
-+                        getService(Ci.nsIStringBundleService);
-+    var torBtnBundle;
-+    try {
-+      torBtnBundle = bundleSvc.createBundle(
-+                             "chrome://torbutton/locale/torbutton.properties");
-+    } catch (e) {}
-+
-+    var message = getLocalizedString("canvas.siteprompt", [ uri.asciiHost ]);
-+
-+    var mainAction = {
-+      label: getLocalizedString("canvas.allow"),
-+      accessKey: getLocalizedString("canvas.allowAccessKey"),
-+      callback: function() {
-+          setCanvasPermission(uri, Ci.nsIPermissionManager.ALLOW_ACTION);
-+      }
-+    };
-+
-+    var secondaryActions = [
-+      {
-+        label: getLocalizedString("canvas.never"),
-+        accessKey: getLocalizedString("canvas.neverAccessKey"),
-+        callback: function() {
-+          setCanvasPermission(uri, Ci.nsIPermissionManager.DENY_ACTION);
-+        }
-+      }
-+    ];
-+
-+    // Since we have a process in place to perform localization for the
-+    // Torbutton extension, get our strings from the extension if possible.
-+    function getLocalizedString(aID, aParams) {
-+      var s;
-+      if (torBtnBundle) try {
-+        if (aParams)
-+          s = torBtnBundle.formatStringFromName(aID, aParams, aParams.length);
-+        else
-+          s = torBtnBundle.GetStringFromName(aID);
-+      } catch (e) {}
-+
-+      if (!s) {
-+        if (aParams)
-+          s = gNavigatorBundle.getFormattedString(aID, aParams);
-+        else
-+          s = gNavigatorBundle.getString(aID);
-+      }
-+
-+      return s;
-+    }
-+
-+    function setCanvasPermission(aURI, aPerm) {
-+      Services.perms.add(aURI, "canvas/extractData", aPerm,
-+                         Ci.nsIPermissionManager.EXPIRE_NEVER);
-+    }
-+
-+    var browser = OfflineApps._getBrowserForContentWindow(browserWindow,
-+                                                          contentWindow);
-+    notification = PopupNotifications.show(browser, aTopic, message,
-+                                           this._notificationIcon, mainAction,
-+                                           secondaryActions, null);
-+  }
-+};
-+
- function WindowIsClosing()
- {
-   if (TabView.isVisible()) {
-diff --git a/browser/base/content/browser.xul b/browser/base/content/browser.xul
-index 1982eb1..d4a20cd 100644
---- a/browser/base/content/browser.xul
-+++ b/browser/base/content/browser.xul
-@@ -573,6 +573,7 @@
-             <image id="identity-notification-icon" class="notification-anchor-icon" role="button"/>
-             <image id="geo-notification-icon" class="notification-anchor-icon" role="button"/>
-             <image id="addons-notification-icon" class="notification-anchor-icon" role="button"/>
-+            <image id="canvas-notification-icon" class="notification-anchor-icon" role="button"/>
-             <image id="indexedDB-notification-icon" class="notification-anchor-icon" role="button"/>
-             <image id="password-notification-icon" class="notification-anchor-icon" role="button"/>
-             <image id="webapps-notification-icon" class="notification-anchor-icon" role="button"/>
-diff --git a/browser/locales/en-US/chrome/browser/browser.properties b/browser/locales/en-US/chrome/browser/browser.properties
-index 1a9f457..4e61cb9 100644
---- a/browser/locales/en-US/chrome/browser/browser.properties
-+++ b/browser/locales/en-US/chrome/browser/browser.properties
-@@ -218,6 +218,13 @@ offlineApps.usage=This website (%S) is now storing more than %SMB of data on you
- offlineApps.manageUsage=Show settings
- offlineApps.manageUsageAccessKey=S
- 
-+# Canvas permission prompt
-+canvas.siteprompt=This website (%S) attempted to access image data on a canvas. Since canvas image data can be used to discover information about your computer, blank image data was returned this time.
-+canvas.allow=Allow in the Future
-+canvas.allowAccessKey=A
-+canvas.never=Never for This Site
-+canvas.neverAccessKey=e
-+
- # LOCALIZATION NOTE (indexedDB.usage): %1$S is the website host name
- # %2$S a number of megabytes.
- indexedDB.usage=This website (%1$S) is attempting to store more than %2$S MB of data on your computer for offline use.
-diff --git a/browser/themes/gnomestripe/browser.css b/browser/themes/gnomestripe/browser.css
-index a90d500..fd5d042 100644
---- a/browser/themes/gnomestripe/browser.css
-+++ b/browser/themes/gnomestripe/browser.css
-@@ -1185,6 +1185,7 @@ toolbar[iconsize="small"] #feed-button {
-   list-style-image: url("moz-icon://stock/gtk-cancel?size=menu");
- }
- 
-+.popup-notification-icon[popupid="canvas-permissions-prompt"],
- .popup-notification-icon[popupid="indexedDB-permissions-prompt"],
- .popup-notification-icon[popupid="indexedDB-quota-prompt"] {
-   list-style-image: url(chrome://global/skin/icons/question-64.png);
-@@ -1250,6 +1251,7 @@ toolbar[iconsize="small"] #feed-button {
-   list-style-image: url(chrome://mozapps/skin/extensions/extensionGeneric-16.png);
- }
- 
-+#canvas-notification-icon,
- #indexedDB-notification-icon {
-   list-style-image: url(chrome://global/skin/icons/question-16.png);
- }
-diff --git a/browser/themes/pinstripe/browser.css b/browser/themes/pinstripe/browser.css
-index cb98808..69b908f 100644
---- a/browser/themes/pinstripe/browser.css
-+++ b/browser/themes/pinstripe/browser.css
-@@ -2433,10 +2433,12 @@ toolbarbutton.chevron > .toolbarbutton-menu-dropmarker {
-   -moz-image-region: rect(0px, 48px, 16px, 32px);
- }
- 
-+#canvas-notification-icon,
- #indexedDB-notification-icon {
-   list-style-image: url(chrome://global/skin/icons/question-16.png);
- }
- 
-+.popup-notification-icon[popupid="canvas-permissions-prompt"],
- .popup-notification-icon[popupid="indexedDB-permissions-prompt"],
- .popup-notification-icon[popupid="indexedDB-quota-prompt"] {
-   list-style-image: url(chrome://global/skin/icons/question-64.png);
-diff --git a/browser/themes/winstripe/browser.css b/browser/themes/winstripe/browser.css
-index d02eed6..70aab91 100644
---- a/browser/themes/winstripe/browser.css
-+++ b/browser/themes/winstripe/browser.css
-@@ -2319,6 +2319,7 @@ toolbarbutton.bookmark-item[dragover="true"][open="true"] {
-   -moz-image-region: rect(32px, 32px, 48px, 16px);
- }
- 
-+.popup-notification-icon[popupid="canvas-permissions-prompt"],
- .popup-notification-icon[popupid="indexedDB-permissions-prompt"],
- .popup-notification-icon[popupid="indexedDB-quota-prompt"] {
-   list-style-image: url(chrome://global/skin/icons/question-64.png);
-@@ -2382,6 +2383,7 @@ toolbarbutton.bookmark-item[dragover="true"][open="true"] {
-   list-style-image: url(chrome://mozapps/skin/extensions/extensionGeneric-16.png);
- }
- 
-+#canvas-notification-icon,
- #indexedDB-notification-icon {
-   list-style-image: url(chrome://global/skin/icons/question-16.png);
- }
-diff --git a/content/canvas/src/CanvasUtils.cpp b/content/canvas/src/CanvasUtils.cpp
-index 4173891..2ec463f 100644
---- a/content/canvas/src/CanvasUtils.cpp
-+++ b/content/canvas/src/CanvasUtils.cpp
-@@ -24,9 +24,74 @@
- #include "CanvasUtils.h"
- #include "mozilla/gfx/Matrix.h"
- 
-+#include "nsIScriptObjectPrincipal.h"
-+#include "nsIPermissionManager.h"
-+#include "nsIObserverService.h"
-+#include "mozilla/Services.h"
-+#include "mozIThirdPartyUtil.h"
-+#include "nsContentUtils.h"
-+#include "nsUnicharUtils.h"
-+
-+#define TOPIC_CANVAS_PERMISSIONS_PROMPT "canvas-permissions-prompt"
-+#define PERMISSION_CANVAS_EXTRACT_DATA "canvas/extractData"
-+
- namespace mozilla {
- namespace CanvasUtils {
- 
-+// Check site-specific permission and display prompt if appropriate.
-+bool
-+IsImageExtractionAllowed(nsIDocument *aDocument)
-+{
-+  if (!aDocument)
-+    return false;
-+
-+  nsPIDOMWindow *win = aDocument->GetWindow();
-+  nsCOMPtr<nsIScriptObjectPrincipal> sop(do_QueryInterface(win));
-+  if (sop && nsContentUtils::IsSystemPrincipal(sop->GetPrincipal()))
-+    return true;
-+
-+  bool isAllowed = false;
-+  nsCOMPtr<mozIThirdPartyUtil> thirdPartyUtil =
-+                                do_GetService(THIRDPARTYUTIL_CONTRACTID);
-+  nsCOMPtr<nsIPermissionManager> permissionManager =
-+                          do_GetService(NS_PERMISSIONMANAGER_CONTRACTID);
-+  if (thirdPartyUtil && permissionManager) {
-+    nsCOMPtr<nsIURI> uri;
-+    nsresult rv = thirdPartyUtil->GetFirstPartyURI(NULL, aDocument,
-+                                                   getter_AddRefs(uri));
-+    uint32_t permission = nsIPermissionManager::UNKNOWN_ACTION;
-+    if (NS_SUCCEEDED(rv)) {
-+      // Allow local files to access canvas data; check content permissions
-+      // for remote pages.
-+      bool isFileURL = false;
-+      (void)uri->SchemeIs("file", &isFileURL);
-+      if (isFileURL)
-+        permission = nsIPermissionManager::ALLOW_ACTION;
-+      else {
-+        rv = permissionManager->TestPermission(uri,
-+                                PERMISSION_CANVAS_EXTRACT_DATA, &permission);
-+      }
-+    }
-+
-+    if (NS_SUCCEEDED(rv)) {
-+      isAllowed = (permission == nsIPermissionManager::ALLOW_ACTION);
-+
-+      if (!isAllowed && (permission != nsIPermissionManager::DENY_ACTION)) {
-+        // Send notification so that a prompt is displayed.
-+        nsCString spec;
-+        rv = uri->GetSpec(spec);
-+        NS_ENSURE_SUCCESS(rv, rv);
-+        nsCOMPtr<nsIObserverService> obs =
-+                                    mozilla::services::GetObserverService();
-+        obs->NotifyObservers(win, TOPIC_CANVAS_PERMISSIONS_PROMPT,
-+                             NS_ConvertUTF8toUTF16(spec).get());
-+      }
-+    }
-+  }
-+
-+  return isAllowed;
-+}
-+
- void
- DoDrawImageSecurityCheck(nsHTMLCanvasElement *aCanvasElement,
-                          nsIPrincipal *aPrincipal,
-diff --git a/content/canvas/src/CanvasUtils.h b/content/canvas/src/CanvasUtils.h
-index d464d0b..f266de6 100644
---- a/content/canvas/src/CanvasUtils.h
-+++ b/content/canvas/src/CanvasUtils.h
-@@ -45,6 +45,8 @@ void DoDrawImageSecurityCheck(nsHTMLCanvasElement *aCanvasElement,
-                               bool forceWriteOnly,
-                               bool CORSUsed);
- 
-+bool IsImageExtractionAllowed(nsIDocument *aDocument);
-+
- // Make a double out of |v|, treating undefined values as 0.0 (for
- // the sake of sparse arrays).  Return true iff coercion
- // succeeded.
-diff --git a/content/canvas/src/nsCanvasRenderingContext2D.cpp b/content/canvas/src/nsCanvasRenderingContext2D.cpp
-index 1ee7a02..0dec654 100644
---- a/content/canvas/src/nsCanvasRenderingContext2D.cpp
-+++ b/content/canvas/src/nsCanvasRenderingContext2D.cpp
-@@ -3946,6 +3946,22 @@ nsCanvasRenderingContext2D::GetImageDataArray(JSContext* aCx,
- 
-     uint8_t* data = JS_GetUint8ClampedArrayData(darray, aCx);
- 
-+    // Check for site-specific permission and return all-white, opaque pixel
-+    // data if no permission.  This check is not needed if the canvas was
-+    // created with a docshell (that is only done for special internal uses).
-+    bool usePlaceholder = false;
-+    if (mCanvasElement) {
-+      nsCOMPtr<nsIDocument> ownerDoc = mCanvasElement->OwnerDoc();
-+      usePlaceholder = !ownerDoc ||
-+                          !CanvasUtils::IsImageExtractionAllowed(ownerDoc);
-+    }
-+
-+    if (usePlaceholder) {
-+      memset(data, 0xFF, len.value());
-+      *aRetval = darray;
-+      return NS_OK;
-+    }
-+
-     /* Copy the surface contents to the buffer */
-     nsRefPtr<gfxImageSurface> tmpsurf =
-         new gfxImageSurface(data,
-diff --git a/content/canvas/src/nsCanvasRenderingContext2DAzure.cpp b/content/canvas/src/nsCanvasRenderingContext2DAzure.cpp
-index 07b5236..d86ba32 100644
---- a/content/canvas/src/nsCanvasRenderingContext2DAzure.cpp
-+++ b/content/canvas/src/nsCanvasRenderingContext2DAzure.cpp
-@@ -4251,6 +4251,22 @@ nsCanvasRenderingContext2DAzure::GetImageDataArray(JSContext* aCx,
- 
-   uint8_t* data = JS_GetUint8ClampedArrayData(darray, aCx);
- 
-+  // Check for site-specific permission and return all-white, opaque pixel
-+  // data if no permission.  This check is not needed if the canvas was
-+  // created with a docshell (that is only done for special internal uses).
-+  bool usePlaceholder = false;
-+  if (mCanvasElement) {
-+    nsCOMPtr<nsIDocument> ownerDoc = mCanvasElement->OwnerDoc();
-+    usePlaceholder = !ownerDoc ||
-+                        !CanvasUtils::IsImageExtractionAllowed(ownerDoc);
-+  }
-+
-+  if (usePlaceholder) {
-+    memset(data, 0xFF, len.value());
-+    *aRetval = darray;
-+    return NS_OK;
-+  }
-+
-   IntRect srcRect(0, 0, mWidth, mHeight);
-   IntRect destRect(aX, aY, aWidth, aHeight);
- 
-diff --git a/content/html/content/public/nsHTMLCanvasElement.h b/content/html/content/public/nsHTMLCanvasElement.h
-index 2c11600..65da344 100644
---- a/content/html/content/public/nsHTMLCanvasElement.h
-+++ b/content/html/content/public/nsHTMLCanvasElement.h
-@@ -157,13 +157,16 @@ protected:
-   nsresult UpdateContext(nsIPropertyBag *aNewContextOptions = nullptr);
-   nsresult ExtractData(const nsAString& aType,
-                        const nsAString& aOptions,
-+                       bool aUsePlaceholder,
-                        nsIInputStream** aStream,
-                        bool& aFellBackToPNG);
-   nsresult ToDataURLImpl(const nsAString& aMimeType,
-                          nsIVariant* aEncoderOptions,
-+                         bool aUsePlaceholder,
-                          nsAString& aDataURL);
-   nsresult MozGetAsFileImpl(const nsAString& aName,
-                             const nsAString& aType,
-+                            bool aUsePlaceholder,
-                             nsIDOMFile** aResult);
-   nsresult GetContextHelper(const nsAString& aContextId,
-                             bool aForceThebes,
-diff --git a/content/html/content/src/Makefile.in b/content/html/content/src/Makefile.in
-index 9466587..86368a2 100644
---- a/content/html/content/src/Makefile.in
-+++ b/content/html/content/src/Makefile.in
-@@ -113,6 +113,7 @@ INCLUDES	+= \
- 		-I$(srcdir)/../../../events/src \
- 		-I$(srcdir)/../../../xbl/src \
- 		-I$(srcdir)/../../../xul/content/src \
-+		-I$(srcdir)/../../../canvas/src/ \
- 		-I$(srcdir)/../../../../layout/forms \
- 		-I$(srcdir)/../../../../layout/style \
- 		-I$(srcdir)/../../../../layout/tables \
-diff --git a/content/html/content/src/nsHTMLCanvasElement.cpp b/content/html/content/src/nsHTMLCanvasElement.cpp
-index 961ebf1..13a6910 100644
---- a/content/html/content/src/nsHTMLCanvasElement.cpp
-+++ b/content/html/content/src/nsHTMLCanvasElement.cpp
-@@ -31,6 +31,8 @@
- 
- #include "nsIWritablePropertyBag2.h"
- 
-+#include "CanvasUtils.h"
-+
- #define DEFAULT_CANVAS_WIDTH 300
- #define DEFAULT_CANVAS_HEIGHT 150
- 
-@@ -184,7 +186,10 @@ nsHTMLCanvasElement::ToDataURL(const nsAString& aType, nsIVariant* aParams,
-     return NS_ERROR_DOM_SECURITY_ERR;
-   }
- 
--  return ToDataURLImpl(aType, aParams, aDataURL);
-+  // Check site-specific permission and display prompt if appropriate.
-+  // If no permission, return all-white, opaque image data.
-+  bool usePlaceholder = !CanvasUtils::IsImageExtractionAllowed(OwnerDoc());
-+  return ToDataURLImpl(aType, aParams, usePlaceholder, aDataURL);
- }
- 
- // nsHTMLCanvasElement::mozFetchAsStream
-@@ -200,7 +205,7 @@ nsHTMLCanvasElement::MozFetchAsStream(nsIInputStreamCallback *aCallback,
-   bool fellBackToPNG = false;
-   nsCOMPtr<nsIInputStream> inputData;
- 
--  rv = ExtractData(aType, EmptyString(), getter_AddRefs(inputData), fellBackToPNG);
-+  rv = ExtractData(aType, EmptyString(), false, getter_AddRefs(inputData), fellBackToPNG);
-   NS_ENSURE_SUCCESS(rv, rv);
- 
-   nsCOMPtr<nsIAsyncInputStream> asyncData = do_QueryInterface(inputData, &rv);
-@@ -220,19 +225,26 @@ nsHTMLCanvasElement::MozFetchAsStream(nsIInputStreamCallback *aCallback,
- nsresult
- nsHTMLCanvasElement::ExtractData(const nsAString& aType,
-                                  const nsAString& aOptions,
-+                                 bool aUsePlaceholder,
-                                  nsIInputStream** aStream,
-                                  bool& aFellBackToPNG)
- {
-   // note that if we don't have a current context, the spec says we're
-   // supposed to just return transparent black pixels of the canvas
-   // dimensions.
-+  // If placeholder data was requested, return all-white, opaque image data.
-   nsRefPtr<gfxImageSurface> emptyCanvas;
-   nsIntSize size = GetWidthHeight();
--  if (!mCurrentContext) {
-+  if (aUsePlaceholder || !mCurrentContext) {
-     emptyCanvas = new gfxImageSurface(gfxIntSize(size.width, size.height), gfxASurface::ImageFormatARGB32);
-     if (emptyCanvas->CairoStatus()) {
-       return NS_ERROR_INVALID_ARG;
-     }
-+
-+    if (aUsePlaceholder) {
-+      int32_t dataSize = emptyCanvas->GetDataSize();
-+      memset(emptyCanvas->Data(), 0xFF, dataSize);
-+    }
-   }
- 
-   nsresult rv;
-@@ -242,12 +254,13 @@ nsHTMLCanvasElement::ExtractData(const nsAString& aType,
-   NS_ConvertUTF16toUTF8 encoderType(aType);
- 
-  try_again:
--  if (mCurrentContext) {
-+  if (!aUsePlaceholder && mCurrentContext) {
-     rv = mCurrentContext->GetInputStream(encoderType.get(),
-                                          nsPromiseFlatString(aOptions).get(),
-                                          getter_AddRefs(imgStream));
-   } else {
--    // no context, so we have to encode the empty image we created above
-+    // Using placeholder or we have no context:  encode the empty/white image
-+    // we created above.
-     nsCString enccid("@mozilla.org/image/encoder;2?type=");
-     enccid += encoderType;
- 
-@@ -285,6 +298,7 @@ nsHTMLCanvasElement::ExtractData(const nsAString& aType,
- nsresult
- nsHTMLCanvasElement::ToDataURLImpl(const nsAString& aMimeType,
-                                    nsIVariant* aEncoderOptions,
-+                                   bool aUsePlaceholder,
-                                    nsAString& aDataURL)
- {
-   bool fallbackToPNG = false;
-@@ -340,13 +354,15 @@ nsHTMLCanvasElement::ToDataURLImpl(const nsAString& aMimeType,
-   }
- 
-   nsCOMPtr<nsIInputStream> stream;
--  rv = ExtractData(type, params, getter_AddRefs(stream), fallbackToPNG);
-+  rv = ExtractData(type, params, aUsePlaceholder,
-+                   getter_AddRefs(stream), fallbackToPNG);
- 
-   // If there are unrecognized custom parse options, we should fall back to 
-   // the default values for the encoder without any options at all.
-   if (rv == NS_ERROR_INVALID_ARG && usingCustomParseOptions) {
-     fallbackToPNG = false;
--    rv = ExtractData(type, EmptyString(), getter_AddRefs(stream), fallbackToPNG);
-+    rv = ExtractData(type, EmptyString(), aUsePlaceholder,
-+                     getter_AddRefs(stream), fallbackToPNG);
-   }
- 
-   NS_ENSURE_SUCCESS(rv, rv);
-@@ -378,19 +394,23 @@ nsHTMLCanvasElement::MozGetAsFile(const nsAString& aName,
-     return NS_ERROR_DOM_SECURITY_ERR;
-   }
- 
--  return MozGetAsFileImpl(aName, aType, aResult);
-+  // Check site-speciifc permission and display prompt if appropriate.
-+  // If no permission, return all-white, opaque image data.
-+  bool usePlaceholder = !CanvasUtils::IsImageExtractionAllowed(OwnerDoc());
-+  return MozGetAsFileImpl(aName, aType, usePlaceholder, aResult);
- }
- 
- nsresult
- nsHTMLCanvasElement::MozGetAsFileImpl(const nsAString& aName,
-                                       const nsAString& aType,
-+                                      bool aUsePlaceholder,
-                                       nsIDOMFile** aResult)
- {
-   bool fallbackToPNG = false;
- 
-   nsCOMPtr<nsIInputStream> stream;
--  nsresult rv = ExtractData(aType, EmptyString(), getter_AddRefs(stream),
--                            fallbackToPNG);
-+  nsresult rv = ExtractData(aType, EmptyString(), aUsePlaceholder,
-+                            getter_AddRefs(stream), fallbackToPNG);
-   NS_ENSURE_SUCCESS(rv, rv);
- 
-   nsAutoString type(aType);
--- 
-1.7.5.4
-
diff --git a/src/current-patches/firefox/0021-Return-client-window-coordinates-for-mouse-event-scr.patch b/src/current-patches/firefox/0021-Return-client-window-coordinates-for-mouse-event-scr.patch
deleted file mode 100644
index 0cee032..0000000
--- a/src/current-patches/firefox/0021-Return-client-window-coordinates-for-mouse-event-scr.patch
+++ /dev/null
@@ -1,77 +0,0 @@
-From b0696055ca1d34426ae1c8ce2761404d3261525e Mon Sep 17 00:00:00 2001
-From: Kathleen Brade <brade at pearlcrescent.com>
-Date: Wed, 28 Nov 2012 10:49:09 -0500
-Subject: [PATCH 21/27] Return client window coordinates for mouse event
- screenX/Y (for dragend, 0,0 is returned).
-
----
- content/events/src/nsDOMMouseEvent.cpp |   22 ++++++++++++++++++++++
- content/events/src/nsDOMTouchEvent.cpp |    6 ++++--
- 2 files changed, 26 insertions(+), 2 deletions(-)
-
-diff --git a/content/events/src/nsDOMMouseEvent.cpp b/content/events/src/nsDOMMouseEvent.cpp
-index 0817397..3d8b26a 100644
---- a/content/events/src/nsDOMMouseEvent.cpp
-+++ b/content/events/src/nsDOMMouseEvent.cpp
-@@ -301,6 +301,20 @@ nsDOMMouseEvent::GetMozMovementY(int32_t* aMovementY)
- NS_METHOD nsDOMMouseEvent::GetScreenX(int32_t* aScreenX)
- {
-   NS_ENSURE_ARG_POINTER(aScreenX);
-+  bool isChrome = nsContentUtils::IsCallerChrome();
-+  if (!isChrome)
-+  {
-+    // For non-chrome callers, return client coordinates instead.
-+    // For some events, the result will be zero; specifically, for dragend
-+    // events (there is no widget associated with dragend events, which
-+    // causes GetClientX() to return zero).  Since dragend is for the drag
-+    // originator and not for the receiver, it is probably not widely used
-+    // (receivers get a drop event).  Therefore, returning 0 should not break
-+    // many web pages.  Also, a few years ago Firefox returned 0.
-+    // See:  https://bugzilla.mozilla.org/show_bug.cgi?id=466379
-+    return GetClientX(aScreenX);
-+  }
-+
-   *aScreenX = nsDOMEvent::GetScreenCoords(mPresContext,
-                                           mEvent,
-                                           mEvent->refPoint).x;
-@@ -311,6 +325,14 @@ NS_IMETHODIMP
- nsDOMMouseEvent::GetScreenY(int32_t* aScreenY)
- {
-   NS_ENSURE_ARG_POINTER(aScreenY);
-+  bool isChrome = nsContentUtils::IsCallerChrome();
-+  if (!isChrome)
-+  {
-+    // For non-chrome callers, return client coordinates instead.
-+    // See also the comment in nsDOMMouseEvent::GetScreenX().
-+    return GetClientY(aScreenY);
-+  }
-+
-   *aScreenY = nsDOMEvent::GetScreenCoords(mPresContext,
-                                           mEvent,
-                                           mEvent->refPoint).y;
-diff --git a/content/events/src/nsDOMTouchEvent.cpp b/content/events/src/nsDOMTouchEvent.cpp
-index ccf4864..64ab0e8 100644
---- a/content/events/src/nsDOMTouchEvent.cpp
-+++ b/content/events/src/nsDOMTouchEvent.cpp
-@@ -44,14 +44,16 @@ nsDOMTouch::GetTarget(nsIDOMEventTarget** aTarget)
- NS_IMETHODIMP
- nsDOMTouch::GetScreenX(int32_t* aScreenX)
- {
--  *aScreenX = mScreenPoint.x;
-+  bool isChrome = nsContentUtils::IsCallerChrome();
-+  *aScreenX = isChrome ? mScreenPoint.x : mClientPoint.x;
-   return NS_OK;
- }
- 
- NS_IMETHODIMP
- nsDOMTouch::GetScreenY(int32_t* aScreenY)
- {
--  *aScreenY = mScreenPoint.y;
-+  bool isChrome = nsContentUtils::IsCallerChrome();
-+  *aScreenY = isChrome ? mScreenPoint.y : mClientPoint.y;
-   return NS_OK;
- }
- 
--- 
-1.7.5.4
-
diff --git a/src/current-patches/firefox/0022-Do-not-expose-physical-screen-info.-via-window-and-w.patch b/src/current-patches/firefox/0022-Do-not-expose-physical-screen-info.-via-window-and-w.patch
deleted file mode 100644
index 621d2a8..0000000
--- a/src/current-patches/firefox/0022-Do-not-expose-physical-screen-info.-via-window-and-w.patch
+++ /dev/null
@@ -1,310 +0,0 @@
-From 73dd7935b3e9a226e868844bf9a92b257416c5ec Mon Sep 17 00:00:00 2001
-From: Kathleen Brade <brade at pearlcrescent.com>
-Date: Wed, 28 Nov 2012 11:25:14 -0500
-Subject: [PATCH 22/27] Do not expose physical screen info. via window and
- window.screen.
-
----
- dom/base/nsGlobalWindow.cpp |   46 ++++++++++++++++++++++
- dom/base/nsGlobalWindow.h   |    2 +
- dom/base/nsScreen.cpp       |   90 +++++++++++++++++++++++++++++++++++++++++++
- dom/base/nsScreen.h         |    3 +
- 4 files changed, 141 insertions(+), 0 deletions(-)
-
-diff --git a/dom/base/nsGlobalWindow.cpp b/dom/base/nsGlobalWindow.cpp
-index f675f87..48bd71d 100644
---- a/dom/base/nsGlobalWindow.cpp
-+++ b/dom/base/nsGlobalWindow.cpp
-@@ -3745,6 +3745,10 @@ nsGlobalWindow::GetOuterWidth(int32_t* aOuterWidth)
- {
-   FORWARD_TO_OUTER(GetOuterWidth, (aOuterWidth), NS_ERROR_NOT_INITIALIZED);
- 
-+  // For non-chrome callers, return inner width to prevent fingerprinting.
-+  if (!IsChrome())
-+    return GetInnerWidth(aOuterWidth);
-+
-   nsIntSize sizeCSSPixels;
-   nsresult rv = GetOuterSize(&sizeCSSPixels);
-   NS_ENSURE_SUCCESS(rv, rv);
-@@ -3758,6 +3762,10 @@ nsGlobalWindow::GetOuterHeight(int32_t* aOuterHeight)
- {
-   FORWARD_TO_OUTER(GetOuterHeight, (aOuterHeight), NS_ERROR_NOT_INITIALIZED);
- 
-+  // For non-chrome callers, return inner height to prevent fingerprinting.
-+  if (!IsChrome())
-+    return GetInnerHeight(aOuterHeight);
-+
-   nsIntSize sizeCSSPixels;
-   nsresult rv = GetOuterSize(&sizeCSSPixels);
-   NS_ENSURE_SUCCESS(rv, rv);
-@@ -3820,6 +3828,12 @@ nsGlobalWindow::GetScreenX(int32_t* aScreenX)
- {
-   FORWARD_TO_OUTER(GetScreenX, (aScreenX), NS_ERROR_NOT_INITIALIZED);
- 
-+  // For non-chrome callers, always return 0 to prevent fingerprinting.
-+  if (!IsChrome()) {
-+    *aScreenX = 0;
-+    return NS_OK;
-+  }
-+
-   nsCOMPtr<nsIBaseWindow> treeOwnerAsWin;
-   GetTreeOwner(getter_AddRefs(treeOwnerAsWin));
-   NS_ENSURE_TRUE(treeOwnerAsWin, NS_ERROR_FAILURE);
-@@ -3861,6 +3875,12 @@ nsGlobalWindow::GetMozInnerScreenX(float* aScreenX)
- {
-   FORWARD_TO_OUTER(GetMozInnerScreenX, (aScreenX), NS_ERROR_NOT_INITIALIZED);
- 
-+  // For non-chrome callers, always return 0 to prevent fingerprinting.
-+  if (!IsChrome()) {
-+    *aScreenX = 0;
-+    return NS_OK;
-+  }
-+
-   nsRect r = GetInnerScreenRect();
-   *aScreenX = nsPresContext::AppUnitsToFloatCSSPixels(r.x);
-   return NS_OK;
-@@ -3871,6 +3891,12 @@ nsGlobalWindow::GetMozInnerScreenY(float* aScreenY)
- {
-   FORWARD_TO_OUTER(GetMozInnerScreenY, (aScreenY), NS_ERROR_NOT_INITIALIZED);
- 
-+  // For non-chrome callers, always return 0 to prevent fingerprinting.
-+  if (!IsChrome()) {
-+    *aScreenY = 0;
-+    return NS_OK;
-+  }
-+
-   nsRect r = GetInnerScreenRect();
-   *aScreenY = nsPresContext::AppUnitsToFloatCSSPixels(r.y);
-   return NS_OK;
-@@ -4028,6 +4054,12 @@ nsGlobalWindow::GetScreenY(int32_t* aScreenY)
- {
-   FORWARD_TO_OUTER(GetScreenY, (aScreenY), NS_ERROR_NOT_INITIALIZED);
- 
-+  // For non-chrome callers, always return 0 to prevent fingerprinting.
-+  if (!IsChrome()) {
-+    *aScreenY = 0;
-+    return NS_OK;
-+  }
-+
-   nsCOMPtr<nsIBaseWindow> treeOwnerAsWin;
-   GetTreeOwner(getter_AddRefs(treeOwnerAsWin));
-   NS_ENSURE_TRUE(treeOwnerAsWin, NS_ERROR_FAILURE);
-@@ -4074,6 +4106,20 @@ nsGlobalWindow::SetScreenY(int32_t aScreenY)
-   return NS_OK;
- }
- 
-+bool
-+nsGlobalWindow::IsChrome()
-+{
-+  bool isChrome = false;
-+
-+  if (mDocShell) {
-+    nsRefPtr<nsPresContext> presContext;
-+    mDocShell->GetPresContext(getter_AddRefs(presContext));
-+    isChrome = (presContext && presContext->IsChrome());
-+  }
-+
-+  return isChrome;
-+}
-+
- // NOTE: Arguments to this function should have values scaled to
- // CSS pixels, not device pixels.
- nsresult
-diff --git a/dom/base/nsGlobalWindow.h b/dom/base/nsGlobalWindow.h
-index 9acc1ea..4cb6938 100644
---- a/dom/base/nsGlobalWindow.h
-+++ b/dom/base/nsGlobalWindow.h
-@@ -827,6 +827,8 @@ protected:
-   nsresult SetOuterSize(int32_t aLengthCSSPixels, bool aIsWidth);
-   nsRect GetInnerScreenRect();
- 
-+  bool IsChrome();
-+
-   bool IsFrame()
-   {
-     return GetParentInternal() != nullptr;
-diff --git a/dom/base/nsScreen.cpp b/dom/base/nsScreen.cpp
-index 41c32ad..4f3904d 100644
---- a/dom/base/nsScreen.cpp
-+++ b/dom/base/nsScreen.cpp
-@@ -115,6 +115,12 @@ NS_IMPL_EVENT_HANDLER(nsScreen, mozorientationchange)
- NS_IMETHODIMP
- nsScreen::GetTop(int32_t* aTop)
- {
-+  // For non-chrome callers, always return 0 to prevent fingerprinting.
-+  if (!IsChrome()) {
-+    *aTop = 0;
-+    return NS_OK;
-+  }
-+
-   nsRect rect;
-   nsresult rv = GetRect(rect);
- 
-@@ -127,6 +133,12 @@ nsScreen::GetTop(int32_t* aTop)
- NS_IMETHODIMP
- nsScreen::GetLeft(int32_t* aLeft)
- {
-+  // For non-chrome callers, always return 0 to prevent fingerprinting.
-+  if (!IsChrome()) {
-+    *aLeft = 0;
-+    return NS_OK;
-+  }
-+
-   nsRect rect;
-   nsresult rv = GetRect(rect);
- 
-@@ -139,6 +151,14 @@ nsScreen::GetLeft(int32_t* aLeft)
- NS_IMETHODIMP
- nsScreen::GetWidth(int32_t* aWidth)
- {
-+  // For non-chrome callers, return content width to prevent fingerprinting.
-+  if (!IsChrome()) {
-+    nsCOMPtr<nsIDOMWindow> win;
-+    nsresult rv = GetDOMWindow(getter_AddRefs(win));
-+    NS_ENSURE_SUCCESS(rv, rv);
-+    return win->GetInnerWidth(aWidth);
-+  }
-+
-   nsRect rect;
-   nsresult rv = GetRect(rect);
- 
-@@ -150,6 +170,14 @@ nsScreen::GetWidth(int32_t* aWidth)
- NS_IMETHODIMP
- nsScreen::GetHeight(int32_t* aHeight)
- {
-+  // For non-chrome callers, return content height to prevent fingerprinting.
-+  if (!IsChrome()) {
-+    nsCOMPtr<nsIDOMWindow> win;
-+    nsresult rv = GetDOMWindow(getter_AddRefs(win));
-+    NS_ENSURE_SUCCESS(rv, rv);
-+    return win->GetInnerHeight(aHeight);
-+  }
-+
-   nsRect rect;
-   nsresult rv = GetRect(rect);
- 
-@@ -161,6 +189,12 @@ nsScreen::GetHeight(int32_t* aHeight)
- NS_IMETHODIMP
- nsScreen::GetPixelDepth(int32_t* aPixelDepth)
- {
-+  // For non-chrome callers, always return 24 to prevent fingerprinting.
-+  if (!IsChrome()) {
-+    *aPixelDepth = 24;
-+    return NS_OK;
-+  }
-+
-   nsDeviceContext* context = GetDeviceContext();
- 
-   if (!context) {
-@@ -186,6 +220,14 @@ nsScreen::GetColorDepth(int32_t* aColorDepth)
- NS_IMETHODIMP
- nsScreen::GetAvailWidth(int32_t* aAvailWidth)
- {
-+  // For non-chrome callers, return content width to prevent fingerprinting.
-+  if (!IsChrome()) {
-+    nsCOMPtr<nsIDOMWindow> win;
-+    nsresult rv = GetDOMWindow(getter_AddRefs(win));
-+    NS_ENSURE_SUCCESS(rv, rv);
-+    return win->GetInnerWidth(aAvailWidth);
-+  }
-+
-   nsRect rect;
-   nsresult rv = GetAvailRect(rect);
- 
-@@ -197,6 +239,14 @@ nsScreen::GetAvailWidth(int32_t* aAvailWidth)
- NS_IMETHODIMP
- nsScreen::GetAvailHeight(int32_t* aAvailHeight)
- {
-+  // For non-chrome callers, return content height to prevent fingerprinting.
-+  if (!IsChrome()) {
-+    nsCOMPtr<nsIDOMWindow> win;
-+    nsresult rv = GetDOMWindow(getter_AddRefs(win));
-+    NS_ENSURE_SUCCESS(rv, rv);
-+    return win->GetInnerHeight(aAvailHeight);
-+  }
-+
-   nsRect rect;
-   nsresult rv = GetAvailRect(rect);
- 
-@@ -208,6 +258,12 @@ nsScreen::GetAvailHeight(int32_t* aAvailHeight)
- NS_IMETHODIMP
- nsScreen::GetAvailLeft(int32_t* aAvailLeft)
- {
-+  // For non-chrome callers, always return 0 to prevent fingerprinting.
-+  if (!IsChrome()) {
-+    *aAvailLeft = 0;
-+    return NS_OK;
-+  }
-+
-   nsRect rect;
-   nsresult rv = GetAvailRect(rect);
- 
-@@ -219,6 +275,12 @@ nsScreen::GetAvailLeft(int32_t* aAvailLeft)
- NS_IMETHODIMP
- nsScreen::GetAvailTop(int32_t* aAvailTop)
- {
-+  // For non-chrome callers, always return 0 to prevent fingerprinting.
-+  if (!IsChrome()) {
-+    *aAvailTop = 0;
-+    return NS_OK;
-+  }
-+
-   nsRect rect;
-   nsresult rv = GetAvailRect(rect);
- 
-@@ -458,3 +520,31 @@ nsScreen::FullScreenEventListener::HandleEvent(nsIDOMEvent* aEvent)
- 
-   return NS_OK;
- }
-+
-+bool
-+nsScreen::IsChrome()
-+{
-+  bool isChrome = false;
-+  nsCOMPtr<nsPIDOMWindow> owner = GetOwner();
-+  if (owner)
-+    isChrome = IsChromeType(owner->GetDocShell());
-+
-+  return isChrome;
-+}
-+
-+nsresult
-+nsScreen::GetDOMWindow(nsIDOMWindow **aResult)
-+{
-+  NS_ENSURE_ARG_POINTER(aResult);
-+  *aResult = NULL;
-+
-+  nsCOMPtr<nsPIDOMWindow> owner = GetOwner();
-+  if (!owner)
-+    return NS_ERROR_FAILURE;
-+
-+  nsCOMPtr<nsIDOMWindow> win = do_QueryInterface(owner);
-+  NS_ENSURE_STATE(win);
-+  win.swap(*aResult);
-+
-+  return NS_OK;
-+}
-diff --git a/dom/base/nsScreen.h b/dom/base/nsScreen.h
-index 869d4fd..de18504 100644
---- a/dom/base/nsScreen.h
-+++ b/dom/base/nsScreen.h
-@@ -16,6 +16,7 @@
- 
- class nsIDocShell;
- class nsDeviceContext;
-+class nsIDOMWindow;
- struct nsRect;
- 
- // Script "screen" object
-@@ -41,6 +42,8 @@ protected:
-   nsDeviceContext* GetDeviceContext();
-   nsresult GetRect(nsRect& aRect);
-   nsresult GetAvailRect(nsRect& aRect);
-+  bool IsChrome();
-+  nsresult GetDOMWindow(nsIDOMWindow **aResult);
- 
-   mozilla::dom::ScreenOrientation mOrientation;
- 
--- 
-1.7.5.4
-
diff --git a/src/current-patches/firefox/0023-Do-not-expose-system-colors-to-CSS-or-canvas.patch b/src/current-patches/firefox/0023-Do-not-expose-system-colors-to-CSS-or-canvas.patch
deleted file mode 100644
index 2bd9ffc..0000000
--- a/src/current-patches/firefox/0023-Do-not-expose-system-colors-to-CSS-or-canvas.patch
+++ /dev/null
@@ -1,631 +0,0 @@
-From 6f70c68258eb81dc898622f1f2629d71441fb1d3 Mon Sep 17 00:00:00 2001
-From: Kathleen Brade <brade at pearlcrescent.com>
-Date: Wed, 28 Nov 2012 15:08:40 -0500
-Subject: [PATCH 23/28] Do not expose system colors to CSS or canvas.
-
-This patch also contains a hack to use properly contrasting colors if the
-desktop theme specifies white on black for text colors (see
-https://trac.torproject.org/projects/tor/ticket/7920). These color choices are
-also not exposed to content.
----
- content/canvas/src/nsCanvasRenderingContext2D.cpp  |   28 ++-
- .../canvas/src/nsCanvasRenderingContext2DAzure.cpp |   34 +++-
- .../canvas/src/nsCanvasRenderingContext2DAzure.h   |    5 +-
- layout/base/nsLayoutUtils.cpp                      |   50 +++++
- layout/base/nsLayoutUtils.h                        |    4 +
- layout/generic/nsFrame.cpp                         |    6 +-
- layout/style/nsRuleNode.cpp                        |    5 +-
- widget/LookAndFeel.h                               |   12 ++
- widget/xpwidgets/nsXPLookAndFeel.cpp               |  214 +++++++++++++++++++-
- widget/xpwidgets/nsXPLookAndFeel.h                 |    5 +-
- 10 files changed, 342 insertions(+), 21 deletions(-)
-
-diff --git a/content/canvas/src/nsCanvasRenderingContext2D.cpp b/content/canvas/src/nsCanvasRenderingContext2D.cpp
-index 0dec654..7132e4f 100644
---- a/content/canvas/src/nsCanvasRenderingContext2D.cpp
-+++ b/content/canvas/src/nsCanvasRenderingContext2D.cpp
-@@ -32,6 +32,7 @@
- #include "nsCSSParser.h"
- #include "mozilla/css/StyleRule.h"
- #include "mozilla/css/Declaration.h"
-+#include "mozilla/css/Loader.h"
- #include "nsComputedDOMStyle.h"
- #include "nsStyleSet.h"
- 
-@@ -159,8 +160,9 @@ class nsCanvasGradient MOZ_FINAL : public nsIDOMCanvasGradient
- public:
-     NS_DECLARE_STATIC_IID_ACCESSOR(NS_CANVASGRADIENT_PRIVATE_IID)
- 
--    nsCanvasGradient(gfxPattern* pat)
--        : mPattern(pat)
-+    nsCanvasGradient(mozilla::css::Loader* aLoader, gfxPattern* pat)
-+        : mCSSLoader(aLoader)
-+        , mPattern(pat)
-     {
-     }
- 
-@@ -181,8 +183,17 @@ public:
-             return NS_ERROR_DOM_SYNTAX_ERR;
-         }
- 
-+        nsIPresShell* presShell = nullptr;
-+        if (mCSSLoader) {
-+          nsIDocument *doc = mCSSLoader->GetDocument();
-+          if (doc)
-+            presShell = doc->GetShell();
-+        }
-+
-         nscolor color;
--        if (!nsRuleNode::ComputeColor(value, nullptr, nullptr, color)) {
-+        if (!nsRuleNode::ComputeColor(value,
-+                           presShell ? presShell->GetPresContext() : nullptr,
-+                           nullptr, color)) {
-             return NS_ERROR_DOM_SYNTAX_ERR;
-         }
- 
-@@ -194,6 +205,7 @@ public:
-     NS_DECL_ISUPPORTS
- 
- protected:
-+    mozilla::css::Loader* mCSSLoader; // not ref counted, it owns us
-     nsRefPtr<gfxPattern> mPattern;
- };
- 
-@@ -1814,7 +1826,10 @@ nsCanvasRenderingContext2D::CreateLinearGradient(float x0, float y0, float x1, f
-     if (!gradpat)
-         return NS_ERROR_OUT_OF_MEMORY;
- 
--    nsRefPtr<nsIDOMCanvasGradient> grad = new nsCanvasGradient(gradpat);
-+    nsIDocument* doc = mCanvasElement ? mCanvasElement->OwnerDoc() : nullptr;
-+    mozilla::css::Loader* cssLoader = doc ? doc->CSSLoader() : nullptr;
-+    nsRefPtr<nsIDOMCanvasGradient> grad = new nsCanvasGradient(cssLoader,
-+                                                               gradpat);
-     if (!grad)
-         return NS_ERROR_OUT_OF_MEMORY;
- 
-@@ -1836,7 +1851,10 @@ nsCanvasRenderingContext2D::CreateRadialGradient(float x0, float y0, float r0, f
-     if (!gradpat)
-         return NS_ERROR_OUT_OF_MEMORY;
- 
--    nsRefPtr<nsIDOMCanvasGradient> grad = new nsCanvasGradient(gradpat);
-+    nsIDocument* doc = mCanvasElement ? mCanvasElement->OwnerDoc() : nullptr;
-+    mozilla::css::Loader* cssLoader = doc ? doc->CSSLoader() : nullptr;
-+    nsRefPtr<nsIDOMCanvasGradient> grad = new nsCanvasGradient(cssLoader,
-+                                                               gradpat);
-     if (!grad)
-         return NS_ERROR_OUT_OF_MEMORY;
- 
-diff --git a/content/canvas/src/nsCanvasRenderingContext2DAzure.cpp b/content/canvas/src/nsCanvasRenderingContext2DAzure.cpp
-index d86ba32..84c1927 100644
---- a/content/canvas/src/nsCanvasRenderingContext2DAzure.cpp
-+++ b/content/canvas/src/nsCanvasRenderingContext2DAzure.cpp
-@@ -31,6 +31,7 @@
- #include "nsCSSParser.h"
- #include "mozilla/css/StyleRule.h"
- #include "mozilla/css/Declaration.h"
-+#include "mozilla/css/Loader.h"
- #include "nsComputedDOMStyle.h"
- #include "nsStyleSet.h"
- 
-@@ -140,9 +141,10 @@ NS_MEMORY_REPORTER_IMPLEMENT(CanvasAzureMemory,
- class nsCanvasRadialGradientAzure : public nsCanvasGradientAzure
- {
- public:
--  nsCanvasRadialGradientAzure(const Point &aBeginOrigin, Float aBeginRadius,
-+  nsCanvasRadialGradientAzure(mozilla::css::Loader* aLoader,
-+                              const Point &aBeginOrigin, Float aBeginRadius,
-                               const Point &aEndOrigin, Float aEndRadius)
--    : nsCanvasGradientAzure(RADIAL)
-+    : nsCanvasGradientAzure(aLoader, RADIAL)
-     , mCenter1(aBeginOrigin)
-     , mCenter2(aEndOrigin)
-     , mRadius1(aBeginRadius)
-@@ -159,8 +161,9 @@ public:
- class nsCanvasLinearGradientAzure : public nsCanvasGradientAzure
- {
- public:
--  nsCanvasLinearGradientAzure(const Point &aBegin, const Point &aEnd)
--    : nsCanvasGradientAzure(LINEAR)
-+  nsCanvasLinearGradientAzure(mozilla::css::Loader* aLoader,
-+                              const Point &aBegin, const Point &aEnd)
-+    : nsCanvasGradientAzure(aLoader, LINEAR)
-     , mBegin(aBegin)
-     , mEnd(aEnd)
-   {
-@@ -363,8 +366,17 @@ nsCanvasGradientAzure::AddColorStop(float offset, const nsAString& colorstr)
-     return NS_ERROR_DOM_SYNTAX_ERR;
-   }
- 
-+  nsIPresShell* presShell = nullptr;
-+  if (mCSSLoader) {
-+    nsIDocument *doc = mCSSLoader->GetDocument();
-+    if (doc)
-+      presShell = doc->GetShell();
-+  }
-+
-   nscolor color;
--  if (!nsRuleNode::ComputeColor(value, nullptr, nullptr, color)) {
-+  if (!nsRuleNode::ComputeColor(value,
-+                          presShell ? presShell->GetPresContext() : nullptr,
-+                          nullptr, color)) {
-     return NS_ERROR_DOM_SYNTAX_ERR;
-   }
- 
-@@ -1788,8 +1800,10 @@ nsCanvasRenderingContext2DAzure::CreateLinearGradient(double x0, double y0, doub
-     return nullptr;
-   }
- 
--  nsRefPtr<nsIDOMCanvasGradient> grad =
--    new nsCanvasLinearGradientAzure(Point(x0, y0), Point(x1, y1));
-+  nsIDocument* doc = mCanvasElement ? mCanvasElement->OwnerDoc() : nullptr;
-+  mozilla::css::Loader* cssLoader = doc ? doc->CSSLoader() : nullptr;
-+  nsRefPtr<nsIDOMCanvasGradient> grad = new nsCanvasLinearGradientAzure(
-+                                     cssLoader, Point(x0, y0), Point(x1, y1));
- 
-   return grad.forget();
- }
-@@ -1818,8 +1832,10 @@ nsCanvasRenderingContext2DAzure::CreateRadialGradient(double x0, double y0, doub
-     return nullptr;
-   }
- 
--  nsRefPtr<nsIDOMCanvasGradient> grad =
--    new nsCanvasRadialGradientAzure(Point(x0, y0), r0, Point(x1, y1), r1);
-+  nsIDocument* doc = mCanvasElement ? mCanvasElement->OwnerDoc() : nullptr;
-+  mozilla::css::Loader* cssLoader = doc ? doc->CSSLoader() : nullptr;
-+  nsRefPtr<nsIDOMCanvasGradient> grad = new nsCanvasRadialGradientAzure(
-+                            cssLoader, Point(x0, y0), r0, Point(x1, y1), r1);
- 
-   return grad.forget();
- }
-diff --git a/content/canvas/src/nsCanvasRenderingContext2DAzure.h b/content/canvas/src/nsCanvasRenderingContext2DAzure.h
-index 05ccf61..629d78a 100644
---- a/content/canvas/src/nsCanvasRenderingContext2DAzure.h
-+++ b/content/canvas/src/nsCanvasRenderingContext2DAzure.h
-@@ -71,11 +71,14 @@ public:
-   NS_IMETHOD AddColorStop(float offset, const nsAString& colorstr);
- 
- protected:
--  nsCanvasGradientAzure(Type aType) : mType(aType)
-+  nsCanvasGradientAzure(mozilla::css::Loader* aLoader, Type aType)
-+      : mCSSLoader(aLoader)
-+      , mType(aType)
-   {}
- 
-   nsTArray<mozilla::gfx::GradientStop> mRawStops;
-   mozilla::RefPtr<mozilla::gfx::GradientStops> mStops;
-+  mozilla::css::Loader* mCSSLoader; // not ref counted, it owns us
-   Type mType;
-   virtual ~nsCanvasGradientAzure() {}
- };
-diff --git a/layout/base/nsLayoutUtils.cpp b/layout/base/nsLayoutUtils.cpp
-index 87b0d34..65515d9 100644
---- a/layout/base/nsLayoutUtils.cpp
-+++ b/layout/base/nsLayoutUtils.cpp
-@@ -76,6 +76,7 @@
- #include "nsSVGForeignObjectFrame.h"
- #include "nsSVGOuterSVGFrame.h"
- #include "nsStyleStructInlines.h"
-+#include "mozilla/LookAndFeel.h"
- 
- #include "mozilla/Preferences.h"
- 
-@@ -3134,13 +3135,62 @@ ShouldDarkenColors(nsPresContext* aPresContext)
- nscolor
- nsLayoutUtils::GetColor(nsIFrame* aFrame, nsCSSProperty aProperty)
- {
-+  if (aProperty == eCSSProperty_color)
-+  {
-+    nscolor nativeColor = NS_RGB(0, 0, 0);
-+    if (GetNativeTextColor(aFrame, nativeColor))
-+      return nativeColor;
-+  }
-+
-   nscolor color = aFrame->GetVisitedDependentColor(aProperty);
-   if (ShouldDarkenColors(aFrame->PresContext())) {
-     color = DarkenColor(color);
-   }
-+
-   return color;
- }
- 
-+bool
-+nsLayoutUtils::GetNativeTextColor(nsIFrame* aFrame, nscolor& aColor)
-+{
-+  nsPresContext *presContext = aFrame->PresContext();
-+  if (!presContext->IsChrome()) {
-+    // If native appearance was used to draw the background of the containing
-+    // frame, return a contrasting native foreground color instead of the
-+    // color from the element's style.  This avoids a problem where black
-+    // text was displayed on a black background when a Windows theme such as
-+    // "High Contrast Black" was used.  The background is drawn inside
-+    // nsNativeThemeWin::ClassicDrawWidgetBackground().
-+    //
-+    // Because both the background color and this foreground color are used
-+    // directly without exposing the colors via CSS computed styles, the
-+    // native colors are not leaked to content.
-+    nsIFrame* bgFrame =
-+                    nsCSSRendering::FindNonTransparentBackgroundFrame(aFrame);
-+    if (bgFrame) {
-+      const nsStyleDisplay* displayData = bgFrame->GetStyleDisplay();
-+      uint8_t widgetType = displayData->mAppearance;
-+      nsITheme *theme = presContext->GetTheme();
-+      if (widgetType && theme->ThemeSupportsWidget(presContext, bgFrame,
-+                                                   widgetType)) {
-+        bool isDisabled = false;
-+        nsIContent* frameContent = bgFrame->GetContent();
-+        if (frameContent && frameContent->IsElement()) {
-+          nsEventStates es = frameContent->AsElement()->State();
-+          isDisabled = es.HasState(NS_EVENT_STATE_DISABLED); 
-+        } 
-+
-+        if (NS_SUCCEEDED(LookAndFeel::GetColorForNativeAppearance(widgetType,
-+                                                       isDisabled, &aColor))) {
-+            return true;
-+        }
-+      }
-+    }
-+  }
-+
-+  return false;
-+}
-+
- gfxFloat
- nsLayoutUtils::GetSnappedBaselineY(nsIFrame* aFrame, gfxContext* aContext,
-                                    nscoord aY, nscoord aAscent)
-diff --git a/layout/base/nsLayoutUtils.h b/layout/base/nsLayoutUtils.h
-index 4fb1f93..6552f04 100644
---- a/layout/base/nsLayoutUtils.h
-+++ b/layout/base/nsLayoutUtils.h
-@@ -989,6 +989,10 @@ public:
-   // Get a suitable foreground color for painting aProperty for aFrame.
-   static nscolor GetColor(nsIFrame* aFrame, nsCSSProperty aProperty);
- 
-+  // Get the native text color if appropriate.  If false is returned, callers
-+  // should fallback to the CSS color.
-+  static bool GetNativeTextColor(nsIFrame* aFrame, nscolor& aColor);
-+
-   // Get a baseline y position in app units that is snapped to device pixels.
-   static gfxFloat GetSnappedBaselineY(nsIFrame* aFrame, gfxContext* aContext,
-                                       nscoord aY, nscoord aAscent);
-diff --git a/layout/generic/nsFrame.cpp b/layout/generic/nsFrame.cpp
-index 75a2bb9..d684a62 100644
---- a/layout/generic/nsFrame.cpp
-+++ b/layout/generic/nsFrame.cpp
-@@ -1446,7 +1446,11 @@ nsIFrame::DisplayCaret(nsDisplayListBuilder* aBuilder,
- nscolor
- nsIFrame::GetCaretColorAt(int32_t aOffset)
- {
--  // Use text color.
-+  nscolor color = NS_RGB(0, 0, 0);
-+  if (nsLayoutUtils::GetNativeTextColor(this, color))
-+    return color;
-+
-+  // Use CSS text color.
-   return GetStyleColor()->mColor;
- }
- 
-diff --git a/layout/style/nsRuleNode.cpp b/layout/style/nsRuleNode.cpp
-index 86eff1f..732b1fe 100644
---- a/layout/style/nsRuleNode.cpp
-+++ b/layout/style/nsRuleNode.cpp
-@@ -747,7 +747,10 @@ static bool SetColor(const nsCSSValue& aValue, const nscolor aParentColor,
-     int32_t intValue = aValue.GetIntValue();
-     if (0 <= intValue) {
-       LookAndFeel::ColorID colorID = (LookAndFeel::ColorID) intValue;
--      if (NS_SUCCEEDED(LookAndFeel::GetColor(colorID, &aResult))) {
-+      bool useStandinsForNativeColors = aPresContext &&
-+                                        !aPresContext->IsChrome();
-+      if (NS_SUCCEEDED(LookAndFeel::GetColor(colorID,
-+                                    useStandinsForNativeColors, &aResult))) {
-         result = true;
-       }
-     }
-diff --git a/widget/LookAndFeel.h b/widget/LookAndFeel.h
-index e46bb13..f947084 100644
---- a/widget/LookAndFeel.h
-+++ b/widget/LookAndFeel.h
-@@ -446,6 +446,18 @@ public:
-   static nsresult GetColor(ColorID aID, nscolor* aResult);
- 
-   /**
-+   * This variant of GetColor() take an extra Boolean parameter that allows
-+   * the caller to ask that hard-coded color values be substituted for
-+   * native colors (used when it is desireable to hide system colors to
-+   * avoid system fingerprinting).
-+   */
-+  static nsresult GetColor(ColorID aID, bool aUseStandinsForNativeColors,
-+                           nscolor* aResult);
-+
-+  static nsresult GetColorForNativeAppearance(uint8_t aWidgetType,
-+                                          bool aIsDisabled, nscolor* aResult);
-+
-+  /**
-    * GetInt() and GetFloat() return a int or float value for aID.  The result
-    * might be distance, time, some flags or a int value which has particular
-    * meaning.  See each document at definition of each ID for the detail.
-diff --git a/widget/xpwidgets/nsXPLookAndFeel.cpp b/widget/xpwidgets/nsXPLookAndFeel.cpp
-index 50c2c86..704963a 100644
---- a/widget/xpwidgets/nsXPLookAndFeel.cpp
-+++ b/widget/xpwidgets/nsXPLookAndFeel.cpp
-@@ -11,6 +11,7 @@
- #include "nsLookAndFeel.h"
- #include "nsCRT.h"
- #include "nsFont.h"
-+#include "nsThemeConstants.h"
- #include "mozilla/Preferences.h"
- 
- #include "gfxPlatform.h"
-@@ -476,6 +477,155 @@ nsXPLookAndFeel::IsSpecialColor(ColorID aID, nscolor &aColor)
-   return false;
- }
- 
-+bool
-+nsXPLookAndFeel::ColorIsNotCSSAccessible(ColorID aID)
-+{
-+  bool result = false;
-+
-+  switch (aID) {
-+    case eColorID_WindowBackground:
-+    case eColorID_WindowForeground:
-+    case eColorID_WidgetBackground:
-+    case eColorID_WidgetForeground:
-+    case eColorID_WidgetSelectBackground:
-+    case eColorID_WidgetSelectForeground:
-+    case eColorID_Widget3DHighlight:
-+    case eColorID_Widget3DShadow:
-+    case eColorID_TextBackground:
-+    case eColorID_TextForeground:
-+    case eColorID_TextSelectBackground:
-+    case eColorID_TextSelectForeground:
-+    case eColorID_TextSelectBackgroundDisabled:
-+    case eColorID_TextSelectBackgroundAttention:
-+    case eColorID_TextHighlightBackground:
-+    case eColorID_TextHighlightForeground:
-+    case eColorID_IMERawInputBackground:
-+    case eColorID_IMERawInputForeground:
-+    case eColorID_IMERawInputUnderline:
-+    case eColorID_IMESelectedRawTextBackground:
-+    case eColorID_IMESelectedRawTextForeground:
-+    case eColorID_IMESelectedRawTextUnderline:
-+    case eColorID_IMEConvertedTextBackground:
-+    case eColorID_IMEConvertedTextForeground:
-+    case eColorID_IMEConvertedTextUnderline:
-+    case eColorID_IMESelectedConvertedTextBackground:
-+    case eColorID_IMESelectedConvertedTextForeground:
-+    case eColorID_IMESelectedConvertedTextUnderline:
-+    case eColorID_SpellCheckerUnderline:
-+      result = true;
-+      break;
-+    default:
-+      break;
-+  }
-+
-+  return result;
-+}
-+
-+nscolor
-+nsXPLookAndFeel::GetStandinForNativeColor(ColorID aID)
-+{
-+  nscolor result = NS_RGB(0xFF, 0xFF, 0xFF);
-+
-+  // The stand-in colors are taken from the Windows 7 Aero theme
-+  // except Mac-specific colors which are taken from Mac OS 10.7.
-+  switch (aID) {
-+    // CSS 2 colors:
-+    case eColorID_activeborder:      result = NS_RGB(0xB4, 0xB4, 0xB4); break;
-+    case eColorID_activecaption:     result = NS_RGB(0x99, 0xB4, 0xD1); break;
-+    case eColorID_appworkspace:      result = NS_RGB(0xAB, 0xAB, 0xAB); break;
-+    case eColorID_background:        result = NS_RGB(0x00, 0x00, 0x00); break;
-+    case eColorID_buttonface:        result = NS_RGB(0xF0, 0xF0, 0xF0); break;
-+    case eColorID_buttonhighlight:   result = NS_RGB(0xFF, 0xFF, 0xFF); break;
-+    case eColorID_buttonshadow:      result = NS_RGB(0xA0, 0xA0, 0xA0); break;
-+    case eColorID_buttontext:        result = NS_RGB(0x00, 0x00, 0x00); break;
-+    case eColorID_captiontext:       result = NS_RGB(0x00, 0x00, 0x00); break;
-+    case eColorID_graytext:          result = NS_RGB(0x6D, 0x6D, 0x6D); break;
-+    case eColorID_highlight:         result = NS_RGB(0x33, 0x99, 0xFF); break;
-+    case eColorID_highlighttext:     result = NS_RGB(0xFF, 0xFF, 0xFF); break;
-+    case eColorID_inactiveborder:    result = NS_RGB(0xF4, 0xF7, 0xFC); break;
-+    case eColorID_inactivecaption:   result = NS_RGB(0xBF, 0xCD, 0xDB); break;
-+    case eColorID_inactivecaptiontext:
-+      result = NS_RGB(0x43, 0x4E, 0x54); break;
-+    case eColorID_infobackground:    result = NS_RGB(0xFF, 0xFF, 0xE1); break;
-+    case eColorID_infotext:          result = NS_RGB(0x00, 0x00, 0x00); break;
-+    case eColorID_menu:              result = NS_RGB(0xF0, 0xF0, 0xF0); break;
-+    case eColorID_menutext:          result = NS_RGB(0x00, 0x00, 0x00); break;
-+    case eColorID_scrollbar:         result = NS_RGB(0xC8, 0xC8, 0xC8); break;
-+    case eColorID_threeddarkshadow:  result = NS_RGB(0x69, 0x69, 0x69); break;
-+    case eColorID_threedface:        result = NS_RGB(0xF0, 0xF0, 0xF0); break;
-+    case eColorID_threedhighlight:   result = NS_RGB(0xFF, 0xFF, 0xFF); break;
-+    case eColorID_threedlightshadow: result = NS_RGB(0xE3, 0xE3, 0xE3); break;
-+    case eColorID_threedshadow:      result = NS_RGB(0xA0, 0xA0, 0xA0); break;
-+    case eColorID_window:            result = NS_RGB(0xFF, 0xFF, 0xFF); break;
-+    case eColorID_windowframe:       result = NS_RGB(0x64, 0x64, 0x64); break;
-+    case eColorID_windowtext:        result = NS_RGB(0x00, 0x00, 0x00); break;
-+    case eColorID__moz_buttondefault:
-+      result = NS_RGB(0x69, 0x69, 0x69); break;
-+    case eColorID__moz_field:        result = NS_RGB(0xFF, 0xFF, 0xFF); break;
-+    case eColorID__moz_fieldtext:    result = NS_RGB(0x00, 0x00, 0x00); break;
-+    case eColorID__moz_dialog:       result = NS_RGB(0xF0, 0xF0, 0xF0); break;
-+    case eColorID__moz_dialogtext:   result = NS_RGB(0x00, 0x00, 0x00); break;
-+    case eColorID__moz_dragtargetzone:
-+      result = NS_RGB(0xFF, 0xFF, 0xFF); break;
-+    case eColorID__moz_cellhighlight:
-+      result = NS_RGB(0xF0, 0xF0, 0xF0); break;
-+    case eColorID__moz_cellhighlighttext:
-+      result = NS_RGB(0x00, 0x00, 0x00); break;
-+    case eColorID__moz_html_cellhighlight:
-+      result = NS_RGB(0x33, 0x99, 0xFF); break;
-+    case eColorID__moz_html_cellhighlighttext:
-+      result = NS_RGB(0xFF, 0xFF, 0xFF); break;
-+    case eColorID__moz_buttonhoverface:
-+      result = NS_RGB(0xF0, 0xF0, 0xF0); break;
-+    case eColorID__moz_buttonhovertext:
-+      result = NS_RGB(0x00, 0x00, 0x00); break;
-+    case eColorID__moz_menuhover:
-+      result = NS_RGB(0x33, 0x99, 0xFF); break;
-+    case eColorID__moz_menuhovertext:
-+      result = NS_RGB(0x00, 0x00, 0x00); break;
-+    case eColorID__moz_menubartext:
-+      result = NS_RGB(0x00, 0x00, 0x00); break;
-+    case eColorID__moz_menubarhovertext:
-+      result = NS_RGB(0x00, 0x00, 0x00); break;
-+    case eColorID__moz_oddtreerow:
-+      result = NS_RGB(0xFF, 0xFF, 0xFF); break;
-+    case eColorID__moz_mac_chrome_active:
-+      result = NS_RGB(0xB2, 0xB2, 0xB2); break;
-+    case eColorID__moz_mac_chrome_inactive:
-+      result = NS_RGB(0xE1, 0xE1, 0xE1); break;
-+    case eColorID__moz_mac_focusring:
-+      result = NS_RGB(0x60, 0x9D, 0xD7); break;
-+    case eColorID__moz_mac_menuselect:
-+      result = NS_RGB(0x38, 0x75, 0xD7); break;
-+    case eColorID__moz_mac_menushadow:
-+      result = NS_RGB(0xA3, 0xA3, 0xA3); break;
-+    case eColorID__moz_mac_menutextdisable:
-+      result = NS_RGB(0x88, 0x88, 0x88); break;
-+    case eColorID__moz_mac_menutextselect:
-+      result = NS_RGB(0xFF, 0xFF, 0xFF); break;
-+    case eColorID__moz_mac_disabledtoolbartext:
-+      result = NS_RGB(0x3F, 0x3F, 0x3F); break;
-+    case eColorID__moz_mac_alternateprimaryhighlight:
-+      result = NS_RGB(0x38, 0x75, 0xD7); break;
-+    case eColorID__moz_mac_secondaryhighlight:
-+      result = NS_RGB(0xD4, 0xD4, 0xD4); break;
-+    case eColorID__moz_win_mediatext:
-+      result = NS_RGB(0xFF, 0xFF, 0xFF); break;
-+    case eColorID__moz_win_communicationstext:
-+      result = NS_RGB(0xFF, 0xFF, 0xFF); break;
-+    case eColorID__moz_nativehyperlinktext:
-+      result = NS_RGB(0x00, 0x66, 0xCC); break;
-+    case eColorID__moz_comboboxtext:
-+      result = NS_RGB(0x00, 0x00, 0x00); break;
-+    case eColorID__moz_combobox:
-+      result = NS_RGB(0xFF, 0xFF, 0xFF); break;
-+    default:
-+      break;
-+  }
-+
-+  return result;
-+}
-+
- //
- // All these routines will return NS_OK if they have a value,
- // in which case the nsLookAndFeel should use that value;
-@@ -483,7 +633,8 @@ nsXPLookAndFeel::IsSpecialColor(ColorID aID, nscolor &aColor)
- // platform-specific nsLookAndFeel should use its own values instead.
- //
- nsresult
--nsXPLookAndFeel::GetColorImpl(ColorID aID, nscolor &aResult)
-+nsXPLookAndFeel::GetColorImpl(ColorID aID, bool aUseStandinsForNativeColors,
-+                              nscolor &aResult)
- {
-   if (!sInitialized)
-     Init();
-@@ -569,7 +720,10 @@ nsXPLookAndFeel::GetColorImpl(ColorID aID, nscolor &aResult)
-   }
- #endif // DEBUG_SYSTEM_COLOR_USE
- 
--  if (IS_COLOR_CACHED(aID)) {
-+  if (aUseStandinsForNativeColors && ColorIsNotCSSAccessible(aID))
-+    aUseStandinsForNativeColors = false;
-+
-+  if (!aUseStandinsForNativeColors && IS_COLOR_CACHED(aID)) {
-     aResult = sCachedColors[aID];
-     return NS_OK;
-   }
-@@ -603,6 +757,12 @@ nsXPLookAndFeel::GetColorImpl(ColorID aID, nscolor &aResult)
-     return NS_OK;
-   }
- 
-+  if (sUseNativeColors && aUseStandinsForNativeColors)
-+  {
-+    aResult = GetStandinForNativeColor(aID);
-+    return NS_OK;
-+  }
-+
-   if (sUseNativeColors && NS_SUCCEEDED(NativeGetColor(aID, aResult))) {
-     if ((gfxPlatform::GetCMSMode() == eCMSMode_All) &&
-          !IsSpecialColor(aID, aResult)) {
-@@ -693,7 +853,55 @@ namespace mozilla {
- nsresult
- LookAndFeel::GetColor(ColorID aID, nscolor* aResult)
- {
--  return nsLookAndFeel::GetInstance()->GetColorImpl(aID, *aResult);
-+  return nsLookAndFeel::GetInstance()->GetColorImpl(aID, false, *aResult);
-+}
-+
-+nsresult
-+LookAndFeel::GetColor(ColorID aID, bool aUseStandinsForNativeColors,
-+                      nscolor* aResult)
-+{
-+  return nsLookAndFeel::GetInstance()->GetColorImpl(aID,
-+                                       aUseStandinsForNativeColors, *aResult);
-+}
-+
-+// static
-+nsresult
-+LookAndFeel::GetColorForNativeAppearance(uint8_t aWidgetType, bool aIsDisabled,
-+                                         nscolor* aResult)
-+{
-+  NS_ENSURE_ARG_POINTER(aResult);
-+
-+  ColorID colorID = eColorID_LAST_COLOR;
-+  switch (aWidgetType) {
-+    case NS_THEME_TEXTFIELD:
-+    case NS_THEME_TEXTFIELD_MULTILINE:
-+    case NS_THEME_LISTBOX:
-+    case NS_THEME_DROPDOWN:
-+    case NS_THEME_DROPDOWN_TEXTFIELD:
-+    case NS_THEME_TREEVIEW:
-+      colorID = (aIsDisabled) ? eColorID_graytext : eColorID__moz_fieldtext;
-+      break;
-+
-+    case NS_THEME_TOOLTIP:
-+      colorID = eColorID_infotext;
-+      break;
-+
-+    case NS_THEME_BUTTON:
-+    case NS_THEME_GROUPBOX:
-+    case NS_THEME_PROGRESSBAR:
-+    case NS_THEME_PROGRESSBAR_VERTICAL:
-+    case NS_THEME_TAB_PANEL:
-+    case NS_THEME_STATUSBAR:
-+    case NS_THEME_STATUSBAR_RESIZER_PANEL:
-+      colorID = (aIsDisabled) ? eColorID_graytext : eColorID_buttontext;
-+      break;
-+  }
-+
-+  if (LookAndFeel::eColorID_LAST_COLOR == colorID)
-+    return NS_ERROR_FAILURE;
-+
-+  *aResult = NS_RGB(0, 0, 0);
-+  return nsLookAndFeel::GetInstance()->NativeGetColor(colorID, *aResult);
- }
- 
- // static
-diff --git a/widget/xpwidgets/nsXPLookAndFeel.h b/widget/xpwidgets/nsXPLookAndFeel.h
-index 69627d2..2729803 100644
---- a/widget/xpwidgets/nsXPLookAndFeel.h
-+++ b/widget/xpwidgets/nsXPLookAndFeel.h
-@@ -52,7 +52,8 @@ public:
-   // otherwise we'll return NS_ERROR_NOT_AVAILABLE, in which case, the
-   // platform-specific nsLookAndFeel should use its own values instead.
-   //
--  nsresult GetColorImpl(ColorID aID, nscolor &aResult);
-+  nsresult GetColorImpl(ColorID aID, bool aUseStandinsForNativeColors,
-+                        nscolor &aResult);
-   virtual nsresult GetIntImpl(IntID aID, int32_t &aResult);
-   virtual nsresult GetFloatImpl(FloatID aID, float &aResult);
- 
-@@ -89,6 +90,8 @@ protected:
-   void InitColorFromPref(int32_t aIndex);
-   virtual nsresult NativeGetColor(ColorID aID, nscolor &aResult) = 0;
-   bool IsSpecialColor(ColorID aID, nscolor &aColor);
-+  bool ColorIsNotCSSAccessible(ColorID aID);
-+  nscolor GetStandinForNativeColor(ColorID aID);
- 
-   static int OnPrefChanged(const char* aPref, void* aClosure);
- 
--- 
-1.7.9.5
-
diff --git a/src/current-patches/firefox/0024-Isolate-the-Image-Cache-per-url-bar-domain.patch b/src/current-patches/firefox/0024-Isolate-the-Image-Cache-per-url-bar-domain.patch
deleted file mode 100644
index a6e9c61..0000000
--- a/src/current-patches/firefox/0024-Isolate-the-Image-Cache-per-url-bar-domain.patch
+++ /dev/null
@@ -1,922 +0,0 @@
-From f097490e5043195bb0dfc27b288ff8b485b148e6 Mon Sep 17 00:00:00 2001
-From: Mike Perry <mikeperry-git at torproject.org>
-Date: Thu, 6 Dec 2012 14:19:34 -0800
-Subject: [PATCH 24/27] Isolate the Image Cache per url bar domain.
-
-The image cache maintains its own table outside of the main cache, and does
-not obey cacheKeys by default.
----
- content/base/src/nsContentUtils.cpp                |   13 +-
- embedding/browser/webBrowser/nsContextMenuInfo.cpp |   27 +-
- extensions/cookie/nsCookiePermission.cpp           |    3 +
- image/public/imgILoader.idl                        |    4 +-
- image/src/imgLoader.cpp                            |  262 +++++++++++++-------
- image/src/imgLoader.h                              |   20 +-
- image/src/imgRequest.cpp                           |   11 +-
- image/src/imgRequest.h                             |    3 +
- layout/generic/nsImageFrame.cpp                    |   14 +-
- netwerk/cookie/nsICookiePermission.idl             |    1 +
- toolkit/system/gnome/nsAlertsIconListener.cpp      |    3 +-
- widget/cocoa/nsMenuItemIconX.mm                    |    9 +-
- 12 files changed, 250 insertions(+), 120 deletions(-)
-
-diff --git a/content/base/src/nsContentUtils.cpp b/content/base/src/nsContentUtils.cpp
-index 8d58d8b..6a9c87c 100644
---- a/content/base/src/nsContentUtils.cpp
-+++ b/content/base/src/nsContentUtils.cpp
-@@ -121,6 +121,7 @@ static NS_DEFINE_CID(kXTFServiceCID, NS_XTFSERVICE_CID);
- #include "nsIWebNavigation.h"
- #include "nsTextFragment.h"
- #include "mozilla/Selection.h"
-+#include "mozIThirdPartyUtil.h"
- 
- #ifdef IBMBIDI
- #include "nsIBidiKeyboard.h"
-@@ -2743,8 +2744,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;
-@@ -2761,11 +2760,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(nullptr, 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 0a99427..02cd634 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) {
-@@ -305,7 +306,13 @@ nsContextMenuInfo::GetBackgroundImageRequestInternal(nsIDOMNode *aDOMNode, imgIR
-                                     "@mozilla.org/image/loader;1"));
-           NS_ENSURE_TRUE(il, NS_ERROR_FAILURE);
- 
--          return il->LoadImage(bgUri, nullptr, nullptr, principal, nullptr,
-+          nsCOMPtr<nsIURI> firstPartyURI;
-+          nsCOMPtr<mozIThirdPartyUtil> thirdPartySvc
-+              = do_GetService(THIRDPARTYUTIL_CONTRACTID);
-+          thirdPartySvc->GetFirstPartyURI(nullptr, doc,
-+                                          getter_AddRefs(firstPartyURI));
-+
-+          return il->LoadImage(bgUri, firstPartyURI, nullptr, principal, nullptr,
-                                nullptr, nullptr, nsIRequest::LOAD_NORMAL, nullptr,
-                                nullptr, channelPolicy, aRequest);
-         }
-diff --git a/extensions/cookie/nsCookiePermission.cpp b/extensions/cookie/nsCookiePermission.cpp
-index befa81a..e0b6e12 100644
---- a/extensions/cookie/nsCookiePermission.cpp
-+++ b/extensions/cookie/nsCookiePermission.cpp
-@@ -407,6 +407,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 ea51e8d..8e52af8 100644
---- a/image/src/imgLoader.cpp
-+++ b/image/src/imgLoader.cpp
-@@ -39,6 +39,7 @@
- #include "nsCRT.h"
- #include "nsIDocument.h"
- #include "nsPIDOMWindow.h"
-+#include "nsIConsoleService.h"
- 
- #include "netCore.h"
- 
-@@ -58,6 +59,7 @@
- #include "nsIHttpChannelInternal.h"  
- #include "nsIContentSecurityPolicy.h"
- #include "nsIChannelPolicy.h"
-+#include "mozIThirdPartyUtil.h"
- 
- #include "nsContentUtils.h"
- 
-@@ -432,7 +434,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,
-@@ -484,7 +486,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);
-   }
- 
-@@ -925,34 +927,62 @@ 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 = nullptr;
- 
--  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 (uint32_t 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();
-+        NS_ADDREF(*_retval);
-+      }
-     }
-   }
- 
--  return NS_OK;
-+  if (*_retval)
-+    return NS_OK;
-+  
-+  return NS_ERROR_NOT_AVAILABLE;
- }
- 
- void imgLoader::Shutdown()
-@@ -980,20 +1010,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", nullptr));
-     nsRefPtr<imgRequest> tmpRequest = getter_AddRefs(tmpCacheEntry->GetRequest());
-@@ -1003,13 +1031,13 @@ bool imgLoader::PutIntoCache(nsIURI *key, imgCacheEntry *entry)
-     PR_LOG(gImgLog, PR_LOG_DEBUG,
-            ("[this=%p] imgLoader::PutIntoCache -- Replacing cached element", nullptr));
- 
--    RemoveFromCache(key);
-+    RemoveKeyFromCache(cache, queue, key);
-   } else {
-     PR_LOG(gImgLog, PR_LOG_DEBUG,
-            ("[this=%p] imgLoader::PutIntoCache -- Element NOT already in the cache", nullptr));
-   }
- 
--  cache.Put(spec, entry);
-+  cache.Put(key, entry);
- 
-   // We can be called to resurrect an evicted entry.
-   if (entry->Evicted())
-@@ -1024,7 +1052,6 @@ bool imgLoader::PutIntoCache(nsIURI *key, imgCacheEntry *entry)
-       addrv = gCacheTracker->AddObject(entry);
- 
-     if (NS_SUCCEEDED(addrv)) {
--      imgCacheQueue &queue = GetCacheQueue(key);
-       queue.Push(entry);
-     }
-   }
-@@ -1035,11 +1062,11 @@ bool imgLoader::PutIntoCache(nsIURI *key, imgCacheEntry *entry)
-   return true;
- }
- 
--bool imgLoader::SetHasNoProxies(nsIURI *key, imgCacheEntry *entry)
-+bool imgLoader::SetHasNoProxies(nsIURI *imgURI, imgCacheEntry *entry)
- {
- #if defined(PR_LOGGING)
-   nsCAutoString spec;
--  key->GetSpec(spec);
-+  imgURI->GetSpec(spec);
- 
-   LOG_STATIC_FUNC_WITH_PARAM(gImgLog, "imgLoader::SetHasNoProxies", "uri", spec.get());
- #endif
-@@ -1047,7 +1074,7 @@ bool imgLoader::SetHasNoProxies(nsIURI *key, imgCacheEntry *entry)
-   if (entry->Evicted())
-     return false;
- 
--  imgCacheQueue &queue = GetCacheQueue(key);
-+  imgCacheQueue &queue = GetCacheQueue(imgURI);
- 
-   nsresult addrv = NS_OK;
- 
-@@ -1059,26 +1086,27 @@ bool imgLoader::SetHasNoProxies(nsIURI *key, imgCacheEntry *entry)
-     entry->SetHasNoProxies(true);
-   }
- 
--  imgCacheTable &cache = GetCache(key);
-+  imgCacheTable &cache = GetCache(imgURI);
-   CheckCacheLimits(cache, queue);
- 
-   return true;
- }
- 
--bool imgLoader::SetHasProxies(nsIURI *key)
-+bool imgLoader::SetHasProxies(nsIURI *firstPartyURI, nsIURI *imgURI)
- {
-   VerifyCacheSizes();
- 
--  imgCacheTable &cache = GetCache(key);
-+  imgCacheTable &cache = GetCache(imgURI);
- 
-   nsCAutoString spec;
--  key->GetSpec(spec);
-+  imgURI->GetSpec(spec);
- 
-   LOG_STATIC_FUNC_WITH_PARAM(gImgLog, "imgLoader::SetHasProxies", "uri", spec.get());
- 
-+  nsCAutoString key = GetCacheKey(firstPartyURI, imgURI);
-   nsRefPtr<imgCacheEntry> entry;
--  if (cache.Get(spec, getter_AddRefs(entry)) && entry && entry->HasNoProxies()) {
--    imgCacheQueue &queue = GetCacheQueue(key);
-+  if (cache.Get(key, getter_AddRefs(entry)) && entry && entry->HasNoProxies()) {
-+    imgCacheQueue &queue = GetCacheQueue(imgURI);
-     queue.Remove(entry);
- 
-     if (gCacheTracker)
-@@ -1130,7 +1158,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,
-@@ -1182,7 +1210,7 @@ bool imgLoader::ValidateRequestWithNewChannel(imgRequest *request,
-     rv = NewImageChannel(getter_AddRefs(newChannel),
-                          &forcePrincipalCheck,
-                          aURI,
--                         aInitialDocumentURI,
-+                         aFirstPartyURI,
-                          aReferrerURI,
-                          aLoadGroup,
-                          mAcceptHeader,
-@@ -1251,7 +1279,7 @@ bool imgLoader::ValidateRequestWithNewChannel(imgRequest *request,
- 
- bool imgLoader::ValidateEntry(imgCacheEntry *aEntry,
-                                 nsIURI *aURI,
--                                nsIURI *aInitialDocumentURI,
-+                                nsIURI *aFirstPartyURI,
-                                 nsIURI *aReferrerURI,
-                                 nsILoadGroup *aLoadGroup,
-                                 imgIDecoderObserver *aObserver,
-@@ -1357,7 +1385,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,
-@@ -1367,22 +1395,40 @@ bool imgLoader::ValidateEntry(imgCacheEntry *aEntry,
-   return !validateRequest;
- }
- 
--
--bool imgLoader::RemoveFromCache(nsIURI *aKey)
-+bool imgLoader::RemoveMatchingUrlsFromCache(nsIURI *aImgURI)
- {
--  if (!aKey) return false;
-+  if (!aImgURI) return false;
- 
--  imgCacheTable &cache = GetCache(aKey);
--  imgCacheQueue &queue = GetCacheQueue(aKey);
-+  bool rv = true;
-+  imgCacheTable &cache = GetCache(aImgURI);
- 
--  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 (uint32_t i = 0; i < entries.Length(); ++i) {
-+    bool isEqual = false;
-+
-+    entries[i]->mRequest->mURI->Equals(aImgURI, &isEqual);
-+    if (isEqual && !RemoveFromCache(entries[i]))
-+      rv = false;
-+  }
-+
-+  return rv;
-+}
-+
-+bool imgLoader::RemoveKeyFromCache(imgCacheTable &cache, 
-+                                   imgCacheQueue &queue,
-+                                   nsCAutoString key)
-+{
-+  if (key.IsEmpty()) return false;
- 
--  LOG_STATIC_FUNC_WITH_PARAM(gImgLog, "imgLoader::RemoveFromCache", "uri", spec.get());
-+  LOG_STATIC_FUNC_WITH_PARAM(gImgLog, "imgLoader::RemoveKeyFromCache", "uri", key.get());
- 
-   nsRefPtr<imgCacheEntry> entry;
--  if (cache.Get(spec, getter_AddRefs(entry)) && entry) {
--    cache.Remove(spec);
-+  if (cache.Get(key, getter_AddRefs(entry)) && entry) {
-+    cache.Remove(key);
- 
-     NS_ABORT_IF_FALSE(!entry->Evicted(), "Evicting an already-evicted cache entry!");
- 
-@@ -1410,12 +1456,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) {
-+      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());
- 
-@@ -1438,32 +1485,21 @@ 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)
- {
-+  nsresult rv = NS_OK;
-   LOG_STATIC_FUNC(gImgLog, "imgLoader::EvictEntries table");
- 
-   // 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 (uint32_t i = 0; i < entries.Length(); ++i)
-     if (!RemoveFromCache(entries[i]))
--      return NS_ERROR_FAILURE;
-+      rv = NS_ERROR_FAILURE;
- 
--  return NS_OK;
-+  return rv;
- }
- 
- nsresult imgLoader::EvictEntries(imgCacheQueue &aQueueToClear)
-@@ -1490,11 +1526,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,
-@@ -1513,8 +1548,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 = nullptr;
-@@ -1566,7 +1601,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());
-@@ -1605,7 +1640,7 @@ NS_IMETHODIMP imgLoader::LoadImage(nsIURI *aURI,
-     rv = NewImageChannel(getter_AddRefs(newChannel),
-                          &forcePrincipalCheck,
-                          aURI,
--                         aInitialDocumentURI,
-+                         aFirstPartyURI,
-                          aReferrerURI,
-                          aLoadGroup,
-                          mAcceptHeader,
-@@ -1627,8 +1662,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);
-@@ -1676,7 +1711,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);
-@@ -1736,6 +1771,49 @@ NS_IMETHODIMP imgLoader::LoadImage(nsIURI *aURI,
-   return NS_OK;
- }
- 
-+nsCAutoString imgLoader::GetCacheKey(nsIURI *firstPartyURI, nsIURI *imgURI)
-+{
-+  NS_ASSERTION(imgURI, "imgLoader::GetCacheKey -- NULL imgURI");
-+
-+  nsCAutoString spec, hostKey;
-+  if (imgURI)
-+    imgURI->GetSpec(spec);
-+
-+#if 0
-+  bool isChrome = false;
-+  if (imgURI)
-+    imgURI->SchemeIs("chrome", &isChrome);
-+  if (isChrome)
-+    return spec;  // No partitioning needed for chrome; just use a simple key.
-+#endif
-+
-+  // FIXME: Should we use mozIThirdPartyUtil to get a domain from this?
-+  if (firstPartyURI)
-+    firstPartyURI->GetHost(hostKey);
-+  else {
-+    hostKey = "--NoFirstParty--";
-+    nsCOMPtr<nsIConsoleService> consoleSvc =
-+                                do_GetService(NS_CONSOLESERVICE_CONTRACTID);
-+    if (consoleSvc) {
-+      nsAutoString msg(NS_LITERAL_STRING(
-+                       "imgLoader::GetCacheKey: NULL firstPartyURI for ")
-+                       .get());
-+      msg.AppendASCII(spec.get());
-+      consoleSvc->LogStringMessage(msg.get());
-+    }
-+
-+#ifdef DEBUG
-+    printf("imgLoader::GetCacheKey: NULL firstPartyURI for %s\n", spec.get());
-+#endif
-+  }
-+
-+  // 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)
- {
-@@ -1746,22 +1824,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, nullptr,
-+                                  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
-@@ -1833,7 +1916,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, nullptr, imgIRequest::CORS_NONE);
- 
-     ProxyListener *pl = new ProxyListener(static_cast<nsIStreamListener *>(request.get()));
-@@ -1845,7 +1928,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(firstPartyURI, originalURI), entry);
- 
-     rv = CreateNewProxyForRequest(request, loadGroup, aObserver,
-                                   requestFlags, nullptr, _retval);
-@@ -2132,6 +2215,7 @@ NS_IMETHODIMP imgCacheValidator::OnStartRequest(nsIRequest *aRequest, nsISupport
- 
-   int32_t corsmode = mRequest->GetCORSMode();
-   nsCOMPtr<nsIPrincipal> loadingPrincipal = mRequest->GetLoadingPrincipal();
-+  nsCOMPtr<nsIURI> firstPartyURI = mRequest->mFirstPartyURI;
- 
-   // Doom the old request's cache entry
-   mRequest->RemoveFromCache();
-@@ -2142,16 +2226,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);
- 
-   uint32_t count = mProxies.Count();
-   for (int32_t i = count-1; i>=0; i--) {
-diff --git a/image/src/imgLoader.h b/image/src/imgLoader.h
-index 64d3563..c275d83 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|.
-@@ -269,14 +270,14 @@ public:
-   // HasObservers(). The request's cache entry will be re-set before this
-   // happens, by calling imgRequest::SetCacheEntry() when an entry with no
-   // observers is re-requested.
--  static bool SetHasNoProxies(nsIURI *key, imgCacheEntry *entry);
--  static bool SetHasProxies(nsIURI *key);
-+  static bool SetHasProxies(nsIURI *firstPartyURI, nsIURI *imgURI);
-+  static bool SetHasNoProxies(nsIURI *imgURI, imgCacheEntry *entry);
- 
- private: // methods
- 
- 
--  bool ValidateEntry(imgCacheEntry *aEntry, nsIURI *aKey,
--                       nsIURI *aInitialDocumentURI, nsIURI *aReferrerURI, 
-+  bool ValidateEntry(imgCacheEntry *aEntry, nsIURI *aURI,
-+                       nsIURI *aFirstPartyURI, nsIURI *aReferrerURI, 
-                        nsILoadGroup *aLoadGroup,
-                        imgIDecoderObserver *aObserver, nsISupports *aCX,
-                        nsLoadFlags aLoadFlags, bool aCanMakeNewChannel,
-@@ -315,9 +316,14 @@ private: // methods
-   static void CacheEntriesChanged(nsIURI *aURI, int32_t 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 e89e05a..71afe2c 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);
-@@ -178,7 +180,7 @@ nsresult imgRequest::AddProxy(imgRequestProxy *proxy)
-   // proxies.
-   if (mObservers.IsEmpty()) {
-     NS_ABORT_IF_FALSE(mURI, "Trying to SetHasProxies without key uri.");
--    imgLoader::SetHasProxies(mURI);
-+    imgLoader::SetHasProxies(mFirstPartyURI, mURI);
-   }
- 
-   // If we don't have any current observers, we should restart any animation.
-@@ -329,8 +331,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 = nullptr;
-diff --git a/image/src/imgRequest.h b/image/src/imgRequest.h
-index 424631b..7e1180f 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 748107d..3ecb1e9 100644
---- a/layout/generic/nsImageFrame.cpp
-+++ b/layout/generic/nsImageFrame.cpp
-@@ -63,6 +63,7 @@
- #include "nsError.h"
- #include "nsBidiUtils.h"
- #include "nsBidiPresUtils.h"
-+#include "mozIThirdPartyUtil.h"
- 
- #include "gfxRect.h"
- #include "ImageLayers.h"
-@@ -1777,6 +1778,7 @@ nsImageFrame::LoadIcon(const nsAString& aSpec,
- {
-   nsresult rv = NS_OK;
-   NS_PRECONDITION(!aSpec.IsEmpty(), "What happened??");
-+  NS_PRECONDITION(aPresContext, "NULL PresContext");
- 
-   if (!sIOService) {
-     rv = CallGetService(NS_IOSERVICE_CONTRACTID, &sIOService);
-@@ -1794,9 +1796,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(nullptr, aPresContext->Document(),
-+                                 getter_AddRefs(firstPartyURI));
-+ 
-   return il->LoadImage(realURI,     /* icon URI */
--                       nullptr,      /* initial document URI; this is only
-+                       firstPartyURI, /* initial document URI; this is only
-                                        relevant for cookies, so does not
-                                        apply to icons. */
-                        nullptr,      /* referrer (not relevant for icons) */
-diff --git a/netwerk/cookie/nsICookiePermission.idl b/netwerk/cookie/nsICookiePermission.idl
-index 379695c..7ad3f3b 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 bfc43d1..37e93c3 100644
---- a/toolkit/system/gnome/nsAlertsIconListener.cpp
-+++ b/toolkit/system/gnome/nsAlertsIconListener.cpp
-@@ -261,7 +261,8 @@ nsAlertsIconListener::StartRequest(const nsAString & aImageUrl)
-   if (!il)
-     return ShowAlert(NULL);
- 
--  return il->LoadImage(imageUri, nullptr, nullptr, nullptr, nullptr, this,
-+  // XXX: Hrmm.... Bypass cache, or isolate to imageUrl?
-+  return il->LoadImage(imageUri, imageUri, nullptr, nullptr, nullptr, this,
-                        nullptr, nsIRequest::LOAD_NORMAL, nullptr, nullptr,
-                        nullptr, getter_AddRefs(mIconRequest));
- }
-diff --git a/widget/cocoa/nsMenuItemIconX.mm b/widget/cocoa/nsMenuItemIconX.mm
-index e0c07c4..368df5f 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 uint32_t kIconWidth = 16;
- static const uint32_t 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(nullptr, document,
-+                                  getter_AddRefs(firstPartyURI));
-+
-   // Passing in null for channelPolicy here since nsMenuItemIconX::LoadIcon is
-   // not exposed to web content
--  rv = loader->LoadImage(aIconURI, nullptr, nullptr, nullptr, loadGroup, this,
-+  rv = loader->LoadImage(aIconURI, firstPartyURI, nullptr, nullptr, loadGroup, this,
-                          nullptr, nsIRequest::LOAD_NORMAL, nullptr, nullptr,
-                          nullptr, getter_AddRefs(mIconRequest));
-   if (NS_FAILED(rv)) return rv;
--- 
-1.7.9.5
-
diff --git a/src/current-patches/firefox/0025-nsIHTTPChannel.redirectTo-API.patch b/src/current-patches/firefox/0025-nsIHTTPChannel.redirectTo-API.patch
deleted file mode 100644
index dfcf8ba..0000000
--- a/src/current-patches/firefox/0025-nsIHTTPChannel.redirectTo-API.patch
+++ /dev/null
@@ -1,474 +0,0 @@
-From 27633d970ddfa360c553aaf3e8697354309f0839 Mon Sep 17 00:00:00 2001
-From: Mike Perry <mikeperry-git at torproject.org>
-Date: Mon, 14 Jan 2013 19:36:14 -0800
-Subject: [PATCH 25/27] nsIHTTPChannel.redirectTo API.
-
-Provides an API for HTTPS-Everywhere to perform redirects to https
-in a more secure and reliable way.
----
- netwerk/protocol/http/HttpBaseChannel.cpp          |   13 +++++
- netwerk/protocol/http/HttpBaseChannel.h            |   10 ++++
- netwerk/protocol/http/HttpChannelChild.cpp         |   34 ++++++++----
- netwerk/protocol/http/HttpChannelParent.cpp        |   12 ++++-
- netwerk/protocol/http/HttpChannelParent.h          |    4 +-
- netwerk/protocol/http/PHttpChannel.ipdl            |    4 +-
- netwerk/protocol/http/nsHttpChannel.cpp            |   57 ++++++++++++++++---
- netwerk/protocol/http/nsHttpChannel.h              |    8 ++-
- netwerk/protocol/http/nsIHttpChannel.idl           |   14 +++++-
- .../protocol/viewsource/nsViewSourceChannel.cpp    |   10 +++-
- 10 files changed, 139 insertions(+), 27 deletions(-)
-
-diff --git a/netwerk/protocol/http/HttpBaseChannel.cpp b/netwerk/protocol/http/HttpBaseChannel.cpp
-index ec58de6..2926428 100644
---- a/netwerk/protocol/http/HttpBaseChannel.cpp
-+++ b/netwerk/protocol/http/HttpBaseChannel.cpp
-@@ -37,6 +37,7 @@ HttpBaseChannel::HttpBaseChannel()
-   , mIsPending(false)
-   , mWasOpened(false)
-   , mResponseHeadersModified(false)
-+  , mRequestObserversCalled(false)
-   , mAllowPipelining(true)
-   , mForceAllowThirdPartyCookie(false)
-   , mUploadStreamHasHeaders(false)
-@@ -1119,6 +1120,18 @@ HttpBaseChannel::GetRequestSucceeded(bool *aValue)
-   return NS_OK;
- }
- 
-+NS_IMETHODIMP
-+HttpBaseChannel::RedirectTo(nsIURI *newURI)
-+{
-+  // We can only redirect unopened channels
-+  ENSURE_CALLED_BEFORE_ASYNC_OPEN();
-+
-+  // The redirect is stored internally for use in AsyncOpen
-+  mAPIRedirectToURI = newURI;
-+
-+  return NS_OK;
-+}
-+
- //-----------------------------------------------------------------------------
- // HttpBaseChannel::nsIHttpChannelInternal
- //-----------------------------------------------------------------------------
-diff --git a/netwerk/protocol/http/HttpBaseChannel.h b/netwerk/protocol/http/HttpBaseChannel.h
-index 971958c..125734d 100644
---- a/netwerk/protocol/http/HttpBaseChannel.h
-+++ b/netwerk/protocol/http/HttpBaseChannel.h
-@@ -17,6 +17,7 @@
- #include "nsHttpConnectionInfo.h"
- #include "nsIEncodedChannel.h"
- #include "nsIHttpChannel.h"
-+#include "nsHttpHandler.h"
- #include "nsIHttpChannelInternal.h"
- #include "nsIUploadChannel.h"
- #include "nsIUploadChannel2.h"
-@@ -117,6 +118,7 @@ public:
-   NS_IMETHOD GetResponseStatus(uint32_t *aValue);
-   NS_IMETHOD GetResponseStatusText(nsACString& aValue);
-   NS_IMETHOD GetRequestSucceeded(bool *aValue);
-+  NS_IMETHOD RedirectTo(nsIURI *newURI);
- 
-   // nsIHttpChannelInternal
-   NS_IMETHOD GetDocumentURI(nsIURI **aDocumentURI);
-@@ -199,6 +201,12 @@ protected:
-                                            nsIChannel *,
-                                            bool preserveMethod);
- 
-+  // bundle calling OMR observers and marking flag into one function
-+  inline void CallOnModifyRequestObservers() {
-+    gHttpHandler->OnModifyRequest(this);
-+    mRequestObserversCalled = true;
-+  }
-+
-   // Helper function to simplify getting notification callbacks.
-   template <class T>
-   void GetCallback(nsCOMPtr<T> &aResult)
-@@ -252,6 +260,7 @@ protected:
-   uint32_t                          mIsPending                  : 1;
-   uint32_t                          mWasOpened                  : 1;
-   uint32_t                          mResponseHeadersModified    : 1;
-+  uint32_t                          mRequestObserversCalled     : 1;
-   uint32_t                          mAllowPipelining            : 1;
-   uint32_t                          mForceAllowThirdPartyCookie : 1;
-   uint32_t                          mUploadStreamHasHeaders     : 1;
-@@ -268,6 +277,7 @@ protected:
-   // Current suspension depth for this channel object
-   uint32_t                          mSuspendCount;
- 
-+  nsCOMPtr<nsIURI>                  mAPIRedirectToURI;
-   nsAutoPtr<nsTArray<nsCString> >   mRedirectedCachekeys;
- };
- 
-diff --git a/netwerk/protocol/http/HttpChannelChild.cpp b/netwerk/protocol/http/HttpChannelChild.cpp
-index 5d82f7e..35697be 100644
---- a/netwerk/protocol/http/HttpChannelChild.cpp
-+++ b/netwerk/protocol/http/HttpChannelChild.cpp
-@@ -854,6 +854,7 @@ HttpChannelChild::CompleteRedirectSetup(nsIStreamListener *listener,
- NS_IMETHODIMP
- HttpChannelChild::OnRedirectVerifyCallback(nsresult result)
- {
-+  OptionalURIParams redirectURI;
-   nsCOMPtr<nsIHttpChannel> newHttpChannel =
-       do_QueryInterface(mRedirectChannelChild);
- 
-@@ -872,13 +873,25 @@ HttpChannelChild::OnRedirectVerifyCallback(nsresult result)
-     newHttpChannelChild->GetClientSetRequestHeaders(&headerTuples);
-   }
- 
--  // After we verify redirect, nsHttpChannel may hit the network: must give
--  // "http-on-modify-request" observers the chance to cancel before that.
--  if (NS_SUCCEEDED(result))
--    gHttpHandler->OnModifyRequest(newHttpChannel);
--
--  if (mIPCOpen)
--    SendRedirect2Verify(result, *headerTuples);
-+  if (NS_SUCCEEDED(result)) {
-+    // we know this is an HttpChannelChild
-+    HttpChannelChild* base =
-+      static_cast<HttpChannelChild*>(mRedirectChannelChild.get());
-+    // After we verify redirect, nsHttpChannel may hit the network: must give
-+    // "http-on-modify-request" observers the chance to cancel before that.
-+    base->CallOnModifyRequestObservers();
-+
-+    /* If there was an API redirect of this redirect, we need to send it
-+     * down here, since it can't get sent via SendAsyncOpen. */
-+    SerializeURI(base->mAPIRedirectToURI, redirectURI);
-+  } else {
-+    /* If the redirect was canceled, bypass OMR and send an empty API
-+     * redirect URI */
-+    SerializeURI(nullptr, redirectURI);
-+  }
-+ 
-+   if (mIPCOpen)
-+    SendRedirect2Verify(result, *headerTuples, redirectURI);
- 
-   return NS_OK;
- }
-@@ -985,7 +998,7 @@ HttpChannelChild::AsyncOpen(nsIStreamListener *listener, nsISupports *aContext)
-   //
- 
-   // notify "http-on-modify-request" observers
--  gHttpHandler->OnModifyRequest(this);
-+  CallOnModifyRequestObservers();
- 
-   mIsPending = true;
-   mWasOpened = true;
-@@ -1042,15 +1055,16 @@ HttpChannelChild::AsyncOpen(nsIStreamListener *listener, nsISupports *aContext)
-   URIParams uri;
-   SerializeURI(mURI, uri);
- 
--  OptionalURIParams originalURI, documentURI, referrer;
-+  OptionalURIParams originalURI, documentURI, referrer, redirectURI;
-   SerializeURI(mOriginalURI, originalURI);
-   SerializeURI(mDocumentURI, documentURI);
-   SerializeURI(mReferrer, referrer);
-+  SerializeURI(mAPIRedirectToURI, redirectURI);
- 
-   OptionalInputStreamParams uploadStream;
-   SerializeInputStream(mUploadStream, uploadStream);
- 
--  SendAsyncOpen(uri, originalURI, documentURI, referrer, mLoadFlags,
-+  SendAsyncOpen(uri, originalURI, documentURI, referrer, redirectURI, mLoadFlags,
-                 mClientSetRequestHeaders, mRequestHead.Method(), uploadStream,
-                 mUploadStreamHasHeaders, mPriority, mRedirectionLimit,
-                 mAllowPipelining, mForceAllowThirdPartyCookie, mSendResumeAt,
-diff --git a/netwerk/protocol/http/HttpChannelParent.cpp b/netwerk/protocol/http/HttpChannelParent.cpp
-index 0a9ccc4..d01f162 100644
---- a/netwerk/protocol/http/HttpChannelParent.cpp
-+++ b/netwerk/protocol/http/HttpChannelParent.cpp
-@@ -110,6 +110,7 @@ HttpChannelParent::RecvAsyncOpen(const URIParams&           aURI,
-                                  const OptionalURIParams&   aOriginalURI,
-                                  const OptionalURIParams&   aDocURI,
-                                  const OptionalURIParams&   aReferrerURI,
-+                                 const OptionalURIParams&   aAPIRedirectToURI,
-                                  const uint32_t&            loadFlags,
-                                  const RequestHeaderTuples& requestHeaders,
-                                  const nsHttpAtom&          requestMethod,
-@@ -131,6 +132,7 @@ HttpChannelParent::RecvAsyncOpen(const URIParams&           aURI,
-   nsCOMPtr<nsIURI> originalUri = DeserializeURI(aOriginalURI);
-   nsCOMPtr<nsIURI> docUri = DeserializeURI(aDocURI);
-   nsCOMPtr<nsIURI> referrerUri = DeserializeURI(aReferrerURI);
-+  nsCOMPtr<nsIURI> apiRedirectToUri = DeserializeURI(aAPIRedirectToURI);
- 
-   nsCString uriSpec;
-   uri->GetSpec(uriSpec);
-@@ -161,6 +163,8 @@ HttpChannelParent::RecvAsyncOpen(const URIParams&           aURI,
-     httpChan->SetDocumentURI(docUri);
-   if (referrerUri)
-     httpChan->SetReferrerInternal(referrerUri);
-+  if (apiRedirectToUri)
-+    httpChan->RedirectTo(apiRedirectToUri);
-   if (loadFlags != nsIRequest::LOAD_NORMAL)
-     httpChan->SetLoadFlags(loadFlags);
- 
-@@ -315,13 +319,19 @@ HttpChannelParent::RecvUpdateAssociatedContentSecurity(const int32_t& high,
- 
- bool
- HttpChannelParent::RecvRedirect2Verify(const nsresult& result, 
--                                       const RequestHeaderTuples& changedHeaders)
-+                                       const RequestHeaderTuples& changedHeaders,
-+                                       const OptionalURIParams&   aAPIRedirectURI)
- {
-   if (NS_SUCCEEDED(result)) {
-     nsCOMPtr<nsIHttpChannel> newHttpChannel =
-         do_QueryInterface(mRedirectChannel);
- 
-     if (newHttpChannel) {
-+      nsCOMPtr<nsIURI> apiRedirectUri = DeserializeURI(aAPIRedirectURI);
-+
-+      if (apiRedirectUri)
-+        newHttpChannel->RedirectTo(apiRedirectUri);
-+
-       for (uint32_t i = 0; i < changedHeaders.Length(); i++) {
-         newHttpChannel->SetRequestHeader(changedHeaders[i].mHeader,
-                                          changedHeaders[i].mValue,
-diff --git a/netwerk/protocol/http/HttpChannelParent.h b/netwerk/protocol/http/HttpChannelParent.h
-index e869d63..96f3f3c 100644
---- a/netwerk/protocol/http/HttpChannelParent.h
-+++ b/netwerk/protocol/http/HttpChannelParent.h
-@@ -47,6 +47,7 @@ protected:
-                              const OptionalURIParams&   originalUri,
-                              const OptionalURIParams&   docUri,
-                              const OptionalURIParams&   referrerUri,
-+                             const OptionalURIParams&   internalRedirectUri,
-                              const uint32_t&            loadFlags,
-                              const RequestHeaderTuples& requestHeaders,
-                              const nsHttpAtom&          requestMethod,
-@@ -71,7 +72,8 @@ protected:
-   virtual bool RecvResume();
-   virtual bool RecvCancel(const nsresult& status);
-   virtual bool RecvRedirect2Verify(const nsresult& result,
--                                   const RequestHeaderTuples& changedHeaders);
-+                                   const RequestHeaderTuples& changedHeaders,
-+                                   const OptionalURIParams&   apiRedirectUri);
-   virtual bool RecvUpdateAssociatedContentSecurity(const int32_t& high,
-                                                    const int32_t& low,
-                                                    const int32_t& broken,
-diff --git a/netwerk/protocol/http/PHttpChannel.ipdl b/netwerk/protocol/http/PHttpChannel.ipdl
-index c13c969..e16afd6 100644
---- a/netwerk/protocol/http/PHttpChannel.ipdl
-+++ b/netwerk/protocol/http/PHttpChannel.ipdl
-@@ -37,6 +37,7 @@ parent:
-             OptionalURIParams   original,
-             OptionalURIParams   doc,
-             OptionalURIParams   referrer,
-+            OptionalURIParams   apiRedirectTo,
-             uint32_t            loadFlags,
-             RequestHeaderTuples requestHeaders,
-             nsHttpAtom          requestMethod,
-@@ -72,7 +73,8 @@ parent:
-   Cancel(nsresult status);
- 
-   // Reports approval/veto of redirect by child process redirect observers
--  Redirect2Verify(nsresult result, RequestHeaderTuples changedHeaders);
-+  Redirect2Verify(nsresult result, RequestHeaderTuples changedHeaders,
-+                  OptionalURIParams apiRedirectTo);
- 
-   // For document loads we keep this protocol open after child's
-   // OnStopRequest, and send this msg (instead of __delete__) to allow
-diff --git a/netwerk/protocol/http/nsHttpChannel.cpp b/netwerk/protocol/http/nsHttpChannel.cpp
-index 6242ddc..bcfa0c9 100644
---- a/netwerk/protocol/http/nsHttpChannel.cpp
-+++ b/netwerk/protocol/http/nsHttpChannel.cpp
-@@ -1584,18 +1584,17 @@ nsHttpChannel::HandleAsyncRedirectChannelToHttps()
-         return;
-     }
- 
--    nsresult rv = AsyncRedirectChannelToHttps();
-+    nsresult rv = StartRedirectChannelToHttps();
-     if (NS_FAILED(rv))
--        ContinueAsyncRedirectChannelToHttps(rv);
-+        ContinueAsyncRedirectChannelToURI(rv);
- }
- 
- nsresult
--nsHttpChannel::AsyncRedirectChannelToHttps()
-+nsHttpChannel::StartRedirectChannelToHttps()
- {
-     nsresult rv = NS_OK;
-     LOG(("nsHttpChannel::HandleAsyncRedirectChannelToHttps() [STS]\n"));
- 
--    nsCOMPtr<nsIChannel> newChannel;
-     nsCOMPtr<nsIURI> upgradedURI;
- 
-     rv = mURI->Clone(getter_AddRefs(upgradedURI));
-@@ -1617,6 +1616,36 @@ nsHttpChannel::AsyncRedirectChannelToHttps()
-     else
-         upgradedURI->SetPort(oldPort);
- 
-+    return StartRedirectChannelToURI(upgradedURI);
-+}
-+
-+void
-+nsHttpChannel::HandleAsyncAPIRedirect()
-+{
-+    NS_PRECONDITION(!mCallOnResume, "How did that happen?");
-+    NS_PRECONDITION(mAPIRedirectToURI, "How did that happen?");
-+
-+    if (mSuspendCount) {
-+        LOG(("Waiting until resume to do async API redirect [this=%p]\n", this));
-+        mCallOnResume = &nsHttpChannel::HandleAsyncAPIRedirect;
-+        return;
-+    }
-+
-+    nsresult rv = StartRedirectChannelToURI(mAPIRedirectToURI);
-+    if (NS_FAILED(rv))
-+        ContinueAsyncRedirectChannelToURI(rv);
-+
-+    return;
-+}
-+
-+nsresult
-+nsHttpChannel::StartRedirectChannelToURI(nsIURI *upgradedURI)
-+{
-+    nsresult rv = NS_OK;
-+    LOG(("nsHttpChannel::StartRedirectChannelToURI()\n"));
-+
-+    nsCOMPtr<nsIChannel> newChannel;
-+
-     nsCOMPtr<nsIIOService> ioService;
-     rv = gHttpHandler->GetIOService(getter_AddRefs(ioService));
-     NS_ENSURE_SUCCESS(rv, rv);
-@@ -1632,7 +1661,7 @@ nsHttpChannel::AsyncRedirectChannelToHttps()
-     uint32_t flags = nsIChannelEventSink::REDIRECT_PERMANENT;
- 
-     PushRedirectAsyncFunc(
--        &nsHttpChannel::ContinueAsyncRedirectChannelToHttps);
-+        &nsHttpChannel::ContinueAsyncRedirectChannelToURI);
-     rv = gHttpHandler->AsyncOnChannelRedirect(this, newChannel, flags);
- 
-     if (NS_SUCCEEDED(rv))
-@@ -1640,15 +1669,19 @@ nsHttpChannel::AsyncRedirectChannelToHttps()
- 
-     if (NS_FAILED(rv)) {
-         AutoRedirectVetoNotifier notifier(this);
-+
-+        /* Remove the async call to ContinueAsyncRedirectChannelToURI().
-+         * It is called directly by our callers upon return (to clean up
-+         * the failed redirect). */
-         PopRedirectAsyncFunc(
--            &nsHttpChannel::ContinueAsyncRedirectChannelToHttps);
-+            &nsHttpChannel::ContinueAsyncRedirectChannelToURI);
-     }
- 
-     return rv;
- }
- 
- nsresult
--nsHttpChannel::ContinueAsyncRedirectChannelToHttps(nsresult rv)
-+nsHttpChannel::ContinueAsyncRedirectChannelToURI(nsresult rv)
- {
-     AutoRedirectVetoNotifier notifier(this);
- 
-@@ -4399,7 +4432,7 @@ nsHttpChannel::AsyncOpen(nsIStreamListener *listener, nsISupports *context)
-     mAuthProvider->AddAuthorizationHeaders();
- 
-     // notify "http-on-modify-request" observers
--    gHttpHandler->OnModifyRequest(this);
-+    CallOnModifyRequestObservers();
- 
-     // Adjust mCaps according to our request headers:
-     //  - If "Connection: close" is set as a request header, then do not bother
-@@ -4431,6 +4464,12 @@ nsHttpChannel::AsyncOpen(nsIStreamListener *listener, nsISupports *context)
-     if (mLoadGroup)
-         mLoadGroup->AddRequest(this, nullptr);
- 
-+    // Check to see if we should redirect this channel elsewhere by
-+    // nsIHttpChannel.redirectTo API request
-+    if (mAPIRedirectToURI) {
-+        return AsyncCall(&nsHttpChannel::HandleAsyncAPIRedirect);
-+    }
-+
-     // Collect mAsyncOpenTime after we have called all obsrevers like
-     // "http-on-modify-request" and load group observers that may set
-     // mTimingEnabled flag.
-@@ -5561,7 +5600,7 @@ nsHttpChannel::DoAuthRetry(nsAHttpConnection *conn)
-     AddCookiesToRequest();
-     
-     // notify "http-on-modify-request" observers
--    gHttpHandler->OnModifyRequest(this);
-+    CallOnModifyRequestObservers();
- 
-     mIsPending = true;
- 
-diff --git a/netwerk/protocol/http/nsHttpChannel.h b/netwerk/protocol/http/nsHttpChannel.h
-index b1f0848..a05e70d 100644
---- a/netwerk/protocol/http/nsHttpChannel.h
-+++ b/netwerk/protocol/http/nsHttpChannel.h
-@@ -174,12 +174,14 @@ private:
- 
-     // redirection specific methods
-     void     HandleAsyncRedirect();
-+    void     HandleAsyncAPIRedirect();
-     nsresult ContinueHandleAsyncRedirect(nsresult);
-     void     HandleAsyncNotModified();
-     void     HandleAsyncFallback();
-     nsresult ContinueHandleAsyncFallback(nsresult);
-     nsresult PromptTempRedirect();
--    virtual nsresult SetupReplacementChannel(nsIURI *, nsIChannel *, bool preserveMethod);
-+    nsresult StartRedirectChannelToURI(nsIURI *);
-+    virtual  nsresult SetupReplacementChannel(nsIURI *, nsIChannel *, bool preserveMethod);
- 
-     // proxy specific methods
-     nsresult ProxyFailover();
-@@ -236,8 +238,8 @@ private:
-     nsresult DoAuthRetry(nsAHttpConnection *);
- 
-     void     HandleAsyncRedirectChannelToHttps();
--    nsresult AsyncRedirectChannelToHttps();
--    nsresult ContinueAsyncRedirectChannelToHttps(nsresult rv);
-+    nsresult StartRedirectChannelToHttps();
-+    nsresult ContinueAsyncRedirectChannelToURI(nsresult rv);
- 
-     /**
-      * A function that takes care of reading STS headers and enforcing STS 
-diff --git a/netwerk/protocol/http/nsIHttpChannel.idl b/netwerk/protocol/http/nsIHttpChannel.idl
-index c541df1..7037f95 100644
---- a/netwerk/protocol/http/nsIHttpChannel.idl
-+++ b/netwerk/protocol/http/nsIHttpChannel.idl
-@@ -14,7 +14,7 @@ interface nsIHttpHeaderVisitor;
-  * the inspection of the resulting HTTP response status and headers when they
-  * become available.
-  */
--[scriptable, uuid(9277fe09-f0cc-4cd9-bbce-581dd94b0260)]
-+[scriptable, uuid(a01362a0-5c45-11e2-bcfd-0800200c9a66)]
- interface nsIHttpChannel : nsIChannel
- {
-     /**************************************************************************
-@@ -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 643ed0e..c63c2a5 100644
---- a/netwerk/protocol/viewsource/nsViewSourceChannel.cpp
-+++ b/netwerk/protocol/viewsource/nsViewSourceChannel.cpp
-@@ -671,4 +671,12 @@ nsViewSourceChannel::IsNoCacheResponse(bool *_retval)
- {
-     return !mHttpChannel ? NS_ERROR_NULL_POINTER :
-         mHttpChannel->IsNoCacheResponse(_retval);
--} 
-+}
-+
-+NS_IMETHODIMP
-+nsViewSourceChannel::RedirectTo(nsIURI *uri)
-+{
-+    return !mHttpChannel ? NS_ERROR_NULL_POINTER :
-+        mHttpChannel->RedirectTo(uri);
-+}
-+
--- 
-1.7.5.4
-
diff --git a/src/current-patches/firefox/0026-Isolate-DOM-storage-to-first-party-URI.patch b/src/current-patches/firefox/0026-Isolate-DOM-storage-to-first-party-URI.patch
deleted file mode 100644
index 6a08d8b..0000000
--- a/src/current-patches/firefox/0026-Isolate-DOM-storage-to-first-party-URI.patch
+++ /dev/null
@@ -1,776 +0,0 @@
-From caf469aa331ab9d92cc83b378cf554f087625dc8 Mon Sep 17 00:00:00 2001
-From: Kathleen Brade <brade at pearlcrescent.com>
-Date: Thu, 28 Feb 2013 18:02:34 -0800
-Subject: [PATCH 26/27] Isolate DOM storage to first party URI
-
-Also prevents DOM storage from writing to disk (hardcoded).
----
- docshell/base/nsDocShell.cpp                       |   78 ++++++++++++++++++-
- docshell/base/nsDocShell.h                         |    6 +-
- docshell/base/nsIDocShell.idl                      |   33 ++++++++-
- dom/base/nsGlobalWindow.cpp                        |   13 +++-
- dom/interfaces/storage/nsIDOMStorageManager.idl    |   11 +++-
- dom/interfaces/storage/nsPIDOMStorage.h            |    8 +-
- dom/src/storage/StorageChild.cpp                   |    6 +-
- dom/src/storage/StorageChild.h                     |    3 +-
- dom/src/storage/nsDOMStorage.cpp                   |   44 ++++++++---
- dom/src/storage/nsDOMStorage.h                     |   14 +++-
- dom/src/storage/nsDOMStorageDBWrapper.cpp          |   41 ++++++++---
- dom/src/storage/nsDOMStorageDBWrapper.h            |   14 ++-
- dom/src/storage/nsDOMStorageMemoryDB.cpp           |   21 +++++-
- dom/src/storage/nsDOMStoragePersistentDB.cpp       |    8 ++-
- .../windowwatcher/src/nsWindowWatcher.cpp          |    5 +-
- 15 files changed, 255 insertions(+), 50 deletions(-)
-
-diff --git a/docshell/base/nsDocShell.cpp b/docshell/base/nsDocShell.cpp
-index 0d56d9e..0726c07 100644
---- a/docshell/base/nsDocShell.cpp
-+++ b/docshell/base/nsDocShell.cpp
-@@ -184,6 +184,7 @@
- #include "nsIChannelPolicy.h"
- #include "nsIContentSecurityPolicy.h"
- #include "nsSandboxFlags.h"
-+#include "mozIThirdPartyUtil.h"
- 
- #include "nsXULAppAPI.h"
- 
-@@ -2395,6 +2396,17 @@ nsDocShell::GetSessionStorageForPrincipal(nsIPrincipal* aPrincipal,
-                                           bool aCreate,
-                                           nsIDOMStorage** aStorage)
- {
-+    return GetSessionStorageForFirstParty(nullptr, aPrincipal, aDocumentURI,
-+                                          aCreate, aStorage);
-+}
-+
-+NS_IMETHODIMP
-+nsDocShell::GetSessionStorageForFirstParty(nsIURI *aFirstPartyURI,
-+                                           nsIPrincipal* aPrincipal,
-+                                           const nsAString& aDocumentURI,
-+                                           bool aCreate,
-+                                           nsIDOMStorage** aStorage)
-+{
-     NS_ENSURE_ARG_POINTER(aStorage);
-     *aStorage = nullptr;
- 
-@@ -2426,7 +2438,11 @@ nsDocShell::GetSessionStorageForPrincipal(nsIPrincipal* aPrincipal,
-     if (origin.IsEmpty())
-         return NS_OK;
- 
--    if (!mStorages.Get(origin, aStorage) && aCreate) {
-+    nsXPIDLCString key;
-+    rv = GetSessionStorageKey(aFirstPartyURI, origin, key);
-+    NS_ENSURE_SUCCESS(rv, rv);
-+
-+    if (!mStorages.Get(key, aStorage) && aCreate) {
-         nsCOMPtr<nsIDOMStorage> newstorage =
-             do_CreateInstance("@mozilla.org/dom/storage;2");
-         if (!newstorage)
-@@ -2440,7 +2456,7 @@ nsDocShell::GetSessionStorageForPrincipal(nsIPrincipal* aPrincipal,
-         if (NS_FAILED(rv))
-             return rv;
- 
--        mStorages.Put(origin, newstorage);
-+        mStorages.Put(key, newstorage);
- 
-         newstorage.swap(*aStorage);
- #if defined(PR_LOGGING) && defined(DEBUG)
-@@ -2454,7 +2470,7 @@ nsDocShell::GetSessionStorageForPrincipal(nsIPrincipal* aPrincipal,
-         if (piStorage) {
-             nsCOMPtr<nsIPrincipal> storagePrincipal = piStorage->Principal();
- 
--            // The origin string used to map items in the hash table is 
-+            // The key string used to map items in the hash table is 
-             // an implicit security check. That check is double-confirmed 
-             // by checking the principal a storage was demanded for 
-             // really is the principal for which that storage was originally 
-@@ -2513,6 +2529,14 @@ nsresult
- nsDocShell::AddSessionStorage(nsIPrincipal* aPrincipal,
-                               nsIDOMStorage* aStorage)
- {
-+    return AddSessionStorageForFirstParty(nullptr, aPrincipal, aStorage);
-+}
-+
-+nsresult
-+nsDocShell::AddSessionStorageForFirstParty(nsIURI* aFirstPartyURI,
-+                                           nsIPrincipal* aPrincipal,
-+                                           nsIDOMStorage* aStorage)
-+{
-     NS_ENSURE_ARG_POINTER(aStorage);
- 
-     if (!aPrincipal)
-@@ -2534,8 +2558,12 @@ nsDocShell::AddSessionStorage(nsIPrincipal* aPrincipal,
-             if (origin.IsEmpty())
-                 return NS_ERROR_FAILURE;
- 
-+            nsXPIDLCString key;
-+            rv = GetSessionStorageKey(aFirstPartyURI, origin, key);
-+            NS_ENSURE_SUCCESS(rv, rv);
-+
-             // Do not replace an existing session storage.
--            if (mStorages.GetWeak(origin))
-+            if (mStorages.GetWeak(key))
-                 return NS_ERROR_NOT_AVAILABLE;
- 
- #if defined(PR_LOGGING) && defined(DEBUG)
-@@ -2543,7 +2571,7 @@ nsDocShell::AddSessionStorage(nsIPrincipal* aPrincipal,
-                    ("nsDocShell[%p]: was added a sessionStorage %p",
-                     this, aStorage));
- #endif
--            mStorages.Put(origin, aStorage);
-+            mStorages.Put(key, aStorage);
-         }
-         else {
-             return topDocShell->AddSessionStorage(aPrincipal, aStorage);
-@@ -2568,6 +2596,10 @@ CloneSessionStorages(nsCStringHashKey::KeyType aKey, nsIDOMStorage* aStorage,
-     return PL_DHASH_NEXT;
- }
- 
-+// CloneSessionStoragesTo() copies all session storage data from aDocShell to
-+// this doc shell.  It does not check if that is an appropriate thing to do,
-+// e.g., by verifying that the first party URIs are the same.  For now that is
-+// okay because no Firefox code uses this method.
- NS_IMETHODIMP
- nsDocShell::CloneSessionStoragesTo(nsIDocShell* aDocShell)
- {
-@@ -12411,3 +12443,39 @@ nsDocShell::HasUnloadedParent()
-     }
-     return false;
- }
-+
-+nsresult
-+nsDocShell::GetSessionStorageKey(nsIURI *aFirstPartyURI,
-+                                 nsXPIDLCString& aOrigin,
-+                                 nsXPIDLCString& aResult)
-+{
-+    aResult.Truncate();
-+
-+    if (!aOrigin)
-+        return NS_ERROR_FAILURE;
-+
-+    aResult.Append(aOrigin);
-+
-+    nsCOMPtr<nsIURI> firstPartyURI = aFirstPartyURI;
-+    if (!firstPartyURI) {
-+        nsCOMPtr<mozIThirdPartyUtil> thirdPartyUtil =
-+                                do_GetService(THIRDPARTYUTIL_CONTRACTID);
-+        if (!thirdPartyUtil)
-+          return NS_ERROR_FAILURE;
-+
-+        nsCOMPtr<nsIDocument> doc(do_GetInterface(GetAsSupports(this)));
-+        nsresult rv = thirdPartyUtil->GetFirstPartyURI(nullptr, doc,
-+                                               getter_AddRefs(firstPartyURI));
-+        NS_ENSURE_SUCCESS(rv, rv);
-+    }
-+
-+    nsCAutoString host;
-+    nsresult rv = firstPartyURI->GetHost(host);
-+    if (NS_SUCCEEDED(rv) && (host.Length() > 0)) {
-+        aResult.AppendLiteral("&");
-+        aResult.Append(host);
-+    }
-+
-+    return NS_OK;
-+}
-+
-diff --git a/docshell/base/nsDocShell.h b/docshell/base/nsDocShell.h
-index 427630a..4bcd341 100644
---- a/docshell/base/nsDocShell.h
-+++ b/docshell/base/nsDocShell.h
-@@ -681,7 +681,7 @@ protected:
- 
-     bool HasUnloadedParent();
- 
--    // hash of session storages, keyed by domain
-+    // hash of session storages, keyed by domain&firstPartyHost
-     nsInterfaceHashtable<nsCStringHashKey, nsIDOMStorage> mStorages;
- 
-     // Dimensions of the docshell
-@@ -848,6 +848,10 @@ private:
-     static unsigned long gNumberOfDocShells;
- #endif /* DEBUG */
- 
-+    nsresult GetSessionStorageKey(nsIURI *aFirstPartyURI,
-+                                  nsXPIDLCString& aOrigin,
-+                                  nsXPIDLCString& aResult);
-+
- public:
-     class InterfaceRequestorProxy : public nsIInterfaceRequestor {
-     public:
-diff --git a/docshell/base/nsIDocShell.idl b/docshell/base/nsIDocShell.idl
-index 986f4b4..4f26a04 100644
---- a/docshell/base/nsIDocShell.idl
-+++ b/docshell/base/nsIDocShell.idl
-@@ -39,7 +39,7 @@ interface nsIWebBrowserPrint;
- interface nsIVariant;
- interface nsIPrivacyTransitionObserver;
- 
--[scriptable, builtinclass, uuid(9b283337-097d-4fa8-a2da-916318eaf828)]
-+[scriptable, builtinclass, uuid(5289f25a-1175-4b01-bc56-b1628ef097b9)]
- interface nsIDocShell : nsISupports
- {
-   /**
-@@ -416,6 +416,24 @@ interface nsIDocShell : nsISupports
-                                               in boolean create);
- 
-   /*
-+   * A variant of getSessionStorageForPrincipal that is used when cloning
-+   * session storage during creation of new windows/tabs (the first party URI
-+   * of the new window/tab must be used to generate the key that is used to
-+   * access the session data).
-+   *
-+   * @param firstPartyURI the URL bar URI
-+   * @param principal returns a storage for this principal
-+   * @param documentURI new storage will be created with reference to this
-+   *                    document.documentURI that will appear in storage event
-+   * @param create If true and a session storage object doesn't
-+   *               already exist, a new one will be created.
-+   */
-+  nsIDOMStorage getSessionStorageForFirstParty(in nsIURI firstPartyURI,
-+                                               in nsIPrincipal principal,
-+                                               in DOMString documentURI,
-+                                               in boolean create);
-+
-+  /*
-    * Add a WebApps session storage object to the docshell.
-    *
-    * @param principal the principal the storage object is associated with
-@@ -423,6 +441,19 @@ interface nsIDocShell : nsISupports
-    */
-   void addSessionStorage(in nsIPrincipal principal, in nsIDOMStorage storage);
- 
-+  /*
-+   * A variant of addSessionStorage that is used when cloning session storage
-+   * during creation of new windows/tabs (the cloning must occur before the
-+   * document load begins).
-+   *
-+   * @param firstPartyURI the URL bar URI
-+   * @param principal the principal the storage object is associated with
-+   * @param storage the storage object to add
-+   */
-+  void addSessionStorageForFirstParty(in nsIURI firstPartyURI,
-+                                      in nsIPrincipal principal,
-+                                      in nsIDOMStorage storage);
-+
-   /**
-    * Clones all session storage objects and attaches them to the given docshell.
-    * Useful when duplicating tabs and their states.
-diff --git a/dom/base/nsGlobalWindow.cpp b/dom/base/nsGlobalWindow.cpp
-index 48bd71d..1e16c03 100644
---- a/dom/base/nsGlobalWindow.cpp
-+++ b/dom/base/nsGlobalWindow.cpp
-@@ -8385,7 +8385,18 @@ nsGlobalWindow::GetLocalStorage(nsIDOMStorage ** aLocalStorage)
-     nsIDocShell* docShell = GetDocShell();
-     nsCOMPtr<nsILoadContext> loadContext = do_QueryInterface(docShell);
- 
--    rv = storageManager->GetLocalStorageForPrincipal(principal,
-+    nsCOMPtr<mozIThirdPartyUtil> thirdPartyUtil =
-+                                do_GetService(THIRDPARTYUTIL_CONTRACTID);
-+    if (!thirdPartyUtil)
-+      return NS_ERROR_FAILURE;
-+ 
-+    nsCOMPtr<nsIURI> firstPartyURI;
-+    nsCOMPtr<nsIDocument> doc = do_QueryInterface(mDocument);
-+    rv = thirdPartyUtil->GetFirstPartyURI(NULL, doc, 
-+                                          getter_AddRefs(firstPartyURI));
-+    NS_ENSURE_SUCCESS(rv, rv);
-+
-+    rv = storageManager->GetLocalStorageForFirstParty(firstPartyURI, principal,
-                                                      documentURI,
-                                                      loadContext && loadContext->UsePrivateBrowsing(),
-                                                      getter_AddRefs(mLocalStorage));
-diff --git a/dom/interfaces/storage/nsIDOMStorageManager.idl b/dom/interfaces/storage/nsIDOMStorageManager.idl
-index 94b8789..21bedf0 100644
---- a/dom/interfaces/storage/nsIDOMStorageManager.idl
-+++ b/dom/interfaces/storage/nsIDOMStorageManager.idl
-@@ -7,8 +7,9 @@
- 
- interface nsIDOMStorage;
- interface nsIPrincipal;
-+interface nsIURI;
- 
--[scriptable, uuid(1541da6c-a9fb-4a8f-af9d-4493c981491d)]
-+[scriptable, uuid(682edebf-7bbe-4b4b-b5f8-752cacfb2afa)]
- interface nsIDOMStorageManager : nsISupports
- {
-   /**
-@@ -35,4 +36,12 @@ interface nsIDOMStorageManager : nsISupports
-   nsIDOMStorage getLocalStorageForPrincipal(in nsIPrincipal aPrincipal,
-                                             in DOMString aDocumentURI,
-                                             [optional] in bool aPrivate);
-+
-+  /**
-+   * Returns instance of localStorage object.
-+   */
-+  nsIDOMStorage getLocalStorageForFirstParty(in nsIURI aFirstPartyURI,
-+                                             in nsIPrincipal aPrincipal,
-+                                             in DOMString aDocumentURI,
-+                                             [optional] in bool aPrivate);
- };
-diff --git a/dom/interfaces/storage/nsPIDOMStorage.h b/dom/interfaces/storage/nsPIDOMStorage.h
-index fabb5cc..9f8de6b 100644
---- a/dom/interfaces/storage/nsPIDOMStorage.h
-+++ b/dom/interfaces/storage/nsPIDOMStorage.h
-@@ -15,8 +15,8 @@ class nsIURI;
- class nsIPrincipal;
- 
- #define NS_PIDOMSTORAGE_IID \
--{ 0x86dfe3c4, 0x4286, 0x4648, \
--  { 0xb2, 0x09, 0x55, 0x27, 0x50, 0x59, 0x26, 0xac } }
-+{ 0x0db5e488, 0x08f4, 0x4155, \
-+  { 0x81, 0x9b, 0x2b, 0x5a, 0x44, 0xaa, 0xa2, 0x45 } }
- 
- class nsPIDOMStorage : public nsISupports
- {
-@@ -31,7 +31,9 @@ public:
- 
-   virtual nsresult InitAsSessionStorage(nsIPrincipal *aPrincipal, const nsSubstring &aDocumentURI,
-                                         bool aPrivate) = 0;
--  virtual nsresult InitAsLocalStorage(nsIPrincipal *aPrincipal, const nsSubstring &aDocumentURI,
-+  virtual nsresult InitAsLocalStorage(nsIURI *aFirstPartyURI,
-+                                      nsIPrincipal *aPrincipal,
-+                                      const nsSubstring &aDocumentURI,
-                                       bool aPrivate) = 0;
- 
-   virtual already_AddRefed<nsIDOMStorage> Clone() = 0;
-diff --git a/dom/src/storage/StorageChild.cpp b/dom/src/storage/StorageChild.cpp
-index 6754fde..5d24973 100644
---- a/dom/src/storage/StorageChild.cpp
-+++ b/dom/src/storage/StorageChild.cpp
-@@ -95,9 +95,11 @@ StorageChild::InitAsSessionStorage(nsIURI* aDomainURI, bool aPrivate)
- }
- 
- void
--StorageChild::InitAsLocalStorage(nsIURI* aDomainURI, bool aCanUseChromePersist, bool aPrivate)
-+StorageChild::InitAsLocalStorage(nsIURI* aFirstPartyURI, nsIURI* aDomainURI,
-+                                 bool aCanUseChromePersist, bool aPrivate)
- {
--  DOMStorageBase::InitAsLocalStorage(aDomainURI, aCanUseChromePersist, aPrivate);
-+  DOMStorageBase::InitAsLocalStorage(aFirstPartyURI, aDomainURI,
-+                                     aCanUseChromePersist, aPrivate);
-   InitRemote();
- }
- 
-diff --git a/dom/src/storage/StorageChild.h b/dom/src/storage/StorageChild.h
-index 297f093..81ddabe 100644
---- a/dom/src/storage/StorageChild.h
-+++ b/dom/src/storage/StorageChild.h
-@@ -27,7 +27,8 @@ public:
-   StorageChild(nsDOMStorage* aOwner, StorageChild& aOther);
- 
-   virtual void InitAsSessionStorage(nsIURI* aDomainURI, bool aPrivate);
--  virtual void InitAsLocalStorage(nsIURI* aDomainURI, bool aCanUseChromePersist, bool aPrivate);
-+  virtual void InitAsLocalStorage(nsIURI* aFirstPartyURI, nsIURI* aDomainURI,
-+                                  bool aCanUseChromePersist, bool aPrivate);
- 
-   virtual bool CacheStoragePermissions();
-   
-diff --git a/dom/src/storage/nsDOMStorage.cpp b/dom/src/storage/nsDOMStorage.cpp
-index 2dd0fbc..23e8739 100644
---- a/dom/src/storage/nsDOMStorage.cpp
-+++ b/dom/src/storage/nsDOMStorage.cpp
-@@ -496,6 +496,17 @@ nsDOMStorageManager::GetLocalStorageForPrincipal(nsIPrincipal *aPrincipal,
-                                                  bool aPrivate,
-                                                  nsIDOMStorage **aResult)
- {
-+  return GetLocalStorageForFirstParty(nullptr, aPrincipal, aDocumentURI,
-+                                     aPrivate, aResult);
-+}
-+
-+NS_IMETHODIMP
-+nsDOMStorageManager::GetLocalStorageForFirstParty(nsIURI *aFirstPartyURI,
-+                                               nsIPrincipal *aPrincipal,
-+                                               const nsSubstring &aDocumentURI,
-+                                               bool aPrivate,
-+                                               nsIDOMStorage **aResult)
-+{
-   NS_ENSURE_ARG_POINTER(aPrincipal);
-   *aResult = nullptr;
- 
-@@ -505,7 +516,8 @@ nsDOMStorageManager::GetLocalStorageForPrincipal(nsIPrincipal *aPrincipal,
-   if (!storage)
-     return NS_ERROR_OUT_OF_MEMORY;
- 
--  rv = storage->InitAsLocalStorage(aPrincipal, aDocumentURI, aPrivate);
-+  rv = storage->InitAsLocalStorage(aFirstPartyURI, aPrincipal, aDocumentURI,
-+                                   aPrivate);
-   if (NS_FAILED(rv))
-     return rv;
- 
-@@ -622,7 +634,8 @@ DOMStorageBase::InitAsSessionStorage(nsIURI* aDomainURI, bool aPrivate)
- }
- 
- void
--DOMStorageBase::InitAsLocalStorage(nsIURI* aDomainURI,
-+DOMStorageBase::InitAsLocalStorage(nsIURI* aFirstPartyURI,
-+                                   nsIURI* aDomainURI,
-                                    bool aCanUseChromePersist,
-                                    bool aPrivate)
- {
-@@ -634,7 +647,8 @@ DOMStorageBase::InitAsLocalStorage(nsIURI* aDomainURI,
-   // mPrincipal in bug 455070. It is not even used for localStorage.
-   aDomainURI->GetAsciiHost(mDomain);
- 
--  nsDOMStorageDBWrapper::CreateOriginScopeDBKey(aDomainURI, mScopeDBKey);
-+  nsDOMStorageDBWrapper::CreateOriginScopeDBKey(aFirstPartyURI, aDomainURI,
-+                                                mScopeDBKey);
- 
-   // XXX Bug 357323, we have to solve the issue how to define
-   // origin for file URLs. In that case CreateOriginScopeDBKey
-@@ -642,9 +656,9 @@ DOMStorageBase::InitAsLocalStorage(nsIURI* aDomainURI,
-   // in that case because it produces broken entries w/o owner.
-   mUseDB = !mScopeDBKey.IsEmpty();
- 
--  nsDOMStorageDBWrapper::CreateQuotaDomainDBKey(mDomain,
-+  nsDOMStorageDBWrapper::CreateQuotaDomainDBKey(aFirstPartyURI, mDomain,
-                                                 true, false, mQuotaDomainDBKey);
--  nsDOMStorageDBWrapper::CreateQuotaDomainDBKey(mDomain,
-+  nsDOMStorageDBWrapper::CreateQuotaDomainDBKey(aFirstPartyURI, mDomain,
-                                                 true, true, mQuotaETLDplus1DomainDBKey);
-   mCanUseChromePersist = aCanUseChromePersist;
-   mStorageType = nsPIDOMStorage::LocalStorage;
-@@ -763,11 +777,13 @@ DOMStorageImpl::InitAsSessionStorage(nsIURI* aDomainURI, bool aPrivate)
- }
- 
- void
--DOMStorageImpl::InitAsLocalStorage(nsIURI* aDomainURI,
-+DOMStorageImpl::InitAsLocalStorage(nsIURI *aFirstPartyURI,
-+                                   nsIURI* aDomainURI,
-                                    bool aCanUseChromePersist,
-                                    bool aPrivate)
- {
--  DOMStorageBase::InitAsLocalStorage(aDomainURI, aCanUseChromePersist, aPrivate);
-+  DOMStorageBase::InitAsLocalStorage(aFirstPartyURI, aDomainURI,
-+                                     aCanUseChromePersist, aPrivate);
- }
- 
- bool
-@@ -1352,7 +1368,9 @@ nsDOMStorage::InitAsSessionStorage(nsIPrincipal *aPrincipal, const nsSubstring &
- }
- 
- nsresult
--nsDOMStorage::InitAsLocalStorage(nsIPrincipal *aPrincipal, const nsSubstring &aDocumentURI,
-+nsDOMStorage::InitAsLocalStorage(nsIURI *aFirstPartyURI,
-+                                 nsIPrincipal *aPrincipal,
-+                                 const nsSubstring &aDocumentURI,
-                                  bool aPrivate)
- {
-   nsCOMPtr<nsIURI> domainURI;
-@@ -1370,7 +1388,8 @@ nsDOMStorage::InitAsLocalStorage(nsIPrincipal *aPrincipal, const nsSubstring &aD
-     canUseChromePersist = URICanUseChromePersist(URI);
-   }
-   
--  mStorageImpl->InitAsLocalStorage(domainURI, canUseChromePersist, aPrivate);
-+  mStorageImpl->InitAsLocalStorage(aFirstPartyURI, domainURI,
-+                                   canUseChromePersist, aPrivate);
-   return NS_OK;
- }
- 
-@@ -1782,7 +1801,9 @@ nsDOMStorage2::InitAsSessionStorage(nsIPrincipal *aPrincipal, const nsSubstring
- }
- 
- nsresult
--nsDOMStorage2::InitAsLocalStorage(nsIPrincipal *aPrincipal, const nsSubstring &aDocumentURI,
-+nsDOMStorage2::InitAsLocalStorage(nsIURI *aFirstPartyURI,
-+                                  nsIPrincipal *aPrincipal,
-+                                  const nsSubstring &aDocumentURI,
-                                   bool aPrivate)
- {
-   mStorage = new nsDOMStorage();
-@@ -1792,7 +1813,8 @@ nsDOMStorage2::InitAsLocalStorage(nsIPrincipal *aPrincipal, const nsSubstring &a
-   mPrincipal = aPrincipal;
-   mDocumentURI = aDocumentURI;
- 
--  return mStorage->InitAsLocalStorage(aPrincipal, aDocumentURI, aPrivate);
-+  return mStorage->InitAsLocalStorage(aFirstPartyURI, aPrincipal,
-+                                      aDocumentURI, aPrivate);
- }
- 
- already_AddRefed<nsIDOMStorage>
-diff --git a/dom/src/storage/nsDOMStorage.h b/dom/src/storage/nsDOMStorage.h
-index 7add846..b795397 100644
---- a/dom/src/storage/nsDOMStorage.h
-+++ b/dom/src/storage/nsDOMStorage.h
-@@ -114,7 +114,8 @@ public:
-   DOMStorageBase(DOMStorageBase&);
- 
-   virtual void InitAsSessionStorage(nsIURI* aDomainURI, bool aPrivate);
--  virtual void InitAsLocalStorage(nsIURI* aDomainURI, bool aCanUseChromePersist, bool aPrivate);
-+  virtual void InitAsLocalStorage(nsIURI* aFirstPartyURI, nsIURI* aDomainURI,
-+                                  bool aCanUseChromePersist, bool aPrivate);
- 
-   virtual nsTArray<nsString>* GetKeys(bool aCallerSecure) = 0;
-   virtual nsresult GetLength(bool aCallerSecure, uint32_t* aLength) = 0;
-@@ -221,7 +222,8 @@ public:
-   ~DOMStorageImpl();
- 
-   virtual void InitAsSessionStorage(nsIURI* aDomainURI, bool aPrivate);
--  virtual void InitAsLocalStorage(nsIURI* aDomainURI, bool aCanUseChromePersist, bool aPrivate);
-+  virtual void InitAsLocalStorage(nsIURI *aFirstPartyURI, nsIURI* aDomainURI,
-+                                  bool aCanUseChromePersist, bool aPrivate);
- 
-   bool SessionOnly() {
-     return mSessionOnly;
-@@ -336,7 +338,9 @@ public:
-   // nsPIDOMStorage
-   virtual nsresult InitAsSessionStorage(nsIPrincipal *aPrincipal, const nsSubstring &aDocumentURI,
-                                         bool aPrivate);
--  virtual nsresult InitAsLocalStorage(nsIPrincipal *aPrincipal, const nsSubstring &aDocumentURI,
-+  virtual nsresult InitAsLocalStorage(nsIURI *aFirstPartyURI,
-+                                      nsIPrincipal *aPrincipal,
-+                                      const nsSubstring &aDocumentURI,
-                                       bool aPrivate);
-   virtual already_AddRefed<nsIDOMStorage> Clone();
-   virtual already_AddRefed<nsIDOMStorage> Fork(const nsSubstring &aDocumentURI);
-@@ -411,7 +415,9 @@ public:
-   // nsPIDOMStorage
-   virtual nsresult InitAsSessionStorage(nsIPrincipal *aPrincipal, const nsSubstring &aDocumentURI,
-                                         bool aPrivate);
--  virtual nsresult InitAsLocalStorage(nsIPrincipal *aPrincipal, const nsSubstring &aDocumentURI,
-+  virtual nsresult InitAsLocalStorage(nsIURI *aFirstPartyURI,
-+                                      nsIPrincipal *aPrincipal,
-+                                      const nsSubstring &aDocumentURI,
-                                       bool aPrivate);
-   virtual already_AddRefed<nsIDOMStorage> Clone();
-   virtual already_AddRefed<nsIDOMStorage> Fork(const nsSubstring &aDocumentURI);
-diff --git a/dom/src/storage/nsDOMStorageDBWrapper.cpp b/dom/src/storage/nsDOMStorageDBWrapper.cpp
-index bd2581b..048738a 100644
---- a/dom/src/storage/nsDOMStorageDBWrapper.cpp
-+++ b/dom/src/storage/nsDOMStorageDBWrapper.cpp
-@@ -47,7 +47,6 @@ nsDOMStorageDBWrapper::~nsDOMStorageDBWrapper()
- void
- nsDOMStorageDBWrapper::Close()
- {
--  mPersistentDB.Close();
-   mChromePersistentDB.Close();
- }
- 
-@@ -56,13 +55,13 @@ nsDOMStorageDBWrapper::Init()
- {
-   nsresult rv;
- 
--  rv = mPersistentDB.Init(NS_LITERAL_STRING("webappsstore.sqlite"));
-+  rv = mPersistentDB.Init();
-   NS_ENSURE_SUCCESS(rv, rv);
- 
-   rv = mChromePersistentDB.Init(NS_LITERAL_STRING("chromeappsstore.sqlite"));
-   NS_ENSURE_SUCCESS(rv, rv);
- 
--  rv = mSessionOnlyDB.Init(&mPersistentDB);
-+  rv = mSessionOnlyDB.Init();
-   NS_ENSURE_SUCCESS(rv, rv);
- 
-   rv = mPrivateBrowsingDB.Init();
-@@ -74,16 +73,14 @@ nsDOMStorageDBWrapper::Init()
- nsresult
- nsDOMStorageDBWrapper::FlushAndDeleteTemporaryTables(bool force)
- {
--  nsresult rv1, rv2;
-+  nsresult rv1;
-   rv1 = mChromePersistentDB.FlushTemporaryTables(force);
--  rv2 = mPersistentDB.FlushTemporaryTables(force);
- 
-   // Everything flushed?  Then no need for a timer.
--  if (!mChromePersistentDB.mTempTableLoads.Count() && 
--      !mPersistentDB.mTempTableLoads.Count())
-+  if (!mChromePersistentDB.mTempTableLoads.Count())
-     StopTempTableFlushTimer();
- 
--  return NS_FAILED(rv1) ? rv1 : rv2;
-+  return rv1;
- }
- 
- #define IMPL_FORWARDER_GUTS(_return, _code)                                \
-@@ -243,7 +240,8 @@ nsDOMStorageDBWrapper::GetUsage(const nsACString& aDomain,
- }
- 
- nsresult
--nsDOMStorageDBWrapper::CreateOriginScopeDBKey(nsIURI* aUri, nsACString& aKey)
-+nsDOMStorageDBWrapper::CreateOriginScopeDBKey(nsIURI *aFirstPartyURI,
-+                                              nsIURI* aUri, nsACString& aKey)
- {
-   nsresult rv;
- 
-@@ -264,6 +262,17 @@ nsDOMStorageDBWrapper::CreateOriginScopeDBKey(nsIURI* aUri, nsACString& aKey)
-     aKey.Append(nsPrintfCString("%d", port));
-   }
- 
-+  // Isolate scope keys to the URL bar domain by appending &firstPartyHost
-+  // if available.
-+  if (aFirstPartyURI) {
-+    nsCAutoString host;
-+    rv = aFirstPartyURI->GetHost(host);
-+    if (NS_SUCCEEDED(rv) && (host.Length() > 0)) {
-+      aKey.AppendLiteral("&");
-+      aKey.Append(host);
-+    }
-+  }
-+
-   return NS_OK;
- }
- 
-@@ -317,7 +326,8 @@ nsDOMStorageDBWrapper::CreateDomainScopeDBKey(const nsACString& aAsciiDomain,
- }
- 
- nsresult
--nsDOMStorageDBWrapper::CreateQuotaDomainDBKey(const nsACString& aAsciiDomain,
-+nsDOMStorageDBWrapper::CreateQuotaDomainDBKey(nsIURI *aFirstPartyURI,
-+                                              const nsACString& aAsciiDomain,
-                                               bool aIncludeSubDomains,
-                                               bool aEffectiveTLDplus1Only,
-                                               nsACString& aKey)
-@@ -351,6 +361,17 @@ nsDOMStorageDBWrapper::CreateQuotaDomainDBKey(const nsACString& aAsciiDomain,
-   if (!aIncludeSubDomains)
-     subdomainsDBKey.AppendLiteral(":");
- 
-+  // Isolate quota keys to the URL bar domain by appending &firstPartyHost
-+  // if available.
-+  if (aFirstPartyURI) {
-+    nsCAutoString host;
-+    rv = aFirstPartyURI->GetHost(host);
-+    if (NS_SUCCEEDED(rv) && (host.Length() > 0)) {
-+      subdomainsDBKey.AppendLiteral("&");
-+      subdomainsDBKey.Append(host);
-+    }
-+  }
-+
-   aKey.Assign(subdomainsDBKey);
-   return NS_OK;
- }
-diff --git a/dom/src/storage/nsDOMStorageDBWrapper.h b/dom/src/storage/nsDOMStorageDBWrapper.h
-index 94d28af..60a4f91 100644
---- a/dom/src/storage/nsDOMStorageDBWrapper.h
-+++ b/dom/src/storage/nsDOMStorageDBWrapper.h
-@@ -178,9 +178,11 @@ public:
-   /**
-     * Turns "http://foo.bar.com:80" to "moc.rab.oof.:http:80",
-     * i.e. reverses the host, appends a dot, appends the schema
--    * and a port number.
-+    * and a port number.  If aFirstPartyURI is present, the first party
-+    * host is appended, e.g., "moc.rab.oof.:http:80:example.com"
-     */
--  static nsresult CreateOriginScopeDBKey(nsIURI* aUri, nsACString& aKey);
-+  static nsresult CreateOriginScopeDBKey(nsIURI *aFirstPartyURI,
-+                                         nsIURI* aUri, nsACString& aKey);
- 
-   /**
-     * Turns "http://foo.bar.com" to "moc.rab.oof.",
-@@ -192,9 +194,11 @@ public:
-   /**
-     * Turns "foo.bar.com" to "moc.rab.",
-     * i.e. extracts eTLD+1 from the host, reverses the result
--    * and appends a dot.
-+    * and appends a dot.  If aFirstPartyURI is present, the first party
-+    * host is appended, e.g., "moc.rab.:example.com"
-     */
--  static nsresult CreateQuotaDomainDBKey(const nsACString& aAsciiDomain,
-+  static nsresult CreateQuotaDomainDBKey(nsIURI *aFirstPartyURI,
-+                                         const nsACString& aAsciiDomain,
-                                          bool aIncludeSubDomains, bool aETLDplus1Only,
-                                          nsACString& aKey);
- 
-@@ -222,7 +226,7 @@ public:
- 
- protected:
-   nsDOMStoragePersistentDB mChromePersistentDB;
--  nsDOMStoragePersistentDB mPersistentDB;
-+  nsDOMStorageMemoryDB mPersistentDB; // No longer an nsDOMStoragePersistentDB
-   nsDOMStorageMemoryDB mSessionOnlyDB;
-   nsDOMStorageMemoryDB mPrivateBrowsingDB;
- 
-diff --git a/dom/src/storage/nsDOMStorageMemoryDB.cpp b/dom/src/storage/nsDOMStorageMemoryDB.cpp
-index 5cc2e5d..639f516 100644
---- a/dom/src/storage/nsDOMStorageMemoryDB.cpp
-+++ b/dom/src/storage/nsDOMStorageMemoryDB.cpp
-@@ -382,7 +382,12 @@ nsDOMStorageMemoryDB::GetUsage(const nsACString& aDomain,
-   nsresult rv;
- 
-   nsCAutoString quotadomainDBKey;
--  rv = nsDOMStorageDBWrapper::CreateQuotaDomainDBKey(aDomain,
-+  // This GetUsage() call is only used to report usage totals in the
-+  // preferences and page info. UI, and only for sites that have been
-+  // granted "offline application" permission.  Since we pass nullptr
-+  // for the firstPartURI, the usage total returned will not be
-+  // partitioned by first party, which is OK for the UI.
-+  rv = nsDOMStorageDBWrapper::CreateQuotaDomainDBKey(nullptr, aDomain,
-                                                      aIncludeSubDomains,
-                                                      false,
-                                                      quotadomainDBKey);
-@@ -395,6 +400,7 @@ struct GetUsageEnumStruc
- {
-   int32_t mUsage;
-   int32_t mExcludeOfflineFromUsage;
-+  nsCString mFirstPartyHostSuffix;	// e.g., &example.com
-   nsCString mSubdomain;
- };
- 
-@@ -405,7 +411,9 @@ GetUsageEnum(const nsACString& key,
- {
-   GetUsageEnumStruc* struc = (GetUsageEnumStruc*)closure;
- 
--  if (StringBeginsWith(key, struc->mSubdomain)) {
-+  if (StringBeginsWith(key, struc->mSubdomain) &&
-+      ((0 == struc->mFirstPartyHostSuffix.Length()) ||
-+       StringEndsWith(key, struc->mFirstPartyHostSuffix))) {
-     if (struc->mExcludeOfflineFromUsage) {
-       nsCAutoString domain;
-       nsresult rv = nsDOMStorageDBWrapper::GetDomainFromScopeKey(key, domain);
-@@ -428,6 +436,15 @@ nsDOMStorageMemoryDB::GetUsageInternal(const nsACString& aQuotaDomainDBKey,
-   struc.mUsage = 0;
-   struc.mExcludeOfflineFromUsage = aExcludeOfflineFromUsage;
-   struc.mSubdomain = aQuotaDomainDBKey;
-+  nsCAutoString tmpQuotaKey(aQuotaDomainDBKey);
-+  int32_t idx = tmpQuotaKey.RFindChar('&');
-+  if (idx > 0) {
-+    const nsDependentCSubstring& tmpStr = Substring(tmpQuotaKey, idx);
-+    if (tmpStr.Length() > 1) {
-+      struc.mFirstPartyHostSuffix = tmpStr;
-+      struc.mSubdomain = Substring(tmpQuotaKey, 0, idx - 1);
-+    }
-+  }
- 
-   if (mPreloadDB) {
-     nsresult rv;
-diff --git a/dom/src/storage/nsDOMStoragePersistentDB.cpp b/dom/src/storage/nsDOMStoragePersistentDB.cpp
-index 93ad303..7814a60 100644
---- a/dom/src/storage/nsDOMStoragePersistentDB.cpp
-+++ b/dom/src/storage/nsDOMStoragePersistentDB.cpp
-@@ -813,7 +813,13 @@ nsDOMStoragePersistentDB::GetUsage(const nsACString& aDomain,
-   nsresult rv;
- 
-   nsCAutoString quotadomainDBKey;
--  rv = nsDOMStorageDBWrapper::CreateQuotaDomainDBKey(aDomain,
-+  // This GetUsage() call is only used to report usage totals in the
-+  // preferences and page info. UI, and only for sites that have been
-+  // granted "offline application" permission.  Since we pass nullptr
-+  // for the firstPartURI, the usage total returned will not be
-+  // partitioned by first party, which is OK for the UI.
-+  // Also, Tor does not use currently use nsDOMStoragePersistentDB.
-+  rv = nsDOMStorageDBWrapper::CreateQuotaDomainDBKey(nullptr, aDomain,
-                                                      aIncludeSubDomains,
-                                                      false,
-                                                      quotadomainDBKey);
-diff --git a/embedding/components/windowwatcher/src/nsWindowWatcher.cpp b/embedding/components/windowwatcher/src/nsWindowWatcher.cpp
-index 6abbed7..0bad9ed 100644
---- a/embedding/components/windowwatcher/src/nsWindowWatcher.cpp
-+++ b/embedding/components/windowwatcher/src/nsWindowWatcher.cpp
-@@ -963,14 +963,15 @@ nsWindowWatcher::OpenWindowInternal(nsIDOMWindow *aParent,
- 
-   if (subjectPrincipal && parentDocShell) {
-     nsCOMPtr<nsIDOMStorage> storage;
--    parentDocShell->GetSessionStorageForPrincipal(subjectPrincipal,
-+    parentDocShell->GetSessionStorageForFirstParty(uriToLoad, subjectPrincipal,
-                                                   EmptyString(), false,
-                                                   getter_AddRefs(storage));
-     nsCOMPtr<nsPIDOMStorage> piStorage =
-       do_QueryInterface(storage);
-     if (piStorage){
-       storage = piStorage->Clone();
--      newDocShell->AddSessionStorage(
-+      newDocShell->AddSessionStorageForFirstParty(
-+        uriToLoad,
-         piStorage->Principal(),
-         storage);
-     }
--- 
-1.7.5.4
-
diff --git a/src/current-patches/firefox/0027-Remove-This-plugin-is-disabled-barrier.patch b/src/current-patches/firefox/0027-Remove-This-plugin-is-disabled-barrier.patch
deleted file mode 100644
index 53ecfba..0000000
--- a/src/current-patches/firefox/0027-Remove-This-plugin-is-disabled-barrier.patch
+++ /dev/null
@@ -1,46 +0,0 @@
-From cc9807d0dc7907cddfcd4053f26ca6ad01b5a070 Mon Sep 17 00:00:00 2001
-From: Mike Perry <mikeperry-git at torproject.org>
-Date: Thu, 28 Feb 2013 17:41:57 -0800
-Subject: [PATCH 27/27] Remove "This plugin is disabled" barrier.
-
-We do not want to encourage our users to enable plugins at this point.
-
-The barrier also causes bad UX for HTML5 video fallback on YouTube.
----
- browser/base/content/browser-plugins.js           |    6 ++++--
- toolkit/mozapps/plugins/content/pluginProblem.xml |    2 +-
- 2 files changed, 5 insertions(+), 3 deletions(-)
-
-diff --git a/browser/base/content/browser-plugins.js b/browser/base/content/browser-plugins.js
-index c2abebf..655c2bf 100644
---- a/browser/base/content/browser-plugins.js
-+++ b/browser/base/content/browser-plugins.js
-@@ -228,8 +228,10 @@ var gPluginHandler = {
-         break;
- 
-       case "PluginDisabled":
--        let manageLink = doc.getAnonymousElementByAttribute(plugin, "class", "managePluginsLink");
--        self.addLinkClickCallback(manageLink, "managePlugins");
-+        // Screw the disabled message. It messes with HTML5 fallback on YouTube
-+        let plugin_overlay = doc.getAnonymousElementByAttribute(plugin, "class", "mainBox");
-+        if (plugin_overlay != null)
-+          plugin_overlay.style.visibility = "hidden";
-         break;
- 
-       case "PluginScripted":
-diff --git a/toolkit/mozapps/plugins/content/pluginProblem.xml b/toolkit/mozapps/plugins/content/pluginProblem.xml
-index f61cb48..ed83569 100644
---- a/toolkit/mozapps/plugins/content/pluginProblem.xml
-+++ b/toolkit/mozapps/plugins/content/pluginProblem.xml
-@@ -38,7 +38,7 @@
-             <html:div class="installStatus">
-                 <html:div class="msg msgInstallPlugin"><html:a class="installPluginLink" href="">&installPlugin;</html:a></html:div>
-             </html:div>
--            <html:div class="msg msgManagePlugins"><html:a class="managePluginsLink" href="">&managePlugins;</html:a></html:div>
-+            <html:div class="msg msgManagePlugins"><html:a class="managePluginsLink" href=""></html:a></html:div>
-             <html:div class="submitStatus">
-                 <!-- links set at runtime -->
-                 <html:div class="msg msgPleaseSubmit"><html:a class="pleaseSubmitLink" href="">&report.please;</html:a></html:div>
--- 
-1.7.5.4
-
diff --git a/src/current-patches/firefox/0028-Use-Optimistic-Data-SOCKS-variant.patch b/src/current-patches/firefox/0028-Use-Optimistic-Data-SOCKS-variant.patch
deleted file mode 100644
index b6d43c1..0000000
--- a/src/current-patches/firefox/0028-Use-Optimistic-Data-SOCKS-variant.patch
+++ /dev/null
@@ -1,82 +0,0 @@
-From 64548e75e1cb68a2449b001629c0ee0d10636d90 Mon Sep 17 00:00:00 2001
-From: Tao Wang <t55wang at uwaterloo.ca>
-Date: Tue, 2 Apr 2013 15:56:49 -0700
-Subject: [PATCH 28/28] Use Optimistic Data SOCKS variant.
-
-This patch alters Firefox's SOCKS handshake to preemptively send data before
-it is actually connected. This allows us to save a round trip during
-connection setup.
-
-See:
-https://gitweb.torproject.org/torspec.git/blob/HEAD:/proposals/181-optimistic-data-client.txt
----
- netwerk/base/src/nsSocketTransport2.cpp |   20 ++++++++++++++++++--
- netwerk/base/src/nsSocketTransport2.h   |    4 +++-
- netwerk/socket/nsSOCKSIOLayer.cpp       |    4 +++-
- 3 files changed, 24 insertions(+), 4 deletions(-)
-
-diff --git a/netwerk/base/src/nsSocketTransport2.cpp b/netwerk/base/src/nsSocketTransport2.cpp
-index 15870bb..668d18f 100644
---- a/netwerk/base/src/nsSocketTransport2.cpp
-+++ b/netwerk/base/src/nsSocketTransport2.cpp
-@@ -1543,9 +1543,25 @@ nsSocketTransport::OnSocketReady(PRFileDesc *fd, int16_t outFlags)
-         // Update poll timeout in case it was changed
-         mPollTimeout = mTimeouts[TIMEOUT_READ_WRITE];
-     }
--    else if (mState == STATE_CONNECTING) {
-+
-+//STATE_SENDINGGET: handshake proceeded to state "sent connect"
-+//one more poll to OnSocketReady will trigger the get request, and state STATE_SENTGET
-+//STATE_SENTGET: continue and finish handshake
-+    else if (mState == STATE_SENDINGGET) {
-+        if ((mPollFlags & PR_POLL_WRITE) && (outFlags & ~PR_POLL_READ)) {
-+            mOutput.OnSocketReady(NS_OK);
-+        }
-+        mPollTimeout = mTimeouts[TIMEOUT_READ_WRITE];
-+        mState = STATE_SENTGET;
-+    }
-+
-+    else if (mState == STATE_CONNECTING || mState == STATE_SENTGET) {
-         PRStatus status = PR_ConnectContinue(fd, outFlags);
--        if (status == PR_SUCCESS) {
-+        if (status == PR_SUCCESS && mState == STATE_CONNECTING) {
-+            OnSocketConnected();
-+            mState = STATE_SENDINGGET;
-+        }
-+        else if (status == PR_SUCCESS && mState == STATE_SENTGET) {
-             //
-             // we are connected!
-             //
-diff --git a/netwerk/base/src/nsSocketTransport2.h b/netwerk/base/src/nsSocketTransport2.h
-index d9ac3d3..0c92d0a 100644
---- a/netwerk/base/src/nsSocketTransport2.h
-+++ b/netwerk/base/src/nsSocketTransport2.h
-@@ -154,7 +154,9 @@ private:
-         STATE_IDLE,
-         STATE_RESOLVING,
-         STATE_CONNECTING,
--        STATE_TRANSFERRING
-+        STATE_TRANSFERRING,
-+        STATE_SENDINGGET,
-+        STATE_SENTGET
-     };
- 
-     //-------------------------------------------------------------------------
-diff --git a/netwerk/socket/nsSOCKSIOLayer.cpp b/netwerk/socket/nsSOCKSIOLayer.cpp
-index 24edc78..64f6001 100644
---- a/netwerk/socket/nsSOCKSIOLayer.cpp
-+++ b/netwerk/socket/nsSOCKSIOLayer.cpp
-@@ -77,7 +77,9 @@ public:
-     void SetConnectTimeout(PRIntervalTime to);
-     PRStatus DoHandshake(PRFileDesc *fd, int16_t oflags = -1);
-     int16_t GetPollFlags() const;
--    bool IsConnected() const { return mState == SOCKS_CONNECTED; }
-+    bool IsConnected() const { return (mState == SOCKS_CONNECTED ||
-+                                       mState == SOCKS5_READ_CONNECT_RESPONSE_TOP); }
-+ 
-     void ForgetFD() { mFD = nullptr; }
- 
- private:
--- 
-1.7.9.5
-
diff --git a/src/current-patches/firefox/0029-Disable-library-timestamping.patch b/src/current-patches/firefox/0029-Disable-library-timestamping.patch
deleted file mode 100644
index 8a37556..0000000
--- a/src/current-patches/firefox/0029-Disable-library-timestamping.patch
+++ /dev/null
@@ -1,27 +0,0 @@
-From 756c1673881ae104e20305fadad41cfea5f04608 Mon Sep 17 00:00:00 2001
-From: Mike Perry <mikeperry-git at torproject.org>
-Date: Thu, 1 Jan 1970 00:00:00 +0000
-Subject: [PATCH 29/29] Disable library timestamping.
-
-This timestamp prevents deterministic builds, and is set in a way that
-libfaketime can't correct.
----
- nsprpub/config/now.c |    2 +-
- 1 file changed, 1 insertion(+), 1 deletion(-)
-
-diff --git a/nsprpub/config/now.c b/nsprpub/config/now.c
-index 165b924..5e07a72 100644
---- a/nsprpub/config/now.c
-+++ b/nsprpub/config/now.c
-@@ -14,7 +14,7 @@
- #error "Architecture not supported"
- #endif
- 
--
-+#define OMIT_LIB_BUILD_TIME
- int main(int argc, char **argv)
- {
- #if defined(OMIT_LIB_BUILD_TIME)
--- 
-1.7.9.5
-





More information about the tor-commits mailing list