[tor-commits] [torbrowser/maint-2.3] Include anti-fingerprinting patches from Pearl Crescent, LLC.
mikeperry at torproject.org
mikeperry at torproject.org
Tue Oct 9 22:22:00 UTC 2012
commit 1720f1520443c0c1e3be03abbb467662d4d54e33
Author: Mike Perry <mikeperry-git at fscked.org>
Date: Tue Oct 9 15:04:56 2012 -0700
Include anti-fingerprinting patches from Pearl Crescent, LLC.
---
...nents.interfaces-lookupMethod-from-conten.patch | 10 +-
...0002-Make-Permissions-Manager-memory-only.patch | 4 +-
...-Make-Intermediate-Cert-Store-memory-only.patch | 4 +-
.../firefox/0004-Add-a-string-based-cacheKey.patch | 4 +-
.../0005-Block-all-plugins-except-flash.patch | 4 +-
...ontent-pref-service-memory-only-clearable.patch | 4 +-
...owser-exit-when-not-launched-from-Vidalia.patch | 6 +-
.../0008-Disable-SSL-Session-ID-tracking.patch | 6 +-
...observer-event-to-close-persistent-connec.patch | 4 +-
...ice-and-system-specific-CSS-Media-Queries.patch | 68 ++-
...11-Limit-the-number-of-fonts-per-document.patch | 4 +-
.../0012-Rebrand-Firefox-to-TorBrowser.patch | 4 +-
.../0013-Make-Download-manager-memory-only.patch | 4 +-
.../0014-Add-DDG-and-StartPage-to-Omnibox.patch | 4 +-
...-nsICacheService.EvictEntries-synchronous.patch | 8 +-
.../firefox/0016-Prevent-WebSocket-DNS-leak.patch | 4 +-
...ize-HTTP-request-order-and-pipeline-depth.patch | 4 +-
...th-headers-before-the-modify-request-obse.patch | 4 +-
...Adapt-Steven-Michaud-s-Mac-crashfix-patch.patch | 4 +-
...d-mozIThirdPartyUtil.getFirstPartyURI-API.patch | 4 +-
.../0021-Add-canvas-image-extraction-prompt.patch | 551 ++++++++++++++++++++
...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 | 537 +++++++++++++++++++
24 files changed, 1541 insertions(+), 60 deletions(-)
diff --git a/src/current-patches/firefox/0001-Block-Components.interfaces-lookupMethod-from-conten.patch b/src/current-patches/firefox/0001-Block-Components.interfaces-lookupMethod-from-conten.patch
index c99e10a..1a82800 100644
--- 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
@@ -1,7 +1,7 @@
-From 18fea351a9f218893514ccbca82c492ce81d038d Mon Sep 17 00:00:00 2001
+From 1c2ccbea73720db5405602e4033c69b706068a8b Mon Sep 17 00:00:00 2001
From: Mike Perry <mikeperry-git at torproject.org>
Date: Wed, 1 Feb 2012 15:40:40 -0800
-Subject: [PATCH 01/19] Block Components.interfaces,lookupMethod from content
+Subject: [PATCH 01/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.
@@ -20,10 +20,10 @@ https://trac.torproject.org/projects/tor/ticket/2874
1 files changed, 6 insertions(+), 2 deletions(-)
diff --git a/js/xpconnect/src/XPCComponents.cpp b/js/xpconnect/src/XPCComponents.cpp
-index 3bcbf91..d5c020a 100644
+index 38bfe08..7224b9b 100644
--- a/js/xpconnect/src/XPCComponents.cpp
+++ b/js/xpconnect/src/XPCComponents.cpp
-@@ -4456,7 +4456,9 @@ nsXPCComponents::CanCreateWrapper(const nsIID * iid, char **_retval)
+@@ -4502,7 +4502,9 @@ nsXPCComponents::CanCreateWrapper(const nsIID * iid, char **_retval)
NS_IMETHODIMP
nsXPCComponents::CanCallMethod(const nsIID * iid, const PRUnichar *methodName, char **_retval)
{
@@ -34,7 +34,7 @@ index 3bcbf91..d5c020a 100644
*_retval = xpc_CheckAccessList(methodName, allowed);
return NS_OK;
}
-@@ -4465,7 +4467,9 @@ nsXPCComponents::CanCallMethod(const nsIID * iid, const PRUnichar *methodName, c
+@@ -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)
{
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 5d5a741..fa23d93 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 336217485d707ff63ef42d2a0bc3705c2c7f7a3c Mon Sep 17 00:00:00 2001
+From cd983b1b57b1f4ae10c8deec5aa12ec957fdc855 Mon Sep 17 00:00:00 2001
From: Mike Perry <mikeperry-git at torproject.org>
Date: Wed, 1 Feb 2012 15:45:16 -0800
-Subject: [PATCH 02/19] Make Permissions Manager memory-only
+Subject: [PATCH 02/24] 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
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 912d82f..b10fb85 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,7 +1,7 @@
-From e6d127b805461470bff0dad12f5ad89fc3cd3df3 Mon Sep 17 00:00:00 2001
+From f100a7979e1a44863a8a67a09743f0e17b5dd14e Mon Sep 17 00:00:00 2001
From: Mike Perry <mikeperry-git at fscked.org>
Date: Fri, 19 Aug 2011 17:58:23 -0700
-Subject: [PATCH 03/19] Make Intermediate Cert Store memory-only.
+Subject: [PATCH 03/24] Make Intermediate Cert Store memory-only.
This patch makes the intermediate SSL cert store exist in memory only.
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 af88b70..f3afa97 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 84668dfe7bdcd35d96ffcaf273ade5a5d8d470f8 Mon Sep 17 00:00:00 2001
+From d674d09bc233d200b1ebc47f8e6ac4ebd6e4225a Mon Sep 17 00:00:00 2001
From: Mike Perry <mikeperry-git at fscked.org>
Date: Fri, 2 Sep 2011 20:47:02 -0700
-Subject: [PATCH 04/19] Add a string-based cacheKey.
+Subject: [PATCH 04/24] Add a string-based cacheKey.
Used for isolating cache according to same-origin policy.
---
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 e6d5adc..e7a831e 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 3457f78e346df5962449cbd5aa86624e19fd5f64 Mon Sep 17 00:00:00 2001
+From 88a390822d232ba037de1f15091977ca7e1064bf Mon Sep 17 00:00:00 2001
From: Mike Perry <mikeperry-git at torproject.org>
Date: Wed, 1 Feb 2012 15:50:15 -0800
-Subject: [PATCH 05/19] Block all plugins except flash.
+Subject: [PATCH 05/24] 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
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 1ea7e14..17af793 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 66ff6c30d5b1de5d549181acbba686f792fe4cb4 Mon Sep 17 00:00:00 2001
+From 71ba98d81a6ecada62af4d2ee03be050d371d996 Mon Sep 17 00:00:00 2001
From: Mike Perry <mikeperry-git at fscked.org>
Date: Thu, 8 Sep 2011 08:40:17 -0700
-Subject: [PATCH 06/19] Make content pref service memory-only + clearable
+Subject: [PATCH 06/24] 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
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 5d384a7..cc496d3 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 d6956a597662f3d753622377183cb317ef6a3ad4 Mon Sep 17 00:00:00 2001
+From 12579def59d67416b841f6b0a6eadfd94bba72e9 Mon Sep 17 00:00:00 2001
From: Mike Perry <mikeperry-git at fscked.org>
Date: Sun, 9 Oct 2011 22:50:07 -0700
-Subject: [PATCH 07/19] Make Tor Browser exit when not launched from Vidalia
+Subject: [PATCH 07/24] 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
@@ -16,7 +16,7 @@ actually be common.
1 files changed, 15 insertions(+), 0 deletions(-)
diff --git a/browser/base/content/browser.js b/browser/base/content/browser.js
-index b06a17b..fc1d305 100644
+index f16a0c5..20e3666 100644
--- a/browser/base/content/browser.js
+++ b/browser/base/content/browser.js
@@ -1217,6 +1217,21 @@ function BrowserStartup() {
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 82438c2..39e1483 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 70161b38e1855ce4b7a61ac1e9572fb07dfbedda Mon Sep 17 00:00:00 2001
+From 7586e413761858ce705d25d4a1673e608a162bed Mon Sep 17 00:00:00 2001
From: Mike Perry <mikeperry-git at fscked.org>
Date: Wed, 7 Dec 2011 19:36:38 -0800
-Subject: [PATCH 08/19] Disable SSL Session ID tracking.
+Subject: [PATCH 08/24] 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
@@ -11,7 +11,7 @@ https://www.torproject.org/projects/torbrowser/design/#identifier-linkability.
1 files changed, 1 insertions(+), 1 deletions(-)
diff --git a/security/nss/lib/ssl/sslsock.c b/security/nss/lib/ssl/sslsock.c
-index 28e6210..fa48ecd 100644
+index 0c4d0c7..8d23fc0 100644
--- a/security/nss/lib/ssl/sslsock.c
+++ b/security/nss/lib/ssl/sslsock.c
@@ -173,7 +173,7 @@ static sslOptions ssl_defaults = {
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 39a71a4..e693c71 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 d5ef29d9219a7ff9a78f9523845a2e2966c2a266 Mon Sep 17 00:00:00 2001
+From 9c6f997dd9a44336af9a1db17f5b680cc80a0e6c Mon Sep 17 00:00:00 2001
From: Mike Perry <mikeperry-git at torproject.org>
Date: Wed, 1 Feb 2012 15:53:28 -0800
-Subject: [PATCH 09/19] Provide an observer event to close persistent
+Subject: [PATCH 09/24] Provide an observer event to close persistent
connections
We need to prevent linkability across "New Identity", which includes closing
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 d4f1a1a..14e584c 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,19 +1,14 @@
-From d3261423b0bd07fb3c0ca7b9448c9abb97053be2 Mon Sep 17 00:00:00 2001
-From: Shondoit Walker <shondoit at gmail.com>
-Date: Mon, 4 Jun 2012 19:15:31 +0200
-Subject: [PATCH 10/19] Limit device- and system-specific CSS Media Queries
+From 8f97f2f36adb9e4416f3d19af10880c800c846c2 Mon Sep 17 00:00:00 2001
+From: Kathleen Brade <brade at pearlcrescent.com>
+Date: Thu, 4 Oct 2012 14:28:48 -0400
+Subject: [PATCH 10/24] Limit device and system specific CSS Media Queries.
-This is done to address
-https://www.torproject.org/projects/torbrowser/design/#fingerprinting-linkability
-
-This also fixes bug #4795 by making queries still available for chrome windows,
-whilst returning nothing or non-device-specific values for web pages or extensions.
---
- layout/style/nsMediaFeatures.cpp | 42 ++++++++++++++++++++++++-------------
- 1 files changed, 27 insertions(+), 15 deletions(-)
+ layout/style/nsMediaFeatures.cpp | 71 ++++++++++++++++++++++++-------------
+ 1 files changed, 46 insertions(+), 25 deletions(-)
diff --git a/layout/style/nsMediaFeatures.cpp b/layout/style/nsMediaFeatures.cpp
-index 6eca06e..25735e8 100644
+index 6eca06e..5b1df7e 100644
--- a/layout/style/nsMediaFeatures.cpp
+++ b/layout/style/nsMediaFeatures.cpp
@@ -130,6 +130,9 @@ GetDeviceContextFor(nsPresContext* aPresContext)
@@ -63,7 +58,50 @@ index 6eca06e..25735e8 100644
}
static nsresult
-@@ -311,8 +315,12 @@ static nsresult
+@@ -236,13 +240,17 @@ static nsresult
+ GetColor(nsPresContext* aPresContext, const nsMediaFeature*,
+ nsCSSValue& aResult)
+ {
+- // FIXME: This implementation is bogus. nsDeviceContext
+- // doesn't provide reliable information (should be fixed in bug
+- // 424386).
+- // FIXME: On a monochrome device, return 0!
+- nsDeviceContext *dx = GetDeviceContextFor(aPresContext);
+- PRUint32 depth;
+- dx->GetDepth(depth);
++ PRUint32 depth = 24; // Always return 24 to non-chrome callers.
++
++ if (aPresContext->IsChrome()) {
++ // FIXME: This implementation is bogus. nsDeviceContext
++ // doesn't provide reliable information (should be fixed in bug
++ // 424386).
++ // FIXME: On a monochrome device, return 0!
++ nsDeviceContext *dx = GetDeviceContextFor(aPresContext);
++ dx->GetDepth(depth);
++ }
++
+ // The spec says to use bits *per color component*, so divide by 3,
+ // and round down, since the spec says to use the smallest when the
+ // color components differ.
+@@ -280,9 +288,14 @@ 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());
++ 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());
++ }
++
+ aResult.SetFloatValue(dpi, eCSSUnit_Inch);
+ return NS_OK;
+ }
+@@ -311,8 +324,12 @@ static nsresult
GetDevicePixelRatio(nsPresContext* aPresContext, const nsMediaFeature*,
nsCSSValue& aResult)
{
@@ -78,7 +116,7 @@ index 6eca06e..25735e8 100644
return NS_OK;
}
-@@ -320,18 +328,21 @@ static nsresult
+@@ -320,18 +337,21 @@ static nsresult
GetSystemMetric(nsPresContext* aPresContext, const nsMediaFeature* aFeature,
nsCSSValue& aResult)
{
@@ -101,7 +139,7 @@ index 6eca06e..25735e8 100644
aResult.Reset();
#ifdef XP_WIN
PRUint8 windowsThemeId =
-@@ -350,7 +361,8 @@ GetWindowsTheme(nsPresContext* aPresContext, const nsMediaFeature* aFeature,
+@@ -350,7 +370,8 @@ GetWindowsTheme(nsPresContext* aPresContext, const nsMediaFeature* aFeature,
}
}
#endif
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 33500a7..ff9e618 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 b562518157b03735bc4a17ecb9a233f11ff99a45 Mon Sep 17 00:00:00 2001
+From cb3a6f45dd2c15d6b75084e1a4dded18ed638632 Mon Sep 17 00:00:00 2001
From: Mike Perry <mikeperry-git at torproject.org>
Date: Wed, 1 Feb 2012 16:01:21 -0800
-Subject: [PATCH 11/19] Limit the number of fonts per document.
+Subject: [PATCH 11/24] Limit the number of fonts per document.
We create two prefs:
browser.display.max_font_count and browser.display.max_font_attempts.
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 583d1bf..e627238 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 235aa1bffd7ada80e14d7a15b2d3e7f89f4af710 Mon Sep 17 00:00:00 2001
+From 5820fc300fe1cae27752673e8721a19e70bf727c Mon Sep 17 00:00:00 2001
From: Erinn Clark <erinn at torproject.org>
Date: Wed, 25 Apr 2012 09:14:00 -0300
-Subject: [PATCH 12/19] Rebrand Firefox to TorBrowser
+Subject: [PATCH 12/24] 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.
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 9a0533b..1ad0972 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 6eba0489502d7298e0941df12a0823b13078c52b Mon Sep 17 00:00:00 2001
+From 28178fb406d86b317b13b16ade3b06e5e1500c7e Mon Sep 17 00:00:00 2001
From: Mike Perry <mikeperry-git at torproject.org>
Date: Wed, 25 Apr 2012 13:39:35 -0700
-Subject: [PATCH 13/19] Make Download manager memory only.
+Subject: [PATCH 13/24] Make Download manager memory only.
Solves https://trac.torproject.org/projects/tor/ticket/4017.
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 df71776..adbd3d4 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 c47053eea6488c5c949ff98c37a9669f969e4175 Mon Sep 17 00:00:00 2001
+From 2a80e84755c97cf4ff3ab63bda1bd5f0936d9594 Mon Sep 17 00:00:00 2001
From: Mike Perry <mikeperry-git at torproject.org>
Date: Wed, 25 Apr 2012 15:03:46 -0700
-Subject: [PATCH 14/19] Add DDG and StartPage to Omnibox.
+Subject: [PATCH 14/24] 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 840c1c9..93a989b 100644
--- a/src/current-patches/firefox/0015-Make-nsICacheService.EvictEntries-synchronous.patch
+++ b/src/current-patches/firefox/0015-Make-nsICacheService.EvictEntries-synchronous.patch
@@ -1,7 +1,7 @@
-From 231dc894259f16bb39ff7d9fe3cc3fa1cda30eb1 Mon Sep 17 00:00:00 2001
+From 20c94cb890a8872c07ba13686e293ca147b85cd6 Mon Sep 17 00:00:00 2001
From: Mike Perry <mikeperry-git at torproject.org>
Date: Tue, 1 May 2012 15:02:03 -0700
-Subject: [PATCH 15/19] Make nsICacheService.EvictEntries synchronous
+Subject: [PATCH 15/24] 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".
@@ -12,10 +12,10 @@ https://trac.torproject.org/projects/tor/ticket/5715
1 files changed, 13 insertions(+), 2 deletions(-)
diff --git a/netwerk/cache/nsCacheService.cpp b/netwerk/cache/nsCacheService.cpp
-index 8af611f..65686c7 100644
+index 83ce887..e9f1a76 100644
--- a/netwerk/cache/nsCacheService.cpp
+++ b/netwerk/cache/nsCacheService.cpp
-@@ -1315,10 +1315,21 @@ NS_IMETHODIMP nsCacheService::VisitEntries(nsICacheVisitor *visitor)
+@@ -1316,10 +1316,21 @@ NS_IMETHODIMP nsCacheService::VisitEntries(nsICacheVisitor *visitor)
return NS_OK;
}
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 05f1923..bb70b17 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 bf5c8236b9b995e01e7909181dfe3f01bec05149 Mon Sep 17 00:00:00 2001
+From 976f0d4fabb6b0b50c83192d622827357c761bd3 Mon Sep 17 00:00:00 2001
From: Mike Perry <mikeperry-git at torproject.org>
Date: Wed, 2 May 2012 17:44:39 -0700
-Subject: [PATCH 16/19] Prevent WebSocket DNS leak.
+Subject: [PATCH 16/24] Prevent WebSocket DNS leak.
This is due to an improper implementation of the WebSocket spec by Mozilla.
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 4d0ee81..f1814e7 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 276cc8cd478a6ad495758ab7aee27a6a88d12bcc Mon Sep 17 00:00:00 2001
+From 36f826e64411a74912ba1adebd1a30b84716bf84 Mon Sep 17 00:00:00 2001
From: Mike Perry <mikeperry-git at torproject.org>
Date: Wed, 6 Jun 2012 11:08:56 -0700
-Subject: [PATCH 17/19] Randomize HTTP request order and pipeline depth.
+Subject: [PATCH 17/24] Randomize HTTP request order and pipeline depth.
This is an experimental defense against
http://lorre.uni.lu/~andriy/papers/acmccs-wpes11-fingerprinting.pdf
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
index 845d60e..46cf611 100644
--- 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
@@ -1,7 +1,7 @@
-From 3a0261c7fdbed4a4705d5c6c39edeed4c127121f Mon Sep 17 00:00:00 2001
+From c1e26c8a294abe426fd6fb84508db6074ef23379 Mon Sep 17 00:00:00 2001
From: Mike Perry <mikeperry-git at fscked.org>
Date: Fri, 2 Sep 2011 15:33:20 -0700
-Subject: [PATCH 18/19] Add HTTP auth headers before the modify-request
+Subject: [PATCH 18/24] Add HTTP auth headers before the modify-request
observer.
Otherwise, how are we supposed to modify them?
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
index 16ce98a..7f3869c 100644
--- 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
@@ -1,7 +1,7 @@
-From e263c559a4799a26a9ef5ca3490372fc93a62d3e Mon Sep 17 00:00:00 2001
+From 49cccdba3e6fc10e0e376d423b3ba1b6135f62e1 Mon Sep 17 00:00:00 2001
From: Mike Perry <mikeperry-git at torproject.org>
Date: Thu, 7 Jun 2012 16:25:48 -0700
-Subject: [PATCH 19/19] Adapt Steven Michaud's Mac crashfix patch
+Subject: [PATCH 19/24] Adapt Steven Michaud's Mac crashfix patch
Source is: https://bugzilla.mozilla.org/show_bug.cgi?id=715885#c35
diff --git a/src/current-patches/firefox/0020-Add-mozIThirdPartyUtil.getFirstPartyURI-API.patch b/src/current-patches/firefox/0020-Add-mozIThirdPartyUtil.getFirstPartyURI-API.patch
index 56d9848..700a795 100644
--- a/src/current-patches/firefox/0020-Add-mozIThirdPartyUtil.getFirstPartyURI-API.patch
+++ b/src/current-patches/firefox/0020-Add-mozIThirdPartyUtil.getFirstPartyURI-API.patch
@@ -1,7 +1,7 @@
-From 73e548ceee36b99f06e33010163ed8b8cc86b3dd Mon Sep 17 00:00:00 2001
+From 24f62d79a6179598ed633481e2bbeac1b2ccd9bc Mon Sep 17 00:00:00 2001
From: Mike Perry <mikeperry-git at torproject.org>
Date: Tue, 28 Aug 2012 18:35:33 -0700
-Subject: [PATCH 20/20] Add mozIThirdPartyUtil.getFirstPartyURI API
+Subject: [PATCH 20/24] Add mozIThirdPartyUtil.getFirstPartyURI API
API allows you to get the url bar URI for a channel or nsIDocument.
---
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
new file mode 100644
index 0000000..f303683
--- /dev/null
+++ b/src/current-patches/firefox/0021-Add-canvas-image-extraction-prompt.patch
@@ -0,0 +1,551 @@
+From 3e8d778866d96e1ca82f2b08e7b8d948c1c3853d Mon Sep 17 00:00:00 2001
+From: Kathleen Brade <brade at 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/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
new file mode 100644
index 0000000..2532e5f
--- /dev/null
+++ b/src/current-patches/firefox/0022-Return-client-window-coordinates-for-mouse-event-scr.patch
@@ -0,0 +1,43 @@
+From eb9cc23d7b04d9c441f69e98834561622533f6ba Mon Sep 17 00:00:00 2001
+From: Kathleen Brade <brade at 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
new file mode 100644
index 0000000..1907906
--- /dev/null
+++ b/src/current-patches/firefox/0023-Do-not-expose-physical-screen-info.-via-window-and-w.patch
@@ -0,0 +1,312 @@
+From f842f612d98477ad36014338a72f812cf4183e2f Mon Sep 17 00:00:00 2001
+From: Kathleen Brade <brade at 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/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
new file mode 100644
index 0000000..5b808ad
--- /dev/null
+++ b/src/current-patches/firefox/0024-Do-not-expose-system-colors-to-CSS-or-canvas.patch
@@ -0,0 +1,537 @@
+From a3a36dbaebcacdcf6b4343a587ea673e6245102d Mon Sep 17 00:00:00 2001
+From: Kathleen Brade <brade at 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
+
More information about the tor-commits
mailing list