tor-commits
Threads by month
- ----- 2025 -----
- June
- May
- April
- March
- February
- January
- ----- 2024 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2023 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2022 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2021 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2020 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2019 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2018 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2017 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2016 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2015 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2014 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2013 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2012 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2011 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
January 2013
- 19 participants
- 1125 discussions

17 Jan '13
commit 4281125f4d3d7a2c337d48b6569689ab254083da
Author: Mike Perry <mikeperry-git(a)fscked.org>
Date: Wed Jan 16 00:19:54 2013 -0800
Update patches for Firefox 17ESR.
---
...-Block-Components.interfaces-from-content.patch | 37 +
...nents.interfaces-lookupMethod-from-conten.patch | 50 --
...0002-Make-Permissions-Manager-memory-only.patch | 28 +-
...-Make-Intermediate-Cert-Store-memory-only.patch | 21 +-
.../firefox/0004-Add-a-string-based-cacheKey.patch | 32 +-
.../0005-Block-all-plugins-except-flash.patch | 20 +-
...ontent-pref-service-memory-only-clearable.patch | 10 +-
...owser-exit-when-not-launched-from-Vidalia.patch | 52 +-
.../0008-Disable-SSL-Session-ID-tracking.patch | 4 +-
...observer-event-to-close-persistent-connec.patch | 20 +-
...ice-and-system-specific-CSS-Media-Queries.patch | 101 +--
...11-Limit-the-number-of-fonts-per-document.patch | 97 ++-
.../0012-Rebrand-Firefox-to-TorBrowser.patch | 29 +-
.../0013-Make-Download-manager-memory-only.patch | 18 +-
.../0014-Add-DDG-and-StartPage-to-Omnibox.patch | 4 +-
...-nsICacheService.EvictEntries-synchronous.patch | 23 +-
.../firefox/0016-Prevent-WebSocket-DNS-leak.patch | 55 +-
...ize-HTTP-request-order-and-pipeline-depth.patch | 296 +++-----
...Adapt-Steven-Michaud-s-Mac-crashfix-patch.patch | 545 ++++++++++++
...th-headers-before-the-modify-request-obse.patch | 52 --
...Adapt-Steven-Michaud-s-Mac-crashfix-patch.patch | 532 ------------
...d-mozIThirdPartyUtil.getFirstPartyURI-API.patch | 154 ++++
.../0020-Add-canvas-image-extraction-prompt.patch | 548 ++++++++++++
...d-mozIThirdPartyUtil.getFirstPartyURI-API.patch | 155 ----
.../0021-Add-canvas-image-extraction-prompt.patch | 551 ------------
...nt-window-coordinates-for-mouse-event-scr.patch | 77 ++
...se-physical-screen-info.-via-window-and-w.patch | 310 +++++++
...nt-window-coordinates-for-mouse-event-scr.patch | 43 -
...se-physical-screen-info.-via-window-and-w.patch | 312 -------
...not-expose-system-colors-to-CSS-or-canvas.patch | 466 ++++++++++
...not-expose-system-colors-to-CSS-or-canvas.patch | 537 ------------
...solate-the-Image-Cache-per-url-bar-domain.patch | 912 ++++++++++++++++++++
.../0025-nsIHTTPChannel.redirectTo-API.patch | 474 ++++++++++
...26-Isolate-DOM-storage-to-first-party-URI.patch | 776 +++++++++++++++++
34 files changed, 4673 insertions(+), 2668 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
new file mode 100644
index 0000000..7a2faac
--- /dev/null
+++ b/src/current-patches/firefox/0001-Block-Components.interfaces-from-content.patch
@@ -0,0 +1,37 @@
+From 60f2318ffa6e9a3bdb37192378e0711aa14bd772 Mon Sep 17 00:00:00 2001
+From: Mike Perry <mikeperry-git(a)torproject.org>
+Date: Tue, 4 Dec 2012 15:41:09 -0800
+Subject: [PATCH 01/26] Block Components.interfaces from content
+
+This patch removes the ability of content script to access
+Components.interfaces.*.
+
+Components.interfaces is useful for fingerprinting the platform, OS, and
+Firebox version.
+
+It appears to have no other legitimate use. See also:
+https://bugzilla.mozilla.org/show_bug.cgi?id=429070
+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(-)
+
+diff --git a/js/xpconnect/src/XPCComponents.cpp b/js/xpconnect/src/XPCComponents.cpp
+index 3a14254..4040349 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
+ NS_IMETHODIMP
+ nsXPCComponents::CanGetProperty(const nsIID * iid, const PRUnichar *propertyName, char **_retval)
+ {
+- static const char* allowed[] = { "interfaces", "interfacesByID", "results", nullptr};
++ static const char* allowed[] = { "results", nullptr};
+ *_retval = xpc_CheckAccessList(propertyName, allowed);
+ return NS_OK;
+ }
+--
+1.7.5.4
+
diff --git a/src/current-patches/firefox/0001-Block-Components.interfaces-lookupMethod-from-conten.patch b/src/current-patches/firefox/0001-Block-Components.interfaces-lookupMethod-from-conten.patch
deleted file mode 100644
index 1a82800..0000000
--- a/src/current-patches/firefox/0001-Block-Components.interfaces-lookupMethod-from-conten.patch
+++ /dev/null
@@ -1,50 +0,0 @@
-From 1c2ccbea73720db5405602e4033c69b706068a8b Mon Sep 17 00:00:00 2001
-From: Mike Perry <mikeperry-git(a)torproject.org>
-Date: Wed, 1 Feb 2012 15:40:40 -0800
-Subject: [PATCH 01/24] Block Components.interfaces,lookupMethod from content
-
-This patch removes the ability of content script to access
-Components.interfaces.* as well as call or access Components.lookupMethod.
-
-These two interfaces seem to be exposed to content script only to make our
-lives difficult. Components.lookupMethod can undo our JS hooks, and
-Components.interfaces is useful for fingerprinting the platform, OS, and
-Firebox version.
-
-They appear to have no other legitimate use. See also:
-https://bugzilla.mozilla.org/show_bug.cgi?id=429070
-https://trac.torproject.org/projects/tor/ticket/2873
-https://trac.torproject.org/projects/tor/ticket/2874
----
- js/xpconnect/src/XPCComponents.cpp | 8 ++++++--
- 1 files changed, 6 insertions(+), 2 deletions(-)
-
-diff --git a/js/xpconnect/src/XPCComponents.cpp b/js/xpconnect/src/XPCComponents.cpp
-index 38bfe08..7224b9b 100644
---- a/js/xpconnect/src/XPCComponents.cpp
-+++ b/js/xpconnect/src/XPCComponents.cpp
-@@ -4502,7 +4502,9 @@ nsXPCComponents::CanCreateWrapper(const nsIID * iid, char **_retval)
- NS_IMETHODIMP
- nsXPCComponents::CanCallMethod(const nsIID * iid, const PRUnichar *methodName, char **_retval)
- {
-- static const char* allowed[] = { "isSuccessCode", "lookupMethod", nsnull };
-+ // XXX: Pref observer? Also, is this what we want? Seems like a plan
-+ //static const char* allowed[] = { "isSuccessCode", "lookupMethod", nsnull };
-+ static const char* allowed[] = { "isSuccessCode", nsnull };
- *_retval = xpc_CheckAccessList(methodName, allowed);
- return NS_OK;
- }
-@@ -4511,7 +4513,9 @@ nsXPCComponents::CanCallMethod(const nsIID * iid, const PRUnichar *methodName, c
- NS_IMETHODIMP
- nsXPCComponents::CanGetProperty(const nsIID * iid, const PRUnichar *propertyName, char **_retval)
- {
-- static const char* allowed[] = { "interfaces", "interfacesByID", "results", nsnull};
-+ // XXX: Pref observer? Also, is this what we want? Seems like a plan
-+ // static const char* allowed[] = { "interfaces", "interfacesByID", "results", nsnull};
-+ static const char* allowed[] = { "results", nsnull};
- *_retval = xpc_CheckAccessList(propertyName, allowed);
- return NS_OK;
- }
---
-1.7.5.4
-
diff --git a/src/current-patches/firefox/0002-Make-Permissions-Manager-memory-only.patch b/src/current-patches/firefox/0002-Make-Permissions-Manager-memory-only.patch
index fa23d93..cb04eae 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 cd983b1b57b1f4ae10c8deec5aa12ec957fdc855 Mon Sep 17 00:00:00 2001
+From db27e73d62d4f680b98a4ad9e7493b62070e23ae Mon Sep 17 00:00:00 2001
From: Mike Perry <mikeperry-git(a)torproject.org>
-Date: Wed, 1 Feb 2012 15:45:16 -0800
-Subject: [PATCH 02/24] Make Permissions Manager memory-only
+Date: Tue, 4 Dec 2012 15:45:59 -0800
+Subject: [PATCH 02/26] Make Permissions Manager memory-only
This patch exposes a pref 'permissions.memory_only' that properly isolates the
permissions manager to memory, which is responsible for all user specified
@@ -16,21 +16,21 @@ https://trac.torproject.org/projects/tor/ticket/2950
1 files changed, 31 insertions(+), 3 deletions(-)
diff --git a/extensions/cookie/nsPermissionManager.cpp b/extensions/cookie/nsPermissionManager.cpp
-index 67eb216..12cc7cf 100644
+index 9c50080..4102408 100644
--- a/extensions/cookie/nsPermissionManager.cpp
+++ b/extensions/cookie/nsPermissionManager.cpp
-@@ -58,6 +58,10 @@
- #include "mozStorageHelper.h"
- #include "mozStorageCID.h"
- #include "nsXULAppAPI.h"
+@@ -24,6 +24,10 @@
+ #include "nsIPrincipal.h"
+ #include "nsContentUtils.h"
+ #include "nsIScriptSecurityManager.h"
+#include "nsCOMPtr.h"
+#include "nsIPrefService.h"
+#include "nsIPrefBranch.h"
+#include "nsIPrefBranch2.h"
- static nsPermissionManager *gPermissionManager = nsnull;
+ static nsPermissionManager *gPermissionManager = nullptr;
-@@ -203,6 +207,11 @@ nsPermissionManager::Init()
+@@ -301,6 +305,11 @@ nsPermissionManager::Init()
mObserverService->AddObserver(this, "profile-do-change", true);
}
@@ -42,7 +42,7 @@ index 67eb216..12cc7cf 100644
if (IsChildProcess()) {
// Get the permissions from the parent process
InfallibleTArray<IPC::Permission> perms;
-@@ -251,8 +260,18 @@ nsPermissionManager::InitDB(bool aRemoveFile)
+@@ -356,8 +365,18 @@ nsPermissionManager::InitDB(bool aRemoveFile)
if (!storage)
return NS_ERROR_UNEXPECTED;
@@ -62,7 +62,7 @@ index 67eb216..12cc7cf 100644
NS_ENSURE_SUCCESS(rv, rv);
bool ready;
-@@ -262,7 +281,11 @@ nsPermissionManager::InitDB(bool aRemoveFile)
+@@ -367,7 +386,11 @@ nsPermissionManager::InitDB(bool aRemoveFile)
rv = permissionsFile->Remove(false);
NS_ENSURE_SUCCESS(rv, rv);
@@ -75,7 +75,7 @@ index 67eb216..12cc7cf 100644
NS_ENSURE_SUCCESS(rv, rv);
mDBConn->GetConnectionReady(&ready);
-@@ -783,7 +806,12 @@ NS_IMETHODIMP nsPermissionManager::Observe(nsISupports *aSubject, const char *aT
+@@ -1052,7 +1075,12 @@ NS_IMETHODIMP nsPermissionManager::Observe(nsISupports *aSubject, const char *aT
{
ENSURE_NOT_CHILD_PROCESS;
@@ -88,7 +88,7 @@ index 67eb216..12cc7cf 100644
+ } else if (!nsCRT::strcmp(aTopic, "profile-before-change")) {
// The profile is about to change,
// or is going away because the application is shutting down.
- if (!nsCRT::strcmp(someData, NS_LITERAL_STRING("shutdown-cleanse").get())) {
+ mIsShuttingDown = true;
--
1.7.5.4
diff --git a/src/current-patches/firefox/0003-Make-Intermediate-Cert-Store-memory-only.patch b/src/current-patches/firefox/0003-Make-Intermediate-Cert-Store-memory-only.patch
index b10fb85..a367d67 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,25 +1,26 @@
-From f100a7979e1a44863a8a67a09743f0e17b5dd14e Mon Sep 17 00:00:00 2001
-From: Mike Perry <mikeperry-git(a)fscked.org>
-Date: Fri, 19 Aug 2011 17:58:23 -0700
-Subject: [PATCH 03/24] Make Intermediate Cert Store memory-only.
+From ac380269829788ddbd721d642ec57af0fff350de Mon Sep 17 00:00:00 2001
+From: Mike Perry <mikeperry-git(a)torproject.org>
+Date: Tue, 4 Dec 2012 15:51:07 -0800
+Subject: [PATCH 03/26] Make Intermediate Cert Store memory-only.
This patch makes the intermediate SSL cert store exist in memory only.
The pref must be set before startup in prefs.js.
https://trac.torproject.org/projects/tor/ticket/2949
---
- security/manager/ssl/src/nsNSSComponent.cpp | 15 ++++++++++++++-
- 1 files changed, 14 insertions(+), 1 deletions(-)
+ security/manager/ssl/src/nsNSSComponent.cpp | 17 +++++++++++++++--
+ 1 files changed, 15 insertions(+), 2 deletions(-)
diff --git a/security/manager/ssl/src/nsNSSComponent.cpp b/security/manager/ssl/src/nsNSSComponent.cpp
-index a08c4ef..0ec3713 100644
+index c9205bc..159985c 100644
--- a/security/manager/ssl/src/nsNSSComponent.cpp
+++ b/security/manager/ssl/src/nsNSSComponent.cpp
-@@ -1730,8 +1730,21 @@ nsNSSComponent::InitializeNSS(bool showWarningBox)
+@@ -1736,8 +1736,21 @@ nsNSSComponent::InitializeNSS(bool showWarningBox)
// Ubuntu 8.04, which loads any nonexistent "<configdir>/libnssckbi.so" as
// "/usr/lib/nss/libnssckbi.so".
- PRUint32 init_flags = NSS_INIT_NOROOTINIT | NSS_INIT_OPTIMIZESPACE;
+ uint32_t init_flags = NSS_INIT_NOROOTINIT | NSS_INIT_OPTIMIZESPACE;
- SECStatus init_rv = ::NSS_Initialize(profileStr.get(), "", "",
+- SECMOD_DB, init_flags);
+ bool nocertdb = false;
+ mPrefBranch->GetBoolPref("security.nocertdb", &nocertdb);
+
@@ -33,7 +34,7 @@ index a08c4ef..0ec3713 100644
+ init_rv = ::NSS_NoDB_Init(NULL);
+ } else {
+ init_rv = ::NSS_Initialize(profileStr.get(), "", "",
- SECMOD_DB, init_flags);
++ SECMOD_DB, init_flags);
+ }
if (init_rv != SECSuccess) {
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 f3afa97..c1ca50a 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,7 +1,7 @@
-From d674d09bc233d200b1ebc47f8e6ac4ebd6e4225a Mon Sep 17 00:00:00 2001
-From: Mike Perry <mikeperry-git(a)fscked.org>
-Date: Fri, 2 Sep 2011 20:47:02 -0700
-Subject: [PATCH 04/24] Add a string-based cacheKey.
+From e991fbe8787ad8a50621f6a11633a121910d77fb Mon Sep 17 00:00:00 2001
+From: Mike Perry <mikeperry-git(a)torproject.org>
+Date: Tue, 4 Dec 2012 16:01:42 -0800
+Subject: [PATCH 04/26] Add a string-based cacheKey.
Used for isolating cache according to same-origin policy.
---
@@ -11,10 +11,10 @@ Used for isolating cache according to same-origin policy.
3 files changed, 30 insertions(+), 0 deletions(-)
diff --git a/netwerk/base/public/nsICachingChannel.idl b/netwerk/base/public/nsICachingChannel.idl
-index 2da46d6..4ee5774 100644
+index 3119dd9..fd2ec89 100644
--- a/netwerk/base/public/nsICachingChannel.idl
+++ b/netwerk/base/public/nsICachingChannel.idl
-@@ -98,6 +98,13 @@ interface nsICachingChannel : nsICacheInfoChannel
+@@ -65,6 +65,13 @@ interface nsICachingChannel : nsICacheInfoChannel
attribute nsISupports cacheKey;
/**
@@ -29,10 +29,10 @@ index 2da46d6..4ee5774 100644
* may fail if the disk cache is not present. The value of this attribute
* is usually only settable during the processing of a channel's
diff --git a/netwerk/protocol/http/nsHttpChannel.cpp b/netwerk/protocol/http/nsHttpChannel.cpp
-index dec2a83..97bd84c 100644
+index f1ae96a..9223d08 100644
--- a/netwerk/protocol/http/nsHttpChannel.cpp
+++ b/netwerk/protocol/http/nsHttpChannel.cpp
-@@ -2392,6 +2392,12 @@ nsHttpChannel::AssembleCacheKey(const char *spec, PRUint32 postID,
+@@ -2721,6 +2721,12 @@ nsHttpChannel::AssembleCacheKey(const char *spec, uint32_t postID,
cacheKey.Append(buf);
}
@@ -45,8 +45,8 @@ index dec2a83..97bd84c 100644
if (!cacheKey.IsEmpty()) {
cacheKey.AppendLiteral("uri=");
}
-@@ -4695,6 +4701,22 @@ nsHttpChannel::SetCacheForOfflineUse(bool value)
- }
+@@ -5179,6 +5185,22 @@ nsHttpChannel::SetCacheTokenCachedCharset(const nsACString &aCharset)
+ //-----------------------------------------------------------------------------
NS_IMETHODIMP
+nsHttpChannel::GetCacheDomain(nsACString &value)
@@ -65,17 +65,17 @@ index dec2a83..97bd84c 100644
+}
+
+NS_IMETHODIMP
- nsHttpChannel::GetOfflineCacheClientID(nsACString &value)
+ nsHttpChannel::GetCacheToken(nsISupports **token)
{
- value = mOfflineCacheClientID;
+ NS_ENSURE_ARG_POINTER(token);
diff --git a/netwerk/protocol/http/nsHttpChannel.h b/netwerk/protocol/http/nsHttpChannel.h
-index 88ce469..53538cf 100644
+index 5b8c654..5b4ddb9 100644
--- a/netwerk/protocol/http/nsHttpChannel.h
+++ b/netwerk/protocol/http/nsHttpChannel.h
-@@ -303,6 +303,7 @@ private:
- nsCOMPtr<nsICacheEntryDescriptor> mOfflineCacheEntry;
+@@ -298,6 +298,7 @@ private:
nsCacheAccessMode mOfflineCacheAccess;
- nsCString mOfflineCacheClientID;
+ uint32_t mOfflineCacheLastModifiedTime;
+ nsCOMPtr<nsIApplicationCache> mApplicationCacheForWrite;
+ nsCString mCacheDomain;
// auth specific data
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 e7a831e..f452b0f 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 88a390822d232ba037de1f15091977ca7e1064bf Mon Sep 17 00:00:00 2001
+From 1ff6423fed745b7efd041fb6397065bd39a16d1a Mon Sep 17 00:00:00 2001
From: Mike Perry <mikeperry-git(a)torproject.org>
-Date: Wed, 1 Feb 2012 15:50:15 -0800
-Subject: [PATCH 05/24] Block all plugins except flash.
+Date: Tue, 4 Dec 2012 16:03:13 -0800
+Subject: [PATCH 05/26] Block all plugins except flash.
We cannot use the @mozilla.org/extensions/blocklist;1 service, because we
actually want to stop plugins from ever entering the browser's process space
@@ -17,12 +17,12 @@ on a better way. Until then, it is delta-darwinism for us.
2 files changed, 35 insertions(+), 0 deletions(-)
diff --git a/dom/plugins/base/nsPluginHost.cpp b/dom/plugins/base/nsPluginHost.cpp
-index 992bcd4..f56f231 100644
+index b4233fa..1fe506a 100644
--- a/dom/plugins/base/nsPluginHost.cpp
+++ b/dom/plugins/base/nsPluginHost.cpp
-@@ -1968,6 +1968,35 @@ bool nsPluginHost::IsDuplicatePlugin(nsPluginTag * aPluginTag)
- return false;
- }
+@@ -2040,6 +2040,35 @@ struct CompareFilesByTime
+
+ } // anonymous namespace
+PRBool nsPluginHost::GhettoBlacklist(nsIFile *pluginFile)
+{
@@ -56,7 +56,7 @@ index 992bcd4..f56f231 100644
typedef NS_NPAPIPLUGIN_CALLBACK(char *, NP_GETMIMEDESCRIPTION)(void);
nsresult nsPluginHost::ScanPluginsDirectory(nsIFile *pluginsDir,
-@@ -2101,6 +2130,10 @@ nsresult nsPluginHost::ScanPluginsDirectory(nsIFile *pluginsDir,
+@@ -2144,6 +2173,10 @@ nsresult nsPluginHost::ScanPluginsDirectory(nsIFile *pluginsDir,
continue;
}
@@ -68,10 +68,10 @@ index 992bcd4..f56f231 100644
if (!pluginTag) {
nsPluginFile pluginFile(localfile);
diff --git a/dom/plugins/base/nsPluginHost.h b/dom/plugins/base/nsPluginHost.h
-index 39a8891..c262abf 100644
+index fdaa76d..9e328a2 100644
--- a/dom/plugins/base/nsPluginHost.h
+++ b/dom/plugins/base/nsPluginHost.h
-@@ -278,6 +278,8 @@ private:
+@@ -261,6 +261,8 @@ private:
// Loads all cached plugins info into mCachedPlugins
nsresult ReadPluginInfo();
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 17af793..32eb7c2 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,7 +1,7 @@
-From 71ba98d81a6ecada62af4d2ee03be050d371d996 Mon Sep 17 00:00:00 2001
+From 60c8edec8d90c6661ab5577970800c01b1205e02 Mon Sep 17 00:00:00 2001
From: Mike Perry <mikeperry-git(a)fscked.org>
Date: Thu, 8 Sep 2011 08:40:17 -0700
-Subject: [PATCH 06/24] Make content pref service memory-only + clearable
+Subject: [PATCH 06/26] Make content pref service memory-only + clearable
This prevents random urls from being inserted into content-prefs.sqllite in
the profile directory as content prefs change (includes site-zoom and perhaps
@@ -11,10 +11,10 @@ other site prefs?).
1 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/toolkit/components/contentprefs/nsContentPrefService.js b/toolkit/components/contentprefs/nsContentPrefService.js
-index adfb650..1619d5f 100644
+index ed8ad2e..794c9f3 100644
--- a/toolkit/components/contentprefs/nsContentPrefService.js
+++ b/toolkit/components/contentprefs/nsContentPrefService.js
-@@ -1240,7 +1240,7 @@ ContentPrefService.prototype = {
+@@ -1206,7 +1206,7 @@ ContentPrefService.prototype = {
var dbConnection;
@@ -23,7 +23,7 @@ index adfb650..1619d5f 100644
dbConnection = this._dbCreate(dbService, dbFile);
else {
try {
-@@ -1288,7 +1288,7 @@ ContentPrefService.prototype = {
+@@ -1254,7 +1254,7 @@ ContentPrefService.prototype = {
},
_dbCreate: function ContentPrefService__dbCreate(aDBService, aDBFile) {
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
index cc496d3..80c55c2 100644
--- 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
@@ -1,7 +1,7 @@
-From 12579def59d67416b841f6b0a6eadfd94bba72e9 Mon Sep 17 00:00:00 2001
-From: Mike Perry <mikeperry-git(a)fscked.org>
-Date: Sun, 9 Oct 2011 22:50:07 -0700
-Subject: [PATCH 07/24] Make Tor Browser exit when not launched from Vidalia
+From 5f9d3e18c44f8b25f34e68fb6b35b229d3561559 Mon Sep 17 00:00:00 2001
+From: Mike Perry <mikeperry-git(a)torproject.org>
+Date: Tue, 4 Dec 2012 16:29:24 -0800
+Subject: [PATCH 07/26] 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
@@ -12,35 +12,33 @@ https://trac.torproject.org/projects/tor/ticket/4192. We can do a better
localized fix w/ a translated alert menu later, if it seems like this might
actually be common.
---
- browser/base/content/browser.js | 15 +++++++++++++++
- 1 files changed, 15 insertions(+), 0 deletions(-)
+ browser/base/content/browser.js | 13 +++++++++++++
+ 1 files changed, 13 insertions(+), 0 deletions(-)
diff --git a/browser/base/content/browser.js b/browser/base/content/browser.js
-index f16a0c5..20e3666 100644
+index 80174dc..1fc137c 100644
--- a/browser/base/content/browser.js
+++ b/browser/base/content/browser.js
-@@ -1217,6 +1217,21 @@ function BrowserStartup() {
+@@ -1096,6 +1096,19 @@ var gBrowserInit = {
+ // setup simple gestures support
+ gGestureSupport.init(true);
- prepareForStartup();
++ // If this is not a TBB profile, exit.
++ // Solves https://trac.torproject.org/projects/tor/ticket/4192
++ var foundPref = false;
++ try {
++ foundPref = gPrefService.prefHasUserValue("torbrowser.version");
++ } catch(e) {
++ //dump("No pref: "+e);
++ }
++ if(!foundPref) {
++ var appStartup = Components.classes["@mozilla.org/toolkit/app-startup;1"]
++ .getService(Components.interfaces.nsIAppStartup);
++ appStartup.quit(3); // Force all windows to close, and then quit.
++ }
-+ // If this is not a TBB profile, exit.
-+ // Solves https://trac.torproject.org/projects/tor/ticket/4192
-+ var foundPref = false;
-+ try {
-+ foundPref = gPrefService.prefHasUserValue("torbrowser.version");
-+ } catch(e) {
-+ //dump("No pref: "+e);
-+ }
-+ if(!foundPref) {
-+ var appStartup = Components.classes["@mozilla.org/toolkit/app-startup;1"]
-+ .getService(Components.interfaces.nsIAppStartup);
-+ appStartup.quit(3); // Force all windows to close, and then quit.
-+ }
-+
-+
- if (uriToLoad && !isLoadingBlank) {
- if (uriToLoad instanceof Ci.nsISupportsArray) {
- let count = uriToLoad.Count();
+ 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
index 39e1483..9b3de6b 100644
--- a/src/current-patches/firefox/0008-Disable-SSL-Session-ID-tracking.patch
+++ b/src/current-patches/firefox/0008-Disable-SSL-Session-ID-tracking.patch
@@ -1,7 +1,7 @@
-From 7586e413761858ce705d25d4a1673e608a162bed Mon Sep 17 00:00:00 2001
+From 376f1f9b86d4b04e121d25553feed2c4380088d2 Mon Sep 17 00:00:00 2001
From: Mike Perry <mikeperry-git(a)fscked.org>
Date: Wed, 7 Dec 2011 19:36:38 -0800
-Subject: [PATCH 08/24] Disable SSL Session ID tracking.
+Subject: [PATCH 08/26] Disable SSL Session ID tracking.
We can't easily bind SSL Session ID tracking to url bar domain,
so we have to disable them to satisfy
diff --git a/src/current-patches/firefox/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
index e693c71..a366141 100644
--- 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
@@ -1,7 +1,7 @@
-From 9c6f997dd9a44336af9a1db17f5b680cc80a0e6c Mon Sep 17 00:00:00 2001
+From 74b6b99f7ac6e4a4153613feeafef53a5c3b9a4a Mon Sep 17 00:00:00 2001
From: Mike Perry <mikeperry-git(a)torproject.org>
-Date: Wed, 1 Feb 2012 15:53:28 -0800
-Subject: [PATCH 09/24] Provide an observer event to close persistent
+Date: Fri, 7 Sep 2012 16:18:26 -0700
+Subject: [PATCH 09/26] Provide an observer event to close persistent
connections
We need to prevent linkability across "New Identity", which includes closing
@@ -11,20 +11,20 @@ keep-alive connections.
1 files changed, 7 insertions(+), 0 deletions(-)
diff --git a/netwerk/protocol/http/nsHttpHandler.cpp b/netwerk/protocol/http/nsHttpHandler.cpp
-index 281d6ff..8125681 100644
+index d897a2c..e33ff08 100644
--- a/netwerk/protocol/http/nsHttpHandler.cpp
+++ b/netwerk/protocol/http/nsHttpHandler.cpp
-@@ -325,6 +325,7 @@ nsHttpHandler::Init()
+@@ -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", PR_TRUE);
++ mObserverService->AddObserver(this, "net:prune-all-connections", true);
+ mObserverService->AddObserver(this, "net:failed-to-process-uri-content", true);
}
- return NS_OK;
-@@ -1504,6 +1505,12 @@ nsHttpHandler::Observe(nsISupports *subject,
- mConnMgr->PruneDeadConnections();
- }
+@@ -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) {
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
index 14e584c..9e49285 100644
--- 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
@@ -1,17 +1,17 @@
-From 8f97f2f36adb9e4416f3d19af10880c800c846c2 Mon Sep 17 00:00:00 2001
+From 278e285820d9082d2be161fbdee6c230a4477204 Mon Sep 17 00:00:00 2001
From: Kathleen Brade <brade(a)pearlcrescent.com>
-Date: Thu, 4 Oct 2012 14:28:48 -0400
-Subject: [PATCH 10/24] Limit device and system specific CSS Media Queries.
+Date: Wed, 28 Nov 2012 09:49:40 -0500
+Subject: [PATCH 10/26] Limit device and system specific CSS Media Queries.
---
- layout/style/nsMediaFeatures.cpp | 71 ++++++++++++++++++++++++-------------
- 1 files changed, 46 insertions(+), 25 deletions(-)
+ 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 6eca06e..5b1df7e 100644
+index d5741ea..5f2e6dd 100644
--- a/layout/style/nsMediaFeatures.cpp
+++ b/layout/style/nsMediaFeatures.cpp
-@@ -130,6 +130,9 @@ GetDeviceContextFor(nsPresContext* aPresContext)
+@@ -98,6 +98,9 @@ GetDeviceContextFor(nsPresContext* aPresContext)
static nsSize
GetDeviceSize(nsPresContext* aPresContext)
{
@@ -21,7 +21,7 @@ index 6eca06e..5b1df7e 100644
nsSize size;
if (aPresContext->IsRootPaginatedDocument())
// We want the page size, including unprintable areas and margins.
-@@ -140,6 +143,7 @@ GetDeviceSize(nsPresContext* aPresContext)
+@@ -108,6 +111,7 @@ GetDeviceSize(nsPresContext* aPresContext)
GetDeviceContextFor(aPresContext)->
GetDeviceSurfaceDimensions(size.width, size.height);
return size;
@@ -29,36 +29,7 @@ index 6eca06e..5b1df7e 100644
}
static nsresult
-@@ -183,17 +187,17 @@ static nsresult
- GetDeviceOrientation(nsPresContext* aPresContext, const nsMediaFeature*,
- nsCSSValue& aResult)
- {
-- nsSize size = GetDeviceSize(aPresContext);
-- PRInt32 orientation;
-- if (size.width > size.height) {
-- orientation = NS_STYLE_ORIENTATION_LANDSCAPE;
-- } else {
-- // Per spec, square viewports should be 'portrait'
-- orientation = NS_STYLE_ORIENTATION_PORTRAIT;
-- }
--
-- aResult.SetIntValue(orientation, eCSSUnit_Enumerated);
-- return NS_OK;
-+ nsSize size = GetDeviceSize(aPresContext);
-+ PRInt32 orientation;
-+ if (size.width > size.height) {
-+ orientation = NS_STYLE_ORIENTATION_LANDSCAPE;
-+ } else {
-+ // Per spec, square viewports should be 'portrait'
-+ orientation = NS_STYLE_ORIENTATION_PORTRAIT;
-+ }
-+
-+ aResult.SetIntValue(orientation, eCSSUnit_Enumerated);
-+ return NS_OK;
- }
-
- static nsresult
-@@ -236,13 +240,17 @@ static nsresult
+@@ -204,13 +208,17 @@ static nsresult
GetColor(nsPresContext* aPresContext, const nsMediaFeature*,
nsCSSValue& aResult)
{
@@ -67,9 +38,9 @@ index 6eca06e..5b1df7e 100644
- // 424386).
- // FIXME: On a monochrome device, return 0!
- nsDeviceContext *dx = GetDeviceContextFor(aPresContext);
-- PRUint32 depth;
+- uint32_t depth;
- dx->GetDepth(depth);
-+ PRUint32 depth = 24; // Always return 24 to non-chrome callers.
++ uint32_t depth = 24; // Always return 24 to non-chrome callers.
+
+ if (aPresContext->IsChrome()) {
+ // FIXME: This implementation is bogus. nsDeviceContext
@@ -83,25 +54,42 @@ index 6eca06e..5b1df7e 100644
// 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.
-@@ -280,9 +288,14 @@ static nsresult
+@@ -248,18 +256,23 @@ static nsresult
GetResolution(nsPresContext* aPresContext, const nsMediaFeature*,
nsCSSValue& aResult)
{
-- // Resolution values are in device pixels, not CSS pixels.
-- nsDeviceContext *dx = GetDeviceContextFor(aPresContext);
-- float dpi = float(dx->AppUnitsPerPhysicalInch()) / float(dx->AppUnitsPerDevPixel());
+- // 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 values are in device pixels, not CSS pixels.
-+ nsDeviceContext *dx = GetDeviceContextFor(aPresContext);
-+ dpi = float(dx->AppUnitsPerPhysicalInch()) / float(dx->AppUnitsPerDevPixel());
++ // 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;
}
-@@ -311,8 +324,12 @@ static nsresult
+@@ -288,8 +301,12 @@ static nsresult
GetDevicePixelRatio(nsPresContext* aPresContext, const nsMediaFeature*,
nsCSSValue& aResult)
{
@@ -116,10 +104,11 @@ index 6eca06e..5b1df7e 100644
return NS_OK;
}
-@@ -320,18 +337,21 @@ static nsresult
+@@ -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");
@@ -135,16 +124,20 @@ index 6eca06e..5b1df7e 100644
GetWindowsTheme(nsPresContext* aPresContext, const nsMediaFeature* aFeature,
nsCSSValue& aResult)
{
-+ if (aPresContext->IsChrome()) {
- aResult.Reset();
+- aResult.Reset();
++ aResult.Reset();
#ifdef XP_WIN
- PRUint8 windowsThemeId =
-@@ -350,7 +370,8 @@ GetWindowsTheme(nsPresContext* aPresContext, const nsMediaFeature* aFeature,
++ 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;
}
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
index ff9e618..c6eb24f 100644
--- 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
@@ -1,7 +1,7 @@
-From cb3a6f45dd2c15d6b75084e1a4dded18ed638632 Mon Sep 17 00:00:00 2001
+From 9ae4f468446cd1edef028d2b60ccca91cad2bc2e Mon Sep 17 00:00:00 2001
From: Mike Perry <mikeperry-git(a)torproject.org>
-Date: Wed, 1 Feb 2012 16:01:21 -0800
-Subject: [PATCH 11/24] Limit the number of fonts per document.
+Date: Wed, 5 Dec 2012 12:25:21 -0800
+Subject: [PATCH 11/26] Limit the number of fonts per document.
We create two prefs:
browser.display.max_font_count and browser.display.max_font_attempts.
@@ -17,25 +17,39 @@ If a pref is not set or is negative, that limit does not apply.
This is done to address:
https://www.torproject.org/projects/torbrowser/design/#fingerprinting-linka…
---
+ gfx/thebes/gfxPangoFonts.cpp | 1 +
layout/base/nsPresContext.cpp | 100 +++++++++++++++++++++++++++++++++++++++++
layout/base/nsPresContext.h | 9 ++++
- layout/style/nsRuleNode.cpp | 13 ++++-
- 3 files changed, 119 insertions(+), 3 deletions(-)
+ layout/style/nsCSSParser.cpp | 1 +
+ layout/style/nsRuleNode.cpp | 14 +++++-
+ 5 files changed, 122 insertions(+), 3 deletions(-)
+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/layout/base/nsPresContext.cpp b/layout/base/nsPresContext.cpp
-index e1587db..9690d9c 100644
+index d47460a..8064fb4 100644
--- a/layout/base/nsPresContext.cpp
+++ b/layout/base/nsPresContext.cpp
-@@ -98,6 +98,8 @@
- #include "FrameLayerBuilder.h"
+@@ -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"
-@@ -706,6 +708,10 @@ nsPresContext::GetUserPreferences()
+@@ -712,6 +714,10 @@ nsPresContext::GetUserPreferences()
// * use fonts?
mUseDocumentFonts =
Preferences::GetInt("browser.display.use_document_fonts") != 0;
@@ -46,7 +60,7 @@ index e1587db..9690d9c 100644
// * replace backslashes with Yen signs? (bug 245770)
mEnableJapaneseTransform =
-@@ -1300,6 +1306,100 @@ nsPresContext::GetDefaultFont(PRUint8 aFontID) const
+@@ -1328,6 +1334,100 @@ nsPresContext::GetDefaultFont(uint8_t aFontID, nsIAtom *aLanguage) const
return font;
}
@@ -148,10 +162,10 @@ index e1587db..9690d9c 100644
nsPresContext::SetFullZoom(float aZoom)
{
diff --git a/layout/base/nsPresContext.h b/layout/base/nsPresContext.h
-index ecd01d8..552a69a 100644
+index 5f0f528..ffe4766 100644
--- a/layout/base/nsPresContext.h
+++ b/layout/base/nsPresContext.h
-@@ -548,6 +548,13 @@ public:
+@@ -467,6 +467,13 @@ public:
}
}
@@ -162,11 +176,11 @@ index ecd01d8..552a69a 100644
+ PRBool FontUseCountReached(const nsFont &font);
+ PRBool FontAttemptCountReached(const nsFont &font);
+
- PRInt32 MinFontSize() const {
- return NS_MAX(mMinFontSize, mMinimumFontSizePref);
- }
-@@ -1117,6 +1124,8 @@ protected:
- PRUint32 mInterruptChecksToSkip;
+ /**
+ * 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;
@@ -174,32 +188,49 @@ index ecd01d8..552a69a 100644
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/nsRuleNode.cpp b/layout/style/nsRuleNode.cpp
-index 27336bf..827585a 100644
+index 64504fb..33ce21e 100644
--- a/layout/style/nsRuleNode.cpp
+++ b/layout/style/nsRuleNode.cpp
-@@ -3091,6 +3091,7 @@ nsRuleNode::ComputeFontData(void* aStartStruct,
+@@ -2954,6 +2954,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 &&
+@@ -3439,14 +3440,15 @@ nsRuleNode::ComputeFontData(void* aStartStruct,
- // See if there is a minimum font-size constraint to honor
- nscoord minimumFontSize = mPresContext->MinFontSize();
-+ PRBool isXUL = PR_FALSE;
+ bool useDocumentFonts =
+ mPresContext->GetCachedBoolPref(kPresContext_UseDocumentFonts);
++ bool isXUL = PR_FALSE;
- if (minimumFontSize < 0)
- minimumFontSize = 0;
-@@ -3102,10 +3103,10 @@ nsRuleNode::ComputeFontData(void* aStartStruct,
+ // 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), or to
- // determine if we have to override the minimum font-size constraint.
-- if ((!useDocumentFonts || minimumFontSize > 0) && mPresContext->IsChrome()) {
+ // 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 = PR_TRUE;
- minimumFontSize = 0;
++ isXUL = true;
}
-@@ -3120,9 +3121,13 @@ nsRuleNode::ComputeFontData(void* aStartStruct,
+ // Figure out if we are a generic font
+@@ -3460,9 +3462,13 @@ nsRuleNode::ComputeFontData(void* aStartStruct,
// generic?
nsFont::GetGenericID(font->mFont.name, &generic);
@@ -214,8 +245,8 @@ index 27336bf..827585a 100644
// Extract the generic from the specified font family...
nsAutoString genericName;
if (!font->mFont.EnumerateFamilies(ExtractGeneric, &genericName)) {
-@@ -3158,6 +3163,8 @@ nsRuleNode::ComputeFontData(void* aStartStruct,
- minimumFontSize, font);
+@@ -3498,6 +3504,8 @@ nsRuleNode::ComputeFontData(void* aStartStruct,
+ font);
}
+ if (font->mGenericID == kGenericFont_NONE)
diff --git a/src/current-patches/firefox/0012-Rebrand-Firefox-to-TorBrowser.patch b/src/current-patches/firefox/0012-Rebrand-Firefox-to-TorBrowser.patch
index e627238..6fc03f6 100644
--- a/src/current-patches/firefox/0012-Rebrand-Firefox-to-TorBrowser.patch
+++ b/src/current-patches/firefox/0012-Rebrand-Firefox-to-TorBrowser.patch
@@ -1,7 +1,7 @@
-From 5820fc300fe1cae27752673e8721a19e70bf727c Mon Sep 17 00:00:00 2001
-From: Erinn Clark <erinn(a)torproject.org>
-Date: Wed, 25 Apr 2012 09:14:00 -0300
-Subject: [PATCH 12/24] Rebrand Firefox to TorBrowser
+From e0675863770a2a33fef70079a73233a9e78a3c48 Mon Sep 17 00:00:00 2001
+From: Mike Perry <mikeperry-git(a)torproject.org>
+Date: Tue, 28 Aug 2012 18:05:11 -0700
+Subject: [PATCH 12/26] 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.
@@ -12,18 +12,24 @@ branding is done by images and icons.
3 files changed, 7 insertions(+), 7 deletions(-)
diff --git a/browser/branding/official/configure.sh b/browser/branding/official/configure.sh
-index 4d3d297..e9b3738 100644
+index 55f3f18..33102b0 100644
--- a/browser/branding/official/configure.sh
+++ b/browser/branding/official/configure.sh
-@@ -1,2 +1,2 @@
+@@ -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 142d79b..c137e04 100644
+index 8e7f6c9..76e405d 100644
--- a/browser/branding/official/locales/en-US/brand.dtd
+++ b/browser/branding/official/locales/en-US/brand.dtd
-@@ -1,4 +1,4 @@
+@@ -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">
@@ -32,10 +38,13 @@ index 142d79b..c137e04 100644
+<!ENTITY vendorShortName "Tor Project">
<!ENTITY trademarkInfo.part1 "Firefox and the Firefox logos are trademarks of the Mozilla Foundation.">
diff --git a/browser/branding/official/locales/en-US/brand.properties b/browser/branding/official/locales/en-US/brand.properties
-index 5f3ad54..62ac2fd 100644
+index 4a67c55..9ae168e 100644
--- a/browser/branding/official/locales/en-US/brand.properties
+++ b/browser/branding/official/locales/en-US/brand.properties
-@@ -1,6 +1,6 @@
+@@ -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
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
index 1ad0972..f9f938f 100644
--- a/src/current-patches/firefox/0013-Make-Download-manager-memory-only.patch
+++ b/src/current-patches/firefox/0013-Make-Download-manager-memory-only.patch
@@ -1,7 +1,7 @@
-From 28178fb406d86b317b13b16ade3b06e5e1500c7e Mon Sep 17 00:00:00 2001
+From 2b0cc620b5d9af06262c9fdfc1ef8f34b5682859 Mon Sep 17 00:00:00 2001
From: Mike Perry <mikeperry-git(a)torproject.org>
-Date: Wed, 25 Apr 2012 13:39:35 -0700
-Subject: [PATCH 13/24] Make Download manager memory only.
+Date: Tue, 4 Dec 2012 16:05:55 -0800
+Subject: [PATCH 13/26] Make Download manager memory only.
Solves https://trac.torproject.org/projects/tor/ticket/4017.
@@ -18,10 +18,10 @@ this breaks enough times in conflict.
2 files changed, 3 insertions(+), 3 deletions(-)
diff --git a/toolkit/components/downloads/nsDownloadManager.cpp b/toolkit/components/downloads/nsDownloadManager.cpp
-index 00a6e7d..2e83f61 100644
+index 024686f..7845544 100644
--- a/toolkit/components/downloads/nsDownloadManager.cpp
+++ b/toolkit/components/downloads/nsDownloadManager.cpp
-@@ -1992,7 +1992,7 @@ nsDownloadManager::Observe(nsISupports *aSubject,
+@@ -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))
@@ -30,7 +30,7 @@ index 00a6e7d..2e83f61 100644
}
else if (strcmp(aTopic, "alertclickcallback") == 0) {
nsCOMPtr<nsIDownloadManagerUI> dmui =
-@@ -2069,7 +2069,7 @@ nsDownloadManager::OnLeavePrivateBrowsingMode()
+@@ -2079,7 +2079,7 @@ nsDownloadManager::OnLeavePrivateBrowsingMode()
(void)ResumeAllDownloads(false);
// Switch back to the on-disk DB again
@@ -40,10 +40,10 @@ index 00a6e7d..2e83f61 100644
mInPrivateBrowsing = false;
}
diff --git a/toolkit/components/downloads/nsDownloadManager.h b/toolkit/components/downloads/nsDownloadManager.h
-index 54312e4..cb63b52 100644
+index bbe7f39..6bdad89 100644
--- a/toolkit/components/downloads/nsDownloadManager.h
+++ b/toolkit/components/downloads/nsDownloadManager.h
-@@ -90,7 +90,7 @@ public:
+@@ -54,7 +54,7 @@ public:
virtual ~nsDownloadManager();
nsDownloadManager() :
@@ -51,7 +51,7 @@ index 54312e4..cb63b52 100644
+ mDBType(DATABASE_MEMORY)
, mInPrivateBrowsing(false)
#ifdef DOWNLOAD_SCANNER
- , mScanner(nsnull)
+ , 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
index adbd3d4..4cb626f 100644
--- 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
@@ -1,7 +1,7 @@
-From 2a80e84755c97cf4ff3ab63bda1bd5f0936d9594 Mon Sep 17 00:00:00 2001
+From a2de75def3f8ac88a5f5092ab9bd6815d088e7d5 Mon Sep 17 00:00:00 2001
From: Mike Perry <mikeperry-git(a)torproject.org>
Date: Wed, 25 Apr 2012 15:03:46 -0700
-Subject: [PATCH 14/24] Add DDG and StartPage to Omnibox.
+Subject: [PATCH 14/26] 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.
diff --git a/src/current-patches/firefox/0015-Make-nsICacheService.EvictEntries-synchronous.patch b/src/current-patches/firefox/0015-Make-nsICacheService.EvictEntries-synchronous.patch
index 93a989b..87547a7 100644
--- a/src/current-patches/firefox/0015-Make-nsICacheService.EvictEntries-synchronous.patch
+++ b/src/current-patches/firefox/0015-Make-nsICacheService.EvictEntries-synchronous.patch
@@ -1,36 +1,33 @@
-From 20c94cb890a8872c07ba13686e293ca147b85cd6 Mon Sep 17 00:00:00 2001
+From 0d030acc527aa206582e3f19219f4fa128f98bef Mon Sep 17 00:00:00 2001
From: Mike Perry <mikeperry-git(a)torproject.org>
-Date: Tue, 1 May 2012 15:02:03 -0700
-Subject: [PATCH 15/24] Make nsICacheService.EvictEntries synchronous
+Date: Tue, 4 Dec 2012 16:25:52 -0800
+Subject: [PATCH 15/26] Make nsICacheService.EvictEntries synchronous
This fixes a race condition that allows cache-based EverCookies to persist for
a brief time (on the order of minutes?) after cache clearing/"New Identity".
https://trac.torproject.org/projects/tor/ticket/5715
---
- netwerk/cache/nsCacheService.cpp | 15 +++++++++++++--
- 1 files changed, 13 insertions(+), 2 deletions(-)
+ netwerk/cache/nsCacheService.cpp | 14 +++++++++++++-
+ 1 files changed, 13 insertions(+), 1 deletions(-)
diff --git a/netwerk/cache/nsCacheService.cpp b/netwerk/cache/nsCacheService.cpp
-index 83ce887..e9f1a76 100644
+index e88de40..4225742 100644
--- a/netwerk/cache/nsCacheService.cpp
+++ b/netwerk/cache/nsCacheService.cpp
-@@ -1316,10 +1316,21 @@ NS_IMETHODIMP nsCacheService::VisitEntries(nsICacheVisitor *visitor)
- return NS_OK;
- }
+@@ -1555,7 +1555,19 @@ NS_IMETHODIMP nsCacheService::VisitEntries(nsICacheVisitor *visitor)
--
NS_IMETHODIMP nsCacheService::EvictEntries(nsCacheStoragePolicy storagePolicy)
{
-- return EvictEntriesForClient(nsnull, storagePolicy);
+- return EvictEntriesForClient(nullptr, storagePolicy);
+ NS_IMETHODIMP r;
-+ r = EvictEntriesForClient(nsnull, storagePolicy);
++ r = EvictEntriesForClient(nullptr, storagePolicy);
+
+ // XXX: Bloody hack until we get this notifier in FF14.0:
+ // https://developer.mozilla.org/en/XPCOM_Interface_Reference/nsICacheListener…
+ if (storagePolicy == nsICache::STORE_ANYWHERE &&
+ NS_IsMainThread() && gService && gService->mInitialized) {
-+ nsCacheServiceAutoLock lock;
++ nsCacheServiceAutoLock lock(LOCK_TELEM(NSCACHESERVICE_EVICTENTRIESFORCLIENT));
+ gService->DoomActiveEntries();
+ gService->ClearDoomList();
+ (void) SyncWithCacheIOThread();
diff --git a/src/current-patches/firefox/0016-Prevent-WebSocket-DNS-leak.patch b/src/current-patches/firefox/0016-Prevent-WebSocket-DNS-leak.patch
index bb70b17..ef61b59 100644
--- a/src/current-patches/firefox/0016-Prevent-WebSocket-DNS-leak.patch
+++ b/src/current-patches/firefox/0016-Prevent-WebSocket-DNS-leak.patch
@@ -1,7 +1,7 @@
-From 976f0d4fabb6b0b50c83192d622827357c761bd3 Mon Sep 17 00:00:00 2001
+From ac25d901493198966643d88d0541eaa2735b122f Mon Sep 17 00:00:00 2001
From: Mike Perry <mikeperry-git(a)torproject.org>
-Date: Wed, 2 May 2012 17:44:39 -0700
-Subject: [PATCH 16/24] Prevent WebSocket DNS leak.
+Date: Tue, 28 Aug 2012 18:07:37 -0700
+Subject: [PATCH 16/26] Prevent WebSocket DNS leak.
This is due to an improper implementation of the WebSocket spec by Mozilla.
@@ -29,10 +29,10 @@ bug can't turn up in other components or due to 3rd party addons.
3 files changed, 30 insertions(+), 3 deletions(-)
diff --git a/netwerk/dns/nsDNSService2.cpp b/netwerk/dns/nsDNSService2.cpp
-index 68ad8a5..1253b2f 100644
+index 114af2e..4d66dc5 100644
--- a/netwerk/dns/nsDNSService2.cpp
+++ b/netwerk/dns/nsDNSService2.cpp
-@@ -383,6 +383,7 @@ nsDNSService::Init()
+@@ -374,6 +374,7 @@ nsDNSService::Init()
bool enableIDN = true;
bool disableIPv6 = false;
bool disablePrefetch = false;
@@ -40,7 +40,7 @@ index 68ad8a5..1253b2f 100644
int proxyType = nsIProtocolProxyService::PROXYCONFIG_DIRECT;
nsAdoptingCString ipv4OnlyDomains;
-@@ -404,6 +405,10 @@ nsDNSService::Init()
+@@ -399,6 +400,10 @@ nsDNSService::Init()
// If a manual proxy is in use, disable prefetch implicitly
prefs->GetIntPref("network.proxy.type", &proxyType);
@@ -51,7 +51,7 @@ index 68ad8a5..1253b2f 100644
}
if (mFirstTime) {
-@@ -420,7 +425,7 @@ nsDNSService::Init()
+@@ -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
@@ -68,7 +68,7 @@ index 68ad8a5..1253b2f 100644
// Disable prefetching either by explicit preference or if a manual proxy is configured
mDisablePrefetch = disablePrefetch || (proxyType == nsIProtocolProxyService::PROXYCONFIG_MANUAL);
-@@ -547,6 +553,14 @@ nsDNSService::AsyncResolve(const nsACString &hostname,
+@@ -573,6 +579,14 @@ nsDNSService::AsyncResolve(const nsACString &hostname,
if (mDisablePrefetch && (flags & RESOLVE_SPECULATE))
return NS_ERROR_DNS_LOOKUP_QUEUE_FULL;
@@ -82,37 +82,38 @@ index 68ad8a5..1253b2f 100644
+
res = mResolver;
idn = mIDN;
- }
-@@ -597,6 +611,14 @@ nsDNSService::Resolve(const nsACString &hostname,
- MutexAutoLock lock(mLock);
- res = mResolver;
- idn = mIDN;
-+
-+ PRNetAddr tempAddr;
-+ if (mDisableDNS) {
-+ // Allow IP lookups through, but nothing else.
-+ if (PR_StringToNetAddr(hostname.BeginReading(), &tempAddr) != PR_SUCCESS) {
-+ return NS_ERROR_UNKNOWN_PROXY_HOST; // XXX: NS_ERROR_NOT_IMPLEMENTED?
-+ }
-+ }
+ 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 1749b41..3ec8eba 100644
+index 26d0939..c62c9dd 100644
--- a/netwerk/dns/nsDNSService2.h
+++ b/netwerk/dns/nsDNSService2.h
-@@ -70,4 +70,5 @@ private:
+@@ -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 9e446e9..42aa6ca 100644
+index 56a71ab..345df6e 100644
--- a/netwerk/protocol/websocket/WebSocketChannel.cpp
+++ b/netwerk/protocol/websocket/WebSocketChannel.cpp
-@@ -1698,8 +1698,12 @@ WebSocketChannel::ApplyForAdmission()
+@@ -2157,8 +2157,12 @@ WebSocketChannel::ApplyForAdmission()
LOG(("WebSocketChannel::ApplyForAdmission: checking for concurrent open\n"));
nsCOMPtr<nsIThread> mainThread;
NS_GetMainThread(getter_AddRefs(mainThread));
@@ -121,8 +122,8 @@ index 9e446e9..42aa6ca 100644
+ rv = dns->AsyncResolve(hostName, 0, this, mainThread, getter_AddRefs(mDNSRequest));
+ if (NS_FAILED(rv)) {
+ // Fall back to hostname on dispatch failure
-+ mDNSRequest = nsnull;
-+ OnLookupComplete(nsnull, nsnull, rv);
++ mDNSRequest = nullptr;
++ OnLookupComplete(nullptr, nullptr, rv);
+ }
return NS_OK;
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
index f1814e7..118c5d6 100644
--- 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
@@ -1,7 +1,7 @@
-From 36f826e64411a74912ba1adebd1a30b84716bf84 Mon Sep 17 00:00:00 2001
+From 53ec410990f8616d5c3cf3bfbb9feaa4a83ff722 Mon Sep 17 00:00:00 2001
From: Mike Perry <mikeperry-git(a)torproject.org>
-Date: Wed, 6 Jun 2012 11:08:56 -0700
-Subject: [PATCH 17/24] Randomize HTTP request order and pipeline depth.
+Date: Tue, 4 Dec 2012 17:38:51 -0800
+Subject: [PATCH 17/26] Randomize HTTP request order and pipeline depth.
This is an experimental defense against
http://lorre.uni.lu/~andriy/papers/acmccs-wpes11-fingerprinting.pdf
@@ -11,241 +11,149 @@ https://blog.torproject.org/blog/experimental-defense-website-traffic-finge…
This defense has been improved since that blog post to additionally randomize
the order and concurrency of non-pipelined HTTP requests.
+
+This patch is also different from the 10.x ESR patch, as the pipelining
+code has changed. We may want to set network.http.pipelining.aggressive to get
+similar behavior...
+
+The good news is we now randomize SPDY request order as well as pipeline
+request order (though SPDY is still disabled by default in TBB).
---
- netwerk/protocol/http/nsHttpConnectionMgr.cpp | 136 ++++++++++++++++++++++++-
- netwerk/protocol/http/nsHttpConnectionMgr.h | 5 +
- 2 files changed, 136 insertions(+), 5 deletions(-)
+ netwerk/protocol/http/nsHttpConnectionMgr.cpp | 67 +++++++++++++++++++++++--
+ netwerk/protocol/http/nsHttpConnectionMgr.h | 3 +
+ 2 files changed, 65 insertions(+), 5 deletions(-)
diff --git a/netwerk/protocol/http/nsHttpConnectionMgr.cpp b/netwerk/protocol/http/nsHttpConnectionMgr.cpp
-index 23ef893..788368f 100644
+index 526df93..abae041 100644
--- a/netwerk/protocol/http/nsHttpConnectionMgr.cpp
+++ b/netwerk/protocol/http/nsHttpConnectionMgr.cpp
-@@ -94,6 +94,12 @@ nsHttpConnectionMgr::nsHttpConnectionMgr()
- {
- LOG(("Creating nsHttpConnectionMgr @%x\n", this));
- mCT.Init();
+@@ -20,6 +20,8 @@
+ #include "prnetdb.h"
+ #include "mozilla/Telemetry.h"
+
++#include <stdlib.h>
+
-+ nsresult rv;
-+ mRandomGenerator = do_GetService("@mozilla.org/security/random-generator;1", &rv);
-+ if (NS_FAILED(rv)) {
-+ mRandomGenerator = nsnull;
-+ }
- }
+ using namespace mozilla;
+ using namespace mozilla::net;
- nsHttpConnectionMgr::~nsHttpConnectionMgr()
-@@ -342,8 +348,12 @@ nsHttpConnectionMgr::AddTransactionToPipeline(nsHttpPipeline *pipeline)
- nsConnectionEntry *ent = mCT.Get(ci->HashKey());
- if (ent) {
- // search for another request to pipeline...
-- PRInt32 i, count = ent->mPendingQ.Length();
-- for (i=0; i<count; ++i) {
-+ PRInt32 i, h, count = ent->mPendingQ.Length();
-+ PRInt32* ind = new PRInt32[count];
-+ ShuffleRequestOrder((PRUint32*)ind, (PRUint32)count);
-+
-+ for (h=0; h<count; ++h) {
-+ i = ind[h]; // random request sequence
- nsHttpTransaction *trans = ent->mPendingQ[i];
- if (trans->Caps() & NS_HTTP_ALLOW_PIPELINING) {
- pipeline->AddTransaction(trans);
-@@ -354,6 +364,8 @@ nsHttpConnectionMgr::AddTransactionToPipeline(nsHttpPipeline *pipeline)
- break;
- }
- }
+@@ -39,15 +41,46 @@ 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();
++ uint32_t begin = 0, end = len+1;
++ int found_begin = 0;
+
+- for (int32_t i=pendingQ.Length()-1; i>=0; --i) {
++ if (pendingQ.IsEmpty()) {
++ pendingQ.InsertElementAt(0, trans);
++ return;
++ }
+
-+ delete [] ind;
++// #define PRESERVE_PRIORITY_ORDER
++#ifdef PRESERVE_PRIORITY_ORDER
++ // XXX: Untested
++ for (uint32_t i=0; i < len; ++i) {
+ nsHttpTransaction *t = pendingQ[i];
+- if (trans->Priority() >= t->Priority()) {
+- pendingQ.InsertElementAt(i+1, trans);
+- return;
++
++ /* As soon as we see a priority >= us, our insertion
++ * range starts there */
++ if (!found_begin && t->Priority() >= trans->Priority()) {
++ begin = i;
++ found_begin = 1;
++ }
++ /* As soon as we see a priority > us, our insertion
++ * range ends there */
++ if (t->Priority() > trans->Priority()) {
++ end = i;
++ break;
}
}
+- pendingQ.InsertElementAt(0, trans);
++
++ // XXX Verify that begin..end are all == trans->Priority()
++#endif
++
++ // Choose random destination begin..end
++ uint32_t count = end - begin;
++ if (count == 0) count = 1;
++
++ // FIXME: rand() is not crypto-secure.. but meh, this code will probably
++ // change like 2 dozen more times before merge, and rand() is probably
++ // good enough for our purposes anyways.
++ pendingQ.InsertElementAt(begin + (rand()%count), trans);
}
-@@ -585,12 +597,17 @@ nsHttpConnectionMgr::ProcessPendingQForEntry(nsConnectionEntry *ent)
- LOG(("nsHttpConnectionMgr::ProcessPendingQForEntry [ci=%s]\n",
- ent->mConnInfo->HashKey().get()));
-- PRInt32 i, count = ent->mPendingQ.Length();
-+ PRUint32 h, i = 0, count = ent->mPendingQ.Length();
- if (count > 0) {
- LOG((" pending-count=%u\n", count));
- nsHttpTransaction *trans = nsnull;
- nsHttpConnection *conn = nsnull;
-- for (i=0; i<count; ++i) {
+ //-----------------------------------------------------------------------------
+@@ -68,6 +101,12 @@ nsHttpConnectionMgr::nsHttpConnectionMgr()
+ mCT.Init();
+ mAlternateProtocolHash.Init(16);
+ mSpdyPreferredHash.Init();
+
-+ PRUint32* ind = new PRUint32[count];
-+ ShuffleRequestOrder(ind, count);
-+
-+ for (h=0; h<count; ++h) {
-+ i = ind[h]; // random request sequence
- trans = ent->mPendingQ[i];
++ nsresult rv;
++ mRandomGenerator = do_GetService("@mozilla.org/security/random-generator;1", &rv);
++ if (NS_FAILED(rv)) {
++ mRandomGenerator = nullptr;
++ }
+ }
- // When this transaction has already established a half-open
-@@ -610,6 +627,7 @@ nsHttpConnectionMgr::ProcessPendingQForEntry(nsConnectionEntry *ent)
- if (conn)
- break;
- }
-+ delete [] ind;
- if (conn) {
- LOG((" dispatching pending transaction...\n"));
+ nsHttpConnectionMgr::~nsHttpConnectionMgr()
+@@ -1120,6 +1159,19 @@ nsHttpConnectionMgr::AtActiveConnectionLimit(nsConnectionEntry *ent, uint8_t cap
-@@ -694,6 +712,19 @@ nsHttpConnectionMgr::AtActiveConnectionLimit(nsConnectionEntry *ent, PRUint8 cap
- maxPersistConns = mMaxPersistConnsPerHost;
- }
+ LOG((" connection count = %d, limit %d\n", totalCount, maxPersistConns));
+ // Fuzz maxConns for website fingerprinting attack
+ // We create a range of maxConns/5 up to 6*maxConns/5
+ // because this function is called repeatedly, and we'll
-+ // end up converging to the high side of concurrent connections
++ // end up converging on the high side of concurrent connections
+ // after a short while.
-+ PRUint8 *bytes = nsnull;
++ PRUint8 *bytes = nullptr;
+ nsresult rv = mRandomGenerator->GenerateRandomBytes(1, &bytes);
+ NS_ENSURE_SUCCESS(rv, rv);
+
-+ bytes[0] = bytes[0] % (maxConns + 1);
-+ maxConns = (maxConns/5) + bytes[0];
++ bytes[0] = bytes[0] % (maxPersistConns + 1);
++ maxPersistConns = (maxPersistConns/5) + bytes[0];
+ NS_Free(bytes);
+
// use >= just to be safe
- return (totalCount >= maxConns) || ( (caps & NS_HTTP_ALLOW_KEEPALIVE) &&
- (persistCount >= maxPersistConns) );
-@@ -865,7 +896,7 @@ nsHttpConnectionMgr::DispatchTransaction(nsConnectionEntry *ent,
- nsHttpPipeline *pipeline = nsnull;
- if (conn->SupportsPipelining() && (caps & NS_HTTP_ALLOW_PIPELINING)) {
- LOG((" looking to build pipeline...\n"));
-- if (BuildPipeline(ent, trans, &pipeline))
-+ if (BuildRandomizedPipeline(ent, trans, &pipeline))
- trans = pipeline;
- }
+ bool result = (totalCount >= maxPersistConns);
+ LOG((" result: %s", result ? "true" : "false"));
+@@ -1297,6 +1349,11 @@ nsHttpConnectionMgr::AddToShortestPipeline(nsConnectionEntry *ent,
-@@ -938,6 +969,101 @@ nsHttpConnectionMgr::BuildPipeline(nsConnectionEntry *ent,
- return true;
- }
+ maxdepth = PR_MIN(maxdepth, depthLimit);
-+
-+// Generate a shuffled request ordering sequence
-+void
-+nsHttpConnectionMgr::ShuffleRequestOrder(PRUint32 *ind, PRUint32 count)
-+{
-+ PRUint32 i;
-+ PRUint32 *rints;
-+
-+ for (i=0; i<count; ++i) {
-+ ind[i] = i;
-+ }
-+ nsresult rv = mRandomGenerator->GenerateRandomBytes(sizeof(PRUint32)*count,
-+ (PRUint8**)&rints);
-+ if (NS_FAILED(rv))
-+ return; // Leave unshuffled if error
-+
-+ for (i=0; i < count; ++i) {
-+ PRInt32 temp = ind[i];
-+ ind[i] = ind[rints[i]%count];
-+ ind[rints[i]%count] = temp;
-+ }
-+ NS_Free(rints);
-+}
-+
-+bool
-+nsHttpConnectionMgr::BuildRandomizedPipeline(nsConnectionEntry *ent,
-+ nsAHttpTransaction *firstTrans,
-+ nsHttpPipeline **result)
-+{
-+ if (mRandomGenerator == nsnull)
-+ return BuildPipeline(ent, firstTrans, result);
-+ if (mMaxPipelinedRequests < 2)
-+ return PR_FALSE;
-+
-+ nsresult rv;
-+ PRUint8 *bytes = nsnull;
-+
-+ nsHttpPipeline *pipeline = nsnull;
-+ nsHttpTransaction *trans;
-+
-+ PRUint32 i = 0, numAdded = 0, numAllowed = 0;
-+ PRUint32 max = 0;
-+
-+ while (i < ent->mPendingQ.Length()) {
-+ if (ent->mPendingQ[i]->Caps() & NS_HTTP_ALLOW_PIPELINING)
-+ numAllowed++;
-+ i++;
++ if (maxdepth/2 > 1) {
++ // This is a crazy hack to randomize pipeline depth a bit more..
++ maxdepth = 1 + maxdepth/2 + (rand() % (maxdepth/2));
+ }
+
-+ rv = mRandomGenerator->GenerateRandomBytes(1, &bytes);
-+ NS_ENSURE_SUCCESS(rv, rv);
-+ // 4...12
-+ max = 4 + (bytes[0] % (mMaxPipelinedRequests + 1));
-+ NS_Free(bytes);
-+
-+ while (numAllowed > 0) {
-+ rv = mRandomGenerator->GenerateRandomBytes(1, &bytes);
-+ NS_ENSURE_SUCCESS(rv, rv);
-+ i = bytes[0] % ent->mPendingQ.Length();
-+ NS_Free(bytes);
-+
-+ trans = ent->mPendingQ[i];
-+
-+ if (!(ent->mPendingQ[i]->Caps() & NS_HTTP_ALLOW_PIPELINING))
-+ continue;
-+
-+ if (numAdded == 0) {
-+ pipeline = new nsHttpPipeline;
-+ if (!pipeline)
-+ return PR_FALSE;
-+ pipeline->AddTransaction(firstTrans);
-+ numAdded = 1;
-+ }
-+ pipeline->AddTransaction(trans);
-+
-+ // remove transaction from pending queue
-+ ent->mPendingQ.RemoveElementAt(i);
-+ NS_RELEASE(trans);
-+
-+ numAllowed--;
-+
-+ if (++numAdded == max)
-+ break;
-+ }
-+
-+ //fprintf(stderr, "Yay!!! pipelined %u/%u transactions\n", numAdded, max);
-+ LOG((" pipelined %u/%u transactions\n", numAdded, max));
-+
-+ if (numAdded == 0)
-+ return PR_FALSE;
-+
-+ NS_ADDREF(*result = pipeline);
-+ return PR_TRUE;
-+}
-+
- nsresult
- nsHttpConnectionMgr::ProcessNewTransaction(nsHttpTransaction *trans)
- {
+ if (maxdepth < 2)
+ return false;
+
diff --git a/netwerk/protocol/http/nsHttpConnectionMgr.h b/netwerk/protocol/http/nsHttpConnectionMgr.h
-index cdf21a9..81b282a 100644
+index 580710a..b22c669 100644
--- a/netwerk/protocol/http/nsHttpConnectionMgr.h
+++ b/netwerk/protocol/http/nsHttpConnectionMgr.h
-@@ -51,6 +51,7 @@
-
+@@ -23,6 +23,7 @@
#include "nsIObserver.h"
#include "nsITimer.h"
+ #include "nsIX509Cert3.h"
+#include "nsIRandomGenerator.h"
class nsHttpPipeline;
-@@ -276,6 +277,8 @@ private:
- nsresult DispatchTransaction(nsConnectionEntry *, nsAHttpTransaction *,
- PRUint8 caps, nsHttpConnection *);
- bool BuildPipeline(nsConnectionEntry *, nsAHttpTransaction *, nsHttpPipeline **);
-+ bool BuildRandomizedPipeline(nsConnectionEntry *, nsAHttpTransaction *, nsHttpPipeline **);
-+ void ShuffleRequestOrder(PRUint32 *, PRUint32);
- nsresult ProcessNewTransaction(nsHttpTransaction *);
- nsresult EnsureSocketThreadTargetIfOnline();
- void ClosePersistentConnections(nsConnectionEntry *ent);
-@@ -353,6 +356,8 @@ private:
- PRUint64 mTimeOfNextWakeUp;
+@@ -585,6 +586,8 @@ private:
+ uint64_t mTimeOfNextWakeUp;
// Timer for next pruning of dead connections.
nsCOMPtr<nsITimer> mTimer;
+ // Random number generator for reordering HTTP pipeline
+ nsCOMPtr<nsIRandomGenerator> mRandomGenerator;
- //
- // the connection table
+ // A 1s tick to call nsHttpConnection::ReadTimeoutTick on
+ // active http/1 connections and check for orphaned half opens.
--
1.7.5.4
diff --git a/src/current-patches/firefox/0018-Adapt-Steven-Michaud-s-Mac-crashfix-patch.patch b/src/current-patches/firefox/0018-Adapt-Steven-Michaud-s-Mac-crashfix-patch.patch
new file mode 100644
index 0000000..7c2ddee
--- /dev/null
+++ b/src/current-patches/firefox/0018-Adapt-Steven-Michaud-s-Mac-crashfix-patch.patch
@@ -0,0 +1,545 @@
+From 4541bfb12c40ed13871503f7bb46ba8e5f27a8ed Mon Sep 17 00:00:00 2001
+From: Mike Perry <mikeperry-git(a)torproject.org>
+Date: Tue, 4 Dec 2012 17:48:53 -0800
+Subject: [PATCH 18/26] Adapt Steven Michaud's Mac crashfix patch
+
+Source is: https://bugzilla.mozilla.org/show_bug.cgi?id=715885#c35
+
+Some minor tweaks were needed to get it to apply and to compile on
+MacOS.
+---
+ widget/Makefile.in | 1 +
+ widget/cocoa/nsChildView.mm | 28 +++++++++++------
+ widget/gtk2/nsDragService.cpp | 9 +++--
+ widget/nsIDragService.idl | 4 +--
+ widget/nsPIDragService.idl | 48 +++++++++++++++++++++++++++++
+ widget/qt/nsDragService.h | 2 +
+ widget/windows/Makefile.in | 4 ++
+ widget/windows/nsDragService.cpp | 13 +++++---
+ widget/windows/nsDragService.h | 12 +++---
+ widget/windows/nsNativeDragSource.cpp | 7 ++--
+ widget/windows/nsNativeDragTarget.cpp | 28 ++++++++++------
+ widget/windows/nsPIDragServiceWindows.idl | 46 +++++++++++++++++++++++++++
+ widget/xpwidgets/nsBaseDragService.cpp | 16 +++++++++-
+ widget/xpwidgets/nsBaseDragService.h | 9 ++---
+ 14 files changed, 179 insertions(+), 48 deletions(-)
+ create mode 100644 widget/nsPIDragService.idl
+ create mode 100644 widget/windows/nsPIDragServiceWindows.idl
+
+diff --git a/widget/Makefile.in b/widget/Makefile.in
+index 4ab8a48..bc5aa5c 100644
+--- a/widget/Makefile.in
++++ b/widget/Makefile.in
+@@ -106,6 +106,7 @@ XPIDLSRCS = \
+ nsIClipboardDragDropHooks.idl \
+ nsIClipboardDragDropHookList.idl \
+ nsIDragSession.idl \
++ nsPIDragService.idl \
+ nsIDragService.idl \
+ nsIFormatConverter.idl \
+ nsIClipboard.idl \
+diff --git a/widget/cocoa/nsChildView.mm b/widget/cocoa/nsChildView.mm
+index aa919fa..d5fa58f 100644
+--- a/widget/cocoa/nsChildView.mm
++++ b/widget/cocoa/nsChildView.mm
+@@ -4518,11 +4518,12 @@ static int32_t RoundUp(double aDouble)
+ if (!dragService) {
+ dragService = do_GetService(kDragServiceContractID);
+ }
++ nsCOMPtr<nsPIDragService> dragServicePriv = do_QueryInterface(dragService);
+
+ if (dragService) {
+ NSPoint pnt = [NSEvent mouseLocation];
+ FlipCocoaScreenCoordinate(pnt);
+- dragService->DragMoved(NSToIntRound(pnt.x), NSToIntRound(pnt.y));
++ dragServicePriv->DragMoved(NSToIntRound(pnt.x), NSToIntRound(pnt.y));
+ }
+ }
+
+@@ -4543,11 +4544,13 @@ static int32_t RoundUp(double aDouble)
+ }
+
+ if (mDragService) {
+- // set the dragend point from the current mouse location
+- nsDragService* dragService = static_cast<nsDragService *>(mDragService);
+- NSPoint pnt = [NSEvent mouseLocation];
+- FlipCocoaScreenCoordinate(pnt);
+- dragService->SetDragEndPoint(nsIntPoint(NSToIntRound(pnt.x), NSToIntRound(pnt.y)));
++ nsCOMPtr<nsPIDragService> dragServicePriv = do_QueryInterface(mDragService);
++ if (dragServicePriv) {
++ // set the dragend point from the current mouse location
++ NSPoint pnt = [NSEvent mouseLocation];
++ FlipCocoaScreenCoordinate(pnt);
++ dragServicePriv->SetDragEndPoint(NSToIntRound(pnt.x), NSToIntRound(pnt.y));
++ }
+
+ // XXX: dropEffect should be updated per |operation|.
+ // As things stand though, |operation| isn't well handled within "our"
+@@ -4558,10 +4561,15 @@ static int32_t RoundUp(double aDouble)
+ // value for NSDragOperationGeneric that is passed by other applications.
+ // All that said, NSDragOperationNone is still reliable.
+ if (operation == NSDragOperationNone) {
+- nsCOMPtr<nsIDOMDataTransfer> dataTransfer;
+- dragService->GetDataTransfer(getter_AddRefs(dataTransfer));
+- if (dataTransfer)
+- dataTransfer->SetDropEffectInt(nsIDragService::DRAGDROP_ACTION_NONE);
++ nsCOMPtr<nsIDragSession> dragSession;
++ mDragService->GetCurrentSession(getter_AddRefs(dragSession));
++ if (dragSession) {
++ nsCOMPtr<nsIDOMDataTransfer> dataTransfer;
++ dragSession->GetDataTransfer(getter_AddRefs(dataTransfer));
++ if (dataTransfer) {
++ dataTransfer->SetDropEffectInt(nsIDragService::DRAGDROP_ACTION_NONE);
++ }
++ }
+ }
+
+ mDragService->EndDragSession(true);
+diff --git a/widget/gtk2/nsDragService.cpp b/widget/gtk2/nsDragService.cpp
+index 10985cc..bac4160 100644
+--- a/widget/gtk2/nsDragService.cpp
++++ b/widget/gtk2/nsDragService.cpp
+@@ -234,8 +234,8 @@ OnSourceGrabEventAfter(GtkWidget *widget, GdkEvent *event, gpointer user_data)
+ // Update the cursor position. The last of these recorded gets used for
+ // the NS_DRAGDROP_END event.
+ nsDragService *dragService = static_cast<nsDragService*>(user_data);
+- dragService->SetDragEndPoint(nsIntPoint(event->motion.x_root,
+- event->motion.y_root));
++ dragService->SetDragEndPoint(event->motion.x_root,
++ event->motion.y_root);
+ } else if (sMotionEvent && (event->type != GDK_KEY_PRESS ||
+ event->type != GDK_KEY_RELEASE)) {
+ // Update modifier state from keypress events.
+@@ -1343,7 +1343,7 @@ nsDragService::SourceEndDragSession(GdkDragContext *aContext,
+ GdkDisplay* display = gdk_display_get_default();
+ if (display) {
+ gdk_display_get_pointer(display, NULL, &x, &y, NULL);
+- SetDragEndPoint(nsIntPoint(x, y));
++ SetDragEndPoint(x, y);
+ }
+ }
+
+@@ -1760,8 +1760,9 @@ nsDragService::ScheduleDropEvent(nsWindow *aWindow,
+ NS_WARNING("Additional drag drop ignored");
+ return FALSE;
+ }
++ nsIntPoint pt = aWindowPoint + aWindow->WidgetToScreenOffset();
+
+- SetDragEndPoint(aWindowPoint + aWindow->WidgetToScreenOffset());
++ SetDragEndPoint(pt.x, pt.y);
+
+ // We'll reply with gtk_drag_finish().
+ return TRUE;
+diff --git a/widget/nsIDragService.idl b/widget/nsIDragService.idl
+index 196761e..c0565bb 100644
+--- a/widget/nsIDragService.idl
++++ b/widget/nsIDragService.idl
+@@ -15,7 +15,7 @@ interface nsIDOMDragEvent;
+ interface nsIDOMDataTransfer;
+ interface nsISelection;
+
+-[scriptable, uuid(82B58ADA-F490-4C3D-B737-1057C4F1D052), builtinclass]
++[scriptable, uuid(82B58ADA-F490-4C3D-B737-1057C4F1D052)]
+ interface nsIDragService : nsISupports
+ {
+ const long DRAGDROP_ACTION_NONE = 0;
+@@ -112,8 +112,6 @@ interface nsIDragService : nsISupports
+ */
+ void suppress();
+ void unsuppress();
+-
+- [noscript] void dragMoved(in long aX, in long aY);
+ };
+
+
+diff --git a/widget/nsPIDragService.idl b/widget/nsPIDragService.idl
+new file mode 100644
+index 0000000..7a703c1
+--- /dev/null
++++ b/widget/nsPIDragService.idl
+@@ -0,0 +1,48 @@
++/* ***** BEGIN LICENSE BLOCK *****
++ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
++ *
++ * The contents of this file are subject to the Mozilla Public License Version
++ * 1.1 (the "License"); you may not use this file except in compliance with
++ * the License. You may obtain a copy of the License at
++ * http://www.mozilla.org/MPL/
++ *
++ * Software distributed under the License is distributed on an "AS IS" basis,
++ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
++ * for the specific language governing rights and limitations under the
++ * License.
++ *
++ * The Original Code is mozilla.org code.
++ *
++ * The Initial Developer of the Original Code is
++ * The Mozilla Foundation.
++ * Portions created by the Initial Developer are Copyright (C) 2012
++ * the Initial Developer. All Rights Reserved.
++ *
++ * Contributor(s):
++ * Steven Michaud <smichaud(a)pobox.com>
++ *
++ * Alternatively, the contents of this file may be used under the terms of
++ * either the GNU General Public License Version 2 or later (the "GPL"), or
++ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
++ * in which case the provisions of the GPL or the LGPL are applicable instead
++ * of those above. If you wish to allow use of your version of this file only
++ * under the terms of either the GPL or the LGPL, and not to allow others to
++ * use your version of this file under the terms of the MPL, indicate your
++ * decision by deleting the provisions above and replace them with the notice
++ * and other provisions required by the GPL or the LGPL. If you do not delete
++ * the provisions above, a recipient may use your version of this file under
++ * the terms of any one of the MPL, the GPL or the LGPL.
++ *
++ * ***** END LICENSE BLOCK ***** */
++
++#include "nsISupports.idl"
++
++[scriptable, uuid(FAD8C90B-8E1D-446A-9B6C-241486A85CBD)]
++interface nsPIDragService : nsISupports
++{
++ void dragMoved(in long aX, in long aY);
++
++ uint16_t getInputSource();
++
++ void setDragEndPoint(in long aX, in long aY);
++};
+diff --git a/widget/qt/nsDragService.h b/widget/qt/nsDragService.h
+index ee145ad..b03b74e 100644
+--- a/widget/qt/nsDragService.h
++++ b/widget/qt/nsDragService.h
+@@ -17,6 +17,8 @@ public:
+ NS_DECL_ISUPPORTS
+ NS_DECL_NSIDRAGSERVICE
+
++ NS_IMETHOD DragMoved(PRInt32 aX, PRInt32 aY);
++
+ nsDragService();
+
+ private:
+diff --git a/widget/windows/Makefile.in b/widget/windows/Makefile.in
+index ec383bd..7000ec0 100644
+--- a/widget/windows/Makefile.in
++++ b/widget/windows/Makefile.in
+@@ -88,6 +88,10 @@ ifdef MOZ_ENABLE_D3D10_LAYER
+ DEFINES += -DMOZ_ENABLE_D3D10_LAYER
+ endif
+
++XPIDLSRCS += \
++ nsPIDragServiceWindows.idl \
++ $(NULL)
++
+ SHARED_LIBRARY_LIBS = \
+ ../xpwidgets/$(LIB_PREFIX)xpwidgets_s.$(LIB_SUFFIX) \
+ $(NULL)
+diff --git a/widget/windows/nsDragService.cpp b/widget/windows/nsDragService.cpp
+index 899154a..9511457 100644
+--- a/widget/windows/nsDragService.cpp
++++ b/widget/windows/nsDragService.cpp
+@@ -60,6 +60,8 @@ nsDragService::~nsDragService()
+ NS_IF_RELEASE(mDataObject);
+ }
+
++NS_IMPL_ISUPPORTS_INHERITED1(nsDragService, nsBaseDragService, nsPIDragServiceWindows)
++
+ bool
+ nsDragService::CreateDragImage(nsIDOMNode *aDOMNode,
+ nsIScriptableRegion *aRegion,
+@@ -305,7 +307,7 @@ nsDragService::StartInvokingDragSession(IDataObject * aDataObj,
+ POINT cpos;
+ cpos.x = GET_X_LPARAM(pos);
+ cpos.y = GET_Y_LPARAM(pos);
+- SetDragEndPoint(nsIntPoint(cpos.x, cpos.y));
++ SetDragEndPoint(cpos.x, cpos.y);
+ EndDragSession(true);
+
+ mDoingDrag = false;
+@@ -426,25 +428,26 @@ nsDragService::GetData(nsITransferable * aTransferable, uint32_t anItem)
+
+ //---------------------------------------------------------
+ NS_IMETHODIMP
+-nsDragService::SetIDataObject(IDataObject * aDataObj)
++nsDragService::SetIDataObject(nsISupports * aDataObj)
+ {
++ IDataObject *dataObj = (IDataObject*) aDataObj;
+ // When the native drag starts the DragService gets
+ // the IDataObject that is being dragged
+ NS_IF_RELEASE(mDataObject);
+- mDataObject = aDataObj;
++ mDataObject = dataObj;
+ NS_IF_ADDREF(mDataObject);
+
+ return NS_OK;
+ }
+
+ //---------------------------------------------------------
+-void
++NS_IMETHODIMP
+ nsDragService::SetDroppedLocal()
+ {
+ // Sent from the native drag handler, letting us know
+ // a drop occurred within the application vs. outside of it.
+ mSentLocalDropEvent = true;
+- return;
++ return NS_OK;
+ }
+
+ //-------------------------------------------------------------------------
+diff --git a/widget/windows/nsDragService.h b/widget/windows/nsDragService.h
+index 236910a..e83167d 100644
+--- a/widget/windows/nsDragService.h
++++ b/widget/windows/nsDragService.h
+@@ -7,6 +7,7 @@
+ #define nsDragService_h__
+
+ #include "nsBaseDragService.h"
++#include "nsPIDragServiceWindows.h"
+ #include <windows.h>
+ #include <shlobj.h>
+
+@@ -20,12 +21,15 @@ class nsString;
+ * Native Win32 DragService wrapper
+ */
+
+-class nsDragService : public nsBaseDragService
++class nsDragService : public nsBaseDragService, public nsPIDragServiceWindows
+ {
+ public:
+ nsDragService();
+ virtual ~nsDragService();
+-
++
++ NS_DECL_ISUPPORTS_INHERITED
++ NS_DECL_NSPIDRAGSERVICEWINDOWS
++
+ // nsIDragService
+ NS_IMETHOD InvokeDragSession(nsIDOMNode *aDOMNode,
+ nsISupportsArray *anArrayTransferables,
+@@ -39,13 +43,9 @@ public:
+ NS_IMETHOD EndDragSession(bool aDoneDrag);
+
+ // native impl.
+- NS_IMETHOD SetIDataObject(IDataObject * aDataObj);
+ NS_IMETHOD StartInvokingDragSession(IDataObject * aDataObj,
+ uint32_t aActionType);
+
+- // A drop occurred within the application vs. outside of it.
+- void SetDroppedLocal();
+-
+ protected:
+ nsDataObjCollection* GetDataObjCollection(IDataObject * aDataObj);
+
+diff --git a/widget/windows/nsNativeDragSource.cpp b/widget/windows/nsNativeDragSource.cpp
+index 3acee30..3662c18 100644
+--- a/widget/windows/nsNativeDragSource.cpp
++++ b/widget/windows/nsNativeDragSource.cpp
+@@ -10,7 +10,7 @@
+ #include "nsIServiceManager.h"
+ #include "nsToolkit.h"
+ #include "nsWidgetsCID.h"
+-#include "nsIDragService.h"
++#include "nsDragService.h"
+
+ static NS_DEFINE_IID(kCDragServiceCID, NS_DRAGSERVICE_CID);
+
+@@ -69,9 +69,10 @@ STDMETHODIMP
+ nsNativeDragSource::QueryContinueDrag(BOOL fEsc, DWORD grfKeyState)
+ {
+ nsCOMPtr<nsIDragService> dragService = do_GetService(kCDragServiceCID);
+- if (dragService) {
++ nsCOMPtr<nsPIDragService> dragServicePriv = do_QueryInterface(dragService);
++ if (dragServicePriv) {
+ DWORD pos = ::GetMessagePos();
+- dragService->DragMoved(GET_X_LPARAM(pos), GET_Y_LPARAM(pos));
++ dragServicePriv->DragMoved(GET_X_LPARAM(pos), GET_Y_LPARAM(pos));
+ }
+
+ if (fEsc) {
+diff --git a/widget/windows/nsNativeDragTarget.cpp b/widget/windows/nsNativeDragTarget.cpp
+index ec12f8e..8b72f6d 100644
+--- a/widget/windows/nsNativeDragTarget.cpp
++++ b/widget/windows/nsNativeDragTarget.cpp
+@@ -174,7 +174,11 @@ nsNativeDragTarget::DispatchDragDropEvent(uint32_t aEventType, POINTL aPT)
+ ModifierKeyState modifierKeyState;
+ modifierKeyState.InitInputEvent(event);
+
+- event.inputSource = static_cast<nsBaseDragService*>(mDragService)->GetInputSource();
++ event.inputSource = 0;
++ nsCOMPtr<nsPIDragService> dragServicePriv = do_QueryInterface(mDragService);
++ if (dragServicePriv) {
++ dragServicePriv->GetInputSource(&event.inputSource);
++ }
+
+ mWidget->DispatchEvent(&event, status);
+ }
+@@ -261,9 +265,8 @@ nsNativeDragTarget::DragEnter(LPDATAOBJECT pIDataSource,
+ // This cast is ok because in the constructor we created a
+ // the actual implementation we wanted, so we know this is
+ // a nsDragService. It should be a private interface, though.
+- nsDragService * winDragService =
+- static_cast<nsDragService *>(mDragService);
+- winDragService->SetIDataObject(pIDataSource);
++ nsCOMPtr<nsPIDragServiceWindows> winDragService = do_QueryInterface(mDragService);
++ winDragService->SetIDataObject((nsISupports*)pIDataSource);
+
+ // Now process the native drag state and then dispatch the event
+ ProcessDrag(NS_DRAGDROP_ENTER, grfKeyState, ptl, pdwEffect);
+@@ -401,8 +404,8 @@ nsNativeDragTarget::Drop(LPDATAOBJECT pData,
+ // This cast is ok because in the constructor we created a
+ // the actual implementation we wanted, so we know this is
+ // a nsDragService (but it should still be a private interface)
+- nsDragService* winDragService = static_cast<nsDragService*>(mDragService);
+- winDragService->SetIDataObject(pData);
++ nsCOMPtr<nsPIDragServiceWindows> winDragService = do_QueryInterface(mDragService);
++ winDragService->SetIDataObject((nsISupports*)pData);
+
+ // NOTE: ProcessDrag spins the event loop which may destroy arbitrary objects.
+ // We use strong refs to prevent it from destroying these:
+@@ -426,11 +429,14 @@ nsNativeDragTarget::Drop(LPDATAOBJECT pData,
+ // tell the drag service we're done with the session
+ // Use GetMessagePos to get the position of the mouse at the last message
+ // seen by the event loop. (Bug 489729)
+- DWORD pos = ::GetMessagePos();
+- POINT cpos;
+- cpos.x = GET_X_LPARAM(pos);
+- cpos.y = GET_Y_LPARAM(pos);
+- winDragService->SetDragEndPoint(nsIntPoint(cpos.x, cpos.y));
++ nsCOMPtr<nsPIDragService> dragServicePriv = do_QueryInterface(mDragService);
++ if (dragServicePriv) {
++ DWORD pos = ::GetMessagePos();
++ POINT cpos;
++ cpos.x = GET_X_LPARAM(pos);
++ cpos.y = GET_Y_LPARAM(pos);
++ dragServicePriv->SetDragEndPoint(cpos.x, cpos.y);
++ }
+ serv->EndDragSession(true);
+
+ // release the ref that was taken in DragEnter
+diff --git a/widget/windows/nsPIDragServiceWindows.idl b/widget/windows/nsPIDragServiceWindows.idl
+new file mode 100644
+index 0000000..c8a46dd
+--- /dev/null
++++ b/widget/windows/nsPIDragServiceWindows.idl
+@@ -0,0 +1,46 @@
++/* ***** BEGIN LICENSE BLOCK *****
++ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
++ *
++ * The contents of this file are subject to the Mozilla Public License Version
++ * 1.1 (the "License"); you may not use this file except in compliance with
++ * the License. You may obtain a copy of the License at
++ * http://www.mozilla.org/MPL/
++ *
++ * Software distributed under the License is distributed on an "AS IS" basis,
++ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
++ * for the specific language governing rights and limitations under the
++ * License.
++ *
++ * The Original Code is mozilla.org code.
++ *
++ * The Initial Developer of the Original Code is
++ * The Mozilla Foundation.
++ * Portions created by the Initial Developer are Copyright (C) 2012
++ * the Initial Developer. All Rights Reserved.
++ *
++ * Contributor(s):
++ * Steven Michaud <smichaud(a)pobox.com>
++ *
++ * Alternatively, the contents of this file may be used under the terms of
++ * either the GNU General Public License Version 2 or later (the "GPL"), or
++ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
++ * in which case the provisions of the GPL or the LGPL are applicable instead
++ * of those above. If you wish to allow use of your version of this file only
++ * under the terms of either the GPL or the LGPL, and not to allow others to
++ * use your version of this file under the terms of the MPL, indicate your
++ * decision by deleting the provisions above and replace them with the notice
++ * and other provisions required by the GPL or the LGPL. If you do not delete
++ * the provisions above, a recipient may use your version of this file under
++ * the terms of any one of the MPL, the GPL or the LGPL.
++ *
++ * ***** END LICENSE BLOCK ***** */
++
++#include "nsISupports.idl"
++
++[scriptable, uuid(6FC2117D-5EB4-441A-9C12-62A783BEBC0C)]
++interface nsPIDragServiceWindows : nsISupports
++{
++ void setIDataObject(in nsISupports aDataObj);
++
++ void setDroppedLocal();
++};
+diff --git a/widget/xpwidgets/nsBaseDragService.cpp b/widget/xpwidgets/nsBaseDragService.cpp
+index 805d83f..9b69793 100644
+--- a/widget/xpwidgets/nsBaseDragService.cpp
++++ b/widget/xpwidgets/nsBaseDragService.cpp
+@@ -55,7 +55,7 @@ nsBaseDragService::~nsBaseDragService()
+ {
+ }
+
+-NS_IMPL_ISUPPORTS2(nsBaseDragService, nsIDragService, nsIDragSession)
++NS_IMPL_ISUPPORTS3(nsBaseDragService, nsIDragService, nsPIDragService, nsIDragSession)
+
+ //---------------------------------------------------------
+ NS_IMETHODIMP
+@@ -403,6 +403,20 @@ nsBaseDragService::DragMoved(int32_t aX, int32_t aY)
+ return NS_OK;
+ }
+
++NS_IMETHODIMP
++nsBaseDragService::SetDragEndPoint(PRInt32 aX, PRInt32 aY)
++{
++ mEndDragPoint = nsIntPoint(aX, aY);
++ return NS_OK;
++}
++
++NS_IMETHODIMP
++nsBaseDragService::GetInputSource(PRUint16* aInputSource)
++{
++ *aInputSource = mInputSource;
++ return NS_OK;
++}
++
+ static nsIPresShell*
+ GetPresShellForContent(nsIDOMNode* aDOMNode)
+ {
+diff --git a/widget/xpwidgets/nsBaseDragService.h b/widget/xpwidgets/nsBaseDragService.h
+index cb00f8e..741c287 100644
+--- a/widget/xpwidgets/nsBaseDragService.h
++++ b/widget/xpwidgets/nsBaseDragService.h
+@@ -7,6 +7,7 @@
+ #define nsBaseDragService_h__
+
+ #include "nsIDragService.h"
++#include "nsPIDragService.h"
+ #include "nsIDragSession.h"
+ #include "nsITransferable.h"
+ #include "nsISupportsArray.h"
+@@ -32,6 +33,7 @@ class nsICanvasElementExternal;
+ */
+
+ class nsBaseDragService : public nsIDragService,
++ public nsPIDragService,
+ public nsIDragSession
+ {
+
+@@ -42,14 +44,11 @@ public:
+ //nsISupports
+ NS_DECL_ISUPPORTS
+
+- //nsIDragSession and nsIDragService
++ //nsIDragSession, nsIDragService and nsPIDragService
+ NS_DECL_NSIDRAGSERVICE
++ NS_DECL_NSPIDRAGSERVICE
+ NS_DECL_NSIDRAGSESSION
+
+- void SetDragEndPoint(nsIntPoint aEndDragPoint) { mEndDragPoint = aEndDragPoint; }
+-
+- uint16_t GetInputSource() { return mInputSource; }
+-
+ protected:
+
+ /**
+--
+1.7.5.4
+
diff --git a/src/current-patches/firefox/0018-Add-HTTP-auth-headers-before-the-modify-request-obse.patch b/src/current-patches/firefox/0018-Add-HTTP-auth-headers-before-the-modify-request-obse.patch
deleted file mode 100644
index 46cf611..0000000
--- a/src/current-patches/firefox/0018-Add-HTTP-auth-headers-before-the-modify-request-obse.patch
+++ /dev/null
@@ -1,52 +0,0 @@
-From c1e26c8a294abe426fd6fb84508db6074ef23379 Mon Sep 17 00:00:00 2001
-From: Mike Perry <mikeperry-git(a)fscked.org>
-Date: Fri, 2 Sep 2011 15:33:20 -0700
-Subject: [PATCH 18/24] Add HTTP auth headers before the modify-request
- observer.
-
-Otherwise, how are we supposed to modify them?
-
-Thanks to Georg Koppen for spotting both the problem and this fix.
----
- netwerk/protocol/http/nsHttpChannel.cpp | 11 +++++++----
- 1 files changed, 7 insertions(+), 4 deletions(-)
-
-diff --git a/netwerk/protocol/http/nsHttpChannel.cpp b/netwerk/protocol/http/nsHttpChannel.cpp
-index 97bd84c..6205d62 100644
---- a/netwerk/protocol/http/nsHttpChannel.cpp
-+++ b/netwerk/protocol/http/nsHttpChannel.cpp
-@@ -316,9 +316,6 @@ nsHttpChannel::Connect(bool firstTime)
- return NS_ERROR_DOCUMENT_NOT_CACHED;
- }
-
-- // check to see if authorization headers should be included
-- mAuthProvider->AddAuthorizationHeaders();
--
- if (mLoadFlags & LOAD_NO_NETWORK_IO) {
- return NS_ERROR_DOCUMENT_NOT_CACHED;
- }
-@@ -3707,6 +3704,9 @@ nsHttpChannel::AsyncOpen(nsIStreamListener *listener, nsISupports *context)
-
- AddCookiesToRequest();
-
-+ // check to see if authorization headers should be included
-+ mAuthProvider->AddAuthorizationHeaders();
-+
- // notify "http-on-modify-request" observers
- gHttpHandler->OnModifyRequest(this);
-
-@@ -4817,7 +4817,10 @@ nsHttpChannel::DoAuthRetry(nsAHttpConnection *conn)
- // this authentication attempt (bug 84794).
- // TODO: save cookies from auth response and send them here (bug 572151).
- AddCookiesToRequest();
--
-+
-+ // check to see if authorization headers should be included
-+ mAuthProvider->AddAuthorizationHeaders();
-+
- // notify "http-on-modify-request" observers
- gHttpHandler->OnModifyRequest(this);
-
---
-1.7.5.4
-
diff --git a/src/current-patches/firefox/0019-Adapt-Steven-Michaud-s-Mac-crashfix-patch.patch b/src/current-patches/firefox/0019-Adapt-Steven-Michaud-s-Mac-crashfix-patch.patch
deleted file mode 100644
index 7f3869c..0000000
--- a/src/current-patches/firefox/0019-Adapt-Steven-Michaud-s-Mac-crashfix-patch.patch
+++ /dev/null
@@ -1,532 +0,0 @@
-From 49cccdba3e6fc10e0e376d423b3ba1b6135f62e1 Mon Sep 17 00:00:00 2001
-From: Mike Perry <mikeperry-git(a)torproject.org>
-Date: Thu, 7 Jun 2012 16:25:48 -0700
-Subject: [PATCH 19/24] Adapt Steven Michaud's Mac crashfix patch
-
-Source is: https://bugzilla.mozilla.org/show_bug.cgi?id=715885#c35
-
-Some minor tweaks were needed to get it to apply and to compile on
-MacOS.
----
- widget/public/Makefile.in | 2 +
- widget/public/nsIDragService.idl | 1 -
- widget/public/nsPIDragService.idl | 48 ++++++++++++++++++++++++++++
- widget/public/nsPIDragServiceWindows.idl | 46 ++++++++++++++++++++++++++
- widget/src/cocoa/nsChildView.mm | 35 +++++++++++++-------
- widget/src/gtk2/nsDragService.cpp | 2 +-
- widget/src/gtk2/nsWindow.cpp | 2 +-
- widget/src/qt/nsDragService.h | 2 +
- widget/src/windows/Makefile.in | 1 -
- widget/src/windows/nsDragService.cpp | 13 +++++---
- widget/src/windows/nsDragService.h | 12 +++---
- widget/src/windows/nsNativeDragSource.cpp | 7 ++--
- widget/src/windows/nsNativeDragTarget.cpp | 28 ++++++++++------
- widget/src/xpwidgets/nsBaseDragService.cpp | 16 +++++++++-
- widget/src/xpwidgets/nsBaseDragService.h | 9 ++---
- 15 files changed, 176 insertions(+), 48 deletions(-)
- create mode 100644 widget/public/nsPIDragService.idl
- create mode 100644 widget/public/nsPIDragServiceWindows.idl
-
-diff --git a/widget/public/Makefile.in b/widget/public/Makefile.in
-index a70e65a..8a9b73d 100644
---- a/widget/public/Makefile.in
-+++ b/widget/public/Makefile.in
-@@ -110,6 +110,8 @@ XPIDLSRCS = \
- nsIClipboardDragDropHooks.idl \
- nsIClipboardDragDropHookList.idl \
- nsIDragSession.idl \
-+ nsPIDragService.idl \
-+ nsPIDragServiceWindows.idl \
- nsIDragService.idl \
- nsIFormatConverter.idl \
- nsIClipboard.idl \
-diff --git a/widget/public/nsIDragService.idl b/widget/public/nsIDragService.idl
-index 6863a88..c4a1e26 100644
---- a/widget/public/nsIDragService.idl
-+++ b/widget/public/nsIDragService.idl
-@@ -146,7 +146,6 @@ interface nsIDragService : nsISupports
- void suppress();
- void unsuppress();
-
-- [noscript] void dragMoved(in long aX, in long aY);
- };
-
-
-diff --git a/widget/public/nsPIDragService.idl b/widget/public/nsPIDragService.idl
-new file mode 100644
-index 0000000..93a144d
---- /dev/null
-+++ b/widget/public/nsPIDragService.idl
-@@ -0,0 +1,48 @@
-+/* ***** BEGIN LICENSE BLOCK *****
-+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
-+ *
-+ * The contents of this file are subject to the Mozilla Public License Version
-+ * 1.1 (the "License"); you may not use this file except in compliance with
-+ * the License. You may obtain a copy of the License at
-+ * http://www.mozilla.org/MPL/
-+ *
-+ * Software distributed under the License is distributed on an "AS IS" basis,
-+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
-+ * for the specific language governing rights and limitations under the
-+ * License.
-+ *
-+ * The Original Code is mozilla.org code.
-+ *
-+ * The Initial Developer of the Original Code is
-+ * The Mozilla Foundation.
-+ * Portions created by the Initial Developer are Copyright (C) 2012
-+ * the Initial Developer. All Rights Reserved.
-+ *
-+ * Contributor(s):
-+ * Steven Michaud <smichaud(a)pobox.com>
-+ *
-+ * Alternatively, the contents of this file may be used under the terms of
-+ * either the GNU General Public License Version 2 or later (the "GPL"), or
-+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
-+ * in which case the provisions of the GPL or the LGPL are applicable instead
-+ * of those above. If you wish to allow use of your version of this file only
-+ * under the terms of either the GPL or the LGPL, and not to allow others to
-+ * use your version of this file under the terms of the MPL, indicate your
-+ * decision by deleting the provisions above and replace them with the notice
-+ * and other provisions required by the GPL or the LGPL. If you do not delete
-+ * the provisions above, a recipient may use your version of this file under
-+ * the terms of any one of the MPL, the GPL or the LGPL.
-+ *
-+ * ***** END LICENSE BLOCK ***** */
-+
-+#include "nsISupports.idl"
-+
-+[scriptable, uuid(FAD8C90B-8E1D-446A-9B6C-241486A85CBD)]
-+interface nsPIDragService : nsISupports
-+{
-+ void dragMoved(in long aX, in long aY);
-+
-+ PRUint16 getInputSource();
-+
-+ void setDragEndPoint(in long aX, in long aY);
-+};
-diff --git a/widget/public/nsPIDragServiceWindows.idl b/widget/public/nsPIDragServiceWindows.idl
-new file mode 100644
-index 0000000..c8a46dd
---- /dev/null
-+++ b/widget/public/nsPIDragServiceWindows.idl
-@@ -0,0 +1,46 @@
-+/* ***** BEGIN LICENSE BLOCK *****
-+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
-+ *
-+ * The contents of this file are subject to the Mozilla Public License Version
-+ * 1.1 (the "License"); you may not use this file except in compliance with
-+ * the License. You may obtain a copy of the License at
-+ * http://www.mozilla.org/MPL/
-+ *
-+ * Software distributed under the License is distributed on an "AS IS" basis,
-+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
-+ * for the specific language governing rights and limitations under the
-+ * License.
-+ *
-+ * The Original Code is mozilla.org code.
-+ *
-+ * The Initial Developer of the Original Code is
-+ * The Mozilla Foundation.
-+ * Portions created by the Initial Developer are Copyright (C) 2012
-+ * the Initial Developer. All Rights Reserved.
-+ *
-+ * Contributor(s):
-+ * Steven Michaud <smichaud(a)pobox.com>
-+ *
-+ * Alternatively, the contents of this file may be used under the terms of
-+ * either the GNU General Public License Version 2 or later (the "GPL"), or
-+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
-+ * in which case the provisions of the GPL or the LGPL are applicable instead
-+ * of those above. If you wish to allow use of your version of this file only
-+ * under the terms of either the GPL or the LGPL, and not to allow others to
-+ * use your version of this file under the terms of the MPL, indicate your
-+ * decision by deleting the provisions above and replace them with the notice
-+ * and other provisions required by the GPL or the LGPL. If you do not delete
-+ * the provisions above, a recipient may use your version of this file under
-+ * the terms of any one of the MPL, the GPL or the LGPL.
-+ *
-+ * ***** END LICENSE BLOCK ***** */
-+
-+#include "nsISupports.idl"
-+
-+[scriptable, uuid(6FC2117D-5EB4-441A-9C12-62A783BEBC0C)]
-+interface nsPIDragServiceWindows : nsISupports
-+{
-+ void setIDataObject(in nsISupports aDataObj);
-+
-+ void setDroppedLocal();
-+};
-diff --git a/widget/src/cocoa/nsChildView.mm b/widget/src/cocoa/nsChildView.mm
-index 64336e3..b2ab6bc 100644
---- a/widget/src/cocoa/nsChildView.mm
-+++ b/widget/src/cocoa/nsChildView.mm
-@@ -4513,11 +4513,12 @@ NSEvent* gLastDragMouseDownEvent = nil;
- if (!dragService) {
- dragService = do_GetService(kDragServiceContractID);
- }
-+ nsCOMPtr<nsPIDragService> dragServicePriv = do_QueryInterface(dragService);
-
- if (dragService) {
- NSPoint pnt = [NSEvent mouseLocation];
- FlipCocoaScreenCoordinate(pnt);
-- dragService->DragMoved(NSToIntRound(pnt.x), NSToIntRound(pnt.y));
-+ dragServicePriv->DragMoved(NSToIntRound(pnt.x), NSToIntRound(pnt.y));
- }
- }
-
-@@ -4538,11 +4539,13 @@ NSEvent* gLastDragMouseDownEvent = nil;
- }
-
- if (mDragService) {
-- // set the dragend point from the current mouse location
-- nsDragService* dragService = static_cast<nsDragService *>(mDragService);
-- NSPoint pnt = [NSEvent mouseLocation];
-- FlipCocoaScreenCoordinate(pnt);
-- dragService->SetDragEndPoint(nsIntPoint(NSToIntRound(pnt.x), NSToIntRound(pnt.y)));
-+ nsCOMPtr<nsPIDragService> dragServicePriv = do_QueryInterface(mDragService);
-+ if (dragServicePriv) {
-+ // set the dragend point from the current mouse location
-+ NSPoint pnt = [NSEvent mouseLocation];
-+ FlipCocoaScreenCoordinate(pnt);
-+ dragServicePriv->SetDragEndPoint(NSToIntRound(pnt.x), NSToIntRound(pnt.y));
-+ }
-
- // XXX: dropEffect should be updated per |operation|.
- // As things stand though, |operation| isn't well handled within "our"
-@@ -4553,13 +4556,19 @@ NSEvent* gLastDragMouseDownEvent = nil;
- // value for NSDragOperationGeneric that is passed by other applications.
- // All that said, NSDragOperationNone is still reliable.
- if (operation == NSDragOperationNone) {
-- nsCOMPtr<nsIDOMDataTransfer> dataTransfer;
-- dragService->GetDataTransfer(getter_AddRefs(dataTransfer));
-- nsCOMPtr<nsIDOMNSDataTransfer> dataTransferNS =
-- do_QueryInterface(dataTransfer);
--
-- if (dataTransferNS)
-- dataTransferNS->SetDropEffectInt(nsIDragService::DRAGDROP_ACTION_NONE);
-+ nsCOMPtr<nsIDragSession> dragSession;
-+ mDragService->GetCurrentSession(getter_AddRefs(dragSession));
-+ if (dragSession) {
-+ nsCOMPtr<nsIDOMDataTransfer> dataTransfer;
-+ dragSession->GetDataTransfer(getter_AddRefs(dataTransfer));
-+ if (dataTransfer) {
-+ nsCOMPtr<nsIDOMNSDataTransfer> dataTransferNS =
-+ do_QueryInterface(dataTransfer);
-+ if (dataTransferNS) {
-+ dataTransferNS->SetDropEffectInt(nsIDragService::DRAGDROP_ACTION_NONE);
-+ }
-+ }
-+ }
- }
-
- mDragService->EndDragSession(true);
-diff --git a/widget/src/gtk2/nsDragService.cpp b/widget/src/gtk2/nsDragService.cpp
-index ca5a42c..876fd55 100644
---- a/widget/src/gtk2/nsDragService.cpp
-+++ b/widget/src/gtk2/nsDragService.cpp
-@@ -1334,7 +1334,7 @@ nsDragService::SourceEndDragSession(GdkDragContext *aContext,
- GdkDisplay* display = gdk_display_get_default();
- if (display) {
- gdk_display_get_pointer(display, NULL, &x, &y, NULL);
-- SetDragEndPoint(nsIntPoint(x, y));
-+ SetDragEndPoint(x, y);
- }
-
- // Either the drag was aborted or the drop occurred outside the app.
-diff --git a/widget/src/gtk2/nsWindow.cpp b/widget/src/gtk2/nsWindow.cpp
-index 2fd6f64..a2e27e1 100644
---- a/widget/src/gtk2/nsWindow.cpp
-+++ b/widget/src/gtk2/nsWindow.cpp
-@@ -3738,7 +3738,7 @@ nsWindow::OnDragDropEvent(GtkWidget *aWidget,
- if (display) {
- // get the current cursor position
- gdk_display_get_pointer(display, NULL, &x, &y, NULL);
-- ((nsDragService *)dragService.get())->SetDragEndPoint(nsIntPoint(x, y));
-+ ((nsDragService *)dragService.get())->SetDragEndPoint(x, y);
- }
- dragService->EndDragSession(true);
-
-diff --git a/widget/src/qt/nsDragService.h b/widget/src/qt/nsDragService.h
-index 5a3e5bb..50dcfac 100644
---- a/widget/src/qt/nsDragService.h
-+++ b/widget/src/qt/nsDragService.h
-@@ -50,6 +50,8 @@ public:
- NS_DECL_ISUPPORTS
- NS_DECL_NSIDRAGSERVICE
-
-+ NS_IMETHOD DragMoved(PRInt32 aX, PRInt32 aY);
-+
- nsDragService();
-
- private:
-diff --git a/widget/src/windows/Makefile.in b/widget/src/windows/Makefile.in
-index 53277ea..d7ff7ce 100644
---- a/widget/src/windows/Makefile.in
-+++ b/widget/src/windows/Makefile.in
-@@ -115,7 +115,6 @@ ifdef MOZ_ENABLE_D3D10_LAYER
- DEFINES += -DMOZ_ENABLE_D3D10_LAYER
- endif
-
--
- EXPORTS = nsdefs.h WindowHook.h
- EXPORTS_NAMESPACES = mozilla/widget
- EXPORTS_mozilla/widget = AudioSession.h
-diff --git a/widget/src/windows/nsDragService.cpp b/widget/src/windows/nsDragService.cpp
-index 2dcede3..3d8af21 100644
---- a/widget/src/windows/nsDragService.cpp
-+++ b/widget/src/windows/nsDragService.cpp
-@@ -97,6 +97,8 @@ nsDragService::~nsDragService()
- NS_IF_RELEASE(mDataObject);
- }
-
-+NS_IMPL_ISUPPORTS_INHERITED1(nsDragService, nsBaseDragService, nsPIDragServiceWindows)
-+
- bool
- nsDragService::CreateDragImage(nsIDOMNode *aDOMNode,
- nsIScriptableRegion *aRegion,
-@@ -350,7 +352,7 @@ nsDragService::StartInvokingDragSession(IDataObject * aDataObj,
- POINT cpos;
- cpos.x = GET_X_LPARAM(pos);
- cpos.y = GET_Y_LPARAM(pos);
-- SetDragEndPoint(nsIntPoint(cpos.x, cpos.y));
-+ SetDragEndPoint(cpos.x, cpos.y);
- EndDragSession(true);
-
- mDoingDrag = false;
-@@ -468,25 +470,26 @@ nsDragService::GetData(nsITransferable * aTransferable, PRUint32 anItem)
-
- //---------------------------------------------------------
- NS_IMETHODIMP
--nsDragService::SetIDataObject(IDataObject * aDataObj)
-+nsDragService::SetIDataObject(nsISupports * aDataObj)
- {
-+ IDataObject *dataObj = (IDataObject*) aDataObj;
- // When the native drag starts the DragService gets
- // the IDataObject that is being dragged
- NS_IF_RELEASE(mDataObject);
-- mDataObject = aDataObj;
-+ mDataObject = dataObj;
- NS_IF_ADDREF(mDataObject);
-
- return NS_OK;
- }
-
- //---------------------------------------------------------
--void
-+NS_IMETHODIMP
- nsDragService::SetDroppedLocal()
- {
- // Sent from the native drag handler, letting us know
- // a drop occurred within the application vs. outside of it.
- mSentLocalDropEvent = true;
-- return;
-+ return NS_OK;
- }
-
- //-------------------------------------------------------------------------
-diff --git a/widget/src/windows/nsDragService.h b/widget/src/windows/nsDragService.h
-index 067bcf2..2699e47 100644
---- a/widget/src/windows/nsDragService.h
-+++ b/widget/src/windows/nsDragService.h
-@@ -39,6 +39,7 @@
- #define nsDragService_h__
-
- #include "nsBaseDragService.h"
-+#include "nsPIDragServiceWindows.h"
- #include <windows.h>
- #include <shlobj.h>
-
-@@ -52,12 +53,15 @@ class nsString;
- * Native Win32 DragService wrapper
- */
-
--class nsDragService : public nsBaseDragService
-+class nsDragService : public nsBaseDragService, public nsPIDragServiceWindows
- {
- public:
- nsDragService();
- virtual ~nsDragService();
--
-+
-+ NS_DECL_ISUPPORTS_INHERITED
-+ NS_DECL_NSPIDRAGSERVICEWINDOWS
-+
- // nsIDragService
- NS_IMETHOD InvokeDragSession(nsIDOMNode *aDOMNode,
- nsISupportsArray *anArrayTransferables,
-@@ -71,13 +75,9 @@ public:
- NS_IMETHOD EndDragSession(bool aDoneDrag);
-
- // native impl.
-- NS_IMETHOD SetIDataObject(IDataObject * aDataObj);
- NS_IMETHOD StartInvokingDragSession(IDataObject * aDataObj,
- PRUint32 aActionType);
-
-- // A drop occurred within the application vs. outside of it.
-- void SetDroppedLocal();
--
- protected:
- nsDataObjCollection* GetDataObjCollection(IDataObject * aDataObj);
-
-diff --git a/widget/src/windows/nsNativeDragSource.cpp b/widget/src/windows/nsNativeDragSource.cpp
-index e51101e..0fe6ffe 100644
---- a/widget/src/windows/nsNativeDragSource.cpp
-+++ b/widget/src/windows/nsNativeDragSource.cpp
-@@ -42,7 +42,7 @@
- #include "nsIServiceManager.h"
- #include "nsToolkit.h"
- #include "nsWidgetsCID.h"
--#include "nsIDragService.h"
-+#include "nsDragService.h"
-
- static NS_DEFINE_IID(kCDragServiceCID, NS_DRAGSERVICE_CID);
-
-@@ -101,9 +101,10 @@ STDMETHODIMP
- nsNativeDragSource::QueryContinueDrag(BOOL fEsc, DWORD grfKeyState)
- {
- nsCOMPtr<nsIDragService> dragService = do_GetService(kCDragServiceCID);
-- if (dragService) {
-+ nsCOMPtr<nsPIDragService> dragServicePriv = do_QueryInterface(dragService);
-+ if (dragServicePriv) {
- DWORD pos = ::GetMessagePos();
-- dragService->DragMoved(GET_X_LPARAM(pos), GET_Y_LPARAM(pos));
-+ dragServicePriv->DragMoved(GET_X_LPARAM(pos), GET_Y_LPARAM(pos));
- }
-
- if (fEsc) {
-diff --git a/widget/src/windows/nsNativeDragTarget.cpp b/widget/src/windows/nsNativeDragTarget.cpp
-index cf6196b..82ad3c6 100644
---- a/widget/src/windows/nsNativeDragTarget.cpp
-+++ b/widget/src/windows/nsNativeDragTarget.cpp
-@@ -209,7 +209,11 @@ nsNativeDragTarget::DispatchDragDropEvent(PRUint32 aEventType, POINTL aPT)
- event.isControl = IsKeyDown(NS_VK_CONTROL);
- event.isMeta = false;
- event.isAlt = IsKeyDown(NS_VK_ALT);
-- event.inputSource = static_cast<nsBaseDragService*>(mDragService)->GetInputSource();
-+ event.inputSource = 0;
-+ nsCOMPtr<nsPIDragService> dragServicePriv = do_QueryInterface(mDragService);
-+ if (dragServicePriv) {
-+ dragServicePriv->GetInputSource(&event.inputSource);
-+ }
-
- mWindow->DispatchEvent(&event, status);
- }
-@@ -296,9 +300,8 @@ nsNativeDragTarget::DragEnter(LPDATAOBJECT pIDataSource,
- // This cast is ok because in the constructor we created a
- // the actual implementation we wanted, so we know this is
- // a nsDragService. It should be a private interface, though.
-- nsDragService * winDragService =
-- static_cast<nsDragService *>(mDragService);
-- winDragService->SetIDataObject(pIDataSource);
-+ nsCOMPtr<nsPIDragServiceWindows> winDragService = do_QueryInterface(mDragService);
-+ winDragService->SetIDataObject((nsISupports*)pIDataSource);
-
- // Now process the native drag state and then dispatch the event
- ProcessDrag(NS_DRAGDROP_ENTER, grfKeyState, ptl, pdwEffect);
-@@ -436,8 +439,8 @@ nsNativeDragTarget::Drop(LPDATAOBJECT pData,
- // This cast is ok because in the constructor we created a
- // the actual implementation we wanted, so we know this is
- // a nsDragService (but it should still be a private interface)
-- nsDragService* winDragService = static_cast<nsDragService*>(mDragService);
-- winDragService->SetIDataObject(pData);
-+ nsCOMPtr<nsPIDragServiceWindows> winDragService = do_QueryInterface(mDragService);
-+ winDragService->SetIDataObject((nsISupports*)pData);
-
- // NOTE: ProcessDrag spins the event loop which may destroy arbitrary objects.
- // We use strong refs to prevent it from destroying these:
-@@ -461,11 +464,14 @@ nsNativeDragTarget::Drop(LPDATAOBJECT pData,
- // tell the drag service we're done with the session
- // Use GetMessagePos to get the position of the mouse at the last message
- // seen by the event loop. (Bug 489729)
-- DWORD pos = ::GetMessagePos();
-- POINT cpos;
-- cpos.x = GET_X_LPARAM(pos);
-- cpos.y = GET_Y_LPARAM(pos);
-- winDragService->SetDragEndPoint(nsIntPoint(cpos.x, cpos.y));
-+ nsCOMPtr<nsPIDragService> dragServicePriv = do_QueryInterface(mDragService);
-+ if (dragServicePriv) {
-+ DWORD pos = ::GetMessagePos();
-+ POINT cpos;
-+ cpos.x = GET_X_LPARAM(pos);
-+ cpos.y = GET_Y_LPARAM(pos);
-+ dragServicePriv->SetDragEndPoint(cpos.x, cpos.y);
-+ }
- serv->EndDragSession(true);
-
- // release the ref that was taken in DragEnter
-diff --git a/widget/src/xpwidgets/nsBaseDragService.cpp b/widget/src/xpwidgets/nsBaseDragService.cpp
-index 52efb7e..1c35673 100644
---- a/widget/src/xpwidgets/nsBaseDragService.cpp
-+++ b/widget/src/xpwidgets/nsBaseDragService.cpp
-@@ -89,7 +89,7 @@ nsBaseDragService::~nsBaseDragService()
- {
- }
-
--NS_IMPL_ISUPPORTS2(nsBaseDragService, nsIDragService, nsIDragSession)
-+NS_IMPL_ISUPPORTS3(nsBaseDragService, nsIDragService, nsPIDragService, nsIDragSession)
-
- //---------------------------------------------------------
- NS_IMETHODIMP
-@@ -443,6 +443,20 @@ nsBaseDragService::DragMoved(PRInt32 aX, PRInt32 aY)
- return NS_OK;
- }
-
-+NS_IMETHODIMP
-+nsBaseDragService::SetDragEndPoint(PRInt32 aX, PRInt32 aY)
-+{
-+ mEndDragPoint = nsIntPoint(aX, aY);
-+ return NS_OK;
-+}
-+
-+NS_IMETHODIMP
-+nsBaseDragService::GetInputSource(PRUint16* aInputSource)
-+{
-+ *aInputSource = mInputSource;
-+ return NS_OK;
-+}
-+
- static nsIPresShell*
- GetPresShellForContent(nsIDOMNode* aDOMNode)
- {
-diff --git a/widget/src/xpwidgets/nsBaseDragService.h b/widget/src/xpwidgets/nsBaseDragService.h
-index 290c0cb..2ceac2b 100644
---- a/widget/src/xpwidgets/nsBaseDragService.h
-+++ b/widget/src/xpwidgets/nsBaseDragService.h
-@@ -39,6 +39,7 @@
- #define nsBaseDragService_h__
-
- #include "nsIDragService.h"
-+#include "nsPIDragService.h"
- #include "nsIDragSession.h"
- #include "nsITransferable.h"
- #include "nsISupportsArray.h"
-@@ -64,6 +65,7 @@ class nsICanvasElementExternal;
- */
-
- class nsBaseDragService : public nsIDragService,
-+ public nsPIDragService,
- public nsIDragSession
- {
-
-@@ -74,14 +76,11 @@ public:
- //nsISupports
- NS_DECL_ISUPPORTS
-
-- //nsIDragSession and nsIDragService
-+ //nsIDragSession, nsIDragService and nsPIDragService
- NS_DECL_NSIDRAGSERVICE
-+ NS_DECL_NSPIDRAGSERVICE
- NS_DECL_NSIDRAGSESSION
-
-- void SetDragEndPoint(nsIntPoint aEndDragPoint) { mEndDragPoint = aEndDragPoint; }
--
-- PRUint16 GetInputSource() { return mInputSource; }
--
- protected:
-
- /**
---
-1.7.5.4
-
diff --git a/src/current-patches/firefox/0019-Add-mozIThirdPartyUtil.getFirstPartyURI-API.patch b/src/current-patches/firefox/0019-Add-mozIThirdPartyUtil.getFirstPartyURI-API.patch
new file mode 100644
index 0000000..ab855cf
--- /dev/null
+++ b/src/current-patches/firefox/0019-Add-mozIThirdPartyUtil.getFirstPartyURI-API.patch
@@ -0,0 +1,154 @@
+From 4ea73b19b21764c10019e9af1cc68664ed7f7394 Mon Sep 17 00:00:00 2001
+From: Kathleen Brade <brade(a)pearlcrescent.com>
+Date: Wed, 28 Nov 2012 17:08:29 -0500
+Subject: [PATCH 19/26] Add mozIThirdPartyUtil.getFirstPartyURI API
+
+API allows you to get the url bar URI for a channel or nsIDocument.
+---
+ content/base/src/ThirdPartyUtil.cpp | 58 ++++++++++++++++++++++++++++
+ content/base/src/ThirdPartyUtil.h | 2 +
+ netwerk/base/public/mozIThirdPartyUtil.idl | 21 ++++++++++
+ 3 files changed, 81 insertions(+), 0 deletions(-)
+
+diff --git a/content/base/src/ThirdPartyUtil.cpp b/content/base/src/ThirdPartyUtil.cpp
+index 97a000e..ae4fa70 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,57 @@ ThirdPartyUtil::GetBaseDomain(nsIURI* aHostURI,
+
+ return NS_OK;
+ }
++
++NS_IMETHODIMP
++ThirdPartyUtil::GetFirstPartyURI(nsIChannel *aChannel,
++ nsIDocument *aDoc,
++ nsIURI **aOutput)
++{
++ nsresult rv = NS_ERROR_NULL_POINTER;
++
++ if (!aChannel && aDoc) {
++ aChannel = aDoc->GetChannel();
++ }
++
++ // If aChannel is specified or available, use the official route
++ // for sure
++ if (aChannel) {
++ rv = mCookiePermissions->GetOriginatingURI(aChannel, aOutput);
++ }
++
++ // If the channel was missing, closed or broken, try the
++ // window hierarchy directly.
++ //
++ // This might fail to work for first-party loads themselves, but
++ // we don't need this codepath for that case.
++ if (NS_FAILED(rv) && aDoc) {
++ nsCOMPtr<nsIDOMWindow> top;
++ nsCOMPtr<nsIDOMDocument> topDDoc;
++
++ if (aDoc->GetWindow()) {
++ aDoc->GetWindow()->GetTop(getter_AddRefs(top));
++ top->GetDocument(getter_AddRefs(topDDoc));
++
++ nsCOMPtr<nsIDocument> topDoc(do_QueryInterface(topDDoc));
++ *aOutput = topDoc->GetOriginalURI();
++ } 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
new file mode 100644
index 0000000..802dc3f
--- /dev/null
+++ b/src/current-patches/firefox/0020-Add-canvas-image-extraction-prompt.patch
@@ -0,0 +1,548 @@
+From 924f0fb25804b75289f18fe5b5cfe02667aad58f Mon Sep 17 00:00:00 2001
+From: Kathleen Brade <brade(a)pearlcrescent.com>
+Date: Tue, 27 Nov 2012 13:13:40 -0500
+Subject: [PATCH 20/26] 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 1fc137c..e95cebc 100644
+--- a/browser/base/content/browser.js
++++ b/browser/base/content/browser.js
+@@ -1282,6 +1282,7 @@ var gBrowserInit = {
+ BrowserOffline.init();
+ OfflineApps.init();
+ IndexedDBPromptHelper.init();
++ CanvasPermissionPromptHelper.init();
+ gFormSubmitObserver.init();
+ SocialUI.init();
+ AddonManager.addAddonListener(AddonsMgrListener);
+@@ -1639,6 +1640,7 @@ var gBrowserInit = {
+ BrowserOffline.uninit();
+ OfflineApps.uninit();
+ IndexedDBPromptHelper.uninit();
++ CanvasPermissionPromptHelper.uninit();
+ AddonManager.removeAddonListener(AddonsMgrListener);
+ SocialUI.uninit();
+ }
+@@ -6129,6 +6131,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 5bf156e..8699a62 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 aff8ae1..f69f553 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 a44c6b9..ff581ab 100644
+--- a/browser/themes/pinstripe/browser.css
++++ b/browser/themes/pinstripe/browser.css
+@@ -2403,10 +2403,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 470c344..770245b 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/0020-Add-mozIThirdPartyUtil.getFirstPartyURI-API.patch b/src/current-patches/firefox/0020-Add-mozIThirdPartyUtil.getFirstPartyURI-API.patch
deleted file mode 100644
index 114301d..0000000
--- a/src/current-patches/firefox/0020-Add-mozIThirdPartyUtil.getFirstPartyURI-API.patch
+++ /dev/null
@@ -1,155 +0,0 @@
-From 36d57455893bcf6dc08e91a2784970f285c5e84b Mon Sep 17 00:00:00 2001
-From: Mike Perry <mikeperry-git(a)torproject.org>
-Date: Tue, 28 Aug 2012 18:35:33 -0700
-Subject: [PATCH 20/24] Add mozIThirdPartyUtil.getFirstPartyURI API
-
-API allows you to get the url bar URI for a channel or nsIDocument.
----
- content/base/src/ThirdPartyUtil.cpp | 59 ++++++++++++++++++++++++++++
- content/base/src/ThirdPartyUtil.h | 2 +
- netwerk/base/public/mozIThirdPartyUtil.idl | 21 ++++++++++
- 3 files changed, 82 insertions(+), 0 deletions(-)
-
-diff --git a/content/base/src/ThirdPartyUtil.cpp b/content/base/src/ThirdPartyUtil.cpp
-index 6a415e9..52b3dab 100644
---- a/content/base/src/ThirdPartyUtil.cpp
-+++ b/content/base/src/ThirdPartyUtil.cpp
-@@ -40,6 +40,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"
-@@ -54,6 +57,7 @@ ThirdPartyUtil::Init()
-
- nsresult rv;
- mTLDService = do_GetService(NS_EFFECTIVETLDSERVICE_CONTRACTID, &rv);
-+ mCookiePermissions = do_GetService(NS_COOKIEPERMISSION_CONTRACTID);
- return rv;
- }
-
-@@ -315,3 +319,58 @@ ThirdPartyUtil::GetBaseDomain(nsIURI* aHostURI,
-
- return NS_OK;
- }
-+
-+NS_IMETHODIMP
-+ThirdPartyUtil::GetFirstPartyURI(nsIChannel *aChannel,
-+ nsIDocument *aDoc,
-+ nsIURI **aOutput)
-+{
-+ nsresult rv = NS_ERROR_NULL_POINTER;
-+
-+ if (!aChannel && aDoc) {
-+ aChannel = aDoc->GetChannel();
-+ }
-+
-+ // If aChannel is specified or available, use the official route
-+ // for sure
-+ if (aChannel) {
-+ rv = mCookiePermissions->GetOriginatingURI(aChannel, aOutput);
-+ }
-+
-+ // If the channel was missing, closed or broken, try the
-+ // window hierarchy directly.
-+ //
-+ // This might fail to work for first-party loads themselves, but
-+ // we don't need this codepath for that case.
-+ if (NS_FAILED(rv) && aDoc) {
-+ nsCOMPtr<nsIDOMWindow> top;
-+ nsCOMPtr<nsIDOMDocument> topDDoc;
-+
-+ if (aDoc->GetWindow()) {
-+ aDoc->GetWindow()->GetTop(getter_AddRefs(top));
-+ top->GetDocument(getter_AddRefs(topDDoc));
-+
-+ nsCOMPtr<nsIDocument> topDoc(do_QueryInterface(topDDoc));
-+ *aOutput = topDoc->GetOriginalURI();
-+ } 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 58ddb15..c8eab11 100644
---- a/content/base/src/ThirdPartyUtil.h
-+++ b/content/base/src/ThirdPartyUtil.h
-@@ -42,6 +42,7 @@
- #include "nsString.h"
- #include "mozIThirdPartyUtil.h"
- #include "nsIEffectiveTLDService.h"
-+#include "nsICookiePermission.h"
-
- class nsIURI;
- class nsIChannel;
-@@ -61,6 +62,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 ad41985..fd2cb38 100644
---- a/netwerk/base/public/mozIThirdPartyUtil.idl
-+++ b/netwerk/base/public/mozIThirdPartyUtil.idl
-@@ -40,6 +40,7 @@
- interface nsIURI;
- interface nsIDOMWindow;
- interface nsIChannel;
-+interface nsIDocument;
-
- /**
- * Utility functions for determining whether a given URI, channel, or window
-@@ -173,6 +174,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/0021-Add-canvas-image-extraction-prompt.patch b/src/current-patches/firefox/0021-Add-canvas-image-extraction-prompt.patch
deleted file mode 100644
index cf5dd61..0000000
--- a/src/current-patches/firefox/0021-Add-canvas-image-extraction-prompt.patch
+++ /dev/null
@@ -1,551 +0,0 @@
-From 29ce940434ebbb8e54c0d9b8f84ccf6ec6bd71bc Mon Sep 17 00:00:00 2001
-From: Kathleen Brade <brade(a)pearlcrescent.com>
-Date: Tue, 9 Oct 2012 11:21:06 -0400
-Subject: [PATCH 21/24] Add canvas image extraction prompt.
-
----
- browser/base/content/browser.css | 1 +
- browser/base/content/browser.js | 102 ++++++++++++++++++++
- browser/base/content/browser.xul | 1 +
- .../en-US/chrome/browser/browser.properties | 7 ++
- browser/themes/gnomestripe/browser/browser.css | 2 +
- browser/themes/pinstripe/browser/browser.css | 2 +
- browser/themes/winstripe/browser/browser.css | 2 +
- content/canvas/src/CanvasUtils.cpp | 63 ++++++++++++
- content/canvas/src/CanvasUtils.h | 2 +
- content/canvas/src/nsCanvasRenderingContext2D.cpp | 15 +++
- .../canvas/src/nsCanvasRenderingContext2DAzure.cpp | 15 +++
- content/html/content/public/nsHTMLCanvasElement.h | 3 +
- content/html/content/src/Makefile.in | 1 +
- content/html/content/src/nsHTMLCanvasElement.cpp | 39 ++++++--
- 14 files changed, 246 insertions(+), 9 deletions(-)
-
-diff --git a/browser/base/content/browser.css b/browser/base/content/browser.css
-index f033c2b..c709631 100644
---- a/browser/base/content/browser.css
-+++ b/browser/base/content/browser.css
-@@ -440,6 +440,7 @@ window[chromehidden~="toolbar"] toolbar:not(.toolbar-primary):not(.chromeclass-m
- created with a null anchorID, so in that case use a default anchor icon. */
- #notification-popup-box[anchorid="notification-popup-box"] > #default-notification-icon,
- #notification-popup-box[anchorid="geo-notification-icon"] > #geo-notification-icon,
-+#notification-popup-box[anchorid="canvas-notification-icon"] > #canvas-notification-icon,
- #notification-popup-box[anchorid="indexedDB-notification-icon"] > #indexedDB-notification-icon,
- #notification-popup-box[anchorid="addons-notification-icon"] > #addons-notification-icon,
- #notification-popup-box[anchorid="password-notification-icon"] > #password-notification-icon {
-diff --git a/browser/base/content/browser.js b/browser/base/content/browser.js
-index 20e3666..0c6bd46 100644
---- a/browser/base/content/browser.js
-+++ b/browser/base/content/browser.js
-@@ -1522,6 +1522,7 @@ function delayedStartup(isLoadingBlank, mustLoadSidebar) {
- BrowserOffline.init();
- OfflineApps.init();
- IndexedDBPromptHelper.init();
-+ CanvasPermissionPromptHelper.init();
- gFormSubmitObserver.init();
- AddonManager.addAddonListener(AddonsMgrListener);
-
-@@ -1834,6 +1835,7 @@ function BrowserShutdown() {
- BrowserOffline.uninit();
- OfflineApps.uninit();
- IndexedDBPromptHelper.uninit();
-+ CanvasPermissionPromptHelper.uninit();
- AddonManager.removeAddonListener(AddonsMgrListener);
- }
-
-@@ -6656,6 +6658,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 ba2a7cb..1acea43 100644
---- a/browser/base/content/browser.xul
-+++ b/browser/base/content/browser.xul
-@@ -520,6 +520,7 @@
- <image id="default-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"/>
- </box>
-diff --git a/browser/locales/en-US/chrome/browser/browser.properties b/browser/locales/en-US/chrome/browser/browser.properties
-index 380e3c3..98154d1 100644
---- a/browser/locales/en-US/chrome/browser/browser.properties
-+++ b/browser/locales/en-US/chrome/browser/browser.properties
-@@ -197,6 +197,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. Blank (white) 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/browser.css b/browser/themes/gnomestripe/browser/browser.css
-index edc0b72..8ba057e 100644
---- a/browser/themes/gnomestripe/browser/browser.css
-+++ b/browser/themes/gnomestripe/browser/browser.css
-@@ -1227,6 +1227,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);
-@@ -1281,6 +1282,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/browser.css b/browser/themes/pinstripe/browser/browser.css
-index 2a96556..f94a6f2 100644
---- a/browser/themes/pinstripe/browser/browser.css
-+++ b/browser/themes/pinstripe/browser/browser.css
-@@ -2404,10 +2404,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/browser.css b/browser/themes/winstripe/browser/browser.css
-index 0103c79..d352790 100644
---- a/browser/themes/winstripe/browser/browser.css
-+++ b/browser/themes/winstripe/browser/browser.css
-@@ -2294,6 +2294,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);
-@@ -2346,6 +2347,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 2f822eb..d7d0591 100644
---- a/content/canvas/src/CanvasUtils.cpp
-+++ b/content/canvas/src/CanvasUtils.cpp
-@@ -59,6 +59,15 @@
- #include "CanvasUtils.h"
- #include "mozilla/gfx/Matrix.h"
-
-+#include "nsIScriptObjectPrincipal.h"
-+#include "nsIPermissionManager.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 {
-
-@@ -101,6 +110,60 @@ DoDrawImageSecurityCheck(nsHTMLCanvasElement *aCanvasElement,
- aCanvasElement->SetWriteOnly();
- }
-
-+// 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
- LogMessage (const nsCString& errorString)
- {
-diff --git a/content/canvas/src/CanvasUtils.h b/content/canvas/src/CanvasUtils.h
-index 36186dd..067ee46 100644
---- a/content/canvas/src/CanvasUtils.h
-+++ b/content/canvas/src/CanvasUtils.h
-@@ -77,6 +77,8 @@ void DoDrawImageSecurityCheck(nsHTMLCanvasElement *aCanvasElement,
- bool forceWriteOnly,
- bool CORSUsed);
-
-+bool IsImageExtractionAllowed(nsIDocument *aDocument);
-+
- void LogMessage (const nsCString& errorString);
- void LogMessagef (const char *fmt, ...);
-
-diff --git a/content/canvas/src/nsCanvasRenderingContext2D.cpp b/content/canvas/src/nsCanvasRenderingContext2D.cpp
-index 36389b0..0cf97ce 100644
---- a/content/canvas/src/nsCanvasRenderingContext2D.cpp
-+++ b/content/canvas/src/nsCanvasRenderingContext2D.cpp
-@@ -3886,6 +3886,21 @@ nsCanvasRenderingContext2D::GetImageData_explicit(PRInt32 x, PRInt32 y, PRUint32
- if (!rightMost.valid() || !bottomMost.valid())
- return NS_ERROR_DOM_SYNTAX_ERR;
-
-+ // 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 = HTMLCanvasElement()->OwnerDoc();
-+ usePlaceholder = !ownerDoc ||
-+ !CanvasUtils::IsImageExtractionAllowed(ownerDoc);
-+ }
-+
-+ if (usePlaceholder) {
-+ memset(aData, 0xFF, aDataLen);
-+ return NS_OK;
-+ }
-+
- /* Copy the surface contents to the buffer */
- nsRefPtr<gfxImageSurface> tmpsurf =
- new gfxImageSurface(aData,
-diff --git a/content/canvas/src/nsCanvasRenderingContext2DAzure.cpp b/content/canvas/src/nsCanvasRenderingContext2DAzure.cpp
-index 13baaa5..e8dfb1e 100644
---- a/content/canvas/src/nsCanvasRenderingContext2DAzure.cpp
-+++ b/content/canvas/src/nsCanvasRenderingContext2DAzure.cpp
-@@ -4038,6 +4038,21 @@ nsCanvasRenderingContext2DAzure::GetImageData_explicit(PRInt32 x, PRInt32 y, PRU
- return NS_OK;
- }
-
-+ // 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 = HTMLCanvasElement()->OwnerDoc();
-+ usePlaceholder = !ownerDoc ||
-+ !CanvasUtils::IsImageExtractionAllowed(ownerDoc);
-+ }
-+
-+ if (usePlaceholder) {
-+ memset(aData, 0xFF, aDataLen);
-+ return NS_OK;
-+ }
-+
- IntRect srcRect(0, 0, mWidth, mHeight);
- IntRect destRect(x, y, w, h);
-
-diff --git a/content/html/content/public/nsHTMLCanvasElement.h b/content/html/content/public/nsHTMLCanvasElement.h
-index 86202a8..66176f2 100644
---- a/content/html/content/public/nsHTMLCanvasElement.h
-+++ b/content/html/content/public/nsHTMLCanvasElement.h
-@@ -188,13 +188,16 @@ protected:
- nsresult UpdateContext(nsIPropertyBag *aNewContextOptions = nsnull);
- 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 019d297..3db4f7c 100644
---- a/content/html/content/src/Makefile.in
-+++ b/content/html/content/src/Makefile.in
-@@ -138,6 +138,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 a302f67..572a81b 100644
---- a/content/html/content/src/nsHTMLCanvasElement.cpp
-+++ b/content/html/content/src/nsHTMLCanvasElement.cpp
-@@ -60,6 +60,8 @@
-
- #include "nsIWritablePropertyBag2.h"
-
-+#include "CanvasUtils.h"
-+
- #define DEFAULT_CANVAS_WIDTH 300
- #define DEFAULT_CANVAS_HEIGHT 150
-
-@@ -213,25 +215,36 @@ 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);
- }
-
-+// TODO: on FF trunk, we also need to patch mozFetchAsStream().
- 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;
-@@ -241,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;
-
-@@ -284,6 +298,7 @@ nsHTMLCanvasElement::ExtractData(const nsAString& aType,
- nsresult
- nsHTMLCanvasElement::ToDataURLImpl(const nsAString& aMimeType,
- nsIVariant* aEncoderOptions,
-+ bool aUsePlaceholder,
- nsAString& aDataURL)
- {
- bool fallbackToPNG = false;
-@@ -339,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);
-@@ -376,19 +393,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
new file mode 100644
index 0000000..d927f02
--- /dev/null
+++ b/src/current-patches/firefox/0021-Return-client-window-coordinates-for-mouse-event-scr.patch
@@ -0,0 +1,77 @@
+From 5db96e68af26dfbfa2085d76efab8ddc09aaa45c Mon Sep 17 00:00:00 2001
+From: Kathleen Brade <brade(a)pearlcrescent.com>
+Date: Wed, 28 Nov 2012 10:49:09 -0500
+Subject: [PATCH 21/26] 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 c1784c9..9718a90 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
new file mode 100644
index 0000000..13551af
--- /dev/null
+++ b/src/current-patches/firefox/0022-Do-not-expose-physical-screen-info.-via-window-and-w.patch
@@ -0,0 +1,310 @@
+From c4e1460f46fc04d81ec643fa9680b8fad8bc2b29 Mon Sep 17 00:00:00 2001
+From: Kathleen Brade <brade(a)pearlcrescent.com>
+Date: Wed, 28 Nov 2012 11:25:14 -0500
+Subject: [PATCH 22/26] 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 6acd80a..3a370c9 100644
+--- a/dom/base/nsGlobalWindow.cpp
++++ b/dom/base/nsGlobalWindow.cpp
+@@ -3742,6 +3742,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);
+@@ -3755,6 +3759,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);
+@@ -3817,6 +3825,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);
+@@ -3858,6 +3872,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;
+@@ -3868,6 +3888,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;
+@@ -4025,6 +4051,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);
+@@ -4071,6 +4103,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/0022-Return-client-window-coordinates-for-mouse-event-scr.patch b/src/current-patches/firefox/0022-Return-client-window-coordinates-for-mouse-event-scr.patch
deleted file mode 100644
index 6da9c72..0000000
--- a/src/current-patches/firefox/0022-Return-client-window-coordinates-for-mouse-event-scr.patch
+++ /dev/null
@@ -1,43 +0,0 @@
-From 74215e38ba60b74df59216122c4f2cc068e33216 Mon Sep 17 00:00:00 2001
-From: Kathleen Brade <brade(a)pearlcrescent.com>
-Date: Tue, 9 Oct 2012 11:13:45 -0400
-Subject: [PATCH 22/24] Return client window coordinates for mouse event
- screenX/Y (for dragend, 0,0 is returned).
-
----
- content/events/src/nsDOMUIEvent.cpp | 15 +++++++++++++++
- 1 files changed, 15 insertions(+), 0 deletions(-)
-
-diff --git a/content/events/src/nsDOMUIEvent.cpp b/content/events/src/nsDOMUIEvent.cpp
-index fe57f52..d641f0d 100644
---- a/content/events/src/nsDOMUIEvent.cpp
-+++ b/content/events/src/nsDOMUIEvent.cpp
-@@ -135,10 +135,25 @@ nsDOMUIEvent::GetScreenPoint()
- return nsIntPoint(0, 0);
- }
-
-+ bool isChrome = nsContentUtils::IsCallerChrome();
-+
- if (!((nsGUIEvent*)mEvent)->widget ) {
-+ // For non-chrome callers, return 0,0 if there is no widget associated
-+ // with this event, e.g., for dragend events. 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,0 should
-+ // not break many web pages. Also, a few years ago Firefox returned 0,0.
-+ // See: https://bugzilla.mozilla.org/show_bug.cgi?id=466379
-+ if (!isChrome)
-+ return nsIntPoint(0, 0);
-+
- return mEvent->refPoint;
- }
-
-+ // For non-chrome callers, return client area coordinates instead.
-+ if (!isChrome)
-+ return GetClientPoint();
-+
- nsIntPoint offset = mEvent->refPoint +
- ((nsGUIEvent*)mEvent)->widget->WidgetToScreenOffset();
- nscoord factor = mPresContext->DeviceContext()->UnscaledAppUnitsPerDevPixel();
---
-1.7.5.4
-
diff --git a/src/current-patches/firefox/0023-Do-not-expose-physical-screen-info.-via-window-and-w.patch b/src/current-patches/firefox/0023-Do-not-expose-physical-screen-info.-via-window-and-w.patch
deleted file mode 100644
index 1b925e0..0000000
--- a/src/current-patches/firefox/0023-Do-not-expose-physical-screen-info.-via-window-and-w.patch
+++ /dev/null
@@ -1,312 +0,0 @@
-From d944531b020848e09ac280af11d039d992ab6461 Mon Sep 17 00:00:00 2001
-From: Kathleen Brade <brade(a)pearlcrescent.com>
-Date: Wed, 3 Oct 2012 17:06:48 -0400
-Subject: [PATCH 23/24] 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 | 92 +++++++++++++++++++++++++++++++++++++++++++
- dom/base/nsScreen.h | 3 +
- 4 files changed, 143 insertions(+), 0 deletions(-)
-
-diff --git a/dom/base/nsGlobalWindow.cpp b/dom/base/nsGlobalWindow.cpp
-index 2c99571..982d931 100644
---- a/dom/base/nsGlobalWindow.cpp
-+++ b/dom/base/nsGlobalWindow.cpp
-@@ -3817,6 +3817,10 @@ nsGlobalWindow::GetOuterWidth(PRInt32* 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);
-@@ -3830,6 +3834,10 @@ nsGlobalWindow::GetOuterHeight(PRInt32* 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);
-@@ -3892,6 +3900,12 @@ nsGlobalWindow::GetScreenX(PRInt32* 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);
-@@ -3933,6 +3947,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;
-@@ -3943,6 +3963,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;
-@@ -4064,6 +4090,12 @@ nsGlobalWindow::GetScreenY(PRInt32* 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);
-@@ -4110,6 +4142,20 @@ nsGlobalWindow::SetScreenY(PRInt32 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 2ffe4a7..863329c 100644
---- a/dom/base/nsGlobalWindow.h
-+++ b/dom/base/nsGlobalWindow.h
-@@ -744,6 +744,8 @@ protected:
- nsresult SetOuterSize(PRInt32 aLengthCSSPixels, bool aIsWidth);
- nsRect GetInnerScreenRect();
-
-+ bool IsChrome();
-+
- bool IsFrame()
- {
- return GetParentInternal() != nsnull;
-diff --git a/dom/base/nsScreen.cpp b/dom/base/nsScreen.cpp
-index 33a03dc..29a3598 100644
---- a/dom/base/nsScreen.cpp
-+++ b/dom/base/nsScreen.cpp
-@@ -82,6 +82,12 @@ nsScreen::SetDocShell(nsIDocShell* aDocShell)
- NS_IMETHODIMP
- nsScreen::GetTop(PRInt32* aTop)
- {
-+ // For non-chrome callers, always return 0 to prevent fingerprinting.
-+ if (!IsChrome()) {
-+ *aTop = 0;
-+ return NS_OK;
-+ }
-+
- nsRect rect;
- nsresult rv = GetRect(rect);
-
-@@ -94,6 +100,12 @@ nsScreen::GetTop(PRInt32* aTop)
- NS_IMETHODIMP
- nsScreen::GetLeft(PRInt32* aLeft)
- {
-+ // For non-chrome callers, always return 0 to prevent fingerprinting.
-+ if (!IsChrome()) {
-+ *aLeft = 0;
-+ return NS_OK;
-+ }
-+
- nsRect rect;
- nsresult rv = GetRect(rect);
-
-@@ -106,6 +118,14 @@ nsScreen::GetLeft(PRInt32* aLeft)
- NS_IMETHODIMP
- nsScreen::GetWidth(PRInt32* 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);
-
-@@ -117,6 +137,14 @@ nsScreen::GetWidth(PRInt32* aWidth)
- NS_IMETHODIMP
- nsScreen::GetHeight(PRInt32* 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);
-
-@@ -128,6 +156,12 @@ nsScreen::GetHeight(PRInt32* aHeight)
- NS_IMETHODIMP
- nsScreen::GetPixelDepth(PRInt32* aPixelDepth)
- {
-+ // For non-chrome callers, always return 24 to prevent fingerprinting.
-+ if (!IsChrome()) {
-+ *aPixelDepth = 24;
-+ return NS_OK;
-+ }
-+
- nsDeviceContext* context = GetDeviceContext();
-
- if (!context) {
-@@ -153,6 +187,14 @@ nsScreen::GetColorDepth(PRInt32* aColorDepth)
- NS_IMETHODIMP
- nsScreen::GetAvailWidth(PRInt32* 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);
-
-@@ -164,6 +206,14 @@ nsScreen::GetAvailWidth(PRInt32* aAvailWidth)
- NS_IMETHODIMP
- nsScreen::GetAvailHeight(PRInt32* 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);
-
-@@ -175,6 +225,12 @@ nsScreen::GetAvailHeight(PRInt32* aAvailHeight)
- NS_IMETHODIMP
- nsScreen::GetAvailLeft(PRInt32* aAvailLeft)
- {
-+ // For non-chrome callers, always return 0 to prevent fingerprinting.
-+ if (!IsChrome()) {
-+ *aAvailLeft = 0;
-+ return NS_OK;
-+ }
-+
- nsRect rect;
- nsresult rv = GetAvailRect(rect);
-
-@@ -186,6 +242,12 @@ nsScreen::GetAvailLeft(PRInt32* aAvailLeft)
- NS_IMETHODIMP
- nsScreen::GetAvailTop(PRInt32* aAvailTop)
- {
-+ // For non-chrome callers, always return 0 to prevent fingerprinting.
-+ if (!IsChrome()) {
-+ *aAvailTop = 0;
-+ return NS_OK;
-+ }
-+
- nsRect rect;
- nsresult rv = GetAvailRect(rect);
-
-@@ -237,3 +299,33 @@ nsScreen::GetAvailRect(nsRect& aRect)
-
- return NS_OK;
- }
-+
-+bool
-+nsScreen::IsChrome()
-+{
-+ bool isChrome = false;
-+ if (mDocShell) {
-+ nsRefPtr<nsPresContext> presContext;
-+ mDocShell->GetPresContext(getter_AddRefs(presContext));
-+ if (presContext)
-+ isChrome = presContext->IsChrome();
-+ }
-+
-+ return isChrome;
-+}
-+
-+nsresult
-+nsScreen::GetDOMWindow(nsIDOMWindow **aResult)
-+{
-+ NS_ENSURE_ARG_POINTER(aResult);
-+ *aResult = NULL;
-+
-+ if (!mDocShell)
-+ return NS_ERROR_FAILURE;
-+
-+ nsCOMPtr<nsIDOMWindow> win = do_GetInterface(mDocShell);
-+ NS_ENSURE_STATE(win);
-+ win.swap(*aResult);
-+
-+ return NS_OK;
-+}
-diff --git a/dom/base/nsScreen.h b/dom/base/nsScreen.h
-index 52eab29..d4edaa3 100644
---- a/dom/base/nsScreen.h
-+++ b/dom/base/nsScreen.h
-@@ -44,6 +44,7 @@
-
- class nsIDocShell;
- class nsDeviceContext;
-+class nsIDOMWindow;
- struct nsRect;
-
- // Script "screen" object
-@@ -62,6 +63,8 @@ protected:
- nsDeviceContext* GetDeviceContext();
- nsresult GetRect(nsRect& aRect);
- nsresult GetAvailRect(nsRect& aRect);
-+ bool IsChrome();
-+ nsresult GetDOMWindow(nsIDOMWindow **aResult);
-
- nsIDocShell* mDocShell; // Weak Reference
- };
---
-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
new file mode 100644
index 0000000..ea6ee8f
--- /dev/null
+++ b/src/current-patches/firefox/0023-Do-not-expose-system-colors-to-CSS-or-canvas.patch
@@ -0,0 +1,466 @@
+From 0b97e36981bb26406087bbd502a4d9e91e33a150 Mon Sep 17 00:00:00 2001
+From: Kathleen Brade <brade(a)pearlcrescent.com>
+Date: Wed, 28 Nov 2012 15:08:40 -0500
+Subject: [PATCH 23/26] Do not expose system colors to CSS or canvas.
+
+---
+ content/canvas/src/nsCanvasRenderingContext2D.cpp | 28 +++-
+ .../canvas/src/nsCanvasRenderingContext2DAzure.cpp | 34 +++-
+ .../canvas/src/nsCanvasRenderingContext2DAzure.h | 5 +-
+ layout/style/nsRuleNode.cpp | 5 +-
+ widget/LookAndFeel.h | 9 +
+ widget/xpwidgets/nsXPLookAndFeel.cpp | 173 +++++++++++++++++++-
+ widget/xpwidgets/nsXPLookAndFeel.h | 5 +-
+ 7 files changed, 239 insertions(+), 20 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/style/nsRuleNode.cpp b/layout/style/nsRuleNode.cpp
+index 33ce21e..078af3e 100644
+--- a/layout/style/nsRuleNode.cpp
++++ b/layout/style/nsRuleNode.cpp
+@@ -746,7 +746,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..59f00f5 100644
+--- a/widget/LookAndFeel.h
++++ b/widget/LookAndFeel.h
+@@ -446,6 +446,15 @@ 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);
++
++ /**
+ * 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..20ccfef 100644
+--- a/widget/xpwidgets/nsXPLookAndFeel.cpp
++++ b/widget/xpwidgets/nsXPLookAndFeel.cpp
+@@ -476,6 +476,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 +632,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 +719,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 +756,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 +852,15 @@ 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
+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.5.4
+
diff --git a/src/current-patches/firefox/0024-Do-not-expose-system-colors-to-CSS-or-canvas.patch b/src/current-patches/firefox/0024-Do-not-expose-system-colors-to-CSS-or-canvas.patch
deleted file mode 100644
index 629a759..0000000
--- a/src/current-patches/firefox/0024-Do-not-expose-system-colors-to-CSS-or-canvas.patch
+++ /dev/null
@@ -1,537 +0,0 @@
-From 38a469e05779315cb2990be60c13fb167812e54d Mon Sep 17 00:00:00 2001
-From: Kathleen Brade <brade(a)pearlcrescent.com>
-Date: Thu, 4 Oct 2012 14:53:13 -0400
-Subject: [PATCH 24/24] Do not expose system colors to CSS or canvas.
-
----
- content/canvas/src/nsCanvasRenderingContext2D.cpp | 36 +++-
- .../canvas/src/nsCanvasRenderingContext2DAzure.cpp | 51 ++++--
- layout/style/nsCSSParser.cpp | 19 ++-
- layout/style/nsRuleNode.cpp | 4 +-
- widget/public/LookAndFeel.h | 9 +
- widget/src/xpwidgets/nsXPLookAndFeel.cpp | 173 +++++++++++++++++++-
- widget/src/xpwidgets/nsXPLookAndFeel.h | 5 +-
- 7 files changed, 269 insertions(+), 28 deletions(-)
-
-diff --git a/content/canvas/src/nsCanvasRenderingContext2D.cpp b/content/canvas/src/nsCanvasRenderingContext2D.cpp
-index 0cf97ce..6c47821 100644
---- a/content/canvas/src/nsCanvasRenderingContext2D.cpp
-+++ b/content/canvas/src/nsCanvasRenderingContext2D.cpp
-@@ -186,8 +186,9 @@ class nsCanvasGradient : 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)
- {
- }
-
-@@ -203,7 +204,7 @@ public:
- return NS_ERROR_DOM_INDEX_SIZE_ERR;
-
- nscolor color;
-- nsCSSParser parser;
-+ nsCSSParser parser(mCSSLoader);
- nsresult rv = parser.ParseColorString(nsString(colorstr),
- nsnull, 0, &color);
- if (NS_FAILED(rv))
-@@ -217,6 +218,7 @@ public:
- NS_DECL_ISUPPORTS
-
- protected:
-+ mozilla::css::Loader* mCSSLoader; // not ref counted, it owns us
- nsRefPtr<gfxPattern> mPattern;
- };
-
-@@ -875,7 +877,9 @@ nsCanvasRenderingContext2D::SetStyleFromStringOrInterface(const nsAString& aStr,
- HTMLCanvasElement()->OwnerDoc() : nsnull;
-
- // Pass the CSS Loader object to the parser, to allow parser error
-- // reports to include the outer window ID.
-+ // reports to include the outer window ID. The parser also uses it to
-+ // detect whether the caller is chrome in order to avoid exposing
-+ // system colors.
- nsCSSParser parser(document ? document->CSSLoader() : nsnull);
- rv = parser.ParseColorString(aStr, nsnull, 0, &color);
- if (NS_FAILED(rv)) {
-@@ -1778,7 +1782,14 @@ nsCanvasRenderingContext2D::CreateLinearGradient(float x0, float y0, float x1, f
- if (!gradpat)
- return NS_ERROR_OUT_OF_MEMORY;
-
-- nsRefPtr<nsIDOMCanvasGradient> grad = new nsCanvasGradient(gradpat);
-+ // Pass the CSS Loader object to the parser, to allow parser error reports
-+ // to include the outer window ID. The parser also uses it to detect
-+ // whether the caller is chrome in order to avoid exposing system colors.
-+ nsIDocument* doc = mCanvasElement ? HTMLCanvasElement()->OwnerDoc()
-+ : nsnull;
-+ mozilla::css::Loader* cssLoader = doc ? doc->CSSLoader() : nsnull;
-+ nsRefPtr<nsIDOMCanvasGradient> grad = new nsCanvasGradient(cssLoader,
-+ gradpat);
- if (!grad)
- return NS_ERROR_OUT_OF_MEMORY;
-
-@@ -1800,7 +1811,14 @@ nsCanvasRenderingContext2D::CreateRadialGradient(float x0, float y0, float r0, f
- if (!gradpat)
- return NS_ERROR_OUT_OF_MEMORY;
-
-- nsRefPtr<nsIDOMCanvasGradient> grad = new nsCanvasGradient(gradpat);
-+ // Pass the CSS Loader object to the parser, to allow parser error reports
-+ // to include the outer window ID. The parser also uses it to detect
-+ // whether the caller is chrome in order to avoid exposing system colors.
-+ nsIDocument* doc = mCanvasElement ? HTMLCanvasElement()->OwnerDoc()
-+ : nsnull;
-+ mozilla::css::Loader* cssLoader = doc ? doc->CSSLoader() : nsnull;
-+ nsRefPtr<nsIDOMCanvasGradient> grad = new nsCanvasGradient(cssLoader,
-+ gradpat);
- if (!grad)
- return NS_ERROR_OUT_OF_MEMORY;
-
-@@ -1922,7 +1940,8 @@ nsCanvasRenderingContext2D::SetShadowColor(const nsAString& colorstr)
- HTMLCanvasElement()->OwnerDoc() : nsnull;
-
- // Pass the CSS Loader object to the parser, to allow parser error reports
-- // to include the outer window ID.
-+ // to include the outer window ID. The parser also uses it to detect
-+ // whether the caller is chrome in order to avoid exposing system colors.
- nsCSSParser parser(document ? document->CSSLoader() : nsnull);
- nscolor color;
- nsresult rv = parser.ParseColorString(colorstr, nsnull, 0, &color);
-@@ -3694,7 +3713,8 @@ nsCanvasRenderingContext2D::DrawWindow(nsIDOMWindow* aWindow, float aX, float aY
- HTMLCanvasElement()->OwnerDoc() : nsnull;
-
- // Pass the CSS Loader object to the parser, to allow parser error reports
-- // to include the outer window ID.
-+ // to include the outer window ID. The parser also uses it to detect
-+ // whether the caller is chrome in order to avoid exposing system colors.
- nsCSSParser parser(elementDoc ? elementDoc->CSSLoader() : nsnull);
- nsresult rv = parser.ParseColorString(PromiseFlatString(aBGColor),
- nsnull, 0, &bgColor);
-diff --git a/content/canvas/src/nsCanvasRenderingContext2DAzure.cpp b/content/canvas/src/nsCanvasRenderingContext2DAzure.cpp
-index e8dfb1e..cb5a5f5 100644
---- a/content/canvas/src/nsCanvasRenderingContext2DAzure.cpp
-+++ b/content/canvas/src/nsCanvasRenderingContext2DAzure.cpp
-@@ -201,7 +201,10 @@ public:
- }
-
- nscolor color;
-- nsCSSParser parser;
-+ // Pass the CSS Loader object to the parser, to allow parser error reports
-+ // to include the outer window ID. The parser also uses it to detect
-+ // whether the caller is chrome in order to avoid exposing system colors.
-+ nsCSSParser parser(mCSSLoader);;
- nsresult rv = parser.ParseColorString(nsString(colorstr),
- nsnull, 0, &color);
- if (NS_FAILED(rv)) {
-@@ -221,20 +224,24 @@ public:
- }
-
- protected:
-- nsCanvasGradientAzure(Type aType) : mType(aType)
-+ nsCanvasGradientAzure(mozilla::css::Loader* aLoader, Type aType)
-+ : mCSSLoader(aLoader)
-+ , mType(aType)
- {}
-
- nsTArray<GradientStop> mRawStops;
- RefPtr<GradientStops> mStops;
-+ mozilla::css::Loader* mCSSLoader; // not ref counted, it owns us
- Type mType;
- };
-
- 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)
-@@ -251,8 +258,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)
- {
-@@ -1066,8 +1074,9 @@ nsCanvasRenderingContext2DAzure::SetStyleFromStringOrInterface(const nsAString&
- nsIDocument* document = mCanvasElement ?
- HTMLCanvasElement()->OwnerDoc() : nsnull;
-
-- // Pass the CSS Loader object to the parser, to allow parser error
-- // reports to include the outer window ID.
-+ // Pass the CSS Loader object to the parser, to allow parser error reports
-+ // to include the outer window ID. The parser also uses it to detect
-+ // whether the caller is chrome in order to avoid exposing system colors.
- nsCSSParser parser(document ? document->CSSLoader() : nsnull);
- rv = parser.ParseColorString(aStr, nsnull, 0, &color);
- if (NS_FAILED(rv)) {
-@@ -1855,8 +1864,14 @@ nsCanvasRenderingContext2DAzure::CreateLinearGradient(float x0, float y0, float
- return NS_ERROR_DOM_NOT_SUPPORTED_ERR;
- }
-
-- nsRefPtr<nsIDOMCanvasGradient> grad =
-- new nsCanvasLinearGradientAzure(Point(x0, y0), Point(x1, y1));
-+ // Pass the CSS Loader object to the parser, to allow parser error reports
-+ // to include the outer window ID. The parser also uses it to detect
-+ // whether the caller is chrome in order to avoid exposing system colors.
-+ nsIDocument* doc = mCanvasElement ? HTMLCanvasElement()->OwnerDoc()
-+ : nsnull;
-+ mozilla::css::Loader* cssLoader = doc ? doc->CSSLoader() : nsnull;
-+ nsRefPtr<nsIDOMCanvasGradient> grad = new nsCanvasLinearGradientAzure(
-+ cssLoader, Point(x0, y0), Point(x1, y1));
-
- *_retval = grad.forget().get();
- return NS_OK;
-@@ -1875,8 +1890,14 @@ nsCanvasRenderingContext2DAzure::CreateRadialGradient(float x0, float y0, float
- return NS_ERROR_DOM_INDEX_SIZE_ERR;
- }
-
-- nsRefPtr<nsIDOMCanvasGradient> grad =
-- new nsCanvasRadialGradientAzure(Point(x0, y0), r0, Point(x1, y1), r1);
-+ // Pass the CSS Loader object to the parser, to allow parser error reports
-+ // to include the outer window ID. The parser also uses it to detect
-+ // whether the caller is chrome in order to avoid exposing system colors.
-+ nsIDocument* doc = mCanvasElement ? HTMLCanvasElement()->OwnerDoc()
-+ : nsnull;
-+ mozilla::css::Loader* cssLoader = doc ? doc->CSSLoader() : nsnull;
-+ nsRefPtr<nsIDOMCanvasGradient> grad = new nsCanvasRadialGradientAzure(
-+ cssLoader, Point(x0, y0), r0, Point(x1, y1), r1);
-
- *_retval = grad.forget().get();
- return NS_OK;
-@@ -2024,7 +2045,8 @@ nsCanvasRenderingContext2DAzure::SetShadowColor(const nsAString& colorstr)
- HTMLCanvasElement()->OwnerDoc() : nsnull;
-
- // Pass the CSS Loader object to the parser, to allow parser error reports
-- // to include the outer window ID.
-+ // to include the outer window ID. The parser also uses it to detect
-+ // whether the caller is chrome in order to avoid exposing system colors.
- nsCSSParser parser(document ? document->CSSLoader() : nsnull);
- nscolor color;
- nsresult rv = parser.ParseColorString(colorstr, nsnull, 0, &color);
-@@ -3847,7 +3869,8 @@ nsCanvasRenderingContext2DAzure::DrawWindow(nsIDOMWindow* aWindow, float aX, flo
- HTMLCanvasElement()->OwnerDoc() : nsnull;
-
- // Pass the CSS Loader object to the parser, to allow parser error reports
-- // to include the outer window ID.
-+ // to include the outer window ID. The parser also uses it to detect
-+ // whether the caller is chrome in order to avoid exposing system colors.
- nsCSSParser parser(elementDoc ? elementDoc->CSSLoader() : nsnull);
- nsresult rv = parser.ParseColorString(PromiseFlatString(aBGColor),
- nsnull, 0, &bgColor);
-diff --git a/layout/style/nsCSSParser.cpp b/layout/style/nsCSSParser.cpp
-index ae1a474..30e179c 100644
---- a/layout/style/nsCSSParser.cpp
-+++ b/layout/style/nsCSSParser.cpp
-@@ -1216,8 +1216,25 @@ CSSParserImpl::ParseColorString(const nsSubstring& aBuffer,
- // Should remove this limitation at some point.
- return NS_ERROR_FAILURE;
- }
-+
-+ // We do not want to expose system/native colors to content. All callers
-+ // who are working with content should ensure that they set the CSS
-+ // loader (mChildLoader) so we can check here if the content is chrome.
-+ bool isChrome = true;
-+ if (mChildLoader) {
-+ nsIDocument *doc = mChildLoader->GetDocument();
-+ if (doc) {
-+ nsIPresShell *presShell = doc->GetShell();
-+ if (presShell) {
-+ nsPresContext* presCtxt = presShell->GetPresContext();
-+ if (presCtxt)
-+ isChrome = presCtxt->IsChrome();
-+ }
-+ }
-+ }
- nscolor rgba;
-- nsresult rv = LookAndFeel::GetColor(LookAndFeel::ColorID(val), &rgba);
-+ nsresult rv = LookAndFeel::GetColor(LookAndFeel::ColorID(val), !isChrome,
-+ &rgba);
- if (NS_FAILED(rv)) {
- return rv;
- }
-diff --git a/layout/style/nsRuleNode.cpp b/layout/style/nsRuleNode.cpp
-index 827585a..d19524e 100644
---- a/layout/style/nsRuleNode.cpp
-+++ b/layout/style/nsRuleNode.cpp
-@@ -768,7 +768,9 @@ static bool SetColor(const nsCSSValue& aValue, const nscolor aParentColor,
- PRInt32 intValue = aValue.GetIntValue();
- if (0 <= intValue) {
- LookAndFeel::ColorID colorID = (LookAndFeel::ColorID) intValue;
-- if (NS_SUCCEEDED(LookAndFeel::GetColor(colorID, &aResult))) {
-+ bool useStandinsForNativeColors = !aPresContext->IsChrome();
-+ if (NS_SUCCEEDED(LookAndFeel::GetColor(colorID,
-+ useStandinsForNativeColors, &aResult))) {
- result = true;
- }
- }
-diff --git a/widget/public/LookAndFeel.h b/widget/public/LookAndFeel.h
-index aae3b28..bb7be3c 100644
---- a/widget/public/LookAndFeel.h
-+++ b/widget/public/LookAndFeel.h
-@@ -445,6 +445,15 @@ 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);
-+
-+ /**
- * 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/src/xpwidgets/nsXPLookAndFeel.cpp b/widget/src/xpwidgets/nsXPLookAndFeel.cpp
-index 8053432..96937ac 100644
---- a/widget/src/xpwidgets/nsXPLookAndFeel.cpp
-+++ b/widget/src/xpwidgets/nsXPLookAndFeel.cpp
-@@ -502,6 +502,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;
-@@ -509,7 +658,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();
-@@ -595,7 +745,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;
- }
-@@ -629,6 +782,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)) {
-@@ -719,7 +878,15 @@ 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
-diff --git a/widget/src/xpwidgets/nsXPLookAndFeel.h b/widget/src/xpwidgets/nsXPLookAndFeel.h
-index ce06575..c0ecc32 100644
---- a/widget/src/xpwidgets/nsXPLookAndFeel.h
-+++ b/widget/src/xpwidgets/nsXPLookAndFeel.h
-@@ -84,7 +84,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, PRInt32 &aResult);
- virtual nsresult GetFloatImpl(FloatID aID, float &aResult);
-
-@@ -111,6 +112,8 @@ protected:
- void InitColorFromPref(PRInt32 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.5.4
-
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
new file mode 100644
index 0000000..0f1a702
--- /dev/null
+++ b/src/current-patches/firefox/0024-Isolate-the-Image-Cache-per-url-bar-domain.patch
@@ -0,0 +1,912 @@
+From 56d3f40086757ecefe1efbeca00b285a13bde5d4 Mon Sep 17 00:00:00 2001
+From: Mike Perry <mikeperry-git(a)torproject.org>
+Date: Thu, 6 Dec 2012 14:19:34 -0800
+Subject: [PATCH 24/26] 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 | 256 +++++++++++++-------
+ 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, 246 insertions(+), 118 deletions(-)
+
+diff --git a/content/base/src/nsContentUtils.cpp b/content/base/src/nsContentUtils.cpp
+index fe3c8a0..43f8f69 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..88e367c 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);
+
+- nsRefPtr<imgRequest> request = getter_AddRefs(entry->GetRequest());
++ for (uint32_t i = 0; i < entries.Length(); ++i) {
++ bool isEqual = false;
++
++ 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;
++}
+
+- LOG_STATIC_FUNC_WITH_PARAM(gImgLog, "imgLoader::RemoveFromCache", "uri", spec.get());
++bool imgLoader::RemoveKeyFromCache(imgCacheTable &cache,
++ imgCacheQueue &queue,
++ nsCAutoString key)
++{
++ if (key.IsEmpty()) return false;
++
++ 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 && firstPartyURI) {
++ imgCacheTable &cache = GetCache(imgURI);
++ imgCacheQueue &queue = GetCacheQueue(imgURI);
++ nsCAutoString spec = GetCacheKey(firstPartyURI, imgURI);
+
+ LOG_STATIC_FUNC_WITH_PARAM(gImgLog, "imgLoader::RemoveFromCache", "entry's uri", spec.get());
+
+@@ -1438,18 +1485,6 @@ bool imgLoader::RemoveFromCache(imgCacheEntry *entry)
+ return false;
+ }
+
+-static PLDHashOperator EnumEvictEntries(const nsACString&,
+- nsRefPtr<imgCacheEntry> &aData,
+- void *data)
+-{
+- nsTArray<nsRefPtr<imgCacheEntry> > *entries =
+- reinterpret_cast<nsTArray<nsRefPtr<imgCacheEntry> > *>(data);
+-
+- entries->AppendElement(aData);
+-
+- return PL_DHASH_NEXT;
+-}
+-
+ nsresult imgLoader::EvictEntries(imgCacheTable &aCacheToClear)
+ {
+ LOG_STATIC_FUNC(gImgLog, "imgLoader::EvictEntries table");
+@@ -1457,7 +1492,7 @@ nsresult imgLoader::EvictEntries(imgCacheTable &aCacheToClear)
+ // We have to make a temporary, since RemoveFromCache removes the element
+ // from the queue, invalidating iterators.
+ nsTArray<nsRefPtr<imgCacheEntry> > entries;
+- aCacheToClear.Enumerate(EnumEvictEntries, &entries);
++ aCacheToClear.Enumerate(EnumAllEntries, &entries);
+
+ for (uint32_t i = 0; i < entries.Length(); ++i)
+ if (!RemoveFromCache(entries[i]))
+@@ -1490,11 +1525,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 +1547,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 +1600,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 +1639,7 @@ NS_IMETHODIMP imgLoader::LoadImage(nsIURI *aURI,
+ rv = NewImageChannel(getter_AddRefs(newChannel),
+ &forcePrincipalCheck,
+ aURI,
+- aInitialDocumentURI,
++ aFirstPartyURI,
+ aReferrerURI,
+ aLoadGroup,
+ mAcceptHeader,
+@@ -1627,8 +1661,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 +1710,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 +1770,48 @@ 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 +1822,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 +1914,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 +1926,7 @@ NS_IMETHODIMP imgLoader::LoadImageWithChannel(nsIChannel *channel, imgIDecoderOb
+ NS_RELEASE(pl);
+
+ // Try to add the new request into the cache.
+- PutIntoCache(originalURI, entry);
++ PutIntoCache(GetCacheKey(originalURI, firstPartyURI), entry);
+
+ rv = CreateNewProxyForRequest(request, loadGroup, aObserver,
+ requestFlags, nullptr, _retval);
+@@ -2132,6 +2213,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 +2224,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.5.4
+
diff --git a/src/current-patches/firefox/0025-nsIHTTPChannel.redirectTo-API.patch b/src/current-patches/firefox/0025-nsIHTTPChannel.redirectTo-API.patch
new file mode 100644
index 0000000..1d81164
--- /dev/null
+++ b/src/current-patches/firefox/0025-nsIHTTPChannel.redirectTo-API.patch
@@ -0,0 +1,474 @@
+From 87461432d5e55eee144ed18e8551b637f7919950 Mon Sep 17 00:00:00 2001
+From: Mike Perry <mikeperry-git(a)torproject.org>
+Date: Mon, 14 Jan 2013 19:36:14 -0800
+Subject: [PATCH 25/26] 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 9223d08..6bf11a1 100644
+--- a/netwerk/protocol/http/nsHttpChannel.cpp
++++ b/netwerk/protocol/http/nsHttpChannel.cpp
+@@ -1580,18 +1580,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));
+@@ -1613,6 +1612,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);
+@@ -1628,7 +1657,7 @@ nsHttpChannel::AsyncRedirectChannelToHttps()
+ uint32_t flags = nsIChannelEventSink::REDIRECT_PERMANENT;
+
+ PushRedirectAsyncFunc(
+- &nsHttpChannel::ContinueAsyncRedirectChannelToHttps);
++ &nsHttpChannel::ContinueAsyncRedirectChannelToURI);
+ rv = gHttpHandler->AsyncOnChannelRedirect(this, newChannel, flags);
+
+ if (NS_SUCCEEDED(rv))
+@@ -1636,15 +1665,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);
+
+@@ -4374,7 +4407,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
+@@ -4401,6 +4434,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.
+@@ -5531,7 +5570,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 5b4ddb9..1c0c6b7 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
new file mode 100644
index 0000000..89f4ed6
--- /dev/null
+++ b/src/current-patches/firefox/0026-Isolate-DOM-storage-to-first-party-URI.patch
@@ -0,0 +1,776 @@
+From 69a8f50fc6d4881e48f29ef783e6246d6b7fbee4 Mon Sep 17 00:00:00 2001
+From: Kathleen Brade <brade(a)pearlcrescent.com>
+Date: Tue, 15 Jan 2013 14:18:43 -0800
+Subject: [PATCH 26/26] 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 7a141d9..84a0043 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)
+ {
+@@ -12389,3 +12421,39 @@ nsDocShell::GetAsyncPanZoomEnabled(bool* aOut)
+ *aOut = false;
+ return NS_OK;
+ }
++
++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 225a636..aeb00c9 100644
+--- a/docshell/base/nsDocShell.h
++++ b/docshell/base/nsDocShell.h
+@@ -679,7 +679,7 @@ protected:
+ FrameType GetInheritedFrameType();
+ FrameType GetFrameType();
+
+- // hash of session storages, keyed by domain
++ // hash of session storages, keyed by domain&firstPartyHost
+ nsInterfaceHashtable<nsCStringHashKey, nsIDOMStorage> mStorages;
+
+ // Dimensions of the docshell
+@@ -846,6 +846,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 3a370c9..201a0a2 100644
+--- a/dom/base/nsGlobalWindow.cpp
++++ b/dom/base/nsGlobalWindow.cpp
+@@ -8382,7 +8382,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
+
1
0

[torbutton/master] Remove some JavaScript Debugger exception spam.
by mikeperry@torproject.org 17 Jan '13
by mikeperry@torproject.org 17 Jan '13
17 Jan '13
commit 9c15f4a7562ee85cbdc03f546883efd59e85c06d
Author: Mike Perry <mikeperry-git(a)fscked.org>
Date: Tue Jan 15 22:20:20 2013 -0800
Remove some JavaScript Debugger exception spam.
---
src/components/external-app-blocker.js | 18 ++++++++++++++----
1 files changed, 14 insertions(+), 4 deletions(-)
diff --git a/src/components/external-app-blocker.js b/src/components/external-app-blocker.js
index 4605d9e..91f0483 100644
--- a/src/components/external-app-blocker.js
+++ b/src/components/external-app-blocker.js
@@ -30,6 +30,7 @@ const kExternalInterfaces = ["nsIObserver", "nsIMIMEService",
const kREAL_DRAG_CID = "{8b5314bb-db01-11d2-96ce-0060b0fb9956}";
const kDragInterfaces = ["nsIDragService"];
+ //, "nsIDragSession"];
const Cr = Components.results;
const Cc = Components.classes;
@@ -81,12 +82,21 @@ ExternalWrapper.prototype =
return this;
}
- try {
- var external = this._external().QueryInterface(iid);
- this.copyMethods(external);
- } catch(e) {
+ /* We perform this explicit check first because otherwise
+ * the JSD exception logs are full of noise */
+ if (iid.equals(Components.interfaces.nsIDragService)
+ || iid.equals(Components.interfaces.nsIDragSession)) {
var drag = this._drag().QueryInterface(iid);
this.copyMethods(drag);
+ } else {
+ try {
+ var external = this._external().QueryInterface(iid);
+ this.copyMethods(external);
+ } catch(e) {
+ this.logger.log(3, "Drag+drop QI: "+iid);
+ var drag = this._drag().QueryInterface(iid);
+ this.copyMethods(drag);
+ }
}
return this;
},
1
0

[torbutton/master] Bug 5279: Remove old toggle observers and related code.
by mikeperry@torproject.org 17 Jan '13
by mikeperry@torproject.org 17 Jan '13
17 Jan '13
commit 71aa3e36b4d95b8b17a06a7cfb9d2f0fe9e813c7
Author: Mike Perry <mikeperry-git(a)fscked.org>
Date: Tue Jan 15 22:10:28 2013 -0800
Bug 5279: Remove old toggle observers and related code.
I am MiCthulhu, destroyer of code!
---
src/chrome/content/torbutton.js | 1612 ++-------------------------------------
1 files changed, 61 insertions(+), 1551 deletions(-)
diff --git a/src/chrome/content/torbutton.js b/src/chrome/content/torbutton.js
index 75fe7ab..30300fa 100644
--- a/src/chrome/content/torbutton.js
+++ b/src/chrome/content/torbutton.js
@@ -602,15 +602,13 @@ function torbutton_init() {
// listen for our toolbar button being added so we can initialize it
torbutton_init_toolbutton();
- torbutton_init_jshooks();
-
torbutton_log(1, 'registering pref observer');
torbutton_window_pref_observer.register();
//setting up context menu
- var contextMenu = document.getElementById("contentAreaContextMenu");
- if (contextMenu)
- contextMenu.addEventListener("popupshowing", torbutton_check_contextmenu, false);
+ //var contextMenu = document.getElementById("contentAreaContextMenu");
+ //if (contextMenu)
+ // contextMenu.addEventListener("popupshowing", torbutton_check_contextmenu, false);
// Add toolbutton to the bar.
// This should maybe be in the startup function, but we want to add
@@ -690,87 +688,6 @@ function torbutton_inform_about_tbb() {
m_tb_prefs.setBoolPref("extensions.torbutton.prompt_torbrowser", !checkbox.value);
}
-// Bug 1506 P0: This code only matters in toggle mode (for tor:// urls).
-// Kill it.
-//
-//this function checks to see if the context menu is being clicked on a link.
-//if it is, then we show the two context menu items
-function torbutton_check_contextmenu() {
- var torurl = document.getElementById("torcontext-copyurl");
- var tortab = document.getElementById("torcontext-opentortab");
- var torwin = document.getElementById("torcontext-opentorwin");
- torurl.hidden = tortab.hidden = torwin.hidden = (document.popupNode.localName != "A")
-}
-
-// Bug 1506 P0: This code only matters in toggle mode (for tor:// urls).
-// Kill it.
-function torbutton_copy_link() {
- var element = document.popupNode;
- var myURI = Components.classes["@mozilla.org/network/io-service;1"]
- .getService(Components.interfaces.nsIIOService)
- .newURI(element, null, null);
- //check the scheme
- if (myURI.scheme == "http" || myURI.scheme == "tor")
- myURI.scheme = "tor";
- else if (myURI.scheme == "https" || myURI.scheme == "tors")
- myURI.scheme = "tors";
- else
- return;//unsupported scheme
- torbutton_copyToClipboard(myURI.spec);
-}
-
-// Bug 1506 P0: This code only matters in toggle mode (for tor:// urls).
-// Kill it.
-function torbutton_copyToClipboard(copyThis) {
-
- var str = Components.classes["@mozilla.org/supports-string;1"].createInstance(Components.interfaces.nsISupportsString);
- if (!str) return false;
- str.data = copyThis; // unicode string?
-
- var trans = Components.classes["@mozilla.org/widget/transferable;1"].createInstance(Components.interfaces.nsITransferable);
- if (!trans) return false; //no transferable widget found
-
- trans.addDataFlavor("text/unicode");
- trans.setTransferData("text/unicode", str, copyThis.length*2); // *2 cuz it's unicode
-
- var clipid=Components.interfaces.nsIClipboard;
- var clip = Components.classes["@mozilla.org/widget/clipboard;1"].getService(clipid);
- if (!clip) return false; // couldn't get the clipboard
-
- clip.setData(trans, null, clipid.kGlobalClipboard);
- return true;
-}
-
-// Bug 1506 P0: This code only matters in toggle mode (for tor:// urls).
-// Kill it.
-//opens new tab with link with tor:// protocol
-function torbutton_open_link_as_tor(tabFlag) {
- var element = document.popupNode;
- var mainWindow = window.QueryInterface(Components.interfaces.nsIInterfaceRequestor)
- .getInterface(Components.interfaces.nsIWebNavigation)
- .QueryInterface(Components.interfaces.nsIDocShellTreeItem)
- .rootTreeItem
- .QueryInterface(Components.interfaces.nsIInterfaceRequestor)
- .getInterface(Components.interfaces.nsIDOMWindow);
- //make into nsIURI
- var myURI = Components.classes["@mozilla.org/network/io-service;1"]
- .getService(Components.interfaces.nsIIOService)
- .newURI(element, null, null);
- //check the scheme
- if (myURI.scheme == "http" || myURI.scheme == "tor")
- myURI.scheme = "tor";
- else if (myURI.scheme == "https" || myURI.scheme == "tors")
- myURI.scheme = "tors";
- else
- return;//unsupported scheme
- if (tabFlag)
- mainWindow.getBrowser().addTab(myURI.spec);
- else
- mainWindow.open(myURI.spec);
-}
-
-
-
// Bug 1506 P0: Our prefs should be handled by Tor Browser. Even if they're
// not, they should be vastly simplified from this. See also #3100.
//
@@ -1554,9 +1471,8 @@ function torbutton_new_identity() {
}
/* The "New Identity" implementation does the following:
- * 1. Tag all tabs as non-tor
- * 2. Disables Javascript and plugins on all tabs
- * 3. Clears state:
+ * 1. Disables Javascript and plugins on all tabs
+ * 2. Clears state:
* a. OCSP
* b. Cache + image cache
* c. Site-specific zoom
@@ -1566,35 +1482,15 @@ function torbutton_new_identity() {
* g. SSL Session IDs
* h. last open location url
* i. clear content prefs
- * 4. Sends tor the NEWNYM signal to get a new circuit
- * 5. Opens a new window with the default homepage
- * 6. Closes this window
+ * 3. Sends tor the NEWNYM signal to get a new circuit
+ * 4. Opens a new window with the default homepage
+ * 5. Closes this window
*
* XXX: intermediate SSL certificates are not cleared.
*/
// Bug 1506 P4: Needed for New Identity.
function torbutton_do_new_identity() {
- var wm = Components.classes["@mozilla.org/appshell/window-mediator;1"]
- .getService(Components.interfaces.nsIWindowMediator);
- var enumerator = wm.getEnumerator("navigator:browser");
- var closeWins = new Array();
- while(enumerator.hasMoreElements()) {
- var win = enumerator.getNext();
- var browser = win.getBrowser();
- if(!browser) {
- torbutton_log(5, "No browser for possible closed window");
- continue;
- }
- var tabs = browser.browsers.length;
-
- torbutton_log(3, "Length: "+browser.browsers.length);
-
- for(var i = 0; i < tabs; i++) {
- torbutton_apply_tab_tag(browser, browser.browsers[i], false);
- }
- }
-
- torbutton_toggle_jsplugins(true, true, true);
+ torbutton_disable_all_js();
m_tb_prefs.setBoolPref("browser.zoom.siteSpecific",
!m_tb_prefs.getBoolPref("browser.zoom.siteSpecific"));
@@ -1818,10 +1714,6 @@ function torbutton_update_status(mode, force_update) {
// startup, not toggle.
torbutton_toggle_plugins(mode && torprefs.getBoolPref("no_tor_plugins"));
- torbutton_toggle_jsplugins(mode,
- changed && torprefs.getBoolPref("isolate_content"),
- torprefs.getBoolPref("no_tor_plugins"));
-
torbutton_log(2, 'Setting user agent');
if(torprefs.getBoolPref("set_uagent")) {
@@ -2139,19 +2031,6 @@ function torbutton_update_status(mode, force_update) {
"full_page_plugins", m_tb_plugin_string, false, changed);
}
- if(m_tb_ff35) {
- var livemarks = Cc["@mozilla.org/browser/livemark-service;2"].
- getService(Ci.nsILivemarkService);
- if (mode &&
- m_tb_prefs.getBoolPref("extensions.torbutton.disable_livemarks")) {
- livemarks.stopUpdateLivemarks();
- torbutton_log(3, "Disabled livemarks");
- } else {
- livemarks.start();
- torbutton_log(3, "Enabled livemarks");
- }
- }
-
// No need to clear cookies if just updating prefs
if(!changed && force_update) {
// Force prefs to be synced to disk
@@ -2322,9 +2201,7 @@ function torbutton_close_on_toggle(mode, newnym) {
var remove = new Array();
for(var i = 0; i < tabs; i++) {
- if(browser.browsers[i].__tb_tor_fetched != mode) {
- remove.push(browser.browsers[i]);
- }
+ remove.push(browser.browsers[i]);
}
if(browser.browsers.length == remove.length) {
@@ -2877,25 +2754,13 @@ function torbutton_jar_certs(mode) {
// -------------- JS/PLUGIN HANDLING CODE ---------------------
-// Bug 1506 P0: Toggle-only. Kill it.
-function torbutton_check_js_tag(tabbrowser, browser, tor_enabled, js_enabled) {
+// Bug 1506 P3: Defense in depth. Disables JS and events for New Identity.
+function torbutton_disable_browser_js(browser) {
var eventSuppressor = null;
- if (typeof(browser.__tb_tor_fetched) == 'undefined') {
- try {
- torbutton_log(5, "UNTAGGED WINDOW at: "+browser.src);
- } catch(e) {
- torbutton_log(5, "UNTAGGED WINDOW: "+e);
- }
- // Defensive programming to tag this window here to
- // an alternate tor state. It wil lmake this window totally
- // useless, but that is better than some undefined state
- torbutton_apply_tab_tag(tabbrowser, browser, !tor_enabled);
- }
/* Solution from: https://bugzilla.mozilla.org/show_bug.cgi?id=409737 */
- // XXX: This is disabled. It kills the entire window. We need to redirect
+ // XXX: This kills the entire window. We need to redirect
// focus and inform the user via a lightbox.
- // See https://bugs.torproject.org/flyspray/index.php?do=details&id=1283
try {
if (!browser.contentWindow)
torbutton_log(3, "No content window to disable JS events.");
@@ -2903,10 +2768,11 @@ function torbutton_check_js_tag(tabbrowser, browser, tor_enabled, js_enabled) {
eventSuppressor = browser.contentWindow.
QueryInterface(Components.interfaces.nsIInterfaceRequestor).
getInterface(Ci.nsIDOMWindowUtils);
- eventSuppressor = null;
} catch(e) {
torbutton_log(4, "Failed to disable JS events: "+e)
}
+
+ browser.docShell.allowJavascript = false;
try {
// My estimation is that this does not get the inner iframe windows,
@@ -2918,21 +2784,13 @@ function torbutton_check_js_tag(tabbrowser, browser, tor_enabled, js_enabled) {
torbutton_log(4, "Failed to reset window.name: "+e)
}
- if(browser.__tb_tor_fetched == tor_enabled) { // States match, js ok
- browser.docShell.allowJavascript = js_enabled;
- if (eventSuppressor)
- eventSuppressor.suppressEventHandling(!js_enabled);
- } else { // States differ or undefined, js not ok
- browser.docShell.allowJavascript = false;
- if (eventSuppressor)
- eventSuppressor.suppressEventHandling(true);
- }
+ if (eventSuppressor)
+ eventSuppressor.suppressEventHandling(true);
}
// Bug 1506 P3: The JS-killing bits of this are used by
// New Identity as a defense-in-depth measure.
-function torbutton_toggle_win_jsplugins(win, tor_enabled, js_enabled, isolate_dyn,
- kill_plugins) {
+function torbutton_disable_window_js(win) {
var browser = win.getBrowser();
if(!browser) {
torbutton_log(5, "No browser for plugin window...");
@@ -2954,28 +2812,10 @@ function torbutton_toggle_win_jsplugins(win, tor_enabled, js_enabled, isolate_dy
}
}
if (b && b.docShell) {
- // Only allow plugins if the tab load was from an
- // non-tor state and the current tor state is off.
- if (!m_tb_tbb) {
- if(kill_plugins)
- b.docShell.allowPlugins = !b.__tb_tor_fetched && !tor_enabled;
- else
- b.docShell.allowPlugins = true;
- }
-
- // Likewise for DNS prefetch
- if(m_tb_ff35) {
- if(!m_tb_ff36)
- b.docShell.QueryInterface(Ci.nsIDocShell_MOZILLA_1_9_1_dns);
- b.docShell.allowDNSPrefetch = !b.__tb_tor_fetched
- && !tor_enabled;
- }
+ torbutton_disable_browser_js(b);
- if(isolate_dyn) {
- torbutton_check_js_tag(browser, b, tor_enabled, js_enabled);
- // kill meta-refresh and existing page loading
- b.webNavigation.stop(b.webNavigation.STOP_ALL);
- }
+ // kill meta-refresh and existing page loading
+ b.webNavigation.stop(b.webNavigation.STOP_ALL);
}
}
}
@@ -2985,138 +2825,13 @@ function torbutton_toggle_win_jsplugins(win, tor_enabled, js_enabled, isolate_dy
//
// This is an ugly beast.. But unfortunately it has to be so..
// Looping over all tabs twice is not somethign we wanna do..
-function torbutton_toggle_jsplugins(tor_enabled, isolate_dyn, kill_plugins) {
- torbutton_log(1, "Toggle plugins for: "+tor_enabled);
+function torbutton_disable_all_js() {
var wm = Components.classes["@mozilla.org/appshell/window-mediator;1"]
.getService(Components.interfaces.nsIWindowMediator);
var enumerator = wm.getEnumerator("navigator:browser");
- var js_enabled = m_tb_prefs.getBoolPref("javascript.enabled");
while(enumerator.hasMoreElements()) {
var win = enumerator.getNext();
- torbutton_toggle_win_jsplugins(win, tor_enabled, js_enabled, isolate_dyn,
- kill_plugins);
- }
-}
-
-// Bug 1506 P0: Toggle garbage.
-function tbHistoryListener(browser) {
- this.browser = browser;
-
- var o_stringbundle = torbutton_get_stringbundle();
- var warning = o_stringbundle.GetStringFromName("torbutton.popup.history.warning");
-
- this.f1 = function() {
- // Block everything unless we've reached steady state
- if((this.browser.__tb_tor_fetched != m_tb_prefs.getBoolPref("extensions.torbutton.tor_enabled"))
- || (this.browser.__tb_tor_fetched != m_tb_prefs.getBoolPref("extensions.torbutton.settings_applied"))
- && m_tb_prefs.getBoolPref("extensions.torbutton.block_js_history")) {
- torbutton_log(3, "Blocking history manipulation");
- window.alert(warning);
- return false;
- } else {
- return true;
- }
- };
-}
-
-// Bug 1506 P0: Toggle garbage.
-tbHistoryListener.prototype = {
- QueryInterface: function(iid) {
- // XXX: Is this the right way to handle weak references from JS?
- if(iid.equals(Components.interfaces.nsISHistoryListener) ||
- iid.equals(Components.interfaces.nsISupports) ||
- iid.equals(Components.interfaces.nsISupportsWeakReference))
- return this;
- else
- return null;
- },
-
- OnHistoryGoBack: function(url) { return this.f1(); },
- OnHistoryGoForward: function(url) { return this.f1(); },
- OnHistoryGotoIndex: function(idx, url) { return this.f1(); },
- OnHistoryNewEntry: function(url) { return true; },
- OnHistoryPurge: function(ents) { return true; },
- OnHistoryReload: function(uri,flags) { return this.f1(); }
-};
-
-// Bug 1506 P1: Technically, tags are still used by New Identity as
-// defense-in-depth, but they are very expensive to enforce and requires
-// an nsIConentPolicy, which is broken on Android last I checked.
-// Killing this is fine, but be sure to watch out for other places
-// where tab tags are referenced.
-function torbutton_apply_tab_tag(tabbrowser, browser, tag) {
- if (typeof(browser["__tb_tor_fetched"]) == "undefined" ||
- browser.__tb_tor_fetched != tag) {
- // Only update the browser's session store tag if the tag has changed.
- // This is an expensive operation.
- var ss = Components.classes["@mozilla.org/browser/sessionstore;1"]
- .getService(Components.interfaces.nsISessionStore);
-
- var tab = null;
-
- // XXX: if tabbrowser is null, we may either write or omit session store data..
- // This should only happen in toggle mode, though.
- if (tabbrowser) {
- // http://stackoverflow.com/questions/3374056/firefox-gbrowser-getbrowserforta…
- var mTabs = tabbrowser.mTabContainer.childNodes;
- for (var i=0; i<mTabs.length; i++) {
- if (mTabs[i].linkedBrowser == browser) {
- tab = mTabs[i];
- }
- }
- }
- if (tab)
- ss.setTabValue(tab, "__tb_tor_fetched", tag.toString());
- else
- torbutton_log(5, "No tab found for session store tag.");
-
- }
- var oldtag = browser.__tb_tor_fetched;
- browser.__tb_tor_fetched = tag;
- return oldtag != tag;
-}
-
-// Bug 1506 P1: Tagging is pretty much toggle-only. See above.
-function torbutton_tag_new_browser(browser, tor_tag, no_plugins) {
- if (!tor_tag && no_plugins && !m_tb_tbb) {
- browser.docShell.allowPlugins = tor_tag;
- }
-
- if (!tor_tag && m_tb_ff35) {
- if (!m_tb_ff36) /* Unified with nsIDocShell in 3.6 */
- browser.docShell.QueryInterface(Ci.nsIDocShell_MOZILLA_1_9_1_dns);
- browser.docShell.allowDNSPrefetch = tor_tag;
- }
-
- // Only tag new windows
- if (typeof(browser.__tb_tor_fetched) == 'undefined') {
- torbutton_log(3, "Tagging new window: "+tor_tag);
- torbutton_apply_tab_tag(gBrowser, browser, !tor_tag);
-
- // XXX: Do we need to remove this listener on tab close?
- // No, but we probably do need to remove it on window close!
- // FF3.5 may be throwing uncaught exceptions!
- var hlisten = new tbHistoryListener(browser);
-
- var sessionSetter = function() {
- if(!browser.webNavigation.sessionHistory) {
- torbutton_log(4, "Still failed to add historyListener!");
- }
- try {
- browser.webNavigation.sessionHistory.addSHistoryListener(hlisten);
- browser.__tb_hlistener = hlisten;
- torbutton_log(2, "Added history listener");
- } catch(e) {
- torbutton_log(4, "Exception adding history listener: "+e);
- }
- }
-
- if(browser.webNavigation.sessionHistory) {
- sessionSetter();
- } else {
- torbutton_log(3, "Delayed session setter");
- window.setTimeout(sessionSetter, 500);
- }
+ torbutton_disable_window_js(win);
}
}
@@ -3195,7 +2910,6 @@ function torbutton_set_launch_state(state, session_restore) {
}
}
}
- torbutton_apply_tab_tag(browser, b, state);
}
}
@@ -3330,11 +3044,6 @@ function torbutton_crash_recover()
else
torbutton_set_launch_state(false, !m_tb_prefs.getBoolPref("extensions.torbutton.nonontor_sessionstore"));
- if (state) {
- // Need to maybe generate google cookie if tor is enabled
- torbutton_new_google_cookie();
- }
-
m_tb_prefs.setBoolPref("extensions.torbutton.crashed", false);
// Force prefs to be synced to disk
@@ -3349,682 +3058,6 @@ function torbutton_crash_recover()
// ---------------------- Event handlers -----------------
-// Bug 1506 P0: This observer was due to a hack to try to get rid
-// of Google captchas.. It didn't work. Kill it.
-//
-// Observer to handle regeneration of google pref cookies
-var torbutton_cookie_observer = {
-observe: function(subject, topic, data) {
- if (topic == 'cookie-changed') {
- if (data == 'cleared') {
- // XXX: Does this get called for every cookie that is cleared?
- if (m_tb_prefs.getBoolPref("extensions.torbutton.reset_google_cookies")) {
- torbutton_reset_google_cookie();
- } else if (m_tb_prefs.getBoolPref("extensions.torbutton.regen_google_cookies")) {
- torbutton_regen_google_cookie();
- }
- } else if (data == 'deleted') {
- // single cookie deleted or changed - reset just what we need to
- var cookie = subject.QueryInterface(Components.interfaces.nsICookie);
- var host = cookie.host;
- var google_host = m_tb_prefs.getCharPref("extensions.torbutton.google_host");
- if (cookie.host == google_host && cookie.path == "/" && cookie.name == "PREF") {
- if (m_tb_prefs.getBoolPref("extensions.torbutton.reset_google_cookies")) {
- torbutton_reset_google_cookie();
- } else if (m_tb_prefs.getBoolPref("extensions.torbutton.regen_google_cookies")) {
- torbutton_regen_google_cookie();
- }
- }
- }
- }
-},
-
-register: function() {
- var os = Components.classes['@mozilla.org/observer-service;1'].
- getService(Components.interfaces.nsIObserverService);
- os.addObserver(torbutton_cookie_observer, 'cookie-changed', false);
-
-
-},
-
-unregister: function() {
- try {
- var os = Components.classes['@mozilla.org/observer-service;1'].
- getService(Components.interfaces.nsIObserverService);
- os.removeObserver(torbutton_cookie_observer, 'cookie-changed');
- } catch(e) {
- torbutton_log(3, "Already unregistered cookie observer");
- }
-}
-
-};
-
-// Bug 1506 P0: This function was due to a hack to try to get rid
-// of Google captchas.. It didn't work. Kill it.
-function torbutton_new_google_cookie() {
- var regen = m_tb_prefs.getBoolPref("extensions.torbutton.regen_google_cookies");
- var reset = m_tb_prefs.getBoolPref("extensions.torbutton.reset_google_cookies");
- if (!regen && !reset) {
- return;
- }
- var cookieManager = Cc["@mozilla.org/cookiemanager;1"]
- .getService(Ci.nsICookieManager);
- var cookiesEnum = cookieManager.enumerator;
- var gpref = null;
- var google_host = m_tb_prefs.getCharPref("extensions.torbutton.google_host");
- while (cookiesEnum.hasMoreElements()) {
- var cookie = cookiesEnum.getNext().QueryInterface(Ci.nsICookie);
- if (cookie.host == google_host && cookie.path == "/" &&
- cookie.name == "PREF") {
- gpref = cookie;
- }
- }
-
- if (!gpref) {
- torbutton_log(3, "No google cookie found. Regenerating.");
- if (reset) {
- torbutton_reset_google_cookie();
- } else if (regen) {
- torbutton_regen_google_cookie();
- }
- }
-}
-
-// Bug 1506 P0: This function was due to a hack to try to get rid
-// of Google captchas.. It didn't work. Kill it.
-function torbutton_init_hidden_browser() {
- var loaderBox = document.createElement("hbox");
- loaderBox.setAttribute("style", "overflow: hidden; visibility: hidden;");
- loaderBox.setAttribute("flex", "1");
- loaderBox.setAttribute("height", "0");
- loaderBox.setAttribute("maxheight", "0");
- loaderBox.setAttribute("minheight", "0");
-
- var loaderSubBox = document.createElement("vbox");
- loaderSubBox.setAttribute("flex", "0");
- loaderBox.appendChild(loaderSubBox);
- document.documentElement.appendChild(loaderBox);
-
- var win_width = window.getBrowser().contentWindow.innerWidth;
- var win_height = window.getBrowser().contentWindow.innerHeight;
-
- loaderSubBox.setAttribute("width", win_width);
- loaderSubBox.setAttribute("minwidth", win_width);
- loaderSubBox.setAttribute("maxwidth", win_width);
- loaderSubBox.setAttribute("height", win_height);
- loaderSubBox.setAttribute("minheight", win_height);
- loaderSubBox.setAttribute("maxheight", win_height);
-
- loaderSubBox.style.width = win_width + "px !important";
- loaderSubBox.style.maxWidth = loaderSubBox.style.width;
- loaderSubBox.style.minWidth = loaderSubBox.style.width;
- loaderSubBox.style.height = win_height + "px !important";
- loaderSubBox.style.maxHeight = loaderSubBox.style.height;
- loaderSubBox.style.minHeight = loaderSubBox.style.height;
-
- m_tb_hidden_browser = document.createElement("browser");
- m_tb_hidden_browser.setAttribute("class", "torbuttonBrowser");
- m_tb_hidden_browser.setAttribute("type", "content");
- m_tb_hidden_browser.setAttribute("disablehistory", true);
- m_tb_hidden_browser.setAttribute("allowPlugins", false);
- m_tb_hidden_browser.setAttribute("flex", "1");
- m_tb_hidden_browser.setAttribute("id", "torbuttonBrowser");
-
- loaderSubBox.appendChild(m_tb_hidden_browser);
- torbutton_log(3, "Created hidden browser.");
-}
-
-// Bug 1506 P0: This function was due to a hack to try to get rid
-// of Google captchas.. It didn't work. Kill it.
-var torbutton_google_cookie_regen_listener = {
- QueryInterface: function(aIID)
- {
- if (aIID.equals(Components.interfaces.nsIDOMEventListener) ||
- aIID.equals(Components.interfaces.nsIWebProgressListener) ||
- aIID.equals(Components.interfaces.nsISupportsWeakReference) ||
- aIID.equals(Components.interfaces.nsISupports))
- return this;
- throw Components.results.NS_NOINTERFACE;
- },
-
- onStateChange: function(aWebProgress, aRequest, aFlag, aStatus) {
- torbutton_log(3, "Google cookie fetch progress");
- if ((aFlag & Ci.nsIWebProgressListener.STATE_STOP)
- && (aFlag & Ci.nsIWebProgressListener.STATE_IS_WINDOW)) {
- m_tb_hidden_browser.removeProgressListener(torbutton_google_cookie_regen_listener);
- m_tb_hidden_browser.setAttribute("src", "about:blank");
- torbutton_log(3, "Google cookie fetch complete.");
- }
- },
-
- onLocationChange: function(aProgress, aRequest, aURI) { return 0; },
- onProgressChange: function() {return 0;},
- onStatusChange: function() {return 0;},
- onSecurityChange: function() {return 0;},
- onLinkIconAvailable: function() {return 0;}
-};
-
-// Bug 1506 P0: This function was due to a hack to try to get rid
-// of Google captchas.. It didn't work. Kill it.
-function torbutton_regen_google_cookie() {
- // Only fire if tor fully enabled...
- if (m_tb_prefs.getBoolPref("extensions.torbutton.proxies_applied")) {
- torbutton_log(3, "Regenerating google cookie via fetch");
- if (!m_tb_hidden_browser) {
- torbutton_init_hidden_browser();
- }
- // XXX: This is might be forbidden according to
- // https://bugzilla.mozilla.org/show_bug.cgi?id=608628
- m_tb_hidden_browser.addProgressListener(torbutton_google_cookie_regen_listener,
- Ci.nsIWebProgress.NOTIFY_STATE_DOCUMENT);
-
- /* XXX: ideal, but broken..
- m_tb_hidden_browser.loadURIWithFlags(
- "http://www"+m_tb_prefs.getCharPref("extensions.torbutton.google_host")+"/",
- Ci.nsIWebNavigation.LOAD_FLAGS_BYPASS_CACHE
- |Ci.nsIWebNavigation.LOAD_FLAGS_BYPASS_HISTORY, null, null);
- */
-
- torbutton_log(3, "Cookie fetch initiating..");
-
- m_tb_hidden_browser.setAttribute("src",
- "http://www"+m_tb_prefs.getCharPref("extensions.torbutton.google_host")+"/");
-
- }
-}
-
-// Bug 1506 P0: This function was due to a hack to try to get rid
-// of Google captchas.. It didn't work. Kill it.
-function torbutton_reset_google_cookie() {
- // Only fire if tor is fully enabled..
- if (m_tb_prefs.getBoolPref("extensions.torbutton.proxies_applied")) {
- torbutton_log(3, "Resetting google cookie to pref");
- var cm = Components.classes['@mozilla.org/cookiemanager;1'].
- getService(Components.interfaces.nsICookieManager2);
- var expires = (new Date("Jan 1, 3000")).getTime() / 1000;
-
- // Need S, GDSESS, SS (www, /search), SNID (/verify) and NID...
- // But it may be the case that NID, SNID and the others can be tied
- // to a gmail account, search history, prefs, and/or iGoogle customization.
- // Initial testing shows this to be not the case though.
-
- cm.add("www"+m_tb_prefs.getCharPref("extensions.torbutton.google_host"),
- "/search", "SS",
- m_tb_prefs.getCharPref("extensions.torbutton.gss_cookie"),
- false, false, false, expires);
-
- cm.add(m_tb_prefs.getCharPref("extensions.torbutton.google_host"),
- "/verify", "SNID",
- m_tb_prefs.getCharPref("extensions.torbutton.gsnid_cookie"),
- false, false, false, expires);
-
- cm.add(m_tb_prefs.getCharPref("extensions.torbutton.google_host"),
- "/", "NID",
- m_tb_prefs.getCharPref("extensions.torbutton.gnid_cookie"),
- false, false, false, expires);
-
- cm.add(m_tb_prefs.getCharPref("extensions.torbutton.google_host"),
- "/", "PREF", m_tb_prefs.getCharPref("extensions.torbutton.gpref_cookie"),
- false, false, false, expires);
-
- cm.add(m_tb_prefs.getCharPref("extensions.torbutton.google_host"),
- "/", "GDSESS",
- m_tb_prefs.getCharPref("extensions.torbutton.ggdsess_cookie"),
- false, false, false, expires);
-
- cm.add(m_tb_prefs.getCharPref("extensions.torbutton.google_host"),
- "/", "S", m_tb_prefs.getCharPref("extensions.torbutton.gs_cookie"),
- false, false, false, expires);
-
-
- }
-}
-
-/*
-function torbutton_filter_cookies(filter_cookies) {
- var cookieManager = Cc["@mozilla.org/cookiemanager;1"]
- .getService(Ci.nsICookieManager);
- var cookiesEnum = cookieManager.enumerator;
- var new_cookies = [];
- while (cookiesEnum.hasMoreElements()) {
- var cookie = cookiesEnum.getNext().QueryInterface(Ci.nsICookie);
- }
-}
-*/
-
-// Bug 1506 P1: This function was due to a hack to try to limit
-// Google captchas.. It might help, but it's probably not worth
-// it.
-function torbutton_xfer_google_cookies(subject, topic, data) {
- // Only fire if tor is fully enabled
- if (m_tb_prefs.getBoolPref("extensions.torbutton.proxies_applied")) {
- // catch load requests for nsIURI.host of google.(com|[\S\S](.[\S\S])?)$
- // If no pref cookie, generate from google.ca PREF
- var httpChannel = subject.QueryInterface(Ci.nsIHttpChannel);
- var hostmatch =
- subject.URI.host.match(/^www\.google\.(co\.\S\S|com|\S\S|com\.\S\S)$/);
-
- // check nsIURI
- if (hostmatch) {
- var domain = hostmatch[1];
- var google_host = m_tb_prefs.getCharPref("extensions.torbutton.google_host");
- torbutton_log(3, "Got Google request for host: "+subject.URI.host
- +", matched: "+hostmatch[0]);
- var cookieManager = Cc["@mozilla.org/cookiemanager;1"]
- .getService(Ci.nsICookieManager);
- var cookiesEnum = cookieManager.enumerator;
- var copy_cookies = [];
- // Lets always xfer over all cookies from www.google hosts
- var use_google_host = false;
- /* m_tb_prefs.getBoolPref("extensions.torbutton.reset_google_cookies")
- || m_tb_prefs.getBoolPref("extensions.torbutton.regen_google_cookies");
- */
- torbutton_log(3, "Got prefs: "+subject.URI.host);
- while (cookiesEnum.hasMoreElements()) {
- var cookie = cookiesEnum.getNext().QueryInterface(Ci.nsICookie);
- var hostmatched = false;
- if (use_google_host) {
- hostmatched = (cookie.host == google_host);
- } else {
- hostmatched = (new String(cookie.host)).match(
- /^(\.www|www|)\.google\.(co\.\S\S|com|\S\S|com\.\S\S)$/);
- }
- // Copy all relevent cookies (except for ssl)
- // only copy captcha cookie ("S"?)
- if (hostmatched && !cookie.isSecure
- && (cookie.name in {"S":1,"NID":1,"PREF":1,"GDSESS":1,"SNID":1})) {
- copy_cookies.push(cookie);
- }
- }
-
- if (!copy_cookies.length) {
- torbutton_safelog(4, "No cookie to migrate: ", subject.URI.host);
- return;
- }
- var cm = Components.classes['@mozilla.org/cookiemanager;1'].
- getService(Components.interfaces.nsICookieManager2);
- var expires = (new Date("Jan 1, 3000")).getTime() / 1000;
- var i;
-
- var cookies = null;
- try {
- cookies = new String(httpChannel.getRequestHeader("Cookie"));
- torbutton_log(3, "Google cookies: "+(cookies ? cookies : "none"));
- } catch(e) {
- torbutton_log(3, "Google cookies exploded: "+e);
- }
- for (i = 0; i < copy_cookies.length; i++) {
- var cmatch = new RegExp("(^|;)"+copy_cookies[i].name+"=");
- // XXX: Hrmm.. could also replace with most recent cookie..
- // but that requires another O(n^2) loop above
- if (cookies && cookies.match(cmatch))
- continue; // Already present. Skip.
-
- var new_host = new String(copy_cookies[i].host);
- // Regex sub out copy_cookies[i].host
- new_host = new_host.replace(
- /\.google\.(co\.\S\S|com|\S\S|com\.\S\S)$/,
- ".google."+domain);
- try {
- cm.add(
- new_host,
- copy_cookies[i].path, // path
- copy_cookies[i].name,
- copy_cookies[i].value,
- copy_cookies[i].isSecure, // isSecure
- copy_cookies[i].isHttpOnly, // isHttpOnly
- false, // isSession
- expires);
- /* Need to copy only cookies matching the host/domain and
- * path of this request... */
- var dmatch = new RegExp(new_host+"$");
- if (subject.URI.host.match(dmatch)
- && subject.URI.path.indexOf(copy_cookies[i].path) == 0) {
- httpChannel.setRequestHeader("Cookie",
- copy_cookies[i].name+"="+copy_cookies[i].value, true);
- torbutton_log(3, "Google cookie "+copy_cookies[i].name+
- " applied for: "+subject.URI.host+" to domain "+
- new_host+" from "+copy_cookies[i].host);
- } else {
- torbutton_log(3, "Google cookie "+copy_cookies[i].name+
- " transfered for: "+subject.URI.host+" to domain "+
- new_host+" from "+copy_cookies[i].host);
- }
- } catch(e) {
- torbutton_log(3, "Cookie add fail for "+new_host+" "
- +copy_cookies[i].name+": "+e);
- }
- }
-
- /*
- var browser = null;
- if (subject.notificationCallbacks ||
- (subject.loadGroup && subject.loadGroup.notificationCallbacks) {
- try {
- var callbacks = subject.notificationCallbacks;
- if (!callbacks) {
- callbacks = subject.loadGroup.notificationCallbacks;
- }
- var wind = callbacks.QueryInterface(
- Components.interfaces.nsIInterfaceRequestor).getInterface(
- Components.interfaces.nsIDOMWindow);
-
- if (wind instanceof Components.interfaces.nsIDOMChromeWindow) {
- if (wind.browserDOMWindow) {
- browser = wind.getBrowser().selectedTab.linkedBrowser;
- }
- }
- } catch(e) {
- torbutton_eclog(4,
- 'Failure obtaining window for cookie xfer: '+e);
- }
- }
- if (browser) {
- torbutton_eclog(3, "Reload after cookie xfer: "+subject.URI.spec);
- browser.reload();
- } else {
- torbutton_eclog(4, "Could not find browser to reload "+subject.URI.spec);
- }
- */
- }
- }
-}
-
-// Bug 1506 P2: Google captchas really suck. This is still useful
-/* Redirect the user to a different search engine if Google is blocking Tor */
-function torbutton_check_google_captcha(subject, topic, data) {
- if (!m_tb_prefs.getBoolPref("extensions.torbutton.proxies_applied"))
- return;
-
- var httpChannel = subject.QueryInterface(Ci.nsIHttpChannel);
- var hostmatch = subject.URI.host.match(/^(encrypted|www)\.google\.(co\.\S\S|com|\S\S|com\.\S\S)$/);
-
- // check nsIURI
- if (hostmatch && httpChannel.responseStatus == 302) {
- // Now check for 302 to sorry.google.com
- torbutton_log(3, "Got Google 302 response...");
- var redir = httpChannel.getResponseHeader("Location");
- var redirURI = Components.classes["@mozilla.org/network/standard-url;1"]
- .createInstance(Ci.nsIStandardURL);
-
- redirURI.init(Ci.nsIStandardURL.URLTYPE_STANDARD, 80, redir,
- subject.URI.originCharset, null);
- redirURI = redirURI.QueryInterface(Components.interfaces.nsIURI);
- if (redirURI.host == "sorry.google.com"
- || redirURI.path.match("^/sorry/")) {
- var browser = null;
- if(m_tb_ff3 && subject.notificationCallbacks) {
- // Arg. google.timers.load.t is fucking us up!
- try {
- var wind = subject.notificationCallbacks.QueryInterface(
- Components.interfaces.nsIInterfaceRequestor).getInterface(
- Components.interfaces.nsIDOMWindow);
- var wm = Components.classes["@torproject.org/content-window-mapper;1"]
- .getService(Components.interfaces.nsISupports)
- .wrappedJSObject;
- browser = wm.getBrowserForContentWindow(wind.window.top);
- } catch(e) {
- torbutton_log(4, "Exception on google captcha logging: "+e);
- }
- }
-
- var querymatch = subject.URI.path.match("[\?\&]q=([^&]+)(?:[\&]|$)");
- if (!querymatch) {
- torbutton_safelog(4, "No Google query found for captcha in: ",
- subject.URI.spec);
- return;
- }
- var newUrl = m_tb_prefs.getCharPref("extensions.torbutton.redir_url."+
- m_tb_prefs.getIntPref("extensions.torbutton.google_redir_url"));
- var query=newUrl+querymatch[1];
- torbutton_safelog(3, "Got Google query: ",query);
-
- if (!m_tb_prefs.getBoolPref("extensions.torbutton.asked_google_captcha")) {
- var check = {value: false};
- var prompts = Components.classes["@mozilla.org/embedcomp/prompt-service;1"]
- .getService(Components.interfaces.nsIPromptService);
- var flags = prompts.BUTTON_POS_0 * prompts.BUTTON_TITLE_IS_STRING +
- prompts.BUTTON_POS_1 * prompts.BUTTON_TITLE_IS_STRING +
- prompts.BUTTON_POS_1_DEFAULT;
-
- var bundle = torbutton_get_stringbundle();
- var title = bundle.GetStringFromName("torbutton.popup.captcha.title");
- var ask = bundle.GetStringFromName("torbutton.popup.captcha.ask");
- var dontask = bundle.GetStringFromName("torbutton.popup.captcha.always");
- var launch = bundle.GetStringFromName("torbutton.popup.redirect");
- var cancel = bundle.GetStringFromName("torbutton.popup.no_redirect");
-
- var wm = Cc["@mozilla.org/appshell/window-mediator;1"]
- .getService(Components.interfaces.nsIWindowMediator);
- var chrome = wm.getMostRecentWindow("navigator:browser");
-
- var result = prompts.confirmEx(chrome, title, ask, flags,
- launch, cancel, "", dontask, check);
-
- if (check.value) {
- m_tb_prefs.setBoolPref("extensions.torbutton.asked_google_captcha",
- true);
- m_tb_prefs.setBoolPref("extensions.torbutton.dodge_google_captcha",
- (result == 0));
- }
-
- if (result != 0) {
- return;
- }
- }
- torbutton_safelog(3, "Still have Google query: ",query);
- // Split url into [?&]q=...[&$]
- if (browser)
- browser.loadURI(query, null, subject.URI.originCharset);
- else
- httpChannel.setResponseHeader("Location", query, false);
- torbutton_log(4, "Got Google Captcha. Redirecting");
- }
- }
-}
-
-// This observer is to catch some additional http load events
-// to deal with firefox bug 401296
-// TODO: One of these days we should probably unify these http observers
-// with our content policy, like NoScript does.
-//
-// Bug 1506 P2: Most of this is toggle/plugin protections, however
-// the google captcha redirect is also in here.
-var torbutton_http_observer = {
-observe : function(subject, topic, data) {
- torbutton_eclog(2, 'Examine response: '+subject.name);
- if (((subject instanceof Components.interfaces.nsIHttpChannel)
- && !(subject.loadFlags & Components.interfaces.nsIChannel.LOAD_DOCUMENT_URI))) {
- // FIXME: FF3 no longer calls the contet policy for favicons.
- // This is the workaround. Fun fun fun.
- if(m_tb_ff3 && subject.notificationCallbacks) {
- try {
- var wind = subject.notificationCallbacks.QueryInterface(
- Components.interfaces.nsIInterfaceRequestor).getInterface(
- Components.interfaces.nsIDOMWindow);
-
- if(wind instanceof Components.interfaces.nsIDOMChromeWindow) {
- if(wind.browserDOMWindow) {
- var browser = wind.getBrowser().selectedTab.linkedBrowser;
- if(!browser) {
- torbutton_safelog(5,
- "No linked browser for possible favicon request: ",
- subject.name);
- // Hrmm.. fail closed is the safe option here,
- // but how often does this happen?? If this
- // is bug 1035, this request probably is the
- // proxy test.
- //subject.cancel(0x804b0002); // NS_BINDING_ABORTED
- return;
- }
-
- // This can happen in the first request of a new state.
- // block favicons till we've reach steady state
- if((typeof(browser.__tb_tor_fetched) != "undefined")
- && (browser.__tb_tor_fetched !=
- m_tb_prefs.getBoolPref("extensions.torbutton.tor_enabled")
- || browser.__tb_tor_fetched != m_tb_prefs.getBoolPref("extensions.torbutton.settings_applied"))) {
- subject.cancel(0x804b0002); // NS_BINDING_ABORTED
- torbutton_eclog(3, 'Cancelling opposing (favicon?) request: '+subject.name);
- }
- }
- }
- } catch(e) {
- torbutton_eclog(2, 'Failure cancelling opposing (favicon?) request '+subject.name+': '+e);
- }
- }
- return;
- }
- if(!(subject instanceof Components.interfaces.nsIHttpChannel)) {
- torbutton_eclog(2, 'Non-http request '+subject.name);
- }
-
- if (topic == "http-on-examine-response") {
- // Bug 1506 P2: This is the only observer topic you might want
- // to keep in this object
- torbutton_eclog(3, 'Definitaly Examine response: '+subject.name);
- if (m_tb_prefs.getBoolPref("extensions.torbutton.dodge_google_captcha")
- && subject instanceof Ci.nsIHttpChannel) {
- try {
- torbutton_check_google_captcha(subject, topic, data);
- } catch(e) {
- torbutton_log(4, "Explosion on captcha redirect: "+e);
- }
- }
- torbutton_check_progress(null, subject, 0, false);
- } else if (topic == "http-on-modify-request") {
- torbutton_eclog(3, 'Modify request: '+subject.name);
- if (m_tb_prefs.getBoolPref("extensions.torbutton.xfer_google_cookies")
- && subject instanceof Ci.nsIHttpChannel) {
- try {
- torbutton_xfer_google_cookies(subject, topic, data);
- } catch(e) {
- torbutton_log(4, "Explosion on cookie transfer: "+e);
- }
- }
- }
-},
-register : function() {
- var observerService =
- Components.classes["@mozilla.org/observer-service;1"].
- getService(Components.interfaces.nsIObserverService);
- torbutton_log(3, "Observer register");
-
- observerService.addObserver(this, "http-on-modify-request", false);
- observerService.addObserver(this, "http-on-examine-response", false);
- torbutton_log(3, "Observer register");
-},
-unregister : function() {
- var observerService =
- Components.classes["@mozilla.org/observer-service;1"].
- getService(Components.interfaces.nsIObserverService);
-
- observerService.removeObserver(this,"http-on-modify-request");
- observerService.removeObserver(this,"http-on-examine-response");
-}
-}
-
-// Bug 1506 P0: Forces torbutton updates over tor when in non-tor mode.
-// Actually, this observer is already disabled due to being irrelevant.
-var torbutton_proxyservice = {
- applyFilter : function(ps, uri, proxy) {
- try {
- proxyhost = proxy ? 'proxy: '+proxy.host:'no proxy';
- torbutton_eclog(3, 'apply: '+proxyhost);
- if (m_tb_prefs.getBoolPref("extensions.torbutton.tor_enabled")) {
- if (uri.host == "localhost") return null;
- }
-
- if (!m_tb_prefs.getBoolPref("extensions.torbutton.settings_applied")) {
- if (m_tb_prefs.getBoolPref("extensions.torbutton.update_torbutton_via_tor")) {
- var path = new String(uri.path);
- var update_proxy = proxy;
- if (uri.host == "versioncheck.addons.mozilla.org") {
- if (path.indexOf("{e0204bd5-9d31-402b-a99d-a6aa8ffebdca}") != -1) {
- // https_proxy, https_port
- var https_proxy=m_tb_prefs.getCharPref("extensions.torbutton.https_proxy");
- var https_port=m_tb_prefs.getIntPref("extensions.torbutton.https_port");
- if (!https_proxy || !https_port) {
- var socks_host=m_tb_prefs.getCharPref("extensions.torbutton.socks_host");
- var socks_port=m_tb_prefs.getIntPref("extensions.torbutton.socks_port");
- var socks_version=m_tb_prefs.getIntPref("extensions.torbutton.socks_version");
- var flag = 0;
- if (!socks_host || !socks_port)
- return proxy;
- if (m_tb_prefs.getBoolPref("network.proxy.socks_remote_dns"))
- flag = Ci.nsIProxyInfo.TRANSPARENT_PROXY_RESOLVES_HOST;
- if (socks_version == 4) {
- update_proxy = this._proxyservice.newProxyInfo("socks4", socks_proxy, socks_port,
- flag, 0x7ffffffe, null);
- } else {
- update_proxy = this._proxyservice.newProxyInfo("socks", socks_proxy, socks_port,
- flag, 0x7ffffffe, null);
- }
- } else {
- update_proxy = this._proxyservice.newProxyInfo("http", https_proxy, https_port,
- Ci.nsIProxyInfo.TRANSPARENT_PROXY_RESOLVES_HOST, 0x7ffffffe, null);
- }
- }
- } else if (uri.host == "releases.mozilla.org") {
- if (path.indexOf("/pub/mozilla.org/addons/2275/") == 0) {
- var http_proxy=m_tb_prefs.getCharPref("extensions.torbutton.http_proxy");
- var http_port=m_tb_prefs.getIntPref("extensions.torbutton.http_port");
- if (!http_proxy || !http_port) {
- var socks_host=m_tb_prefs.getCharPref("extensions.torbutton.socks_host");
- var socks_port=m_tb_prefs.getIntPref("extensions.torbutton.socks_port");
- var socks_version=m_tb_prefs.getIntPref("extensions.torbutton.socks_version");
- var flag = 0;
- if (!socks_host || !socks_port)
- return proxy;
- if (m_tb_prefs.getBoolPref("network.proxy.socks_remote_dns"))
- flag = Ci.nsIProxyInfo.TRANSPARENT_PROXY_RESOLVES_HOST;
- if (socks_version == 4) {
- update_proxy = this._proxyservice.newProxyInfo("socks4", socks_proxy, socks_port,
- flag, 0x7ffffffe, null);
- } else {
- update_proxy = this._proxyservice.newProxyInfo("socks", socks_proxy, socks_port,
- flag, 0x7ffffffe, null);
- }
- } else {
- update_proxy = this._proxyservice.newProxyInfo("http", http_proxy, http_port,
- Ci.nsIProxyInfo.TRANSPARENT_PROXY_RESOLVES_HOST, 0x7ffffffe, null);
- }
- }
- }
- if (update_proxy != proxy)
- torbutton_log(3, "Performing Torbutton update check via Tor proxy for: "+
- uri.spec);
- return update_proxy;
- }
- }
- return proxy;
- }
- catch (e) {
- torbutton_eclog(3, 'applyFilter failed:' +e);
- }
- },
- register : function() {
- torbutton_eclog(3, 'Proxy filter Registering...');
- try {
- this._proxyservice = Components.classes["@mozilla.org/network/protocol-proxy-service;1"]
- .getService(Components.interfaces.nsIProtocolProxyService);
- this._proxyservice.registerFilter(this, 0);
- } catch (e) {
- torbutton_eclog(3, 'RegisterFilter failed:'+e);
- }
- },
- unregister : function() {
- torbutton_eclog(3, 'Proxy filter Unregistering...');
- try {
- this._proxyservice = Components.classes["@mozilla.org/network/protocol-proxy-service;1"]
- .getService(Components.interfaces.nsIProtocolProxyService);
- this._proxyservice.unregisterFilter(this);
- } catch (e) {
- torbutton_eclog(3, 'UnregisterFilter failed:'+e);
- }
- }
-}
-
// Bug 1506 P1/P3: This removes any platform-specific junk
// from the omnibox. In Tor Browser, it should not be needed.
function torbutton_wrap_search_service()
@@ -4085,19 +3118,12 @@ function torbutton_do_main_window_startup()
getService(Components.interfaces.nsIWebProgress);
progress.addProgressListener(torbutton_weblistener,
- // Components.interfaces.nsIWebProgress.NOTIFY_STATE_ALL|
- // Components.interfaces.nsIWebProgress.NOTIFY_ALL);
- Components.interfaces.nsIWebProgress.NOTIFY_STATE_DOCUMENT|
Components.interfaces.nsIWebProgress.NOTIFY_LOCATION);
// Wrap Google search service.
torbutton_wrap_search_service();
torbutton_unique_pref_observer.register();
- torbutton_http_observer.register();
- torbutton_cookie_observer.register();
- // Not needed
- //torbutton_proxyservice.register();
// Bug 1506: This is probably the most important observer in this function
// XXX: We should fold this into our code/move it to its own component
@@ -4189,17 +3215,6 @@ function torbutton_do_startup()
}
var tor_enabled = torbutton_check_status();
- // XXX: There is a timer at startup. this is not enough..
- if(m_tb_ff35 &&
- m_tb_prefs.getBoolPref("extensions.torbutton.disable_livemarks")) {
- var livemarks = Cc["@mozilla.org/browser/livemark-service;2"].
- getService(Ci.nsILivemarkService);
- if (tor_enabled) {
- livemarks.stopUpdateLivemarks();
- torbutton_log(3, "Disabled livemarks");
- }
- }
-
// Bug 1506: Still want to do this
torbutton_set_timezone(tor_enabled, true);
@@ -4221,12 +3236,6 @@ function torbutton_do_startup()
torbutton_toggle_plugins(tor_enabled
&& m_tb_prefs.getBoolPref("extensions.torbutton.no_tor_plugins"));
-
- if (tor_enabled) {
- // Need to maybe generate google cookie if tor is enabled
- torbutton_new_google_cookie();
- }
-
if (!m_tb_tbb && m_tb_prefs.getBoolPref("extensions.torbutton.prompt_torbrowser")) {
var o_stringbundle = torbutton_get_stringbundle();
var warning = o_stringbundle.GetStringFromName("torbutton.popup.short_torbrowser");
@@ -4274,8 +3283,6 @@ function torbutton_new_tab(event)
torbutton_do_async_versioncheck();
}
- torbutton_tag_new_browser(browser, tor_tag, no_plugins);
-
// XXX: This is possibly slightly the wrong place to do this check,
// but we know the TabOpen effect is late enough to provide the popup
// after firefox is visible, which makes it more clear whose popup this is.
@@ -4314,67 +3321,6 @@ function torbutton_is_windowed(wind) {
return true;
}
-// Bug 1506 P0: Kill this
-//
-// XXX: This function is unused. We can't make it work
-// without a way to tell when the user has stopped resizing..
-function torbutton_do_resize(ev)
-{
- if(m_tb_prefs.getBoolPref("extensions.torbutton.tor_enabled")
- && m_tb_prefs.getBoolPref("extensions.torbutton.resize_on_toggle")) {
- var bWin = window.getBrowser().contentWindow;
- // only resize if outer window size has changed (ignore stuff like
- // scrollbars and find bars)
- if((m_tb_window_height != window.outerHeight ||
- m_tb_window_width != window.outerWidth) &&
- torbutton_is_windowed(window)) {
- torbutton_log(3, "Resizing window on event: "+window.windowState);
- /*
- * Instead of direct adjustment, we must update the outer window
- * size, because firefox is sloppy about repositioning widgets
- * properly after inner size changes.
- bWin.innerHeight = Math.round(bWin.innerHeight/50.0)*50;
- bWin.innerWidth = Math.round(bWin.innerWidth/50.0)*50;
- */
- var hDelta = Math.round(bWin.innerHeight/50.0)*50 - bWin.innerHeight;
- var wDelta = Math.round(bWin.innerWidth/50.0)*50 - bWin.innerWidth;
-
- bWin.resizeBy(wDelta,hDelta);
- torbutton_log(2, "Resized window: ("+window.outerHeight+","+window.outerWidth+") ?= ("
- +bWin.innerHeight+","+bWin.innerWidth+")");
- }
- }
-
- m_tb_window_height = window.outerHeight;
- m_tb_window_width = window.outerWidth;
-}
-
-// Bug 1506 P0: Kill this
-// XXX: unused. Use torbutton_set_window_size instead
-function torbutton_check_round(browser)
-{
- if(torbutton_is_windowed(window)
- && m_tb_prefs.getBoolPref("extensions.torbutton.tor_enabled")
- && m_tb_prefs.getBoolPref("extensions.torbutton.resize_on_toggle")) {
- var bWin = browser.contentWindow;
- var height = Math.round((bWin.innerHeight)/50.0)*50;
- var width = Math.round((bWin.innerWidth)/50.0)*50;
-
- torbutton_log(3, "About to resize load window: "+bWin.innerWidth
- +"x"+bWin.innerHeight+" -> "+width+"x"+height+" in state "
- +window.windowState);
-
- // This is fun. any attempt to directly set the inner window actually resizes the outer width
- // to that value instead. Must use resizeBy() instead of assignment or resizeTo()
- bWin.resizeBy(width-bWin.innerWidth,height-bWin.innerHeight);
- torbutton_log(3, "Resized window on load to: "+bWin.innerWidth+"x"+bWin.innerHeight+" in state "+window.windowState);
-
- m_tb_window_height = window.outerHeight;
- m_tb_window_width = window.outerWidth;
-
- }
-}
-
// Bug 1506 P1/P3: Setting a fixed window size is important, but
// probably not for android.
function torbutton_set_window_size(bWin) {
@@ -4457,10 +3403,6 @@ function torbutton_new_window(event)
torbutton_get_plugin_mimetypes();
- torbutton_tag_new_browser(browser.browsers[0],
- !m_tb_prefs.getBoolPref("extensions.torbutton.tor_enabled"),
- m_tb_prefs.getBoolPref("extensions.torbutton.no_tor_plugins"));
-
torbutton_set_window_size(browser.contentWindow);
// Check the version on every new window. We're already pinging check in these cases.
@@ -4498,10 +3440,6 @@ function torbutton_close_window(event) {
progress.removeProgressListener(torbutton_weblistener);
torbutton_unique_pref_observer.unregister();
- torbutton_http_observer.unregister();
- torbutton_cookie_observer.unregister();
- // Not needed
- //torbutton_proxyservice.unregister();
// XXX: We should fold this into our code..
SSC_controller.removeListener();
@@ -4518,353 +3456,6 @@ function torbutton_close_window(event) {
window.addEventListener('load',torbutton_new_window,false);
window.addEventListener('unload', torbutton_close_window, false);
-// getBrowser() is not available at this point for FF4..
-// XXX: This registration is possibly related to why TabMixPlus fails.
-//getBrowser().tabContainer.addEventListener("TabOpen", torbutton_new_tab, false);
-
-
-// ----------- JAVASCRIPT HOOKING + EVENT HANDLERS ----------------
-// Bug 1506 P1: All of our JS hooks should be redone in patch form (#5856)
-function torbutton_init_jshooks() {
- torbutton_log(2, "torbutton_init_jshooks()");
- var nsio = Components.classes["@mozilla.org/network/io-service;1"]
- .getService(Components.interfaces.nsIIOService);
- var chan = null;
- if (m_tb_ff4) {
- chan = nsio.newChannel("chrome://torbutton/content/jshooks4.js",
- null, null);
- } else {
- chan = nsio.newChannel("chrome://torbutton/content/jshooks.js",
- null, null);
- }
- var istream = Components.classes["@mozilla.org/scriptableinputstream;1"].
- createInstance(Components.interfaces.nsIScriptableInputStream);
-
- istream.init(chan.open());
- m_tb_jshooks = istream.read(istream.available());
- istream.close();
-}
-
-// Bug 1506 P1: All of our JS hooks should be redone in patch form (#5856)
-function torbutton_getbody(doc) {
- if (doc.body)
- return doc.body;
- else if (doc.documentElement)
- return doc.documentElement;
- return null;
-}
-
-/* This seems to be necessary due to javascript's
- * nebulous scoping/parsing/evaluations issues. Having this as
- * a standalone statement seems to cause the flag
- * to become defined after just parsing, not execution */
-// Bug 1506 P1: All of our JS hooks should be redone in patch form (#5856)
-function torbutton_set_flag(obj, flag) {
- obj[flag] = true;
-}
-
-// Bug 1506 P1: All of our JS hooks should be redone in patch form (#5856)
-function torbutton_check_flag(obj, flag) {
- try {
- return (typeof(obj[flag]) != 'undefined');
- } catch(e) {
- torbutton_log(5, "Exception on flag "+flag+" check: "+e);
- return true;
- }
-}
-
-// Bug 1506 P1: All of our JS hooks should be redone in patch form (#5856)
-function torbutton_is_same_origin(win, source, target) { // unused.
- var fixup = Components.classes["@mozilla.org/docshell/urifixup;1"]
- .getService(Components.interfaces.nsIURIFixup);
- var source = fixup.createFixupURI(win.top.location.href, 0);
- var target = fixup.createFixupURI(win.location.href, 0);
-
- var secmgr = Components.classes["@mozilla.org/scriptsecuritymanager;1"]
- .getService(Components.interfaces.nsIScriptSecurityManager);
-
- if(!source || !target) {
- torbutton_log(5, "Can't convert one of: "+win.document.location+", parent is: "+win.top.document.location);
- }
-
- // TODO: this doesn't work.. esp if document modifies document.domain
- // window.windowRoot instead? Also, prints an error message
- // to the error console..
- try {
- secmgr.checkSameOriginURI(source, target);
- torbutton_log(3, "Same-origin non-toplevel window: "+win.document.location+", parent is: "+win.top.document.location);
- win = win.top;
- } catch(e) {
- torbutton_log(3, "Exception w/ non-same-origin non-toplevel window: "+win.document.location+", parent is: "+win.top.document.location);
- }
-}
-
-// Bug 1506 P1: All of our JS hooks should be redone in patch form (#5856)
-// Also, tagging can be deprecated.
-function torbutton_update_tags(win, new_loc) {
- var tag_change = false;
- torbutton_eclog(2, "Updating tags.");
- if(typeof(win.wrappedJSObject) == 'undefined') {
- torbutton_eclog(3, "No JSObject: "+win.location);
- return;
- }
-
- var wm = Components.classes["@torproject.org/content-window-mapper;1"]
- .getService(Components.interfaces.nsISupports)
- .wrappedJSObject;
-
- // Expire the cache on page loads. TODO: Do a timer instead..
- if(win == win.top) wm.expireOldCache();
-
- var browser = wm.getBrowserForContentWindow(win.top);
- if(!browser) {
- torbutton_log(5, "No window found!1");
- return;
- //win.alert("No window found!");
- }
-
- // This sometimes happens with CoolPreviews..
- try {
- // XXX: sometimes we get a dialog window here in FF4?
- if (!browser.contentWindow) {
- torbutton_log(3, "No content window for: "+browser.location);
- return;
- }
-
- torbutton_log(2, "Got browser "+browser.contentWindow.location+" for: "
- + win.location + ", under: "+win.top.location);
- } catch(e) {
- torbutton_log(4, "Missing content window: "+e);
- }
-
- // Base this tag off of proxies_applied, since we want to go
- // by whatever the actual load proxy was
- var tor_tag = !m_tb_prefs.getBoolPref("extensions.torbutton.proxies_applied");
- var js_enabled = m_tb_prefs.getBoolPref("javascript.enabled");
- var kill_plugins = m_tb_prefs.getBoolPref("extensions.torbutton.no_tor_plugins");
-
- if (new_loc && !torbutton_check_flag(win.top, "__tb_js_refresh")) {
- torbutton_log(2, "Tagging browser for: " + win.location);
-
- if(typeof(browser.__tb_tor_fetched) == "undefined") {
- torbutton_log(5, "Untagged browser at: "+win.location);
- // Defensive programming to tag this window here to
- // an alternate tor state. It wil lmake this window totally
- // useless, but that is better than some undefined state
- torbutton_apply_tab_tag(null, browser, tor_tag);
- }
- if(browser.__tb_tor_fetched != !tor_tag) {
- tag_change = true;
- // Purge session history every time we fetch a new doc
- // in a new tor state
- torbutton_log(2, "Purging session history");
- // sessionHistory can be null now...
- if(browser.webNavigation.sessionHistory
- && browser.webNavigation.sessionHistory.count > 1
- && m_tb_prefs.getBoolPref("extensions.torbutton.block_js_history")) {
- // FIXME: This isn't quite right.. For some reason
- // this breaks in some cases..
- /*
- var current = browser.webNavigation
- .QueryInterface(Components.interfaces.nsIDocShellHistory)
- .getChildSHEntry(0).clone(); // FIXME: Use index??
- */
- var current = browser.webNavigation.contentViewer.historyEntry;
-
- browser.webNavigation.sessionHistory.PurgeHistory(
- browser.webNavigation.sessionHistory.count);
-
- if(current) {
- // Add current page back in
- browser.webNavigation
- .QueryInterface(Components.interfaces.nsISHistoryInternal)
- .addChildSHEntry(current, true);
- }
- }
- }
-
- torbutton_apply_tab_tag(null, browser, !tor_tag);
-
- if (!m_tb_tbb) {
- browser.docShell.allowPlugins = tor_tag || !kill_plugins;
- }
-
- /* We want to disable allowDNSPrefetch on Tor-loaded tabs
- * before the load, because we don't want prefetch to be enabled
- * on tor tabs once we leave Tor. */
- if(m_tb_ff35) {
- if (!m_tb_ff36) /* Unified with nsIDocShell in 3.6 */
- browser.docShell.QueryInterface(Ci.nsIDocShell_MOZILLA_1_9_1_dns);
- browser.docShell.allowDNSPrefetch = tor_tag;
- }
-
- if(js_enabled && !browser.docShell.allowJavascript) {
- // Only care about re-enabling javascript.
- // The js engine obeys the pref over the docshell attribute
- // for disabling js, and this is the source of a conflict with
- // NoScript
- torbutton_log(3, "Javascript changed from "+browser.docShell.allowJavascript+" to: "+js_enabled);
- browser.docShell.allowJavascript = js_enabled;
-
- // Tag this specially, so that the next onLocationChange
- // doesn't redo these hooks.
- torbutton_set_flag(win.top, "__tb_js_refresh");
-
- // JS was not fully enabled for some page elements.
- // Need to reload
- browser.reload();
- }
- }
-
- torbutton_log(2, "Tags updated.");
- return tag_change;
-}
-
-// Same-origin policy may prevent our hooks from applying
-// to inner iframes.. Test with frames, iframes, and
-// popups. Test these extensively:
-// http://taossa.com/index.php/2007/02/08/same-origin-policy/
-// - http://www.htmlbasix.com/popup.shtml
-// - http://msdn2.microsoft.com/en-us/library/ms531202.aspx
-// - Url-free: http://www.yourhtmlsource.com/javascript/popupwindows.html#accessiblepopups
-// - Blocked by default (tho perhaps only via onload).
-// see popup blocker detectors:
-// - http://javascript.internet.com/snippets/popup-blocker-detection.html
-// - http://www.visitor-stats.com/articles/detect-popup-blocker.php
-// - http://www.dynamicdrive.com/dynamicindex8/dhtmlwindow.htm
-// - popup blocker tests:
-// - http://swik.net/User:Staple/JavaScript+Popup+Windows+Generation+and+Testing…
-// - pure javascript pages/non-text/html pages
-// - Messing with variables/existing hooks
-// Bug 1506 P1: All of our JS hooks should be redone in patch form (#5856)
-// Also, tagging can be deprecated.
-function torbutton_hookdoc(win, doc, state_change, referrer) {
- /* Firefox 15 broke the last of our JS hooks.
- * So did 10.0.8-ESR... */
- if (m_tb_ff15 || m_tb_ff10_8) {
- return;
- }
-
- if(typeof(win.wrappedJSObject) == 'undefined') {
- torbutton_eclog(3, "No JSObject: "+win.location);
- return;
- }
-
- torbutton_log(2, "Hooking document: "+win.location);
- if(doc && doc.doctype) {
- torbutton_log(2, "Type: "+doc.doctype.name);
- }
-
- try {
- // Ticket #3414: Apply referer policy to window.name.
- //
- // This keeps window.name clean between fresh urls.
- // It should also apply to iframes because hookdoc gets called for all
- // frames and subdocuments.
- //
- // The about:blank check handles the 'name' attribute of framesets, which
- // get set before the referer is set on the channel.
- if ((!referrer || referrer.spec == "") && win.location != "about:blank") {
- if (win.top == win.window) {
- // Only reset if we're the top-level window
- //torbutton_log(4, "Resetting window.name: "+win.name+" for "+win.location);
- win.name = "";
- win.window.name = "";
- }
- }
- } catch(e) {
- torbutton_log(4, "Failed to reset window.name: "+e)
- }
-
- var js_enabled = m_tb_prefs.getBoolPref("javascript.enabled");
-
- // No need to hook js if tor is off
- if(!js_enabled
- || !m_tb_prefs.getBoolPref("extensions.torbutton.tor_enabled")
- || !m_tb_prefs.getBoolPref('extensions.torbutton.kill_bad_js')) {
- torbutton_log(2, "Finished non-hook of: " + win.location);
- return;
- }
-
- // Date Hooking:
-
- /* Q: Do this better with XPCOM?
- * http://www.mozilla.org/projects/xpcom/nsIClassInfo.html
- * A: Negatory.. Date() is not an XPCOM component :(
- */
-
- // So it looks like the race condition is actually a result of
- // the insertion function returning before the injected code is evaluated.
- // This code seems to do what we want.
-
- var str2 = "window.__tb_state_changed="+state_change+";\r\n";
- if(m_tb_ff3) {
- str2 += "window.__tb_set_uagent=false;\r\n";
- str2 += "window.__tb_hook_date=false;\r\n";
- } else {
- str2 += "window.__tb_hook_date=true;\r\n";
- if(m_tb_prefs.getBoolPref("extensions.torbutton.no_tor_plugins")) {
- str2 += "window.__tb_set_uagent="+m_tb_prefs.getBoolPref('extensions.torbutton.set_uagent')+";\r\n";
- } else {
- // Abandon ship on user agent spoofing if user wants plugins.
- // OS+platform can be obtained from plugins anyways, and complications
- // with XPCNativeWrappers makes it hard to provide
- // plugin information in window.navigator properly with plugins
- // enabled.
- str2 += "window.__tb_set_uagent=false;\r\n";
- }
- if(m_tb_prefs.getBoolPref("extensions.torbutton.spoof_english")) {
- str2 += "window.__tb_locale=\""+m_tb_prefs.getCharPref('extensions.torbutton.spoof_locale')+"\";\r\n";
- } else {
- str2 += "window.__tb_locale=false;\r\n";
- }
- str2 += "window.__tb_oscpu=\""+m_tb_prefs.getCharPref('extensions.torbutton.oscpu_override')+"\";\r\n";
- str2 += "window.__tb_platform=\""+m_tb_prefs.getCharPref('extensions.torbutton.platform_override')+"\";\r\n";
- str2 += "window.__tb_productSub=\""+m_tb_prefs.getCharPref('extensions.torbutton.productsub_override')+"\";\r\n";
- }
- str2 += m_tb_jshooks;
-
- try {
- var s = null;
- torbutton_log(2, "Type of window: " + typeof(win));
- torbutton_log(2, "Type of wrapped window: " + typeof(win.wrappedJSObject));
-
- // Workaround for https://bugzilla.mozilla.org/show_bug.cgi?id=627494
- // https://developer.mozilla.org/en/Components.utils.Sandbox#Optional_parameter
-
- if (m_tb_ff4) {
- s = new Components.utils.Sandbox(win.wrappedJSObject,
- { sandboxPrototype: win.wrappedJSObject,
- wantXrays: false });
- } else {
- s = new Components.utils.Sandbox(win.wrappedJSObject);
- }
- torbutton_log(2, "Type of sandbox: " + typeof(s));
-
- // FIXME: FF3 issues
- // http://developer.mozilla.org/en/docs/XPConnect_wrappers#XPCSafeJSObjectWrap…
- // http://developer.mozilla.org/en/docs/Code_snippets:Interaction_between_priv…
- s.window = win.wrappedJSObject;
- //s.__proto__ = win.wrappedJSObject;
- var result = Components.utils.evalInSandbox(str2, s);
- torbutton_log(2, "Type of result: " + typeof(result));
- if(result === 23) { // secret confirmation result code.
- torbutton_log(3, "Javascript hooks applied successfully at: " + win.location);
- } else if(result === 13) {
- torbutton_log(3, "Double-hook at: " + win.location);
- } else {
- window.alert("Torbutton Sandbox evaluation failed. Date hooks not applied!");
- torbutton_log(5, "Hook evaluation failure at " + win.location);
- }
- } catch (e) {
- window.alert("Torbutton Exception in sandbox evaluation. Date hooks not applied:\n"+e);
- torbutton_log(5, "Hook exception at: "+win.location+", "+e);
- }
-
- torbutton_log(2, "Finished hook: " + win.location);
-
- return;
-}
// FIXME: Tons of exceptions get thrown from this function on account
// of its being called so early. Need to find a quick way to check if
@@ -4912,125 +3503,43 @@ function torbutton_check_progress(aProgress, aRequest, aFlags, new_loc) {
} catch(e) { }
}
- // FIXME if intstanceof nsIHttpChannel check headers for
- // Content-Disposition..
-
- // This noise is a workaround for firefox bugs involving
- // enforcement of docShell.allowPlugins and docShell.allowJavascript
- // (Bugs 401296 and 409737 respectively)
- try {
- if(aRequest) {
- var chanreq = aRequest.QueryInterface(Components.interfaces.nsIChannel);
- if(chanreq
- && chanreq instanceof Components.interfaces.nsIChannel
- && aRequest.isPending()) {
-
- try { torbutton_eclog(2, 'Pending request: '+aRequest.name); }
- catch(e) { }
-
- if(DOMWindow && DOMWindow.opener
- && m_tb_prefs.getBoolPref("extensions.torbutton.isolate_content")) {
-
- try { torbutton_eclog(3, 'Popup request: '+aRequest.name); }
- catch(e) { }
-
- if(!(DOMWindow.top instanceof Components.interfaces.nsIDOMChromeWindow)) {
- // Workaround for Firefox bug 409737
- // The idea is that the content policy should stop all
- // forms of javascript fetches except for popups. This
- // code handles blocking popups from alternate tor states.
- var wm = Components.classes["@torproject.org/content-window-mapper;1"]
- .getService(Components.interfaces.nsISupports)
- .wrappedJSObject;
-
- var browser = wm.getBrowserForContentWindow(DOMWindow.opener);
- torbutton_eclog(3, 'Got browser for request: ' + (browser != null));
-
- // XXX: This may block ssl popups in the first tab
- if(browser &&
- (browser.__tb_tor_fetched != m_tb_prefs.getBoolPref("extensions.torbutton.tor_enabled")
- || browser.__tb_tor_fetched != m_tb_prefs.getBoolPref("extensions.torbutton.settings_applied"))) {
- try {
- torbutton_eclog(3, 'Stopping document: '+DOMWindow.location);
- aRequest.cancel(0x804b0002); // NS_BINDING_ABORTED
- DOMWindow.stop();
- torbutton_eclog(3, 'Stopped document: '+DOMWindow.location);
- DOMWindow.document.clear();
- torbutton_eclog(3, 'Cleared document: '+DOMWindow.location);
- } catch(e) {
- }
- torbutton_eclog(4, 'Torbutton blocked state-changed popup');
- DOMWindow.close();
- return 0;
- }
- }
- }
-
- torbutton_eclog(2, 'LocChange: '+aRequest.contentType);
-
- // Workaround for Firefox Bug 401296
- if((m_tb_prefs.getBoolPref("extensions.torbutton.tor_enabled")
- && m_tb_prefs.getBoolPref("extensions.torbutton.no_tor_plugins")
- && aRequest.contentType in m_tb_plugin_mimetypes)) {
- aRequest.cancel(0x804b0002); // NS_BINDING_ABORTED
- var o_stringbundle = torbutton_get_stringbundle();
- var warning = o_stringbundle.GetStringFromName("torbutton.popup.plugin.warning");
- if(DOMWindow) {
- // ZOMG DIE DIE DXIE!!!!!@
- try {
- DOMWindow.stop();
- torbutton_eclog(2, 'Stopped document');
- DOMWindow.document.clear();
- torbutton_eclog(2, 'Cleared document');
-
- if(typeof(DOMWindow.__tb_kill_flag) == 'undefined') {
- var wm = Cc["@mozilla.org/appshell/window-mediator;1"]
- .getService(Components.interfaces.nsIWindowMediator);
- var chrome = wm.getMostRecentWindow("navigator:browser");
- chrome.alert(warning);
- DOMWindow.__tb_kill_flag = true;
- }
- // This doesn't seem to actually remove the child..
- // It usually just causes an exception to be thrown,
- // which strangely enough, actually does finally
- // kill the plugin.
- DOMWindow.document.removeChild(
- DOMWindow.document.firstChild);
- } catch(e) {
- torbutton_eclog(3, 'Exception on stop/clear');
- }
- } else {
- torbutton_eclog(4, 'No progress for document cancel!');
- var wm = Cc["@mozilla.org/appshell/window-mediator;1"]
- .getService(Components.interfaces.nsIWindowMediator);
- var chrome = wm.getMostRecentWindow("navigator:browser");
- chrome.alert(warning);
- }
- torbutton_eclog(3, 'Killed plugin document');
- return 0;
- }
- } else {
- torbutton_eclog(2, 'Nonpending: '+aRequest.name);
- torbutton_eclog(2, 'Type: '+aRequest.contentType);
- }
- }
- } catch(e) {
- torbutton_eclog(3, 'Exception on request cancel');
- }
-
// TODO: separate this from the above?
if(DOMWindow) {
var doc = DOMWindow.document;
try {
if(doc) {
- var tag_change = torbutton_update_tags(DOMWindow.window, new_loc);
if(doc.domain) {
- var referrer = null;
- try {
- var hreq = aRequest.QueryInterface(Ci.nsIHttpChannel);
- referrer = hreq.referrer;
- } catch(e) {}
- torbutton_hookdoc(DOMWindow.window, doc, tag_change, referrer);
+ var referrer = null;
+ var win = DOMWindow.window;
+
+ try {
+ var hreq = aRequest.QueryInterface(Ci.nsIHttpChannel);
+ referrer = hreq.referrer;
+ } catch(e) {}
+
+ try {
+ // XXX: The patch from https://bugzilla.mozilla.org/show_bug.cgi?id=444222
+ // might be better here..
+ //
+ // Ticket #3414: Apply referer policy to window.name.
+ //
+ // This keeps window.name clean between fresh urls.
+ // It should also apply to iframes because hookdoc gets called for all
+ // frames and subdocuments.
+ //
+ // The about:blank check handles the 'name' attribute of framesets, which
+ // get set before the referer is set on the channel.
+ if ((!referrer || referrer.spec == "") && win.location != "about:blank") {
+ if (win.top == win.window) {
+ // Only reset if we're the top-level window
+ //torbutton_log(4, "Resetting window.name: "+win.name+" for "+win.location);
+ win.name = "";
+ win.window.name = "";
+ }
+ }
+ } catch(e) {
+ torbutton_log(4, "Failed to reset window.name: "+e)
+ }
}
}
} catch(e) {
@@ -5072,12 +3581,6 @@ var torbutton_weblistener =
throw Components.results.NS_NOINTERFACE;
},
- onStateChange: function(aProgress, aRequest, aFlag, aStatus)
- {
- torbutton_eclog(2, 'State change()');
- return torbutton_check_progress(aProgress, aRequest, aFlag, false);
- },
-
onLocationChange: function(aProgress, aRequest, aURI)
{
torbutton_eclog(2, 'onLocationChange: '+aURI.asciiSpec);
@@ -5088,6 +3591,13 @@ var torbutton_weblistener =
}
},
+ // XXX: The following can probably go
+ onStateChange: function(aProgress, aRequest, aFlag, aStatus)
+ {
+ torbutton_eclog(2, 'State change()');
+ return torbutton_check_progress(aProgress, aRequest, aFlag, false);
+ },
+
onProgressChange: function(aProgress, aRequest, curSelfProgress, maxSelfProgress, curTotalProgress, maxTotalProgress)
{
torbutton_eclog(2, 'called progressChange');
1
0

[torbutton/master] Remove some more components from the manifest.
by mikeperry@torproject.org 17 Jan '13
by mikeperry@torproject.org 17 Jan '13
17 Jan '13
commit e3f6bc5e39417b09e8085c74394a5ed0f7e860e7
Author: Mike Perry <mikeperry-git(a)fscked.org>
Date: Tue Jan 15 22:20:37 2013 -0800
Remove some more components from the manifest.
They were all unused toggle relics.
---
src/chrome.manifest | 12 ++++++------
1 files changed, 6 insertions(+), 6 deletions(-)
diff --git a/src/chrome.manifest b/src/chrome.manifest
index 5564804..a6b2937 100644
--- a/src/chrome.manifest
+++ b/src/chrome.manifest
@@ -146,17 +146,17 @@ contract @torproject.org/cookie-jar-selector;1 {e6204253-b690-4159-bfe8-d4eedab6
component {f36d72c9-9718-4134-b550-e109638331d7} components/torbutton-logger.js
contract @torproject.org/torbutton-logger;1 {f36d72c9-9718-4134-b550-e109638331d7}
-component {b985e49c-12cb-4f29-9d14-b62603332ec4} components/window-mapper.js
-contract @torproject.org/content-window-mapper;1 {b985e49c-12cb-4f29-9d14-b62603332ec4}
+# component {b985e49c-12cb-4f29-9d14-b62603332ec4} components/window-mapper.js
+# contract @torproject.org/content-window-mapper;1 {b985e49c-12cb-4f29-9d14-b62603332ec4}
# component {65be2be0-ceb4-44c2-91a5-9c75c53430bf} components/torRefSpoofer.js
# contract @torproject.org/torRefSpoofer;1 {65be2be0-ceb4-44c2-91a5-9c75c53430bf}
-component {52183e20-4d4b-11de-8a39-0800200c9a66} components/tor-protocol.js
-contract @mozilla.org/network/protocol;1?name=tor {52183e20-4d4b-11de-8a39-0800200c9a66}
+# component {52183e20-4d4b-11de-8a39-0800200c9a66} components/tor-protocol.js
+# contract @mozilla.org/network/protocol;1?name=tor {52183e20-4d4b-11de-8a39-0800200c9a66}
-component {a5a4bc50-5e8d-11de-8a39-0800200c9a66} components/tors-protocol.js
-contract @mozilla.org/network/protocol;1?name=tors {a5a4bc50-5e8d-11de-8a39-0800200c9a66}
+# component {a5a4bc50-5e8d-11de-8a39-0800200c9a66} components/tors-protocol.js
+# contract @mozilla.org/network/protocol;1?name=tors {a5a4bc50-5e8d-11de-8a39-0800200c9a66}
category profile-after-change CookieJarSelector @torproject.org/cookie-jar-selector;1
# category profile-after-change RefSpoofer @torproject.org/torRefSpoofer;1
1
0
commit ef2de3d6c3779d65682c0bb9c9e5c19b513aab80
Author: Mike Perry <mikeperry-git(a)fscked.org>
Date: Wed Jan 16 00:07:20 2013 -0800
Allow WebGL and DOM storage.
NoScript will still click-to-play WebGL for us.
---
src/chrome/content/torbutton.js | 5 -----
src/defaults/preferences/preferences.js | 2 +-
2 files changed, 1 insertions(+), 6 deletions(-)
diff --git a/src/chrome/content/torbutton.js b/src/chrome/content/torbutton.js
index 30300fa..c924eff 100644
--- a/src/chrome/content/torbutton.js
+++ b/src/chrome/content/torbutton.js
@@ -1888,11 +1888,6 @@ function torbutton_update_status(mode, force_update) {
!mode, mode, changed);
}
- if (m_tb_ff4) {
- torbutton_setBoolPref("webgl.disabled", "webgl_disabled", mode, mode,
- changed);
- }
-
if(m_tb_ff35) {
// Disable geolocation
torbutton_setBoolPref("geo.enabled", "geo_enabled", !mode, mode,
diff --git a/src/defaults/preferences/preferences.js b/src/defaults/preferences/preferences.js
index 8dd2add..a0a26d8 100644
--- a/src/defaults/preferences/preferences.js
+++ b/src/defaults/preferences/preferences.js
@@ -121,7 +121,7 @@ pref("extensions.torbutton.cookie_jars",false);
pref("extensions.torbutton.cookie_protections",true);
pref("extensions.torbutton.cookie_auto_protect",false);
pref("extensions.torbutton.dual_cookie_jars",true);
-pref("extensions.torbutton.disable_domstorage",true);
+pref("extensions.torbutton.disable_domstorage",false);
pref("extensions.torbutton.clear_cache",true);
pref("extensions.torbutton.block_cache",false);
pref("extensions.torbutton.clear_history",false);
1
0

[torbutton/master] Switch our addon ID to something human readable.
by mikeperry@torproject.org 17 Jan '13
by mikeperry@torproject.org 17 Jan '13
17 Jan '13
commit 30c900dd4b6ad0bdfe9ede50c031424006ab9c23
Author: Mike Perry <mikeperry-git(a)fscked.org>
Date: Wed Jan 16 17:08:30 2013 -0800
Switch our addon ID to something human readable.
---
makexpi.sh | 6 ++--
src/chrome/content/torbutton_util.js | 4 +-
src/chrome/locale/en/torbutton.properties | 2 +-
src/defaults/preferences/preferences.js | 5 +--
src/install.rdf | 43 +++++++++++++++-------------
5 files changed, 31 insertions(+), 29 deletions(-)
diff --git a/makexpi.sh b/makexpi.sh
index 42479c3..0180684 100755
--- a/makexpi.sh
+++ b/makexpi.sh
@@ -1,7 +1,7 @@
-#!/bin/bash
+#!/bin/sh
APP_NAME=torbutton
-VERSION=`grep em:version src/install.rdf | sed -e 's/["]//g' | cut -f2 -d=`
-XPI_NAME=$APP_NAME-$VERSION.xpi
+#VERSION=`grep em:version src/install.rdf | sed -e 's/["]//g' | cut -f2 -d=`
+XPI_NAME="$APP_NAME-`grep em:version src/install.rdf | sed -e 's/[<>]/ /g' | cut -f3`.xpi"
if [ -e "pkg/$XPI_NAME" ]; then
echo pkg/$XPI_NAME already exists.
diff --git a/src/chrome/content/torbutton_util.js b/src/chrome/content/torbutton_util.js
index 7d1effd..6f69d85 100644
--- a/src/chrome/content/torbutton_util.js
+++ b/src/chrome/content/torbutton_util.js
@@ -252,7 +252,7 @@ function torbutton_about_init() {
try {
// Firefox 4 and later; Mozilla 2 and later
Components.utils.import("resource://gre/modules/AddonManager.jsm");
- AddonManager.getAddonByID("{e0204bd5-9d31-402b-a99d-a6aa8ffebdca}",function(addon) {
+ AddonManager.getAddonByID("torbutton(a)torproject.org",function(addon) {
var extensionVersion = document.getElementById("torbuttonVersion");
extensionVersion.setAttribute("value", addon.version);
});
@@ -260,7 +260,7 @@ function torbutton_about_init() {
// Firefox 3.6 and before; Mozilla 1.9.2 and before
var em = Components.classes["@mozilla.org/extensions/manager;1"]
.getService(Components.interfaces.nsIExtensionManager);
- var addon = em.getItemForID("{e0204bd5-9d31-402b-a99d-a6aa8ffebdca}");
+ var addon = em.getItemForID("torbutton(a)torproject.org");
var extensionVersion = document.getElementById("torbuttonVersion");
extensionVersion.setAttribute("value", addon.version);
}
diff --git a/src/chrome/locale/en/torbutton.properties b/src/chrome/locale/en/torbutton.properties
index 875240e..f4a8036 100644
--- a/src/chrome/locale/en/torbutton.properties
+++ b/src/chrome/locale/en/torbutton.properties
@@ -6,7 +6,7 @@ torbutton.panel.plugins.disabled = Click to enable plugins
torbutton.panel.plugins.enabled = Click to disable plugins
torbutton.panel.label.disabled = Tor Disabled
torbutton.panel.label.enabled = Tor Enabled
-extensions.{e0204bd5-9d31-402b-a99d-a6aa8ffebdca}.description = Torbutton provides a button to easily enable or disable pointing Firefox to the Tor proxy
+extensions.torbutton(a)torproject.org.description = Torbutton provides a button to configure Tor settings and quickly and easily clear private browsing data.
torbutton.popup.history.warning = Torbutton blocked activity from a tab loaded in a different Tor state.\n\nThis is to work around Firefox Bugs 409737 and 417869.\n\nIf this popup seemed to happen for no reason, one of your tabs is attempting to reload itself in the background, and this was blocked.\n\nTo reload the tab in this Tor state, hit 'enter' in the URL location box.\n\n
torbutton.popup.plugin.warning = Torbutton blocked direct Tor load of plugin content.\n\nUse Save-As instead.\n\n
torbutton.popup.confirm_ca_certs = Torbutton Note: It appears you have no custom Certificate Authorities. Examining the Certificate Authority list is a slow operation and slows down Tor toggle. Would you like to disable the isolation of Certificate Authority certificates? (If you don't understand this, it is safe to click OK)
diff --git a/src/defaults/preferences/preferences.js b/src/defaults/preferences/preferences.js
index a0a26d8..b03dd71 100644
--- a/src/defaults/preferences/preferences.js
+++ b/src/defaults/preferences/preferences.js
@@ -6,7 +6,7 @@ pref("extensions.torbutton.logmethod",1); // 0=stdout, 1=errorconsole, 2=debuglo
// Display prefs
pref("extensions.torbutton.display_panel",true);
pref("extensions.torbutton.panel_style",'text');
-pref("extensions.{e0204bd5-9d31-402b-a99d-a6aa8ffebdca}.description", "chrome://torbutton/locale/torbutton.properties");
+pref("extensions.torbutton(a)torproject.org.description", "chrome://torbutton/locale/torbutton.properties");
// proxy prefs
pref("extensions.torbutton.settings_method",'recommended');
@@ -172,8 +172,7 @@ pref("extensions.torbutton.update_torbutton_via_tor",true);
pref("extensions.torbutton.tor_urls",false);
// Opt out of Firefox addon pings:
// https://developer.mozilla.org/en/Addons/Working_with_AMO
-pref("extensions.e0204bd5-9d31-402b-a99d-a6aa8ffebdca.getAddons.cache.enabled", false);
-pref("extensions.{e0204bd5-9d31-402b-a99d-a6aa8ffebdca}.getAddons.cache.enabled", false);
+pref("extensions.torbutton(a)torproject.org.getAddons.cache.enabled", false);
// Google Captcha prefs
diff --git a/src/install.rdf b/src/install.rdf
index 6eff883..e413c44 100644
--- a/src/install.rdf
+++ b/src/install.rdf
@@ -1,21 +1,24 @@
<?xml version="1.0"?>
-<RDF:RDF xmlns:em="http://www.mozilla.org/2004/em-rdf#"
- xmlns:NC="http://home.netscape.com/NC-rdf#"
- xmlns:RDF="http://www.w3.org/1999/02/22-rdf-syntax-ns#">
- <RDF:Description RDF:about="rdf:#$jIW5u3"
- em:id="{ec8030f7-c20a-464f-9b0e-13a3a9e97384}"
- em:minVersion="3.0"
- em:maxVersion="10000.0" />
- <RDF:Description RDF:about="urn:mozilla:install-manifest"
- em:name="Torbutton"
- em:creator="Mike Perry"
- em:id="{e0204bd5-9d31-402b-a99d-a6aa8ffebdca}"
- em:version="1.5.0pre"
- em:homepageURL="https://www.torproject.org/torbutton/"
- em:optionsURL="chrome://torbutton/content/preferences.xul"
- em:iconURL="chrome://torbutton/skin/tor.png"
- em:updateURL="https://www.torproject.org/torbutton/update.rdf"
- em:updateKey="MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQC1T8SmtWvdBibisbQdmNxSP9sCyoc5rPoTFfntg3uXo6KpCtTzCPSc5a3MCHJIUBuPDfr73IIQvb6cyPG4MB6xe+oVGiffW3Fm4R1u6UX4TtEG/GF5QGxfVTrbyxbGeR5fOm9O8TNZFwUNA/cu3gDtcJz2xGkE44IwYPfITLHBrQIDAQAB">
- <em:targetApplication RDF:resource="rdf:#$jIW5u3"/>
- </RDF:Description>
-</RDF:RDF>
+<RDF xmlns="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+ xmlns:em="http://www.mozilla.org/2004/em-rdf#">
+
+ <Description about="urn:mozilla:install-manifest">
+ <em:name>Torbutton</em:name>
+ <em:creator>Mike Perry</em:creator>
+ <em:id>torbutton(a)torproject.org</em:id>
+ <em:version>1.5.0-alpha</em:version>
+ <em:homepageURL>https://www.torproject.org/projects/torbrowser.html.en</em:homepageURL>
+ <em:optionsURL>chrome://torbutton/content/preferences.xul</em:optionsURL>
+ <em:iconURL>chrome://torbutton/skin/tor.png</em:iconURL>
+ <em:updateURL>https://www.torproject.org/torbutton/update17esr.rdf</em:updateURL>
+ <!-- <em:updateKey></em:updateKey> -->
+ <!-- firefox -->
+ <em:targetApplication>
+ <Description>
+ <em:id>{ec8030f7-c20a-464f-9b0e-13a3a9e97384}</em:id>
+ <em:minVersion>17.0</em:minVersion>
+ <em:maxVersion>10000.0</em:maxVersion>
+ </Description>
+ </em:targetApplication>
+ </Description>
+</RDF>
1
0

[torbutton/master] Add partial changelog. Also make our version more accurate.
by mikeperry@torproject.org 17 Jan '13
by mikeperry@torproject.org 17 Jan '13
17 Jan '13
commit 19fb6d91c2610e988f90dbb3c08fa45fb573e2db
Author: Mike Perry <mikeperry-git(a)fscked.org>
Date: Wed Jan 16 17:17:01 2013 -0800
Add partial changelog. Also make our version more accurate.
---
src/CHANGELOG | 5 +++++
src/install.rdf | 2 +-
2 files changed, 6 insertions(+), 1 deletions(-)
diff --git a/src/CHANGELOG b/src/CHANGELOG
index 8042f6b..940ae73 100644
--- a/src/CHANGELOG
+++ b/src/CHANGELOG
@@ -1,3 +1,8 @@
+1.5.0-alpha
+ ?? Jan 2013
+ * bug 5279: Remove old toggle observers and related code
+ * misc: Allow WebGL and DOM storage.
+
1.4.6.3
9 Oct 2012
* bug 5856: Disable JS hooks to make way for direct Firefox patch
diff --git a/src/install.rdf b/src/install.rdf
index e413c44..37c7348 100644
--- a/src/install.rdf
+++ b/src/install.rdf
@@ -6,7 +6,7 @@
<em:name>Torbutton</em:name>
<em:creator>Mike Perry</em:creator>
<em:id>torbutton(a)torproject.org</em:id>
- <em:version>1.5.0-alpha</em:version>
+ <em:version>1.5.0pre-alpha</em:version>
<em:homepageURL>https://www.torproject.org/projects/torbrowser.html.en</em:homepageURL>
<em:optionsURL>chrome://torbutton/content/preferences.xul</em:optionsURL>
<em:iconURL>chrome://torbutton/skin/tor.png</em:iconURL>
1
0
commit 4a3dfa23088ba69260f3f83e5f0e5933d96a6091
Author: Mike Perry <mikeperry-git(a)fscked.org>
Date: Wed Jan 16 17:16:47 2013 -0800
Bump Firefox version.
---
src/defaults/preferences/preferences.js | 2 +-
1 files changed, 1 insertions(+), 1 deletions(-)
diff --git a/src/defaults/preferences/preferences.js b/src/defaults/preferences/preferences.js
index b03dd71..de15e0e 100644
--- a/src/defaults/preferences/preferences.js
+++ b/src/defaults/preferences/preferences.js
@@ -209,7 +209,7 @@ pref("extensions.torbutton.platform_override","Win32");
pref("extensions.torbutton.oscpu_override", "Windows NT 6.1");
pref("extensions.torbutton.useragent_override",
- "Mozilla/5.0 (Windows NT 6.1; rv:10.0) Gecko/20100101 Firefox/10.0");
+ "Mozilla/5.0 (Windows NT 6.1; rv:17.0) Gecko/20100101 Firefox/17.0");
pref("extensions.torbutton.productsub_override","20100101");
pref("extensions.torbutton.buildID_override","0");
1
0

[translation/gettor_completed] Update translations for gettor_completed
by translation@torproject.org 16 Jan '13
by translation@torproject.org 16 Jan '13
16 Jan '13
commit 8a931db0a4e7c1268eb917704c3a6d6401402e7a
Author: Translation commit bot <translation(a)torproject.org>
Date: Wed Jan 16 22:15:10 2013 +0000
Update translations for gettor_completed
---
es/gettor.po | 4 ++--
1 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/es/gettor.po b/es/gettor.po
index 8e1387e..a4bb36c 100644
--- a/es/gettor.po
+++ b/es/gettor.po
@@ -12,7 +12,7 @@ msgstr ""
"Project-Id-Version: The Tor Project\n"
"Report-Msgid-Bugs-To: https://trac.torproject.org/projects/tor\n"
"POT-Creation-Date: 2011-11-13 22:01+0100\n"
-"PO-Revision-Date: 2013-01-16 19:46+0000\n"
+"PO-Revision-Date: 2013-01-16 21:55+0000\n"
"Last-Translator: strel <strelnic(a)gmail.com>\n"
"Language-Team: Spanish (http://www.transifex.com/projects/p/torproject/language/es/)\n"
"MIME-Version: 1.0\n"
@@ -243,7 +243,7 @@ msgid ""
"is no complete public list of them, even if your ISP is filtering\n"
"connections to all the known Tor relays, they probably won't be able\n"
"to block all the bridges."
-msgstr "Si su conexión a Internet bloquea el acceso a la red Tor, podría\nnecesitar un repetidor puente (bridge). Los bridges son repetidores\nde Tor que no están listados en el repositorio principal de repetidores\n(relays). Al no estar listados públicamente, incluso si su proveedor\nde internet (ISP) está filtrando las conexiones con los repetidores de\nTor conocidos, probablemente no podrá bloquear todos los bridges."
+msgstr "Si su conexión a Internet bloquea el acceso a la red Tor, podría\nnecesitar un repetidor puente (bridge relay). Los bridges son repetidores\nde Tor que no están listados en el repositorio principal de\nrepetidores (relays). Al no haber una lista pública completa de ellos,\nincluso si su proveedor de Internet (ISP) está filtrando las conexiones\ncon los repetidores de Tor conocidos, probablemente no podrá\nbloquear todos los bridges."
#: lib/gettor/i18n.py:162
msgid ""
1
0

16 Jan '13
commit b3edec0de90ae0d2834b7f032aa35571aacbaff0
Author: Translation commit bot <translation(a)torproject.org>
Date: Wed Jan 16 22:15:08 2013 +0000
Update translations for gettor
---
es/gettor.po | 4 ++--
1 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/es/gettor.po b/es/gettor.po
index 8e1387e..a4bb36c 100644
--- a/es/gettor.po
+++ b/es/gettor.po
@@ -12,7 +12,7 @@ msgstr ""
"Project-Id-Version: The Tor Project\n"
"Report-Msgid-Bugs-To: https://trac.torproject.org/projects/tor\n"
"POT-Creation-Date: 2011-11-13 22:01+0100\n"
-"PO-Revision-Date: 2013-01-16 19:46+0000\n"
+"PO-Revision-Date: 2013-01-16 21:55+0000\n"
"Last-Translator: strel <strelnic(a)gmail.com>\n"
"Language-Team: Spanish (http://www.transifex.com/projects/p/torproject/language/es/)\n"
"MIME-Version: 1.0\n"
@@ -243,7 +243,7 @@ msgid ""
"is no complete public list of them, even if your ISP is filtering\n"
"connections to all the known Tor relays, they probably won't be able\n"
"to block all the bridges."
-msgstr "Si su conexión a Internet bloquea el acceso a la red Tor, podría\nnecesitar un repetidor puente (bridge). Los bridges son repetidores\nde Tor que no están listados en el repositorio principal de repetidores\n(relays). Al no estar listados públicamente, incluso si su proveedor\nde internet (ISP) está filtrando las conexiones con los repetidores de\nTor conocidos, probablemente no podrá bloquear todos los bridges."
+msgstr "Si su conexión a Internet bloquea el acceso a la red Tor, podría\nnecesitar un repetidor puente (bridge relay). Los bridges son repetidores\nde Tor que no están listados en el repositorio principal de\nrepetidores (relays). Al no haber una lista pública completa de ellos,\nincluso si su proveedor de Internet (ISP) está filtrando las conexiones\ncon los repetidores de Tor conocidos, probablemente no podrá\nbloquear todos los bridges."
#: lib/gettor/i18n.py:162
msgid ""
1
0