commit 4281125f4d3d7a2c337d48b6569689ab254083da Author: Mike Perry mikeperry-git@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@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@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@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 InfallibleTArrayIPC::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@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@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@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@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@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@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@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@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@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@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@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@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-linkab... --- + 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@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@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@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@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@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@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@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-finger...
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@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@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@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@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@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@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@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@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@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@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@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@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@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@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@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@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) + {} + + nsTArraymozilla::gfx::GradientStop mRawStops; + mozilla::RefPtrmozilla::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@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@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@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@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 +