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

24 Oct '12
commit 808e00dcbda96660447da1b88dfaaf8fc98aa55f
Author: Translation commit bot <translation(a)torproject.org>
Date: Wed Oct 24 15:45:06 2012 +0000
Update translations for orbot
---
values-nl/strings.xml | 5 +++++
1 files changed, 5 insertions(+), 0 deletions(-)
diff --git a/values-nl/strings.xml b/values-nl/strings.xml
index 105f489..b49ef0a 100644
--- a/values-nl/strings.xml
+++ b/values-nl/strings.xml
@@ -75,8 +75,11 @@
<string name="wizard_tips_otrchat">Gibberbot - Veilige instant messaging client voor Android</string>
<string name="wizard_tips_proxy">Proxy Instellingen - Leer hoe je apps te configureren voor Orbot</string>
<string name="wizard_tips_duckgo">Duckduckgo Zoekmachine app</string>
+ <string name="duckgo_apk_url">https://duckduckgo.com/android/latest.apk</string>
<string name="wizard_tips_firefox">Firefox met Proxy Mobile extensie (vergt extra installatie achteraf)</string>
+ <string name="proxymob_setup_url">https://guardianproject.info/releases/proxymob-latest.xpi</string>
<string name="wizard_tips_twitter">Twitter ondersteunt http proxy \"localhost:8118\"</string>
+ <string name="twitter_setup_url">https://guardianproject.info/2012/05/02/orbot-your-twitter/</string>
<string name="wizard_proxy_help_info">Proxy Instellingen</string>
<string name="wizard_proxy_help_msg">Als de Android app die je gebruikt beschikt over een HTTP of SOCKS proxy instelling, dan kun je het configureren zodat het via Orbot over het Tor netwerk gaat.\n\n\nDe host instelling is 127.0.0.1 of \"localhost\". De poort voor SOCKS is 9050 en voor HTTP 8118. Gebruik SOCKS4A of SOCKS5 indien mogelijk.\n\n\nJe kunt meer leren over het proxy-en op Android door naar de FAQ op http://tinyurl.com/proxyandroid te gaan\n </string>
<string name="wizard_final">Orbot is klaar!</string>
@@ -105,6 +108,8 @@
<string name="gibberbot_apk_url">https://market.android.com/details?id=info.guardianproject.otr.app.im</string>
<string name="wizard_tips_orweb">ORWEB (Alleen Android 1.x) - Browser gemaakt voor privacy & voor Orbot</string>
<string name="orweb_apk_url">market://search?q=pname:nfo.guardianproject.browser</string>
+ <string name="wizard_tips_play">Vind alle Guardian Project apps op Google Play</string>
+ <string name="wizard_tips_play_url">https://play.google.com/store/search?q=guardianproject</string>
<!--<string name="wizard_tips_firefox">Firefox - Android browser - To be used along with ProxyMob Add-on </string>
<string name="wizard_tips_proxymob">ProxyMob - Simple Firefox Add-on for setting HTTP, SOCKS and SSL proxy settings</string>
<string name="firefox_apk_url">https://market.android.com/details?id=org.mozilla.firefox</string>
1
0

24 Oct '12
commit 97781606863ec6115bb5e0da47188a510f122826
Author: Arturo Filastò <arturo(a)filasto.net>
Date: Wed Oct 24 15:40:03 2012 +0000
Add to global import table legacy modules
* Refactor test case directory structure separating legacy tests from new tests
---
ooni/__init__.py | 13 ++++++++++-
tests/legacy/test_plugins.py | 40 +++++++++++++++++++++++++++++++++++++
tests/legacy/test_tests.py | 45 ++++++++++++++++++++++++++++++++++++++++++
tests/test_plugins.py | 40 -------------------------------------
tests/test_tests.py | 45 ------------------------------------------
5 files changed, 96 insertions(+), 87 deletions(-)
diff --git a/ooni/__init__.py b/ooni/__init__.py
index e730eb5..9a4e60f 100644
--- a/ooni/__init__.py
+++ b/ooni/__init__.py
@@ -7,8 +7,17 @@ from . import nettest
from . import oonicli
from . import reporter
from . import runner
-from . import template
+from . import templates
from . import utils
+
+# XXX below are legacy related modules
+from . import ooniprobe
+from . import plugoo
+from . import plugins
+from . import oonitests
+
__all__ = ['config', 'input', 'inputunit', 'kit',
'lib', 'nettest', 'oonicli', 'reporter',
- 'runner', 'templates', 'utils']
+ 'runner', 'templates', 'utils',
+ # XXX below are legacy related modules
+ 'ooniprobe', 'plugoo', 'plugins', 'oonitests']
diff --git a/tests/legacy/test_plugins.py b/tests/legacy/test_plugins.py
new file mode 100644
index 0000000..26bee51
--- /dev/null
+++ b/tests/legacy/test_plugins.py
@@ -0,0 +1,40 @@
+from twisted.internet import defer, reactor
+from twisted.trial import unittest
+
+from ooni.ooniprobe import retrieve_plugoo, runTest, Options
+from ooni.plugoo import work, tests
+
+def asset_file(filename):
+ import os
+ file_dir = os.path.normpath(os.path.join(__file__, '..'))
+ return os.path.join(file_dir, 'assets', filename)
+
+class PluginsTestCase(unittest.TestCase):
+ def test_plugin_blocking(self):
+ suboptions = {'asset': asset_file('urllist.txt')}
+ runTest('blocking', suboptions, Options(), reactor)
+ return
+
+ def test_plugin_tcpconnect(self):
+ suboptions = {'asset': asset_file('ipports.txt')}
+ runTest('tcpconnect', suboptions, Options(), reactor)
+ return
+
+
+ def test_plugin_captivep(self):
+ runTest('blocking', None, Options(), reactor)
+ return
+
+
+ def test_plugin_httphost(self):
+ suboptions = {'asset': asset_file('urllist.txt')}
+ runTest('httphost', suboptions, Options(), reactor)
+ return
+
+
+ def test_plugin_httpt(self):
+ suboptions = {'urls': asset_file('urllist.txt')}
+ runTest('httpt', suboptions, Options(), reactor)
+ return
+
+
diff --git a/tests/legacy/test_tests.py b/tests/legacy/test_tests.py
new file mode 100644
index 0000000..dc89b98
--- /dev/null
+++ b/tests/legacy/test_tests.py
@@ -0,0 +1,45 @@
+from twisted.internet import defer
+from twisted.trial import unittest
+
+from ooni.plugoo import work, tests
+
+class TestsTestCase(unittest.TestCase):
+ def setUp(self):
+ class dummyReport:
+ def __call__(self, *args, **kw):
+ pass
+ self.dummyreport = dummyReport()
+ self.callbackResults = None
+ self.errbackResults = None
+
+ def _callback(self, *args, **kw):
+ #print args, kw
+ self.callbackResults = args, kw
+
+ def _errback(self, *args, **kw):
+ pass
+
+ @defer.inlineCallbacks
+ def test_fallThrough(self):
+ """
+ This tests to make sure that what is returned from the experiment
+ method falls all the way through to control and finish.
+ """
+ test_dict = {"hello": "world"}
+ class DummyTest(tests.OONITest):
+ blocking = False
+ def experiment(self, args):
+ def bla(a):
+ print a
+ return test_dict
+ d2 = defer.Deferred()
+ d2.addCallback(bla)
+ from twisted.internet import reactor
+ reactor.callLater(0.1, d2.callback, None)
+ return d2
+
+ test = DummyTest(None, None, self.dummyreport)
+ yield test.startTest(None).addCallback(self._callback)
+ self.assertEqual(self.callbackResults[0][0]['return_value'], test_dict)
+ return
+
diff --git a/tests/test_plugins.py b/tests/test_plugins.py
deleted file mode 100644
index 26bee51..0000000
--- a/tests/test_plugins.py
+++ /dev/null
@@ -1,40 +0,0 @@
-from twisted.internet import defer, reactor
-from twisted.trial import unittest
-
-from ooni.ooniprobe import retrieve_plugoo, runTest, Options
-from ooni.plugoo import work, tests
-
-def asset_file(filename):
- import os
- file_dir = os.path.normpath(os.path.join(__file__, '..'))
- return os.path.join(file_dir, 'assets', filename)
-
-class PluginsTestCase(unittest.TestCase):
- def test_plugin_blocking(self):
- suboptions = {'asset': asset_file('urllist.txt')}
- runTest('blocking', suboptions, Options(), reactor)
- return
-
- def test_plugin_tcpconnect(self):
- suboptions = {'asset': asset_file('ipports.txt')}
- runTest('tcpconnect', suboptions, Options(), reactor)
- return
-
-
- def test_plugin_captivep(self):
- runTest('blocking', None, Options(), reactor)
- return
-
-
- def test_plugin_httphost(self):
- suboptions = {'asset': asset_file('urllist.txt')}
- runTest('httphost', suboptions, Options(), reactor)
- return
-
-
- def test_plugin_httpt(self):
- suboptions = {'urls': asset_file('urllist.txt')}
- runTest('httpt', suboptions, Options(), reactor)
- return
-
-
diff --git a/tests/test_tests.py b/tests/test_tests.py
deleted file mode 100644
index dc89b98..0000000
--- a/tests/test_tests.py
+++ /dev/null
@@ -1,45 +0,0 @@
-from twisted.internet import defer
-from twisted.trial import unittest
-
-from ooni.plugoo import work, tests
-
-class TestsTestCase(unittest.TestCase):
- def setUp(self):
- class dummyReport:
- def __call__(self, *args, **kw):
- pass
- self.dummyreport = dummyReport()
- self.callbackResults = None
- self.errbackResults = None
-
- def _callback(self, *args, **kw):
- #print args, kw
- self.callbackResults = args, kw
-
- def _errback(self, *args, **kw):
- pass
-
- @defer.inlineCallbacks
- def test_fallThrough(self):
- """
- This tests to make sure that what is returned from the experiment
- method falls all the way through to control and finish.
- """
- test_dict = {"hello": "world"}
- class DummyTest(tests.OONITest):
- blocking = False
- def experiment(self, args):
- def bla(a):
- print a
- return test_dict
- d2 = defer.Deferred()
- d2.addCallback(bla)
- from twisted.internet import reactor
- reactor.callLater(0.1, d2.callback, None)
- return d2
-
- test = DummyTest(None, None, self.dummyreport)
- yield test.startTest(None).addCallback(self._callback)
- self.assertEqual(self.callbackResults[0][0]['return_value'], test_dict)
- return
-
1
0
commit 09ea4a73a71aa67f842bcdf845f1b7d9fc7ff4ff
Author: Erinn Clark <erinn(a)torproject.org>
Date: Wed Oct 24 16:34:03 2012 +0100
update recommended-versions
---
build-scripts/recommended-versions | 18 +++++++++---------
1 files changed, 9 insertions(+), 9 deletions(-)
diff --git a/build-scripts/recommended-versions b/build-scripts/recommended-versions
index c252fbb..a63051a 100644
--- a/build-scripts/recommended-versions
+++ b/build-scripts/recommended-versions
@@ -1,11 +1,11 @@
[
-"2.2.39-3-MacOS-i386",
-"2.2.39-3-MacOS-x86_64",
-"2.2.39-3-Windows",
-"2.2.39-3-Linux-i686",
-"2.2.39-3-Linux-x86_64",
-"2.3.22-alpha-1-MacOS-i386",
-"2.3.22-alpha-1-Windows",
-"2.3.22-alpha-1-Linux-i386",
-"2.3.22-alpha-1-Linux-x86_64"
+"2.2.39-4-MacOS-i386",
+"2.2.39-4-MacOS-x86_64",
+"2.2.39-4-Windows",
+"2.2.39-4-Linux-i686",
+"2.2.39-4-Linux-x86_64",
+"2.3.23-alpha-1-MacOS-i386",
+"2.3.23-alpha-1-Windows",
+"2.3.23-alpha-1-Linux-i386",
+"2.3.23-alpha-1-Linux-x86_64"
]
1
0

24 Oct '12
commit 74169fbecb372ad779cae276185606af28e0ed5e
Author: Mike Perry <mikeperry-git(a)fscked.org>
Date: Wed Oct 17 01:34:53 2012 -0700
Bug 7128: Prevent crash on certain links.
NoScript was using the canvas (for ClearClick) without any context..
---
...d-mozIThirdPartyUtil.getFirstPartyURI-API.patch | 29 ++++++++++++-------
.../0021-Add-canvas-image-extraction-prompt.patch | 2 +-
...nt-window-coordinates-for-mouse-event-scr.patch | 2 +-
...se-physical-screen-info.-via-window-and-w.patch | 2 +-
...not-expose-system-colors-to-CSS-or-canvas.patch | 2 +-
5 files changed, 22 insertions(+), 15 deletions(-)
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 700a795..114301d 100644
--- a/src/current-patches/firefox/0020-Add-mozIThirdPartyUtil.getFirstPartyURI-API.patch
+++ b/src/current-patches/firefox/0020-Add-mozIThirdPartyUtil.getFirstPartyURI-API.patch
@@ -1,17 +1,17 @@
-From 24f62d79a6179598ed633481e2bbeac1b2ccd9bc Mon Sep 17 00:00:00 2001
+From 36d57455893bcf6dc08e91a2784970f285c5e84b Mon Sep 17 00:00:00 2001
From: Mike Perry <mikeperry-git(a)torproject.org>
Date: Tue, 28 Aug 2012 18:35:33 -0700
Subject: [PATCH 20/24] Add mozIThirdPartyUtil.getFirstPartyURI API
API allows you to get the url bar URI for a channel or nsIDocument.
---
- content/base/src/ThirdPartyUtil.cpp | 52 ++++++++++++++++++++++++++++
+ content/base/src/ThirdPartyUtil.cpp | 59 ++++++++++++++++++++++++++++
content/base/src/ThirdPartyUtil.h | 2 +
- netwerk/base/public/mozIThirdPartyUtil.idl | 21 +++++++++++
- 3 files changed, 75 insertions(+), 0 deletions(-)
+ 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..62333f3 100644
+index 6a415e9..52b3dab 100644
--- a/content/base/src/ThirdPartyUtil.cpp
+++ b/content/base/src/ThirdPartyUtil.cpp
@@ -40,6 +40,9 @@
@@ -32,7 +32,7 @@ index 6a415e9..62333f3 100644
return rv;
}
-@@ -315,3 +319,51 @@ ThirdPartyUtil::GetBaseDomain(nsIURI* aHostURI,
+@@ -315,3 +319,58 @@ ThirdPartyUtil::GetBaseDomain(nsIURI* aHostURI,
return NS_OK;
}
@@ -62,12 +62,19 @@ index 6a415e9..62333f3 100644
+ if (NS_FAILED(rv) && aDoc) {
+ nsCOMPtr<nsIDOMWindow> top;
+ nsCOMPtr<nsIDOMDocument> topDDoc;
-+
-+ aDoc->GetWindow()->GetTop(getter_AddRefs(top));
-+ top->GetDocument(getter_AddRefs(topDDoc));
++
++ if (aDoc->GetWindow()) {
++ aDoc->GetWindow()->GetTop(getter_AddRefs(top));
++ top->GetDocument(getter_AddRefs(topDDoc));
+
-+ nsCOMPtr<nsIDocument> topDoc(do_QueryInterface(topDDoc));
-+ *aOutput = topDoc->GetOriginalURI();
++ 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;
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
index f303683..cf5dd61 100644
--- a/src/current-patches/firefox/0021-Add-canvas-image-extraction-prompt.patch
+++ b/src/current-patches/firefox/0021-Add-canvas-image-extraction-prompt.patch
@@ -1,4 +1,4 @@
-From 3e8d778866d96e1ca82f2b08e7b8d948c1c3853d Mon Sep 17 00:00:00 2001
+From 29ce940434ebbb8e54c0d9b8f84ccf6ec6bd71bc Mon Sep 17 00:00:00 2001
From: Kathleen Brade <brade(a)pearlcrescent.com>
Date: Tue, 9 Oct 2012 11:21:06 -0400
Subject: [PATCH 21/24] Add canvas image extraction prompt.
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
index 2532e5f..6da9c72 100644
--- 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
@@ -1,4 +1,4 @@
-From eb9cc23d7b04d9c441f69e98834561622533f6ba Mon Sep 17 00:00:00 2001
+From 74215e38ba60b74df59216122c4f2cc068e33216 Mon Sep 17 00:00:00 2001
From: Kathleen Brade <brade(a)pearlcrescent.com>
Date: Tue, 9 Oct 2012 11:13:45 -0400
Subject: [PATCH 22/24] Return client window coordinates for mouse event
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
index 1907906..1b925e0 100644
--- 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
@@ -1,4 +1,4 @@
-From f842f612d98477ad36014338a72f812cf4183e2f Mon Sep 17 00:00:00 2001
+From d944531b020848e09ac280af11d039d992ab6461 Mon Sep 17 00:00:00 2001
From: Kathleen Brade <brade(a)pearlcrescent.com>
Date: Wed, 3 Oct 2012 17:06:48 -0400
Subject: [PATCH 23/24] Do not expose physical screen info. via window and
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
index 5b808ad..629a759 100644
--- 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
@@ -1,4 +1,4 @@
-From a3a36dbaebcacdcf6b4343a587ea673e6245102d Mon Sep 17 00:00:00 2001
+From 38a469e05779315cb2990be60c13fb167812e54d Mon Sep 17 00:00:00 2001
From: Kathleen Brade <brade(a)pearlcrescent.com>
Date: Thu, 4 Oct 2012 14:53:13 -0400
Subject: [PATCH 24/24] Do not expose system colors to CSS or canvas.
1
0

[torbrowser/maint-2.3] bump all stable tbbs to 2.2.39-4 for updated non-crashy firefox
by erinn@torproject.org 24 Oct '12
by erinn@torproject.org 24 Oct '12
24 Oct '12
commit f550eda4c97664237bd78a547c7f9992664e9206
Author: Erinn Clark <erinn(a)torproject.org>
Date: Thu Oct 18 08:46:44 2012 +0100
bump all stable tbbs to 2.2.39-4 for updated non-crashy firefox
---
README.LINUX-2.2 | 4 ++--
README.OSX-2.2 | 4 ++--
README.WIN-2.2 | 4 ++--
build-scripts/linux.mk | 2 +-
build-scripts/osx.mk | 2 +-
build-scripts/versions.mk | 4 ++--
build-scripts/windows.mk | 2 +-
changelog.linux-2.2 | 8 ++++++++
changelog.osx-2.2 | 8 ++++++++
changelog.windows-2.2 | 8 ++++++++
10 files changed, 35 insertions(+), 11 deletions(-)
diff --git a/README.LINUX-2.2 b/README.LINUX-2.2
index 859c854..fe79874 100644
--- a/README.LINUX-2.2
+++ b/README.LINUX-2.2
@@ -8,8 +8,8 @@ Vidalia 0.2.20 (with Qt 4.8.1)
Tor 0.2.2.39 (with libevent-2.0.20-stable, zlib-1.2.7 and openssl-1.0.1c)
Firefox 10.0.9esr
\_ Torbutton 1.4.6.3
- |_ NoScript 2.5.7
- |_ HTTPS-Everywhere 2.2.2
+ |_ NoScript 2.5.8
+ |_ HTTPS-Everywhere 3.0.2
Usage
-----
diff --git a/README.OSX-2.2 b/README.OSX-2.2
index 3ffefa3..9250ce2 100644
--- a/README.OSX-2.2
+++ b/README.OSX-2.2
@@ -8,8 +8,8 @@ Vidalia 0.2.20 (with Qt 4.8.1)
Tor 0.2.2.39 (with libevent-2.0.20-stable, zlib-1.2.7 and openssl-1.0.1c)
Firefox 10.0.9esr
\_ Torbutton 1.4.6.3
- |_ NoScript 2.5.7
- |_ HTTPS-Everywhere 2.2.2
+ |_ NoScript 2.5.8
+ |_ HTTPS-Everywhere 3.0.2
Usage
-----
diff --git a/README.WIN-2.2 b/README.WIN-2.2
index 3c73b5c..bbbd27f 100644
--- a/README.WIN-2.2
+++ b/README.WIN-2.2
@@ -8,8 +8,8 @@ Vidalia 0.2.20 (with Qt 4.8.1)
Tor 0.2.2.39 (with libevent-2.0.20-stable, zlib-1.2.7 and openssl-1.0.1c)
Firefox 10.0.9esr
\_ Torbutton 1.4.6.3
- |_ NoScript 2.5.7
- |_ HTTPS-Everywhere 2.2.2
+ |_ NoScript 2.5.8
+ |_ HTTPS-Everywhere 3.0.2
Usage
-----
diff --git a/build-scripts/linux.mk b/build-scripts/linux.mk
index 5e64cba..1d7feda 100644
--- a/build-scripts/linux.mk
+++ b/build-scripts/linux.mk
@@ -15,7 +15,7 @@
## Architecture
ARCH_TYPE=$(shell uname -m)
-BUILD_NUM=3
+BUILD_NUM=4
PLATFORM=Linux
## Build machine specific settings
diff --git a/build-scripts/osx.mk b/build-scripts/osx.mk
index 6325e5f..dd6154a 100644
--- a/build-scripts/osx.mk
+++ b/build-scripts/osx.mk
@@ -15,7 +15,7 @@
## Architecture
ARCH_TYPE=x86_64
-BUILD_NUM=3
+BUILD_NUM=4
PLATFORM=MacOS
## Set OSX-specific backwards compatibility options
diff --git a/build-scripts/versions.mk b/build-scripts/versions.mk
index 6063f66..3da6032 100644
--- a/build-scripts/versions.mk
+++ b/build-scripts/versions.mk
@@ -14,8 +14,8 @@ FIREFOX_VER=10.0.9esr
MOZBUILD_VER=1.5.1
PYMAKE_VER=87d436cd8974
TORBUTTON_VER=1.4.6.3
-NOSCRIPT_VER=2.5.7
-HTTPSEVERYWHERE_VER=2.2.2
+NOSCRIPT_VER=2.5.8
+HTTPSEVERYWHERE_VER=3.0.2
OTR_VER=3.2.0
OBFSPROXY_VER=0.1.4
diff --git a/build-scripts/windows.mk b/build-scripts/windows.mk
index 54b972c..cbf4451 100644
--- a/build-scripts/windows.mk
+++ b/build-scripts/windows.mk
@@ -13,7 +13,7 @@
### Configuration ###
#####################
-BUILD_NUM=3
+BUILD_NUM=4
PLATFORM=Windows
## Location of required libraries
diff --git a/changelog.linux-2.2 b/changelog.linux-2.2
index 386cab3..10adc35 100644
--- a/changelog.linux-2.2
+++ b/changelog.linux-2.2
@@ -1,3 +1,11 @@
+Tor Browser Bundle (2.2.39-4); suite=linux
+
+ * Update Firefox patches to prevent crashing (closes: #7128)
+ * Update HTTPS Everywhere to 3.0.2
+ * Update NoScript to 2.5.8
+
+ -- Erinn Clark <erinn(a)torproject.org> Thu Oct 18 08:40:15 BST 2012
+
Tor Browser Bundle (2.2.39-3); suite=linux
* Update Firefox to 10.0.9esr
diff --git a/changelog.osx-2.2 b/changelog.osx-2.2
index af3069a..a0cb5d0 100644
--- a/changelog.osx-2.2
+++ b/changelog.osx-2.2
@@ -1,3 +1,11 @@
+Tor Browser Bundle (2.2.39-4); suite=osx
+
+ * Update Firefox patches to prevent crashing (closes: #7128)
+ * Update HTTPS Everywhere to 3.0.2
+ * Update NoScript to 2.5.8
+
+ -- Erinn Clark <erinn(a)torproject.org> Thu Oct 18 08:40:10 BST 2012
+
Tor Browser Bundle (2.2.39-3); suite=osx
* Update Firefox to 10.0.9esr
diff --git a/changelog.windows-2.2 b/changelog.windows-2.2
index 094b8d2..d3006b0 100644
--- a/changelog.windows-2.2
+++ b/changelog.windows-2.2
@@ -1,3 +1,11 @@
+Tor Browser Bundle (2.2.39-4); suite=windows
+
+ * Update Firefox patches to prevent crashing (closes: #7128)
+ * Update HTTPS Everywhere to 3.0.2
+ * Update NoScript to 2.5.8
+
+ -- Erinn Clark <erinn(a)torproject.org> Thu Oct 18 08:40:12 BST 2012
+
Tor Browser Bundle (2.2.39-3); suite=windows
* Update Firefox to 10.0.9esr
1
0

[torbrowser/maint-2.3] Remove NoScript click-to-play confirmation.
by erinn@torproject.org 24 Oct '12
by erinn@torproject.org 24 Oct '12
24 Oct '12
commit de2b71ba70e3654aa29e6368b479c6aaf74c1f69
Author: Mike Perry <mikeperry-git(a)fscked.org>
Date: Wed Oct 17 01:39:09 2012 -0700
Remove NoScript click-to-play confirmation.
---
build-scripts/config/prefs.js | 1 +
1 files changed, 1 insertions(+), 0 deletions(-)
diff --git a/build-scripts/config/prefs.js b/build-scripts/config/prefs.js
index 52f6956..1ddac62 100644
--- a/build-scripts/config/prefs.js
+++ b/build-scripts/config/prefs.js
@@ -118,6 +118,7 @@ user_pref("noscript.ABE.enabled", false);
user_pref("noscript.ABE.notify", false);
user_pref("noscript.ABE.wanIpAsLocal", false);
user_pref("noscript.autoReload", false);
+user_pref("noscript.confirmUnblock", false);
user_pref("noscript.contentBlocker", true);
user_pref("noscript.default", "about:blank about:credits addons.mozilla.org flashgot.net google.com gstatic.com googlesyndication.com informaction.com yahoo.com yimg.com maone.net noscript.net hotmail.com msn.com passport.com passport.net passportimages.com live.com");
user_pref("noscript.firstRunRedirection", false);
1
0

[torbrowser/maint-2.3] add stable firefox patches for alpha bundles
by erinn@torproject.org 24 Oct '12
by erinn@torproject.org 24 Oct '12
24 Oct '12
commit 8ff89c09c4856a91cb2787af97c214bbaefe1cc7
Author: Erinn Clark <erinn(a)torproject.org>
Date: Wed Oct 24 16:32:39 2012 +0100
add stable firefox patches for alpha bundles
---
...nents.interfaces-lookupMethod-from-conten.patch | 50 ++
...0002-Make-Permissions-Manager-memory-only.patch | 94 ++++
...-Make-Intermediate-Cert-Store-memory-only.patch | 43 ++
.../firefox/0004-Add-a-string-based-cacheKey.patch | 85 +++
.../0005-Block-all-plugins-except-flash.patch | 85 +++
...ontent-pref-service-memory-only-clearable.patch | 37 ++
...owser-exit-when-not-launched-from-Vidalia.patch | 46 ++
.../0008-Disable-SSL-Session-ID-tracking.patch | 28 +
...observer-event-to-close-persistent-connec.patch | 40 ++
...ice-and-system-specific-CSS-Media-Queries.patch | 154 ++++++
...11-Limit-the-number-of-fonts-per-document.patch | 228 ++++++++
.../0012-Rebrand-Firefox-to-TorBrowser.patch | 50 ++
.../0013-Make-Download-manager-memory-only.patch | 57 ++
.../0014-Add-DDG-and-StartPage-to-Omnibox.patch | 84 +++
...-nsICacheService.EvictEntries-synchronous.patch | 44 ++
.../firefox/0016-Prevent-WebSocket-DNS-leak.patch | 132 +++++
...ize-HTTP-request-order-and-pipeline-depth.patch | 251 +++++++++
...th-headers-before-the-modify-request-obse.patch | 52 ++
...Adapt-Steven-Michaud-s-Mac-crashfix-patch.patch | 532 +++++++++++++++++++
...d-mozIThirdPartyUtil.getFirstPartyURI-API.patch | 31 +-
.../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, 3554 insertions(+), 12 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
new file mode 100644
index 0000000..1a82800
--- /dev/null
+++ b/src/current-patches/firefox/0001-Block-Components.interfaces-lookupMethod-from-conten.patch
@@ -0,0 +1,50 @@
+From 1c2ccbea73720db5405602e4033c69b706068a8b Mon Sep 17 00:00:00 2001
+From: Mike Perry <mikeperry-git(a)torproject.org>
+Date: Wed, 1 Feb 2012 15:40:40 -0800
+Subject: [PATCH 01/24] Block Components.interfaces,lookupMethod from content
+
+This patch removes the ability of content script to access
+Components.interfaces.* as well as call or access Components.lookupMethod.
+
+These two interfaces seem to be exposed to content script only to make our
+lives difficult. Components.lookupMethod can undo our JS hooks, and
+Components.interfaces is useful for fingerprinting the platform, OS, and
+Firebox version.
+
+They appear to have no other legitimate use. See also:
+https://bugzilla.mozilla.org/show_bug.cgi?id=429070
+https://trac.torproject.org/projects/tor/ticket/2873
+https://trac.torproject.org/projects/tor/ticket/2874
+---
+ js/xpconnect/src/XPCComponents.cpp | 8 ++++++--
+ 1 files changed, 6 insertions(+), 2 deletions(-)
+
+diff --git a/js/xpconnect/src/XPCComponents.cpp b/js/xpconnect/src/XPCComponents.cpp
+index 38bfe08..7224b9b 100644
+--- a/js/xpconnect/src/XPCComponents.cpp
++++ b/js/xpconnect/src/XPCComponents.cpp
+@@ -4502,7 +4502,9 @@ nsXPCComponents::CanCreateWrapper(const nsIID * iid, char **_retval)
+ NS_IMETHODIMP
+ nsXPCComponents::CanCallMethod(const nsIID * iid, const PRUnichar *methodName, char **_retval)
+ {
+- static const char* allowed[] = { "isSuccessCode", "lookupMethod", nsnull };
++ // XXX: Pref observer? Also, is this what we want? Seems like a plan
++ //static const char* allowed[] = { "isSuccessCode", "lookupMethod", nsnull };
++ static const char* allowed[] = { "isSuccessCode", nsnull };
+ *_retval = xpc_CheckAccessList(methodName, allowed);
+ return NS_OK;
+ }
+@@ -4511,7 +4513,9 @@ nsXPCComponents::CanCallMethod(const nsIID * iid, const PRUnichar *methodName, c
+ NS_IMETHODIMP
+ nsXPCComponents::CanGetProperty(const nsIID * iid, const PRUnichar *propertyName, char **_retval)
+ {
+- static const char* allowed[] = { "interfaces", "interfacesByID", "results", nsnull};
++ // XXX: Pref observer? Also, is this what we want? Seems like a plan
++ // static const char* allowed[] = { "interfaces", "interfacesByID", "results", nsnull};
++ static const char* allowed[] = { "results", nsnull};
+ *_retval = xpc_CheckAccessList(propertyName, allowed);
+ return NS_OK;
+ }
+--
+1.7.5.4
+
diff --git a/src/current-patches/firefox/0002-Make-Permissions-Manager-memory-only.patch b/src/current-patches/firefox/0002-Make-Permissions-Manager-memory-only.patch
new file mode 100644
index 0000000..fa23d93
--- /dev/null
+++ b/src/current-patches/firefox/0002-Make-Permissions-Manager-memory-only.patch
@@ -0,0 +1,94 @@
+From cd983b1b57b1f4ae10c8deec5aa12ec957fdc855 Mon Sep 17 00:00:00 2001
+From: Mike Perry <mikeperry-git(a)torproject.org>
+Date: Wed, 1 Feb 2012 15:45:16 -0800
+Subject: [PATCH 02/24] Make Permissions Manager memory-only
+
+This patch exposes a pref 'permissions.memory_only' that properly isolates the
+permissions manager to memory, which is responsible for all user specified
+site permissions, as well as stored STS policy.
+
+The pref does successfully clear the permissions manager memory if toggled. It
+does not need to be set in prefs.js, and can be handled by Torbutton.
+
+https://trac.torproject.org/projects/tor/ticket/2950
+---
+ extensions/cookie/nsPermissionManager.cpp | 34 ++++++++++++++++++++++++++--
+ 1 files changed, 31 insertions(+), 3 deletions(-)
+
+diff --git a/extensions/cookie/nsPermissionManager.cpp b/extensions/cookie/nsPermissionManager.cpp
+index 67eb216..12cc7cf 100644
+--- a/extensions/cookie/nsPermissionManager.cpp
++++ b/extensions/cookie/nsPermissionManager.cpp
+@@ -58,6 +58,10 @@
+ #include "mozStorageHelper.h"
+ #include "mozStorageCID.h"
+ #include "nsXULAppAPI.h"
++#include "nsCOMPtr.h"
++#include "nsIPrefService.h"
++#include "nsIPrefBranch.h"
++#include "nsIPrefBranch2.h"
+
+ static nsPermissionManager *gPermissionManager = nsnull;
+
+@@ -203,6 +207,11 @@ nsPermissionManager::Init()
+ mObserverService->AddObserver(this, "profile-do-change", true);
+ }
+
++ nsCOMPtr<nsIPrefBranch2> pbi = do_GetService(NS_PREFSERVICE_CONTRACTID);
++ if (pbi) {
++ pbi->AddObserver("permissions.", this, PR_FALSE);
++ }
++
+ if (IsChildProcess()) {
+ // Get the permissions from the parent process
+ InfallibleTArray<IPC::Permission> perms;
+@@ -251,8 +260,18 @@ nsPermissionManager::InitDB(bool aRemoveFile)
+ if (!storage)
+ return NS_ERROR_UNEXPECTED;
+
++ bool memory_db = false;
++ nsCOMPtr<nsIPrefBranch> prefs = do_GetService(NS_PREFSERVICE_CONTRACTID);
++ if (prefs) {
++ prefs->GetBoolPref("permissions.memory_only", &memory_db);
++ }
++
+ // cache a connection to the hosts database
+- rv = storage->OpenDatabase(permissionsFile, getter_AddRefs(mDBConn));
++ if (memory_db) {
++ rv = storage->OpenSpecialDatabase("memory", getter_AddRefs(mDBConn));
++ } else {
++ rv = storage->OpenDatabase(permissionsFile, getter_AddRefs(mDBConn));
++ }
+ NS_ENSURE_SUCCESS(rv, rv);
+
+ bool ready;
+@@ -262,7 +281,11 @@ nsPermissionManager::InitDB(bool aRemoveFile)
+ rv = permissionsFile->Remove(false);
+ NS_ENSURE_SUCCESS(rv, rv);
+
+- rv = storage->OpenDatabase(permissionsFile, getter_AddRefs(mDBConn));
++ if (memory_db) {
++ rv = storage->OpenSpecialDatabase("memory", getter_AddRefs(mDBConn));
++ } else {
++ rv = storage->OpenDatabase(permissionsFile, getter_AddRefs(mDBConn));
++ }
+ NS_ENSURE_SUCCESS(rv, rv);
+
+ mDBConn->GetConnectionReady(&ready);
+@@ -783,7 +806,12 @@ NS_IMETHODIMP nsPermissionManager::Observe(nsISupports *aSubject, const char *aT
+ {
+ ENSURE_NOT_CHILD_PROCESS;
+
+- if (!nsCRT::strcmp(aTopic, "profile-before-change")) {
++ if (nsCRT::strcmp(aTopic, NS_PREFBRANCH_PREFCHANGE_TOPIC_ID) == 0) {
++ if (!nsCRT::strcmp(someData, NS_LITERAL_STRING("permissions.memory_only").get())) {
++ // XXX: Should we remove the file? Probably not..
++ InitDB(PR_FALSE);
++ }
++ } 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())) {
+--
+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
new file mode 100644
index 0000000..b10fb85
--- /dev/null
+++ b/src/current-patches/firefox/0003-Make-Intermediate-Cert-Store-memory-only.patch
@@ -0,0 +1,43 @@
+From f100a7979e1a44863a8a67a09743f0e17b5dd14e Mon Sep 17 00:00:00 2001
+From: Mike Perry <mikeperry-git(a)fscked.org>
+Date: Fri, 19 Aug 2011 17:58:23 -0700
+Subject: [PATCH 03/24] Make Intermediate Cert Store memory-only.
+
+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(-)
+
+diff --git a/security/manager/ssl/src/nsNSSComponent.cpp b/security/manager/ssl/src/nsNSSComponent.cpp
+index a08c4ef..0ec3713 100644
+--- a/security/manager/ssl/src/nsNSSComponent.cpp
++++ b/security/manager/ssl/src/nsNSSComponent.cpp
+@@ -1730,8 +1730,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;
+- SECStatus init_rv = ::NSS_Initialize(profileStr.get(), "", "",
++ bool nocertdb = false;
++ mPrefBranch->GetBoolPref("security.nocertdb", &nocertdb);
++
++ // XXX: We can also do the the following to only disable the certdb.
++ // Leaving this codepath in as a fallback in case InitNODB fails
++ if (nocertdb)
++ init_flags |= NSS_INIT_NOCERTDB;
++
++ SECStatus init_rv;
++ if (nocertdb) {
++ init_rv = ::NSS_NoDB_Init(NULL);
++ } else {
++ init_rv = ::NSS_Initialize(profileStr.get(), "", "",
+ SECMOD_DB, init_flags);
++ }
+
+ if (init_rv != SECSuccess) {
+ PR_LOG(gPIPNSSLog, PR_LOG_DEBUG, ("can not init NSS r/w in %s\n", profileStr.get()));
+--
+1.7.5.4
+
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
new file mode 100644
index 0000000..f3afa97
--- /dev/null
+++ b/src/current-patches/firefox/0004-Add-a-string-based-cacheKey.patch
@@ -0,0 +1,85 @@
+From d674d09bc233d200b1ebc47f8e6ac4ebd6e4225a Mon Sep 17 00:00:00 2001
+From: Mike Perry <mikeperry-git(a)fscked.org>
+Date: Fri, 2 Sep 2011 20:47:02 -0700
+Subject: [PATCH 04/24] Add a string-based cacheKey.
+
+Used for isolating cache according to same-origin policy.
+---
+ netwerk/base/public/nsICachingChannel.idl | 7 +++++++
+ netwerk/protocol/http/nsHttpChannel.cpp | 22 ++++++++++++++++++++++
+ netwerk/protocol/http/nsHttpChannel.h | 1 +
+ 3 files changed, 30 insertions(+), 0 deletions(-)
+
+diff --git a/netwerk/base/public/nsICachingChannel.idl b/netwerk/base/public/nsICachingChannel.idl
+index 2da46d6..4ee5774 100644
+--- a/netwerk/base/public/nsICachingChannel.idl
++++ b/netwerk/base/public/nsICachingChannel.idl
+@@ -98,6 +98,13 @@ interface nsICachingChannel : nsICacheInfoChannel
+ attribute nsISupports cacheKey;
+
+ /**
++ * Set/get the cache domain... uniquely identifies the data in the cache
++ * for this channel. Holding a reference to this key does NOT prevent
++ * the cached data from being removed.
++ */
++ attribute AUTF8String cacheDomain;
++
++ /**
+ * Specifies whether or not the data should be cached to a file. This
+ * 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
+--- a/netwerk/protocol/http/nsHttpChannel.cpp
++++ b/netwerk/protocol/http/nsHttpChannel.cpp
+@@ -2392,6 +2392,12 @@ nsHttpChannel::AssembleCacheKey(const char *spec, PRUint32 postID,
+ cacheKey.Append(buf);
+ }
+
++ if (strlen(mCacheDomain.get()) > 0) {
++ cacheKey.AppendLiteral("domain=");
++ cacheKey.Append(mCacheDomain.get());
++ cacheKey.AppendLiteral("&");
++ }
++
+ if (!cacheKey.IsEmpty()) {
+ cacheKey.AppendLiteral("uri=");
+ }
+@@ -4695,6 +4701,22 @@ nsHttpChannel::SetCacheForOfflineUse(bool value)
+ }
+
+ NS_IMETHODIMP
++nsHttpChannel::GetCacheDomain(nsACString &value)
++{
++ value = mCacheDomain;
++
++ return NS_OK;
++}
++
++NS_IMETHODIMP
++nsHttpChannel::SetCacheDomain(const nsACString &value)
++{
++ mCacheDomain = value;
++
++ return NS_OK;
++}
++
++NS_IMETHODIMP
+ nsHttpChannel::GetOfflineCacheClientID(nsACString &value)
+ {
+ value = mOfflineCacheClientID;
+diff --git a/netwerk/protocol/http/nsHttpChannel.h b/netwerk/protocol/http/nsHttpChannel.h
+index 88ce469..53538cf 100644
+--- a/netwerk/protocol/http/nsHttpChannel.h
++++ b/netwerk/protocol/http/nsHttpChannel.h
+@@ -303,6 +303,7 @@ private:
+ nsCOMPtr<nsICacheEntryDescriptor> mOfflineCacheEntry;
+ nsCacheAccessMode mOfflineCacheAccess;
+ nsCString mOfflineCacheClientID;
++ nsCString mCacheDomain;
+
+ // auth specific data
+ nsCOMPtr<nsIHttpChannelAuthProvider> mAuthProvider;
+--
+1.7.5.4
+
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
new file mode 100644
index 0000000..e7a831e
--- /dev/null
+++ b/src/current-patches/firefox/0005-Block-all-plugins-except-flash.patch
@@ -0,0 +1,85 @@
+From 88a390822d232ba037de1f15091977ca7e1064bf Mon Sep 17 00:00:00 2001
+From: Mike Perry <mikeperry-git(a)torproject.org>
+Date: Wed, 1 Feb 2012 15:50:15 -0800
+Subject: [PATCH 05/24] Block all plugins except flash.
+
+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
+and/or executing code (for example, AV plugins that collect statistics/analyse
+urls, magical toolbars that phone home or "help" the user, skype buttons that
+ruin our day, and censorship filters). Hence we rolled our own.
+
+See https://trac.torproject.org/projects/tor/ticket/3547#comment:6 for musings
+on a better way. Until then, it is delta-darwinism for us.
+---
+ dom/plugins/base/nsPluginHost.cpp | 33 +++++++++++++++++++++++++++++++++
+ dom/plugins/base/nsPluginHost.h | 2 ++
+ 2 files changed, 35 insertions(+), 0 deletions(-)
+
+diff --git a/dom/plugins/base/nsPluginHost.cpp b/dom/plugins/base/nsPluginHost.cpp
+index 992bcd4..f56f231 100644
+--- a/dom/plugins/base/nsPluginHost.cpp
++++ b/dom/plugins/base/nsPluginHost.cpp
+@@ -1968,6 +1968,35 @@ bool nsPluginHost::IsDuplicatePlugin(nsPluginTag * aPluginTag)
+ return false;
+ }
+
++PRBool nsPluginHost::GhettoBlacklist(nsIFile *pluginFile)
++{
++ nsCString leaf;
++ const char *leafStr;
++ nsresult rv;
++
++ rv = pluginFile->GetNativeLeafName(leaf);
++ if (NS_FAILED(rv)) {
++ return PR_TRUE; // fuck 'em. blacklist.
++ }
++
++ leafStr = leaf.get();
++
++ if (!leafStr) {
++ return PR_TRUE; // fuck 'em. blacklist.
++ }
++
++ // libgnashplugin.so, libflashplayer.so, Flash Player-10.4-10.5.plugin,
++ // NPSWF32.dll, NPSWF64.dll
++ if (strstr(leafStr, "libgnashplugin") == leafStr ||
++ strstr(leafStr, "libflashplayer") == leafStr ||
++ strstr(leafStr, "Flash Player") == leafStr ||
++ strstr(leafStr, "NPSWF") == leafStr) {
++ return PR_FALSE;
++ }
++
++ return PR_TRUE; // fuck 'em. blacklist.
++}
++
+ typedef NS_NPAPIPLUGIN_CALLBACK(char *, NP_GETMIMEDESCRIPTION)(void);
+
+ nsresult nsPluginHost::ScanPluginsDirectory(nsIFile *pluginsDir,
+@@ -2101,6 +2130,10 @@ nsresult nsPluginHost::ScanPluginsDirectory(nsIFile *pluginsDir,
+ continue;
+ }
+
++ if (GhettoBlacklist(localfile)) {
++ continue;
++ }
++
+ // if it is not found in cache info list or has been changed, create a new one
+ if (!pluginTag) {
+ nsPluginFile pluginFile(localfile);
+diff --git a/dom/plugins/base/nsPluginHost.h b/dom/plugins/base/nsPluginHost.h
+index 39a8891..c262abf 100644
+--- a/dom/plugins/base/nsPluginHost.h
++++ b/dom/plugins/base/nsPluginHost.h
+@@ -278,6 +278,8 @@ private:
+ // Loads all cached plugins info into mCachedPlugins
+ nsresult ReadPluginInfo();
+
++ PRBool GhettoBlacklist(nsIFile *pluginFile);
++
+ // Given a file path, returns the plugins info from our cache
+ // and removes it from the cache.
+ void RemoveCachedPluginsInfo(const char *filePath,
+--
+1.7.5.4
+
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
new file mode 100644
index 0000000..17af793
--- /dev/null
+++ b/src/current-patches/firefox/0006-Make-content-pref-service-memory-only-clearable.patch
@@ -0,0 +1,37 @@
+From 71ba98d81a6ecada62af4d2ee03be050d371d996 Mon Sep 17 00:00:00 2001
+From: Mike Perry <mikeperry-git(a)fscked.org>
+Date: Thu, 8 Sep 2011 08:40:17 -0700
+Subject: [PATCH 06/24] Make content pref service memory-only + clearable
+
+This prevents random urls from being inserted into content-prefs.sqllite in
+the profile directory as content prefs change (includes site-zoom and perhaps
+other site prefs?).
+---
+ .../contentprefs/nsContentPrefService.js | 4 ++--
+ 1 files changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/toolkit/components/contentprefs/nsContentPrefService.js b/toolkit/components/contentprefs/nsContentPrefService.js
+index adfb650..1619d5f 100644
+--- a/toolkit/components/contentprefs/nsContentPrefService.js
++++ b/toolkit/components/contentprefs/nsContentPrefService.js
+@@ -1240,7 +1240,7 @@ ContentPrefService.prototype = {
+
+ var dbConnection;
+
+- if (!dbFile.exists())
++ if (true || !dbFile.exists())
+ dbConnection = this._dbCreate(dbService, dbFile);
+ else {
+ try {
+@@ -1288,7 +1288,7 @@ ContentPrefService.prototype = {
+ },
+
+ _dbCreate: function ContentPrefService__dbCreate(aDBService, aDBFile) {
+- var dbConnection = aDBService.openDatabase(aDBFile);
++ var dbConnection = aDBService.openSpecialDatabase("memory");
+
+ try {
+ this._dbCreateSchema(dbConnection);
+--
+1.7.5.4
+
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
new file mode 100644
index 0000000..cc496d3
--- /dev/null
+++ b/src/current-patches/firefox/0007-Make-Tor-Browser-exit-when-not-launched-from-Vidalia.patch
@@ -0,0 +1,46 @@
+From 12579def59d67416b841f6b0a6eadfd94bba72e9 Mon Sep 17 00:00:00 2001
+From: Mike Perry <mikeperry-git(a)fscked.org>
+Date: Sun, 9 Oct 2011 22:50:07 -0700
+Subject: [PATCH 07/24] Make Tor Browser exit when not launched from Vidalia
+
+Turns out the Windows 7 UI encourages users to "dock" their Tor Browser app
+for easy relaunch. If they manage to do this, we should fail closed rather
+than opened. Hopefully they will get the hint and dock Vidalia instead.
+
+This is an emergency fix for
+https://trac.torproject.org/projects/tor/ticket/4192. We can do a better
+localized fix w/ a translated alert menu later, if it seems like this might
+actually be common.
+---
+ browser/base/content/browser.js | 15 +++++++++++++++
+ 1 files changed, 15 insertions(+), 0 deletions(-)
+
+diff --git a/browser/base/content/browser.js b/browser/base/content/browser.js
+index f16a0c5..20e3666 100644
+--- a/browser/base/content/browser.js
++++ b/browser/base/content/browser.js
+@@ -1217,6 +1217,21 @@ function BrowserStartup() {
+
+ prepareForStartup();
+
++ // If this is not a TBB profile, exit.
++ // Solves https://trac.torproject.org/projects/tor/ticket/4192
++ var foundPref = false;
++ try {
++ foundPref = gPrefService.prefHasUserValue("torbrowser.version");
++ } catch(e) {
++ //dump("No pref: "+e);
++ }
++ if(!foundPref) {
++ var appStartup = Components.classes["@mozilla.org/toolkit/app-startup;1"]
++ .getService(Components.interfaces.nsIAppStartup);
++ appStartup.quit(3); // Force all windows to close, and then quit.
++ }
++
++
+ if (uriToLoad && !isLoadingBlank) {
+ if (uriToLoad instanceof Ci.nsISupportsArray) {
+ let count = uriToLoad.Count();
+--
+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
new file mode 100644
index 0000000..39e1483
--- /dev/null
+++ b/src/current-patches/firefox/0008-Disable-SSL-Session-ID-tracking.patch
@@ -0,0 +1,28 @@
+From 7586e413761858ce705d25d4a1673e608a162bed Mon Sep 17 00:00:00 2001
+From: Mike Perry <mikeperry-git(a)fscked.org>
+Date: Wed, 7 Dec 2011 19:36:38 -0800
+Subject: [PATCH 08/24] Disable SSL Session ID tracking.
+
+We can't easily bind SSL Session ID tracking to url bar domain,
+so we have to disable them to satisfy
+https://www.torproject.org/projects/torbrowser/design/#identifier-linkability.
+---
+ security/nss/lib/ssl/sslsock.c | 2 +-
+ 1 files changed, 1 insertions(+), 1 deletions(-)
+
+diff --git a/security/nss/lib/ssl/sslsock.c b/security/nss/lib/ssl/sslsock.c
+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 = {
+ PR_FALSE, /* enableSSL2 */ /* now defaults to off in NSS 3.13 */
+ PR_TRUE, /* enableSSL3 */
+ PR_TRUE, /* enableTLS */ /* now defaults to on in NSS 3.0 */
+- PR_FALSE, /* noCache */
++ PR_TRUE, /* noCache */
+ PR_FALSE, /* fdx */
+ PR_FALSE, /* v2CompatibleHello */ /* now defaults to off in NSS 3.13 */
+ PR_TRUE, /* detectRollBack */
+--
+1.7.5.4
+
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
new file mode 100644
index 0000000..e693c71
--- /dev/null
+++ b/src/current-patches/firefox/0009-Provide-an-observer-event-to-close-persistent-connec.patch
@@ -0,0 +1,40 @@
+From 9c6f997dd9a44336af9a1db17f5b680cc80a0e6c Mon Sep 17 00:00:00 2001
+From: Mike Perry <mikeperry-git(a)torproject.org>
+Date: Wed, 1 Feb 2012 15:53:28 -0800
+Subject: [PATCH 09/24] Provide an observer event to close persistent
+ connections
+
+We need to prevent linkability across "New Identity", which includes closing
+keep-alive connections.
+---
+ netwerk/protocol/http/nsHttpHandler.cpp | 7 +++++++
+ 1 files changed, 7 insertions(+), 0 deletions(-)
+
+diff --git a/netwerk/protocol/http/nsHttpHandler.cpp b/netwerk/protocol/http/nsHttpHandler.cpp
+index 281d6ff..8125681 100644
+--- a/netwerk/protocol/http/nsHttpHandler.cpp
++++ b/netwerk/protocol/http/nsHttpHandler.cpp
+@@ -325,6 +325,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);
+ }
+
+ return NS_OK;
+@@ -1504,6 +1505,12 @@ nsHttpHandler::Observe(nsISupports *subject,
+ mConnMgr->PruneDeadConnections();
+ }
+ }
++ else if (strcmp(topic, "net:prune-all-connections") == 0) {
++ if (mConnMgr) {
++ mConnMgr->ClosePersistentConnections();
++ mConnMgr->PruneDeadConnections();
++ }
++ }
+
+ return NS_OK;
+ }
+--
+1.7.5.4
+
diff --git a/src/current-patches/firefox/0010-Limit-device-and-system-specific-CSS-Media-Queries.patch b/src/current-patches/firefox/0010-Limit-device-and-system-specific-CSS-Media-Queries.patch
new file mode 100644
index 0000000..14e584c
--- /dev/null
+++ b/src/current-patches/firefox/0010-Limit-device-and-system-specific-CSS-Media-Queries.patch
@@ -0,0 +1,154 @@
+From 8f97f2f36adb9e4416f3d19af10880c800c846c2 Mon Sep 17 00:00:00 2001
+From: Kathleen Brade <brade(a)pearlcrescent.com>
+Date: Thu, 4 Oct 2012 14:28:48 -0400
+Subject: [PATCH 10/24] Limit device and system specific CSS Media Queries.
+
+---
+ 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..5b1df7e 100644
+--- a/layout/style/nsMediaFeatures.cpp
++++ b/layout/style/nsMediaFeatures.cpp
+@@ -130,6 +130,9 @@ GetDeviceContextFor(nsPresContext* aPresContext)
+ static nsSize
+ GetDeviceSize(nsPresContext* aPresContext)
+ {
++ if (!aPresContext->IsChrome()) {
++ return GetSize(aPresContext);
++ } else {
+ nsSize size;
+ if (aPresContext->IsRootPaginatedDocument())
+ // We want the page size, including unprintable areas and margins.
+@@ -140,6 +143,7 @@ GetDeviceSize(nsPresContext* aPresContext)
+ GetDeviceContextFor(aPresContext)->
+ GetDeviceSurfaceDimensions(size.width, size.height);
+ return size;
++ }
+ }
+
+ static nsresult
+@@ -183,17 +187,17 @@ static nsresult
+ GetDeviceOrientation(nsPresContext* aPresContext, const nsMediaFeature*,
+ nsCSSValue& aResult)
+ {
+- nsSize size = GetDeviceSize(aPresContext);
+- PRInt32 orientation;
+- if (size.width > size.height) {
+- orientation = NS_STYLE_ORIENTATION_LANDSCAPE;
+- } else {
+- // Per spec, square viewports should be 'portrait'
+- orientation = NS_STYLE_ORIENTATION_PORTRAIT;
+- }
+-
+- aResult.SetIntValue(orientation, eCSSUnit_Enumerated);
+- return NS_OK;
++ nsSize size = GetDeviceSize(aPresContext);
++ PRInt32 orientation;
++ if (size.width > size.height) {
++ orientation = NS_STYLE_ORIENTATION_LANDSCAPE;
++ } else {
++ // Per spec, square viewports should be 'portrait'
++ orientation = NS_STYLE_ORIENTATION_PORTRAIT;
++ }
++
++ aResult.SetIntValue(orientation, eCSSUnit_Enumerated);
++ return NS_OK;
+ }
+
+ static nsresult
+@@ -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)
+ {
+- float ratio = aPresContext->CSSPixelsToDevPixels(1.0f);
+- aResult.SetFloatValue(ratio, eCSSUnit_Number);
++ if (aPresContext->IsChrome()) {
++ float ratio = aPresContext->CSSPixelsToDevPixels(1.0f);
++ aResult.SetFloatValue(ratio, eCSSUnit_Number);
++ } else {
++ aResult.SetFloatValue(1.0, eCSSUnit_Number);
++ }
+ return NS_OK;
+ }
+
+@@ -320,18 +337,21 @@ static nsresult
+ GetSystemMetric(nsPresContext* aPresContext, const nsMediaFeature* aFeature,
+ nsCSSValue& aResult)
+ {
++ if (aPresContext->IsChrome()) {
+ NS_ABORT_IF_FALSE(aFeature->mValueType == nsMediaFeature::eBoolInteger,
+ "unexpected type");
+ nsIAtom *metricAtom = *aFeature->mData.mMetric;
+ bool hasMetric = nsCSSRuleProcessor::HasSystemMetric(metricAtom);
+ aResult.SetIntValue(hasMetric ? 1 : 0, eCSSUnit_Integer);
+- return NS_OK;
++ }
++ return NS_OK;
+ }
+
+ static nsresult
+ GetWindowsTheme(nsPresContext* aPresContext, const nsMediaFeature* aFeature,
+ nsCSSValue& aResult)
+ {
++ if (aPresContext->IsChrome()) {
+ aResult.Reset();
+ #ifdef XP_WIN
+ PRUint8 windowsThemeId =
+@@ -350,7 +370,8 @@ GetWindowsTheme(nsPresContext* aPresContext, const nsMediaFeature* aFeature,
+ }
+ }
+ #endif
+- return NS_OK;
++ }
++ return NS_OK;
+ }
+
+ /*
+--
+1.7.5.4
+
diff --git a/src/current-patches/firefox/0011-Limit-the-number-of-fonts-per-document.patch b/src/current-patches/firefox/0011-Limit-the-number-of-fonts-per-document.patch
new file mode 100644
index 0000000..ff9e618
--- /dev/null
+++ b/src/current-patches/firefox/0011-Limit-the-number-of-fonts-per-document.patch
@@ -0,0 +1,228 @@
+From cb3a6f45dd2c15d6b75084e1a4dded18ed638632 Mon Sep 17 00:00:00 2001
+From: Mike Perry <mikeperry-git(a)torproject.org>
+Date: Wed, 1 Feb 2012 16:01:21 -0800
+Subject: [PATCH 11/24] Limit the number of fonts per document.
+
+We create two prefs:
+browser.display.max_font_count and browser.display.max_font_attempts.
+max_font_count sets a limit on the number of fonts actually used in the
+document, and max_font_attempts sets a limit on the total number of CSS
+queries that a document is allowed to perform.
+
+Once either limit is reached, the browser behaves as if
+browser.display.use_document_fonts was set to 0 for subsequent font queries.
+
+If a pref is not set or is negative, that limit does not apply.
+
+This is done to address:
+https://www.torproject.org/projects/torbrowser/design/#fingerprinting-linkability
+---
+ layout/base/nsPresContext.cpp | 100 +++++++++++++++++++++++++++++++++++++++++
+ layout/base/nsPresContext.h | 9 ++++
+ layout/style/nsRuleNode.cpp | 13 ++++-
+ 3 files changed, 119 insertions(+), 3 deletions(-)
+
+diff --git a/layout/base/nsPresContext.cpp b/layout/base/nsPresContext.cpp
+index e1587db..9690d9c 100644
+--- a/layout/base/nsPresContext.cpp
++++ b/layout/base/nsPresContext.cpp
+@@ -98,6 +98,8 @@
+ #include "FrameLayerBuilder.h"
+ #include "nsDOMMediaQueryList.h"
+ #include "nsSMILAnimationController.h"
++#include "nsString.h"
++#include "nsUnicharUtils.h"
+
+ #ifdef IBMBIDI
+ #include "nsBidiPresUtils.h"
+@@ -706,6 +708,10 @@ nsPresContext::GetUserPreferences()
+ // * use fonts?
+ mUseDocumentFonts =
+ Preferences::GetInt("browser.display.use_document_fonts") != 0;
++ mMaxFonts =
++ Preferences::GetInt("browser.display.max_font_count", -1);
++ mMaxFontAttempts =
++ Preferences::GetInt("browser.display.max_font_attempts", -1);
+
+ // * replace backslashes with Yen signs? (bug 245770)
+ mEnableJapaneseTransform =
+@@ -1300,6 +1306,100 @@ nsPresContext::GetDefaultFont(PRUint8 aFontID) const
+ return font;
+ }
+
++PRBool
++nsPresContext::FontUseCountReached(const nsFont &font) {
++ if (mMaxFonts < 0) {
++ return PR_FALSE;
++ }
++
++ for (PRUint32 i = 0; i < mFontsUsed.Length(); i++) {
++ if (mFontsUsed[i].name.Equals(font.name,
++ nsCaseInsensitiveStringComparator())
++ // XXX: Style is sometimes filled with garbage??
++ /*&& mFontsUsed[i].style == font.style*/) {
++ // seen it before: OK
++ return PR_FALSE;
++ }
++ }
++
++ if (mFontsUsed.Length() >= mMaxFonts) {
++ return PR_TRUE;
++ }
++
++ return PR_FALSE;
++}
++
++PRBool
++nsPresContext::FontAttemptCountReached(const nsFont &font) {
++ if (mMaxFontAttempts < 0) {
++ return PR_FALSE;
++ }
++
++ for (PRUint32 i = 0; i < mFontsTried.Length(); i++) {
++ if (mFontsTried[i].name.Equals(font.name,
++ nsCaseInsensitiveStringComparator())
++ // XXX: Style is sometimes filled with garbage??
++ /*&& mFontsTried[i].style == font.style*/) {
++ // seen it before: OK
++ return PR_FALSE;
++ }
++ }
++
++ if (mFontsTried.Length() >= mMaxFontAttempts) {
++ return PR_TRUE;
++ }
++
++ return PR_FALSE;
++}
++
++void
++nsPresContext::AddFontUse(const nsFont &font) {
++ if (mMaxFonts < 0) {
++ return;
++ }
++
++ for (PRUint32 i = 0; i < mFontsUsed.Length(); i++) {
++ if (mFontsUsed[i].name.Equals(font.name,
++ nsCaseInsensitiveStringComparator())
++ // XXX: Style is sometimes filled with garbage??
++ /*&& mFontsUsed[i].style == font.style*/) {
++ // seen it before: OK
++ return;
++ }
++ }
++
++ if (mFontsUsed.Length() >= mMaxFonts) {
++ return;
++ }
++
++ mFontsUsed.AppendElement(font);
++ return;
++}
++
++void
++nsPresContext::AddFontAttempt(const nsFont &font) {
++ if (mMaxFontAttempts < 0) {
++ return;
++ }
++
++ for (PRUint32 i = 0; i < mFontsTried.Length(); i++) {
++ if (mFontsTried[i].name.Equals(font.name,
++ nsCaseInsensitiveStringComparator())
++ // XXX: Style is sometimes filled with garbage??
++ /*&& mFontsTried[i].style == font.style*/) {
++ // seen it before: OK
++ return;
++ }
++ }
++
++ if (mFontsTried.Length() >= mMaxFontAttempts) {
++ return;
++ }
++
++ mFontsTried.AppendElement(font);
++ return;
++}
++
+ void
+ nsPresContext::SetFullZoom(float aZoom)
+ {
+diff --git a/layout/base/nsPresContext.h b/layout/base/nsPresContext.h
+index ecd01d8..552a69a 100644
+--- a/layout/base/nsPresContext.h
++++ b/layout/base/nsPresContext.h
+@@ -548,6 +548,13 @@ public:
+ }
+ }
+
++ nsTArray<nsFont> mFontsUsed; // currently for font-count limiting only
++ nsTArray<nsFont> mFontsTried; // currently for font-count limiting only
++ void AddFontUse(const nsFont &font);
++ void AddFontAttempt(const nsFont &font);
++ PRBool FontUseCountReached(const nsFont &font);
++ PRBool FontAttemptCountReached(const nsFont &font);
++
+ PRInt32 MinFontSize() const {
+ return NS_MAX(mMinFontSize, mMinimumFontSizePref);
+ }
+@@ -1117,6 +1124,8 @@ protected:
+ PRUint32 mInterruptChecksToSkip;
+
+ mozilla::TimeStamp mReflowStartTime;
++ PRInt32 mMaxFontAttempts;
++ PRInt32 mMaxFonts;
+
+ unsigned mHasPendingInterrupt : 1;
+ unsigned mInterruptsEnabled : 1;
+diff --git a/layout/style/nsRuleNode.cpp b/layout/style/nsRuleNode.cpp
+index 27336bf..827585a 100644
+--- a/layout/style/nsRuleNode.cpp
++++ b/layout/style/nsRuleNode.cpp
+@@ -3091,6 +3091,7 @@ nsRuleNode::ComputeFontData(void* aStartStruct,
+
+ // See if there is a minimum font-size constraint to honor
+ nscoord minimumFontSize = mPresContext->MinFontSize();
++ PRBool isXUL = PR_FALSE;
+
+ if (minimumFontSize < 0)
+ minimumFontSize = 0;
+@@ -3102,10 +3103,10 @@ nsRuleNode::ComputeFontData(void* aStartStruct,
+ // 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()) {
++ 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;
+ }
+
+@@ -3120,9 +3121,13 @@ nsRuleNode::ComputeFontData(void* aStartStruct,
+ // generic?
+ nsFont::GetGenericID(font->mFont.name, &generic);
+
++ mPresContext->AddFontAttempt(font->mFont);
++
+ // If we aren't allowed to use document fonts, then we are only entitled
+ // to use the user's default variable-width font and fixed-width font
+- if (!useDocumentFonts) {
++ if (!isXUL && (!useDocumentFonts ||
++ mPresContext->FontAttemptCountReached(font->mFont) ||
++ mPresContext->FontUseCountReached(font->mFont))) {
+ // Extract the generic from the specified font family...
+ nsAutoString genericName;
+ if (!font->mFont.EnumerateFamilies(ExtractGeneric, &genericName)) {
+@@ -3158,6 +3163,8 @@ nsRuleNode::ComputeFontData(void* aStartStruct,
+ minimumFontSize, font);
+ }
+
++ if (font->mGenericID == kGenericFont_NONE)
++ mPresContext->AddFontUse(font->mFont);
+ COMPUTE_END_INHERITED(Font, font)
+ }
+
+--
+1.7.5.4
+
diff --git a/src/current-patches/firefox/0012-Rebrand-Firefox-to-TorBrowser.patch b/src/current-patches/firefox/0012-Rebrand-Firefox-to-TorBrowser.patch
new file mode 100644
index 0000000..e627238
--- /dev/null
+++ b/src/current-patches/firefox/0012-Rebrand-Firefox-to-TorBrowser.patch
@@ -0,0 +1,50 @@
+From 5820fc300fe1cae27752673e8721a19e70bf727c Mon Sep 17 00:00:00 2001
+From: Erinn Clark <erinn(a)torproject.org>
+Date: Wed, 25 Apr 2012 09:14:00 -0300
+Subject: [PATCH 12/24] Rebrand Firefox to TorBrowser
+
+This patch does some basic renaming of Firefox to TorBrowser. The rest of the
+branding is done by images and icons.
+---
+ browser/branding/official/configure.sh | 2 +-
+ browser/branding/official/locales/en-US/brand.dtd | 6 +++---
+ .../official/locales/en-US/brand.properties | 6 +++---
+ 3 files changed, 7 insertions(+), 7 deletions(-)
+
+diff --git a/browser/branding/official/configure.sh b/browser/branding/official/configure.sh
+index 4d3d297..e9b3738 100644
+--- a/browser/branding/official/configure.sh
++++ b/browser/branding/official/configure.sh
+@@ -1,2 +1,2 @@
+-MOZ_APP_DISPLAYNAME=Firefox
++MOZ_APP_DISPLAYNAME=TorBrowser
+ MOZ_UA_BUILDID=20100101
+diff --git a/browser/branding/official/locales/en-US/brand.dtd b/browser/branding/official/locales/en-US/brand.dtd
+index 142d79b..c137e04 100644
+--- a/browser/branding/official/locales/en-US/brand.dtd
++++ b/browser/branding/official/locales/en-US/brand.dtd
+@@ -1,4 +1,4 @@
+-<!ENTITY brandShortName "Firefox">
+-<!ENTITY brandFullName "Mozilla Firefox">
+-<!ENTITY vendorShortName "Mozilla">
++<!ENTITY brandShortName "TorBrowser">
++<!ENTITY brandFullName "Tor Browser">
++<!ENTITY vendorShortName "Tor Project">
+ <!ENTITY trademarkInfo.part1 "Firefox and the Firefox logos are trademarks of the Mozilla Foundation.">
+diff --git a/browser/branding/official/locales/en-US/brand.properties b/browser/branding/official/locales/en-US/brand.properties
+index 5f3ad54..62ac2fd 100644
+--- a/browser/branding/official/locales/en-US/brand.properties
++++ b/browser/branding/official/locales/en-US/brand.properties
+@@ -1,6 +1,6 @@
+-brandShortName=Firefox
+-brandFullName=Mozilla Firefox
+-vendorShortName=Mozilla
++brandShortName=TorBrowser
++brandFullName=Tor Browser
++vendorShortName=Tor Project
+
+ homePageSingleStartMain=Firefox Start, a fast home page with built-in search
+ homePageImport=Import your home page from %S
+--
+1.7.5.4
+
diff --git a/src/current-patches/firefox/0013-Make-Download-manager-memory-only.patch b/src/current-patches/firefox/0013-Make-Download-manager-memory-only.patch
new file mode 100644
index 0000000..1ad0972
--- /dev/null
+++ b/src/current-patches/firefox/0013-Make-Download-manager-memory-only.patch
@@ -0,0 +1,57 @@
+From 28178fb406d86b317b13b16ade3b06e5e1500c7e Mon Sep 17 00:00:00 2001
+From: Mike Perry <mikeperry-git(a)torproject.org>
+Date: Wed, 25 Apr 2012 13:39:35 -0700
+Subject: [PATCH 13/24] Make Download manager memory only.
+
+Solves https://trac.torproject.org/projects/tor/ticket/4017.
+
+Yes, this is an ugly hack. We *could* send the observer notification from
+Torbutton to tell the download manager to switch to memory, but then we have
+to dance around and tell it again if the user switches in and out of private
+browsing mode..
+
+The right way to do this is with a pref. Maybe I'll get to that someday, if
+this breaks enough times in conflict.
+---
+ toolkit/components/downloads/nsDownloadManager.cpp | 4 ++--
+ toolkit/components/downloads/nsDownloadManager.h | 2 +-
+ 2 files changed, 3 insertions(+), 3 deletions(-)
+
+diff --git a/toolkit/components/downloads/nsDownloadManager.cpp b/toolkit/components/downloads/nsDownloadManager.cpp
+index 00a6e7d..2e83f61 100644
+--- a/toolkit/components/downloads/nsDownloadManager.cpp
++++ b/toolkit/components/downloads/nsDownloadManager.cpp
+@@ -1992,7 +1992,7 @@ nsDownloadManager::Observe(nsISupports *aSubject,
+ if (NS_LITERAL_STRING("memory").Equals(aData))
+ return SwitchDatabaseTypeTo(DATABASE_MEMORY);
+ else if (NS_LITERAL_STRING("disk").Equals(aData))
+- return SwitchDatabaseTypeTo(DATABASE_DISK);
++ return SwitchDatabaseTypeTo(DATABASE_MEMORY);
+ }
+ else if (strcmp(aTopic, "alertclickcallback") == 0) {
+ nsCOMPtr<nsIDownloadManagerUI> dmui =
+@@ -2069,7 +2069,7 @@ nsDownloadManager::OnLeavePrivateBrowsingMode()
+ (void)ResumeAllDownloads(false);
+
+ // Switch back to the on-disk DB again
+- (void)SwitchDatabaseTypeTo(DATABASE_DISK);
++ //(void)SwitchDatabaseTypeTo(DATABASE_DISK);
+
+ mInPrivateBrowsing = false;
+ }
+diff --git a/toolkit/components/downloads/nsDownloadManager.h b/toolkit/components/downloads/nsDownloadManager.h
+index 54312e4..cb63b52 100644
+--- a/toolkit/components/downloads/nsDownloadManager.h
++++ b/toolkit/components/downloads/nsDownloadManager.h
+@@ -90,7 +90,7 @@ public:
+
+ virtual ~nsDownloadManager();
+ nsDownloadManager() :
+- mDBType(DATABASE_DISK)
++ mDBType(DATABASE_MEMORY)
+ , mInPrivateBrowsing(false)
+ #ifdef DOWNLOAD_SCANNER
+ , mScanner(nsnull)
+--
+1.7.5.4
+
diff --git a/src/current-patches/firefox/0014-Add-DDG-and-StartPage-to-Omnibox.patch b/src/current-patches/firefox/0014-Add-DDG-and-StartPage-to-Omnibox.patch
new file mode 100644
index 0000000..adbd3d4
--- /dev/null
+++ b/src/current-patches/firefox/0014-Add-DDG-and-StartPage-to-Omnibox.patch
@@ -0,0 +1,84 @@
+From 2a80e84755c97cf4ff3ab63bda1bd5f0936d9594 Mon Sep 17 00:00:00 2001
+From: Mike Perry <mikeperry-git(a)torproject.org>
+Date: Wed, 25 Apr 2012 15:03:46 -0700
+Subject: [PATCH 14/24] Add DDG and StartPage to Omnibox.
+
+You mean there are search engines that don't require captchas if you don't
+have a cookie? Holy crap. Get those in there now.
+---
+ browser/locales/en-US/searchplugins/duckduckgo.xml | 29 ++++++++++++++++++++
+ browser/locales/en-US/searchplugins/list.txt | 2 +
+ browser/locales/en-US/searchplugins/startpage.xml | 11 +++++++
+ 3 files changed, 42 insertions(+), 0 deletions(-)
+ create mode 100644 browser/locales/en-US/searchplugins/duckduckgo.xml
+ create mode 100644 browser/locales/en-US/searchplugins/startpage.xml
+
+diff --git a/browser/locales/en-US/searchplugins/duckduckgo.xml b/browser/locales/en-US/searchplugins/duckduckgo.xml
+new file mode 100644
+index 0000000..4f00b4d
+--- /dev/null
++++ b/browser/locales/en-US/searchplugins/duckduckgo.xml
+@@ -0,0 +1,29 @@
++<SearchPlugin xmlns="http://www.mozilla.org/2006/browser/search/">
++<ShortName>DuckDuckGo</ShortName>
++<Description>Duck Duck Go</Description>
++<InputEncoding>UTF-8</InputEncoding>
++<Image width="16" height="16">data:image/png;base64,AAABAAEAEBAAAAEAIABoBAAAFgAAACgAAAAQAAAAIAAAAAEAIAAAAAAAAAAAANcNAADXDQAAAAAA
++AAAAAAAAAAAAAAAAAAAAAAAAAAAAJyDsJmlk8pf6+v3s/v7+++zr/fcnIOyzJyDsgCcg7CYAAAAA
++AAAAAAAAAAAAAAAAAAAAAAAAAAAnIOwBJyDscCcg7PZttJ7/7Pfs//////++xO7/S5GA/ycg7P8n
++IOz2JyDscCcg7AEAAAAAAAAAAAAAAAAnIOwBJyDstScg7P8nIOz/Y8p5/2fHZf9Yv0z/YcF2/1rB
++Uv8nIOz/JyDs/ycg7P8nIOy1JyDsAQAAAAAAAAAAJyDscCcg7P8nIOz/JyDs/4jQoP/p9+n/////
++/05X3v9LkYD/JyDs/ycg7P8nIOz/JyDs/ycg7HAAAAAAJyDsJicg7PYnIOz/JyDs/zUu7f/+/v//
++//////////89N+7/JyDs/yUo7f8nIOz/JyDs/ycg7P8nIOz2JyDsJicg7IAnIOz/JyDs/ycg7P9h
++XPH////////////t/P//GIr2/wfD+/8Gyfz/DKv5/yM57/8nIOz/JyDs/ycg7H8nIOyzJyDs/ycg
++7P8nIOz/jov1////////////Otz9/w3G/P8cWfH/JSvt/ycg7P8nIOz/JyDs/ycg7P8nIOyzJyDs
++5icg7P8nIOz/JyDs/7u5+f///////////27l/v8E0v3/BNL9/wTQ/f8Oofn/IT7v/ycg7P8nIOz/
++JyDs5icg7OYnIOz/JyDs/ycg7P/p6P3/uWsC////////////5fr//6Po/f8Thfb/DKv5/w6f+f8n IOz/JyDs/ycg7OYnIOyzJyDs/ycg7P8nIOz/9/b+/////////////////7lrAv/V1Pv/JyDs/ycg
++7P8nIOz/JyDs/ycg7P8nIOyzJyDsgCcg7P8nIOz/JyDs/8/N+///////////////////////iIX1
++/ycg7P8nIOz/JyDs/ycg7P8nIOz/JyDsfycg7CYnIOz2JyDs/ycg7P9FP+7/q6n4/+7u/f/n5v3/
++fXn0/yoj7P8nIOz/JyDs/ycg7P8nIOz/JyDs9icg7CYAAAAAJyDscCcg7P8nIOz/wsD6/+no/f/Y
++1/z/eHTz/ycg7P8nIOz/JyDs/ycg7P8nIOz/JyDs/ycg7HAAAAAAAAAAACcg7AEnIOy1JyDs/ycg
++7P8nIOz/JyDs/ycg7P8nIOz/JyDs/ycg7P8nIOz/JyDs/ycg7LUnIOwBAAAAAAAAAAAAAAAAJyDs
++AScg7HAnIOz2JyDs/ycg7P8nIOz/JyDs/ycg7P8nIOz/JyDs9icg7HAnIOwBAAAAAAAAAAAAAAAA
++AAAAAAAAAAAAAAAAJyDsJicg7IAnIOyzJyDs5icg7OYnIOyzJyDsgCcg7CYAAAAAAAAAAAAAAAAA
++AAAA+B8AAPAPAADAAwAAwAMAAIABAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAABAACAAQAAwAMAAMAD
++AADwDwAA+B8AAA==</Image>
++<Url type="text/html" method="POST" template="https://duckduckgo.com/html/">
++ <Param name="q" value="{searchTerms}"/>
++</Url>
++<SearchForm>https://duckduckgo.com/html/</SearchForm>
++</SearchPlugin>
+diff --git a/browser/locales/en-US/searchplugins/list.txt b/browser/locales/en-US/searchplugins/list.txt
+index 2a1141a..0466f4e 100644
+--- a/browser/locales/en-US/searchplugins/list.txt
++++ b/browser/locales/en-US/searchplugins/list.txt
+@@ -1,7 +1,9 @@
+ amazondotcom
+ bing
++duckduckgo
+ eBay
+ google
++startpage
+ twitter
+ wikipedia
+ yahoo
+diff --git a/browser/locales/en-US/searchplugins/startpage.xml b/browser/locales/en-US/searchplugins/startpage.xml
+new file mode 100644
+index 0000000..1a310b1
+--- /dev/null
++++ b/browser/locales/en-US/searchplugins/startpage.xml
+@@ -0,0 +1,11 @@
++<SearchPlugin xmlns="http://www.mozilla.org/2006/browser/search/">
++<ShortName>Startpage</ShortName>
++<Description>Start Page</Description>
++<InputEncoding>UTF-8</InputEncoding>
++<Image width="16" height="16">data:image/png;base64,AAABAAEAEBAAAAEAIABoBAAAFgAAACgAAAAQAAAAIAAAAAEAIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD2jkj+9YtD/vWLQ/71i0P+9otD/vaLRP72i0T+9YtE/vWLRP72i0T+9otD/vaNRP72jUT+9otF/vaLRf73kkv+9Yc///WJP//1iT//9Yk///rAmf/94Mz/+sCa//aRTv/1iUH/9ok///aJP//2i0H/9otB//aJQv/2iUL/9otC//aNRP/2jUT/9o1E//aNRP/6wpv////////////96dr/95dQ//aNRP/2kET/9pBG//aQRv/2kEb/9pBG//aRR//3lEz/95BH//mueP/7xJ3/959g//efYf/4p23//vDm//3p2//3kEr/95FJ//aRSf/niFH/95FK//aRSv/2mE//95hS/vq4iP/////////////////81bj/95xZ//q4iP//////+bF+//eZT//njFT/PSqi/2xGjv/2mVD/951V/vedVv783cX///////vQrf/++PP///////748//+8uj///////m3gf/olFr/PSuj/w8Pt/9sSJD/951V//eeWf73oVv++8ul///////5sXf/+KRi//vRsf////////////3r3v/olF//Piyk/w8Pt/9sSJH/+J5Z//ieWv/3oV/++KZf/vihXP/97N7//vn0//zTs//6wJP/+bBy//q6iP/onW//Piyl/w8Pt/8fGbH/m2iB/+icY//4pGD/96hl/viqZf74pmD/+Kxr//3iy/////////n1//ivbP/onGj/Pi2m/w8Pt/8uJKz/fFeQ/x8Zsf8+Lqb/6J9r//ivbP74rm3++Klm//mpZv/5q2f/+bR9//m0e//poW7/Pi6n/w8Pt/9sTZj/+Ktp//ira/+rd4P/Dw+3/4xijv/5snH+
+LN1/vmvbf/5r23/+a5t//mvb//4r2//TTuk/w8Pt/8fGrL/6ah1//ivcP/4r3P/q3yI/w8Pt/+MZpP/+bN5/vm4ev75t3X/+bV1//m1df/5t3X/+Ld3/8qUhP98XZn/Hxqz/+mse//5t3f/2p+B/x8as/8PD7f/u4qK//m7fv76u4D++bl7//m3fP/5uXz/+bl8//m5fP/5t3z/+bl//x8as/9NPKf/fWCb/x8as/8PD7f/bVOh//q5f//6v4X++sGI/vm9g//5voX/+b6F//m9hf/6vYX/+r6F//nCh/+bepr/Hxu0/w8Pt/8PD7f/fWOh//q+hf/6wof/+saN/vrGjf75xIv/+ceL//nEi//5xIv/+sSL//rHi//6x43/+ceN/+m7kP+7lpj/6ruQ//rHkP/6x43/+seQ//rLlf76ypT++seR//rJkf/6yZH/+seR//rJkf/6yZH/+8mR//vJlP/7yZT/+smU//rJlP/6yZT/+8yV//rJlf/6zpn+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA==</Image>
++
++<Url type="text/html" method="POST" template="https://startpage.com/do/search">
++ <Param name="q" value="{searchTerms}"/>
++</Url>
++<SearchForm>https://startpage.com/do/search/</SearchForm>
++</SearchPlugin>
+--
+1.7.5.4
+
diff --git a/src/current-patches/firefox/0015-Make-nsICacheService.EvictEntries-synchronous.patch b/src/current-patches/firefox/0015-Make-nsICacheService.EvictEntries-synchronous.patch
new file mode 100644
index 0000000..93a989b
--- /dev/null
+++ b/src/current-patches/firefox/0015-Make-nsICacheService.EvictEntries-synchronous.patch
@@ -0,0 +1,44 @@
+From 20c94cb890a8872c07ba13686e293ca147b85cd6 Mon Sep 17 00:00:00 2001
+From: Mike Perry <mikeperry-git(a)torproject.org>
+Date: Tue, 1 May 2012 15:02:03 -0700
+Subject: [PATCH 15/24] Make nsICacheService.EvictEntries synchronous
+
+This fixes a race condition that allows cache-based EverCookies to persist for
+a brief time (on the order of minutes?) after cache clearing/"New Identity".
+
+https://trac.torproject.org/projects/tor/ticket/5715
+---
+ netwerk/cache/nsCacheService.cpp | 15 +++++++++++++--
+ 1 files changed, 13 insertions(+), 2 deletions(-)
+
+diff --git a/netwerk/cache/nsCacheService.cpp b/netwerk/cache/nsCacheService.cpp
+index 83ce887..e9f1a76 100644
+--- a/netwerk/cache/nsCacheService.cpp
++++ b/netwerk/cache/nsCacheService.cpp
+@@ -1316,10 +1316,21 @@ NS_IMETHODIMP nsCacheService::VisitEntries(nsICacheVisitor *visitor)
+ return NS_OK;
+ }
+
+-
+ NS_IMETHODIMP nsCacheService::EvictEntries(nsCacheStoragePolicy storagePolicy)
+ {
+- return EvictEntriesForClient(nsnull, storagePolicy);
++ NS_IMETHODIMP r;
++ r = EvictEntriesForClient(nsnull, storagePolicy);
++
++ // XXX: Bloody hack until we get this notifier in FF14.0:
++ // https://developer.mozilla.org/en/XPCOM_Interface_Reference/nsICacheListener…
++ if (storagePolicy == nsICache::STORE_ANYWHERE &&
++ NS_IsMainThread() && gService && gService->mInitialized) {
++ nsCacheServiceAutoLock lock;
++ gService->DoomActiveEntries();
++ gService->ClearDoomList();
++ (void) SyncWithCacheIOThread();
++ }
++ return r;
+ }
+
+ NS_IMETHODIMP nsCacheService::GetCacheIOTarget(nsIEventTarget * *aCacheIOTarget)
+--
+1.7.5.4
+
diff --git a/src/current-patches/firefox/0016-Prevent-WebSocket-DNS-leak.patch b/src/current-patches/firefox/0016-Prevent-WebSocket-DNS-leak.patch
new file mode 100644
index 0000000..bb70b17
--- /dev/null
+++ b/src/current-patches/firefox/0016-Prevent-WebSocket-DNS-leak.patch
@@ -0,0 +1,132 @@
+From 976f0d4fabb6b0b50c83192d622827357c761bd3 Mon Sep 17 00:00:00 2001
+From: Mike Perry <mikeperry-git(a)torproject.org>
+Date: Wed, 2 May 2012 17:44:39 -0700
+Subject: [PATCH 16/24] Prevent WebSocket DNS leak.
+
+This is due to an improper implementation of the WebSocket spec by Mozilla.
+
+"There MUST be no more than one connection in a CONNECTING state. If multiple
+connections to the same IP address are attempted simultaneously, the client
+MUST serialize them so that there is no more than one connection at a time
+running through the following steps.
+
+If the client cannot determine the IP address of the remote host (for
+example, because all communication is being done through a proxy server that
+performs DNS queries itself), then the client MUST assume for the purposes of
+this step that each host name refers to a distinct remote host,"
+
+https://tools.ietf.org/html/rfc6455#page-15
+
+They implmented the first paragraph, but not the second...
+
+While we're at it, we also prevent the DNS service from being used to look up
+anything other than IP addresses if socks_remote_dns is set to true, so this
+bug can't turn up in other components or due to 3rd party addons.
+---
+ netwerk/dns/nsDNSService2.cpp | 24 ++++++++++++++++++++++-
+ netwerk/dns/nsDNSService2.h | 1 +
+ netwerk/protocol/websocket/WebSocketChannel.cpp | 8 +++++-
+ 3 files changed, 30 insertions(+), 3 deletions(-)
+
+diff --git a/netwerk/dns/nsDNSService2.cpp b/netwerk/dns/nsDNSService2.cpp
+index 68ad8a5..1253b2f 100644
+--- a/netwerk/dns/nsDNSService2.cpp
++++ b/netwerk/dns/nsDNSService2.cpp
+@@ -383,6 +383,7 @@ nsDNSService::Init()
+ bool enableIDN = true;
+ bool disableIPv6 = false;
+ bool disablePrefetch = false;
++ bool disableDNS = false;
+ int proxyType = nsIProtocolProxyService::PROXYCONFIG_DIRECT;
+
+ nsAdoptingCString ipv4OnlyDomains;
+@@ -404,6 +405,10 @@ nsDNSService::Init()
+
+ // If a manual proxy is in use, disable prefetch implicitly
+ prefs->GetIntPref("network.proxy.type", &proxyType);
++
++ // If the user wants remote DNS, we should fail any lookups that still
++ // make it here.
++ prefs->GetBoolPref("network.proxy.socks_remote_dns", &disableDNS);
+ }
+
+ if (mFirstTime) {
+@@ -420,7 +425,7 @@ nsDNSService::Init()
+
+ // Monitor these to see if there is a change in proxy configuration
+ // If a manual proxy is in use, disable prefetch implicitly
+- prefs->AddObserver("network.proxy.type", this, false);
++ prefs->AddObserver("network.proxy.", this, false);
+ }
+ }
+
+@@ -448,6 +453,7 @@ nsDNSService::Init()
+ mIDN = idn;
+ mIPv4OnlyDomains = ipv4OnlyDomains; // exchanges buffer ownership
+ mDisableIPv6 = disableIPv6;
++ mDisableDNS = disableDNS;
+
+ // Disable prefetching either by explicit preference or if a manual proxy is configured
+ mDisablePrefetch = disablePrefetch || (proxyType == nsIProtocolProxyService::PROXYCONFIG_MANUAL);
+@@ -547,6 +553,14 @@ nsDNSService::AsyncResolve(const nsACString &hostname,
+ if (mDisablePrefetch && (flags & RESOLVE_SPECULATE))
+ return NS_ERROR_DNS_LOOKUP_QUEUE_FULL;
+
++ PRNetAddr tempAddr;
++ if (mDisableDNS) {
++ // Allow IP lookups through, but nothing else.
++ if (PR_StringToNetAddr(hostname.BeginReading(), &tempAddr) != PR_SUCCESS) {
++ return NS_ERROR_UNKNOWN_PROXY_HOST; // XXX: NS_ERROR_NOT_IMPLEMENTED?
++ }
++ }
++
+ res = mResolver;
+ idn = mIDN;
+ }
+@@ -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?
++ }
++ }
+ }
+ NS_ENSURE_TRUE(res, NS_ERROR_OFFLINE);
+
+diff --git a/netwerk/dns/nsDNSService2.h b/netwerk/dns/nsDNSService2.h
+index 1749b41..3ec8eba 100644
+--- a/netwerk/dns/nsDNSService2.h
++++ b/netwerk/dns/nsDNSService2.h
+@@ -70,4 +70,5 @@ private:
+ bool mDisableIPv6;
+ bool mDisablePrefetch;
+ bool mFirstTime;
++ bool mDisableDNS;
+ };
+diff --git a/netwerk/protocol/websocket/WebSocketChannel.cpp b/netwerk/protocol/websocket/WebSocketChannel.cpp
+index 9e446e9..42aa6ca 100644
+--- a/netwerk/protocol/websocket/WebSocketChannel.cpp
++++ b/netwerk/protocol/websocket/WebSocketChannel.cpp
+@@ -1698,8 +1698,12 @@ WebSocketChannel::ApplyForAdmission()
+ LOG(("WebSocketChannel::ApplyForAdmission: checking for concurrent open\n"));
+ nsCOMPtr<nsIThread> mainThread;
+ NS_GetMainThread(getter_AddRefs(mainThread));
+- dns->AsyncResolve(hostName, 0, this, mainThread, getter_AddRefs(mDNSRequest));
+- NS_ENSURE_SUCCESS(rv, rv);
++ rv = dns->AsyncResolve(hostName, 0, this, mainThread, getter_AddRefs(mDNSRequest));
++ if (NS_FAILED(rv)) {
++ // Fall back to hostname on dispatch failure
++ mDNSRequest = nsnull;
++ OnLookupComplete(nsnull, nsnull, rv);
++ }
+
+ return NS_OK;
+ }
+--
+1.7.5.4
+
diff --git a/src/current-patches/firefox/0017-Randomize-HTTP-request-order-and-pipeline-depth.patch b/src/current-patches/firefox/0017-Randomize-HTTP-request-order-and-pipeline-depth.patch
new file mode 100644
index 0000000..f1814e7
--- /dev/null
+++ b/src/current-patches/firefox/0017-Randomize-HTTP-request-order-and-pipeline-depth.patch
@@ -0,0 +1,251 @@
+From 36f826e64411a74912ba1adebd1a30b84716bf84 Mon Sep 17 00:00:00 2001
+From: Mike Perry <mikeperry-git(a)torproject.org>
+Date: Wed, 6 Jun 2012 11:08:56 -0700
+Subject: [PATCH 17/24] Randomize HTTP request order and pipeline depth.
+
+This is an experimental defense against
+http://lorre.uni.lu/~andriy/papers/acmccs-wpes11-fingerprinting.pdf
+
+See:
+https://blog.torproject.org/blog/experimental-defense-website-traffic-fingerprinting
+
+This defense has been improved since that blog post to additionally randomize
+the order and concurrency of non-pipelined HTTP requests.
+---
+ netwerk/protocol/http/nsHttpConnectionMgr.cpp | 136 ++++++++++++++++++++++++-
+ netwerk/protocol/http/nsHttpConnectionMgr.h | 5 +
+ 2 files changed, 136 insertions(+), 5 deletions(-)
+
+diff --git a/netwerk/protocol/http/nsHttpConnectionMgr.cpp b/netwerk/protocol/http/nsHttpConnectionMgr.cpp
+index 23ef893..788368f 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();
++
++ nsresult rv;
++ mRandomGenerator = do_GetService("@mozilla.org/security/random-generator;1", &rv);
++ if (NS_FAILED(rv)) {
++ mRandomGenerator = nsnull;
++ }
+ }
+
+ 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;
+ }
+ }
++
++ delete [] ind;
+ }
+ }
+ }
+@@ -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) {
++
++ PRUint32* ind = new PRUint32[count];
++ ShuffleRequestOrder(ind, count);
++
++ for (h=0; h<count; ++h) {
++ i = ind[h]; // random request sequence
+ trans = ent->mPendingQ[i];
+
+ // 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"));
+
+@@ -694,6 +712,19 @@ nsHttpConnectionMgr::AtActiveConnectionLimit(nsConnectionEntry *ent, PRUint8 cap
+ maxPersistConns = mMaxPersistConnsPerHost;
+ }
+
++ // 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
++ // after a short while.
++ PRUint8 *bytes = nsnull;
++ nsresult rv = mRandomGenerator->GenerateRandomBytes(1, &bytes);
++ NS_ENSURE_SUCCESS(rv, rv);
++
++ bytes[0] = bytes[0] % (maxConns + 1);
++ maxConns = (maxConns/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;
+ }
+
+@@ -938,6 +969,101 @@ nsHttpConnectionMgr::BuildPipeline(nsConnectionEntry *ent,
+ return true;
+ }
+
++
++// 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++;
++ }
++
++ 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)
+ {
+diff --git a/netwerk/protocol/http/nsHttpConnectionMgr.h b/netwerk/protocol/http/nsHttpConnectionMgr.h
+index cdf21a9..81b282a 100644
+--- a/netwerk/protocol/http/nsHttpConnectionMgr.h
++++ b/netwerk/protocol/http/nsHttpConnectionMgr.h
+@@ -51,6 +51,7 @@
+
+ #include "nsIObserver.h"
+ #include "nsITimer.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;
+ // Timer for next pruning of dead connections.
+ nsCOMPtr<nsITimer> mTimer;
++ // Random number generator for reordering HTTP pipeline
++ nsCOMPtr<nsIRandomGenerator> mRandomGenerator;
+
+ //
+ // the connection table
+--
+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
new file mode 100644
index 0000000..46cf611
--- /dev/null
+++ b/src/current-patches/firefox/0018-Add-HTTP-auth-headers-before-the-modify-request-obse.patch
@@ -0,0 +1,52 @@
+From c1e26c8a294abe426fd6fb84508db6074ef23379 Mon Sep 17 00:00:00 2001
+From: Mike Perry <mikeperry-git(a)fscked.org>
+Date: Fri, 2 Sep 2011 15:33:20 -0700
+Subject: [PATCH 18/24] Add HTTP auth headers before the modify-request
+ observer.
+
+Otherwise, how are we supposed to modify them?
+
+Thanks to Georg Koppen for spotting both the problem and this fix.
+---
+ netwerk/protocol/http/nsHttpChannel.cpp | 11 +++++++----
+ 1 files changed, 7 insertions(+), 4 deletions(-)
+
+diff --git a/netwerk/protocol/http/nsHttpChannel.cpp b/netwerk/protocol/http/nsHttpChannel.cpp
+index 97bd84c..6205d62 100644
+--- a/netwerk/protocol/http/nsHttpChannel.cpp
++++ b/netwerk/protocol/http/nsHttpChannel.cpp
+@@ -316,9 +316,6 @@ nsHttpChannel::Connect(bool firstTime)
+ return NS_ERROR_DOCUMENT_NOT_CACHED;
+ }
+
+- // check to see if authorization headers should be included
+- mAuthProvider->AddAuthorizationHeaders();
+-
+ if (mLoadFlags & LOAD_NO_NETWORK_IO) {
+ return NS_ERROR_DOCUMENT_NOT_CACHED;
+ }
+@@ -3707,6 +3704,9 @@ nsHttpChannel::AsyncOpen(nsIStreamListener *listener, nsISupports *context)
+
+ AddCookiesToRequest();
+
++ // check to see if authorization headers should be included
++ mAuthProvider->AddAuthorizationHeaders();
++
+ // notify "http-on-modify-request" observers
+ gHttpHandler->OnModifyRequest(this);
+
+@@ -4817,7 +4817,10 @@ nsHttpChannel::DoAuthRetry(nsAHttpConnection *conn)
+ // this authentication attempt (bug 84794).
+ // TODO: save cookies from auth response and send them here (bug 572151).
+ AddCookiesToRequest();
+-
++
++ // check to see if authorization headers should be included
++ mAuthProvider->AddAuthorizationHeaders();
++
+ // notify "http-on-modify-request" observers
+ gHttpHandler->OnModifyRequest(this);
+
+--
+1.7.5.4
+
diff --git a/src/current-patches/firefox/0019-Adapt-Steven-Michaud-s-Mac-crashfix-patch.patch b/src/current-patches/firefox/0019-Adapt-Steven-Michaud-s-Mac-crashfix-patch.patch
new file mode 100644
index 0000000..7f3869c
--- /dev/null
+++ b/src/current-patches/firefox/0019-Adapt-Steven-Michaud-s-Mac-crashfix-patch.patch
@@ -0,0 +1,532 @@
+From 49cccdba3e6fc10e0e376d423b3ba1b6135f62e1 Mon Sep 17 00:00:00 2001
+From: Mike Perry <mikeperry-git(a)torproject.org>
+Date: Thu, 7 Jun 2012 16:25:48 -0700
+Subject: [PATCH 19/24] Adapt Steven Michaud's Mac crashfix patch
+
+Source is: https://bugzilla.mozilla.org/show_bug.cgi?id=715885#c35
+
+Some minor tweaks were needed to get it to apply and to compile on
+MacOS.
+---
+ widget/public/Makefile.in | 2 +
+ widget/public/nsIDragService.idl | 1 -
+ widget/public/nsPIDragService.idl | 48 ++++++++++++++++++++++++++++
+ widget/public/nsPIDragServiceWindows.idl | 46 ++++++++++++++++++++++++++
+ widget/src/cocoa/nsChildView.mm | 35 +++++++++++++-------
+ widget/src/gtk2/nsDragService.cpp | 2 +-
+ widget/src/gtk2/nsWindow.cpp | 2 +-
+ widget/src/qt/nsDragService.h | 2 +
+ widget/src/windows/Makefile.in | 1 -
+ widget/src/windows/nsDragService.cpp | 13 +++++---
+ widget/src/windows/nsDragService.h | 12 +++---
+ widget/src/windows/nsNativeDragSource.cpp | 7 ++--
+ widget/src/windows/nsNativeDragTarget.cpp | 28 ++++++++++------
+ widget/src/xpwidgets/nsBaseDragService.cpp | 16 +++++++++-
+ widget/src/xpwidgets/nsBaseDragService.h | 9 ++---
+ 15 files changed, 176 insertions(+), 48 deletions(-)
+ create mode 100644 widget/public/nsPIDragService.idl
+ create mode 100644 widget/public/nsPIDragServiceWindows.idl
+
+diff --git a/widget/public/Makefile.in b/widget/public/Makefile.in
+index a70e65a..8a9b73d 100644
+--- a/widget/public/Makefile.in
++++ b/widget/public/Makefile.in
+@@ -110,6 +110,8 @@ XPIDLSRCS = \
+ nsIClipboardDragDropHooks.idl \
+ nsIClipboardDragDropHookList.idl \
+ nsIDragSession.idl \
++ nsPIDragService.idl \
++ nsPIDragServiceWindows.idl \
+ nsIDragService.idl \
+ nsIFormatConverter.idl \
+ nsIClipboard.idl \
+diff --git a/widget/public/nsIDragService.idl b/widget/public/nsIDragService.idl
+index 6863a88..c4a1e26 100644
+--- a/widget/public/nsIDragService.idl
++++ b/widget/public/nsIDragService.idl
+@@ -146,7 +146,6 @@ interface nsIDragService : nsISupports
+ void suppress();
+ void unsuppress();
+
+- [noscript] void dragMoved(in long aX, in long aY);
+ };
+
+
+diff --git a/widget/public/nsPIDragService.idl b/widget/public/nsPIDragService.idl
+new file mode 100644
+index 0000000..93a144d
+--- /dev/null
++++ b/widget/public/nsPIDragService.idl
+@@ -0,0 +1,48 @@
++/* ***** BEGIN LICENSE BLOCK *****
++ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
++ *
++ * The contents of this file are subject to the Mozilla Public License Version
++ * 1.1 (the "License"); you may not use this file except in compliance with
++ * the License. You may obtain a copy of the License at
++ * http://www.mozilla.org/MPL/
++ *
++ * Software distributed under the License is distributed on an "AS IS" basis,
++ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
++ * for the specific language governing rights and limitations under the
++ * License.
++ *
++ * The Original Code is mozilla.org code.
++ *
++ * The Initial Developer of the Original Code is
++ * The Mozilla Foundation.
++ * Portions created by the Initial Developer are Copyright (C) 2012
++ * the Initial Developer. All Rights Reserved.
++ *
++ * Contributor(s):
++ * Steven Michaud <smichaud(a)pobox.com>
++ *
++ * Alternatively, the contents of this file may be used under the terms of
++ * either the GNU General Public License Version 2 or later (the "GPL"), or
++ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
++ * in which case the provisions of the GPL or the LGPL are applicable instead
++ * of those above. If you wish to allow use of your version of this file only
++ * under the terms of either the GPL or the LGPL, and not to allow others to
++ * use your version of this file under the terms of the MPL, indicate your
++ * decision by deleting the provisions above and replace them with the notice
++ * and other provisions required by the GPL or the LGPL. If you do not delete
++ * the provisions above, a recipient may use your version of this file under
++ * the terms of any one of the MPL, the GPL or the LGPL.
++ *
++ * ***** END LICENSE BLOCK ***** */
++
++#include "nsISupports.idl"
++
++[scriptable, uuid(FAD8C90B-8E1D-446A-9B6C-241486A85CBD)]
++interface nsPIDragService : nsISupports
++{
++ void dragMoved(in long aX, in long aY);
++
++ PRUint16 getInputSource();
++
++ void setDragEndPoint(in long aX, in long aY);
++};
+diff --git a/widget/public/nsPIDragServiceWindows.idl b/widget/public/nsPIDragServiceWindows.idl
+new file mode 100644
+index 0000000..c8a46dd
+--- /dev/null
++++ b/widget/public/nsPIDragServiceWindows.idl
+@@ -0,0 +1,46 @@
++/* ***** BEGIN LICENSE BLOCK *****
++ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
++ *
++ * The contents of this file are subject to the Mozilla Public License Version
++ * 1.1 (the "License"); you may not use this file except in compliance with
++ * the License. You may obtain a copy of the License at
++ * http://www.mozilla.org/MPL/
++ *
++ * Software distributed under the License is distributed on an "AS IS" basis,
++ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
++ * for the specific language governing rights and limitations under the
++ * License.
++ *
++ * The Original Code is mozilla.org code.
++ *
++ * The Initial Developer of the Original Code is
++ * The Mozilla Foundation.
++ * Portions created by the Initial Developer are Copyright (C) 2012
++ * the Initial Developer. All Rights Reserved.
++ *
++ * Contributor(s):
++ * Steven Michaud <smichaud(a)pobox.com>
++ *
++ * Alternatively, the contents of this file may be used under the terms of
++ * either the GNU General Public License Version 2 or later (the "GPL"), or
++ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
++ * in which case the provisions of the GPL or the LGPL are applicable instead
++ * of those above. If you wish to allow use of your version of this file only
++ * under the terms of either the GPL or the LGPL, and not to allow others to
++ * use your version of this file under the terms of the MPL, indicate your
++ * decision by deleting the provisions above and replace them with the notice
++ * and other provisions required by the GPL or the LGPL. If you do not delete
++ * the provisions above, a recipient may use your version of this file under
++ * the terms of any one of the MPL, the GPL or the LGPL.
++ *
++ * ***** END LICENSE BLOCK ***** */
++
++#include "nsISupports.idl"
++
++[scriptable, uuid(6FC2117D-5EB4-441A-9C12-62A783BEBC0C)]
++interface nsPIDragServiceWindows : nsISupports
++{
++ void setIDataObject(in nsISupports aDataObj);
++
++ void setDroppedLocal();
++};
+diff --git a/widget/src/cocoa/nsChildView.mm b/widget/src/cocoa/nsChildView.mm
+index 64336e3..b2ab6bc 100644
+--- a/widget/src/cocoa/nsChildView.mm
++++ b/widget/src/cocoa/nsChildView.mm
+@@ -4513,11 +4513,12 @@ NSEvent* gLastDragMouseDownEvent = nil;
+ if (!dragService) {
+ dragService = do_GetService(kDragServiceContractID);
+ }
++ nsCOMPtr<nsPIDragService> dragServicePriv = do_QueryInterface(dragService);
+
+ if (dragService) {
+ NSPoint pnt = [NSEvent mouseLocation];
+ FlipCocoaScreenCoordinate(pnt);
+- dragService->DragMoved(NSToIntRound(pnt.x), NSToIntRound(pnt.y));
++ dragServicePriv->DragMoved(NSToIntRound(pnt.x), NSToIntRound(pnt.y));
+ }
+ }
+
+@@ -4538,11 +4539,13 @@ NSEvent* gLastDragMouseDownEvent = nil;
+ }
+
+ if (mDragService) {
+- // set the dragend point from the current mouse location
+- nsDragService* dragService = static_cast<nsDragService *>(mDragService);
+- NSPoint pnt = [NSEvent mouseLocation];
+- FlipCocoaScreenCoordinate(pnt);
+- dragService->SetDragEndPoint(nsIntPoint(NSToIntRound(pnt.x), NSToIntRound(pnt.y)));
++ nsCOMPtr<nsPIDragService> dragServicePriv = do_QueryInterface(mDragService);
++ if (dragServicePriv) {
++ // set the dragend point from the current mouse location
++ NSPoint pnt = [NSEvent mouseLocation];
++ FlipCocoaScreenCoordinate(pnt);
++ dragServicePriv->SetDragEndPoint(NSToIntRound(pnt.x), NSToIntRound(pnt.y));
++ }
+
+ // XXX: dropEffect should be updated per |operation|.
+ // As things stand though, |operation| isn't well handled within "our"
+@@ -4553,13 +4556,19 @@ NSEvent* gLastDragMouseDownEvent = nil;
+ // value for NSDragOperationGeneric that is passed by other applications.
+ // All that said, NSDragOperationNone is still reliable.
+ if (operation == NSDragOperationNone) {
+- nsCOMPtr<nsIDOMDataTransfer> dataTransfer;
+- dragService->GetDataTransfer(getter_AddRefs(dataTransfer));
+- nsCOMPtr<nsIDOMNSDataTransfer> dataTransferNS =
+- do_QueryInterface(dataTransfer);
+-
+- if (dataTransferNS)
+- dataTransferNS->SetDropEffectInt(nsIDragService::DRAGDROP_ACTION_NONE);
++ nsCOMPtr<nsIDragSession> dragSession;
++ mDragService->GetCurrentSession(getter_AddRefs(dragSession));
++ if (dragSession) {
++ nsCOMPtr<nsIDOMDataTransfer> dataTransfer;
++ dragSession->GetDataTransfer(getter_AddRefs(dataTransfer));
++ if (dataTransfer) {
++ nsCOMPtr<nsIDOMNSDataTransfer> dataTransferNS =
++ do_QueryInterface(dataTransfer);
++ if (dataTransferNS) {
++ dataTransferNS->SetDropEffectInt(nsIDragService::DRAGDROP_ACTION_NONE);
++ }
++ }
++ }
+ }
+
+ mDragService->EndDragSession(true);
+diff --git a/widget/src/gtk2/nsDragService.cpp b/widget/src/gtk2/nsDragService.cpp
+index ca5a42c..876fd55 100644
+--- a/widget/src/gtk2/nsDragService.cpp
++++ b/widget/src/gtk2/nsDragService.cpp
+@@ -1334,7 +1334,7 @@ nsDragService::SourceEndDragSession(GdkDragContext *aContext,
+ GdkDisplay* display = gdk_display_get_default();
+ if (display) {
+ gdk_display_get_pointer(display, NULL, &x, &y, NULL);
+- SetDragEndPoint(nsIntPoint(x, y));
++ SetDragEndPoint(x, y);
+ }
+
+ // Either the drag was aborted or the drop occurred outside the app.
+diff --git a/widget/src/gtk2/nsWindow.cpp b/widget/src/gtk2/nsWindow.cpp
+index 2fd6f64..a2e27e1 100644
+--- a/widget/src/gtk2/nsWindow.cpp
++++ b/widget/src/gtk2/nsWindow.cpp
+@@ -3738,7 +3738,7 @@ nsWindow::OnDragDropEvent(GtkWidget *aWidget,
+ if (display) {
+ // get the current cursor position
+ gdk_display_get_pointer(display, NULL, &x, &y, NULL);
+- ((nsDragService *)dragService.get())->SetDragEndPoint(nsIntPoint(x, y));
++ ((nsDragService *)dragService.get())->SetDragEndPoint(x, y);
+ }
+ dragService->EndDragSession(true);
+
+diff --git a/widget/src/qt/nsDragService.h b/widget/src/qt/nsDragService.h
+index 5a3e5bb..50dcfac 100644
+--- a/widget/src/qt/nsDragService.h
++++ b/widget/src/qt/nsDragService.h
+@@ -50,6 +50,8 @@ public:
+ NS_DECL_ISUPPORTS
+ NS_DECL_NSIDRAGSERVICE
+
++ NS_IMETHOD DragMoved(PRInt32 aX, PRInt32 aY);
++
+ nsDragService();
+
+ private:
+diff --git a/widget/src/windows/Makefile.in b/widget/src/windows/Makefile.in
+index 53277ea..d7ff7ce 100644
+--- a/widget/src/windows/Makefile.in
++++ b/widget/src/windows/Makefile.in
+@@ -115,7 +115,6 @@ ifdef MOZ_ENABLE_D3D10_LAYER
+ DEFINES += -DMOZ_ENABLE_D3D10_LAYER
+ endif
+
+-
+ EXPORTS = nsdefs.h WindowHook.h
+ EXPORTS_NAMESPACES = mozilla/widget
+ EXPORTS_mozilla/widget = AudioSession.h
+diff --git a/widget/src/windows/nsDragService.cpp b/widget/src/windows/nsDragService.cpp
+index 2dcede3..3d8af21 100644
+--- a/widget/src/windows/nsDragService.cpp
++++ b/widget/src/windows/nsDragService.cpp
+@@ -97,6 +97,8 @@ nsDragService::~nsDragService()
+ NS_IF_RELEASE(mDataObject);
+ }
+
++NS_IMPL_ISUPPORTS_INHERITED1(nsDragService, nsBaseDragService, nsPIDragServiceWindows)
++
+ bool
+ nsDragService::CreateDragImage(nsIDOMNode *aDOMNode,
+ nsIScriptableRegion *aRegion,
+@@ -350,7 +352,7 @@ nsDragService::StartInvokingDragSession(IDataObject * aDataObj,
+ POINT cpos;
+ cpos.x = GET_X_LPARAM(pos);
+ cpos.y = GET_Y_LPARAM(pos);
+- SetDragEndPoint(nsIntPoint(cpos.x, cpos.y));
++ SetDragEndPoint(cpos.x, cpos.y);
+ EndDragSession(true);
+
+ mDoingDrag = false;
+@@ -468,25 +470,26 @@ nsDragService::GetData(nsITransferable * aTransferable, PRUint32 anItem)
+
+ //---------------------------------------------------------
+ NS_IMETHODIMP
+-nsDragService::SetIDataObject(IDataObject * aDataObj)
++nsDragService::SetIDataObject(nsISupports * aDataObj)
+ {
++ IDataObject *dataObj = (IDataObject*) aDataObj;
+ // When the native drag starts the DragService gets
+ // the IDataObject that is being dragged
+ NS_IF_RELEASE(mDataObject);
+- mDataObject = aDataObj;
++ mDataObject = dataObj;
+ NS_IF_ADDREF(mDataObject);
+
+ return NS_OK;
+ }
+
+ //---------------------------------------------------------
+-void
++NS_IMETHODIMP
+ nsDragService::SetDroppedLocal()
+ {
+ // Sent from the native drag handler, letting us know
+ // a drop occurred within the application vs. outside of it.
+ mSentLocalDropEvent = true;
+- return;
++ return NS_OK;
+ }
+
+ //-------------------------------------------------------------------------
+diff --git a/widget/src/windows/nsDragService.h b/widget/src/windows/nsDragService.h
+index 067bcf2..2699e47 100644
+--- a/widget/src/windows/nsDragService.h
++++ b/widget/src/windows/nsDragService.h
+@@ -39,6 +39,7 @@
+ #define nsDragService_h__
+
+ #include "nsBaseDragService.h"
++#include "nsPIDragServiceWindows.h"
+ #include <windows.h>
+ #include <shlobj.h>
+
+@@ -52,12 +53,15 @@ class nsString;
+ * Native Win32 DragService wrapper
+ */
+
+-class nsDragService : public nsBaseDragService
++class nsDragService : public nsBaseDragService, public nsPIDragServiceWindows
+ {
+ public:
+ nsDragService();
+ virtual ~nsDragService();
+-
++
++ NS_DECL_ISUPPORTS_INHERITED
++ NS_DECL_NSPIDRAGSERVICEWINDOWS
++
+ // nsIDragService
+ NS_IMETHOD InvokeDragSession(nsIDOMNode *aDOMNode,
+ nsISupportsArray *anArrayTransferables,
+@@ -71,13 +75,9 @@ public:
+ NS_IMETHOD EndDragSession(bool aDoneDrag);
+
+ // native impl.
+- NS_IMETHOD SetIDataObject(IDataObject * aDataObj);
+ NS_IMETHOD StartInvokingDragSession(IDataObject * aDataObj,
+ PRUint32 aActionType);
+
+- // A drop occurred within the application vs. outside of it.
+- void SetDroppedLocal();
+-
+ protected:
+ nsDataObjCollection* GetDataObjCollection(IDataObject * aDataObj);
+
+diff --git a/widget/src/windows/nsNativeDragSource.cpp b/widget/src/windows/nsNativeDragSource.cpp
+index e51101e..0fe6ffe 100644
+--- a/widget/src/windows/nsNativeDragSource.cpp
++++ b/widget/src/windows/nsNativeDragSource.cpp
+@@ -42,7 +42,7 @@
+ #include "nsIServiceManager.h"
+ #include "nsToolkit.h"
+ #include "nsWidgetsCID.h"
+-#include "nsIDragService.h"
++#include "nsDragService.h"
+
+ static NS_DEFINE_IID(kCDragServiceCID, NS_DRAGSERVICE_CID);
+
+@@ -101,9 +101,10 @@ STDMETHODIMP
+ nsNativeDragSource::QueryContinueDrag(BOOL fEsc, DWORD grfKeyState)
+ {
+ nsCOMPtr<nsIDragService> dragService = do_GetService(kCDragServiceCID);
+- if (dragService) {
++ nsCOMPtr<nsPIDragService> dragServicePriv = do_QueryInterface(dragService);
++ if (dragServicePriv) {
+ DWORD pos = ::GetMessagePos();
+- dragService->DragMoved(GET_X_LPARAM(pos), GET_Y_LPARAM(pos));
++ dragServicePriv->DragMoved(GET_X_LPARAM(pos), GET_Y_LPARAM(pos));
+ }
+
+ if (fEsc) {
+diff --git a/widget/src/windows/nsNativeDragTarget.cpp b/widget/src/windows/nsNativeDragTarget.cpp
+index cf6196b..82ad3c6 100644
+--- a/widget/src/windows/nsNativeDragTarget.cpp
++++ b/widget/src/windows/nsNativeDragTarget.cpp
+@@ -209,7 +209,11 @@ nsNativeDragTarget::DispatchDragDropEvent(PRUint32 aEventType, POINTL aPT)
+ event.isControl = IsKeyDown(NS_VK_CONTROL);
+ event.isMeta = false;
+ event.isAlt = IsKeyDown(NS_VK_ALT);
+- event.inputSource = static_cast<nsBaseDragService*>(mDragService)->GetInputSource();
++ event.inputSource = 0;
++ nsCOMPtr<nsPIDragService> dragServicePriv = do_QueryInterface(mDragService);
++ if (dragServicePriv) {
++ dragServicePriv->GetInputSource(&event.inputSource);
++ }
+
+ mWindow->DispatchEvent(&event, status);
+ }
+@@ -296,9 +300,8 @@ nsNativeDragTarget::DragEnter(LPDATAOBJECT pIDataSource,
+ // This cast is ok because in the constructor we created a
+ // the actual implementation we wanted, so we know this is
+ // a nsDragService. It should be a private interface, though.
+- nsDragService * winDragService =
+- static_cast<nsDragService *>(mDragService);
+- winDragService->SetIDataObject(pIDataSource);
++ nsCOMPtr<nsPIDragServiceWindows> winDragService = do_QueryInterface(mDragService);
++ winDragService->SetIDataObject((nsISupports*)pIDataSource);
+
+ // Now process the native drag state and then dispatch the event
+ ProcessDrag(NS_DRAGDROP_ENTER, grfKeyState, ptl, pdwEffect);
+@@ -436,8 +439,8 @@ nsNativeDragTarget::Drop(LPDATAOBJECT pData,
+ // This cast is ok because in the constructor we created a
+ // the actual implementation we wanted, so we know this is
+ // a nsDragService (but it should still be a private interface)
+- nsDragService* winDragService = static_cast<nsDragService*>(mDragService);
+- winDragService->SetIDataObject(pData);
++ nsCOMPtr<nsPIDragServiceWindows> winDragService = do_QueryInterface(mDragService);
++ winDragService->SetIDataObject((nsISupports*)pData);
+
+ // NOTE: ProcessDrag spins the event loop which may destroy arbitrary objects.
+ // We use strong refs to prevent it from destroying these:
+@@ -461,11 +464,14 @@ nsNativeDragTarget::Drop(LPDATAOBJECT pData,
+ // tell the drag service we're done with the session
+ // Use GetMessagePos to get the position of the mouse at the last message
+ // seen by the event loop. (Bug 489729)
+- DWORD pos = ::GetMessagePos();
+- POINT cpos;
+- cpos.x = GET_X_LPARAM(pos);
+- cpos.y = GET_Y_LPARAM(pos);
+- winDragService->SetDragEndPoint(nsIntPoint(cpos.x, cpos.y));
++ nsCOMPtr<nsPIDragService> dragServicePriv = do_QueryInterface(mDragService);
++ if (dragServicePriv) {
++ DWORD pos = ::GetMessagePos();
++ POINT cpos;
++ cpos.x = GET_X_LPARAM(pos);
++ cpos.y = GET_Y_LPARAM(pos);
++ dragServicePriv->SetDragEndPoint(cpos.x, cpos.y);
++ }
+ serv->EndDragSession(true);
+
+ // release the ref that was taken in DragEnter
+diff --git a/widget/src/xpwidgets/nsBaseDragService.cpp b/widget/src/xpwidgets/nsBaseDragService.cpp
+index 52efb7e..1c35673 100644
+--- a/widget/src/xpwidgets/nsBaseDragService.cpp
++++ b/widget/src/xpwidgets/nsBaseDragService.cpp
+@@ -89,7 +89,7 @@ nsBaseDragService::~nsBaseDragService()
+ {
+ }
+
+-NS_IMPL_ISUPPORTS2(nsBaseDragService, nsIDragService, nsIDragSession)
++NS_IMPL_ISUPPORTS3(nsBaseDragService, nsIDragService, nsPIDragService, nsIDragSession)
+
+ //---------------------------------------------------------
+ NS_IMETHODIMP
+@@ -443,6 +443,20 @@ nsBaseDragService::DragMoved(PRInt32 aX, PRInt32 aY)
+ return NS_OK;
+ }
+
++NS_IMETHODIMP
++nsBaseDragService::SetDragEndPoint(PRInt32 aX, PRInt32 aY)
++{
++ mEndDragPoint = nsIntPoint(aX, aY);
++ return NS_OK;
++}
++
++NS_IMETHODIMP
++nsBaseDragService::GetInputSource(PRUint16* aInputSource)
++{
++ *aInputSource = mInputSource;
++ return NS_OK;
++}
++
+ static nsIPresShell*
+ GetPresShellForContent(nsIDOMNode* aDOMNode)
+ {
+diff --git a/widget/src/xpwidgets/nsBaseDragService.h b/widget/src/xpwidgets/nsBaseDragService.h
+index 290c0cb..2ceac2b 100644
+--- a/widget/src/xpwidgets/nsBaseDragService.h
++++ b/widget/src/xpwidgets/nsBaseDragService.h
+@@ -39,6 +39,7 @@
+ #define nsBaseDragService_h__
+
+ #include "nsIDragService.h"
++#include "nsPIDragService.h"
+ #include "nsIDragSession.h"
+ #include "nsITransferable.h"
+ #include "nsISupportsArray.h"
+@@ -64,6 +65,7 @@ class nsICanvasElementExternal;
+ */
+
+ class nsBaseDragService : public nsIDragService,
++ public nsPIDragService,
+ public nsIDragSession
+ {
+
+@@ -74,14 +76,11 @@ public:
+ //nsISupports
+ NS_DECL_ISUPPORTS
+
+- //nsIDragSession and nsIDragService
++ //nsIDragSession, nsIDragService and nsPIDragService
+ NS_DECL_NSIDRAGSERVICE
++ NS_DECL_NSPIDRAGSERVICE
+ NS_DECL_NSIDRAGSESSION
+
+- void SetDragEndPoint(nsIntPoint aEndDragPoint) { mEndDragPoint = aEndDragPoint; }
+-
+- PRUint16 GetInputSource() { return mInputSource; }
+-
+ protected:
+
+ /**
+--
+1.7.5.4
+
diff --git a/src/current-patches/firefox/0020-Add-mozIThirdPartyUtil.getFirstPartyURI-API.patch b/src/current-patches/firefox/0020-Add-mozIThirdPartyUtil.getFirstPartyURI-API.patch
index 56d9848..114301d 100644
--- a/src/current-patches/firefox/0020-Add-mozIThirdPartyUtil.getFirstPartyURI-API.patch
+++ b/src/current-patches/firefox/0020-Add-mozIThirdPartyUtil.getFirstPartyURI-API.patch
@@ -1,17 +1,17 @@
-From 73e548ceee36b99f06e33010163ed8b8cc86b3dd Mon Sep 17 00:00:00 2001
+From 36d57455893bcf6dc08e91a2784970f285c5e84b Mon Sep 17 00:00:00 2001
From: Mike Perry <mikeperry-git(a)torproject.org>
Date: Tue, 28 Aug 2012 18:35:33 -0700
-Subject: [PATCH 20/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.
---
- content/base/src/ThirdPartyUtil.cpp | 52 ++++++++++++++++++++++++++++
+ content/base/src/ThirdPartyUtil.cpp | 59 ++++++++++++++++++++++++++++
content/base/src/ThirdPartyUtil.h | 2 +
- netwerk/base/public/mozIThirdPartyUtil.idl | 21 +++++++++++
- 3 files changed, 75 insertions(+), 0 deletions(-)
+ 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..62333f3 100644
+index 6a415e9..52b3dab 100644
--- a/content/base/src/ThirdPartyUtil.cpp
+++ b/content/base/src/ThirdPartyUtil.cpp
@@ -40,6 +40,9 @@
@@ -32,7 +32,7 @@ index 6a415e9..62333f3 100644
return rv;
}
-@@ -315,3 +319,51 @@ ThirdPartyUtil::GetBaseDomain(nsIURI* aHostURI,
+@@ -315,3 +319,58 @@ ThirdPartyUtil::GetBaseDomain(nsIURI* aHostURI,
return NS_OK;
}
@@ -62,12 +62,19 @@ index 6a415e9..62333f3 100644
+ if (NS_FAILED(rv) && aDoc) {
+ nsCOMPtr<nsIDOMWindow> top;
+ nsCOMPtr<nsIDOMDocument> topDDoc;
-+
-+ aDoc->GetWindow()->GetTop(getter_AddRefs(top));
-+ top->GetDocument(getter_AddRefs(topDDoc));
++
++ if (aDoc->GetWindow()) {
++ aDoc->GetWindow()->GetTop(getter_AddRefs(top));
++ top->GetDocument(getter_AddRefs(topDDoc));
+
-+ nsCOMPtr<nsIDocument> topDoc(do_QueryInterface(topDDoc));
-+ *aOutput = topDoc->GetOriginalURI();
++ 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;
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..cf5dd61
--- /dev/null
+++ b/src/current-patches/firefox/0021-Add-canvas-image-extraction-prompt.patch
@@ -0,0 +1,551 @@
+From 29ce940434ebbb8e54c0d9b8f84ccf6ec6bd71bc Mon Sep 17 00:00:00 2001
+From: Kathleen Brade <brade(a)pearlcrescent.com>
+Date: Tue, 9 Oct 2012 11:21:06 -0400
+Subject: [PATCH 21/24] Add canvas image extraction prompt.
+
+---
+ browser/base/content/browser.css | 1 +
+ browser/base/content/browser.js | 102 ++++++++++++++++++++
+ browser/base/content/browser.xul | 1 +
+ .../en-US/chrome/browser/browser.properties | 7 ++
+ browser/themes/gnomestripe/browser/browser.css | 2 +
+ browser/themes/pinstripe/browser/browser.css | 2 +
+ browser/themes/winstripe/browser/browser.css | 2 +
+ content/canvas/src/CanvasUtils.cpp | 63 ++++++++++++
+ content/canvas/src/CanvasUtils.h | 2 +
+ content/canvas/src/nsCanvasRenderingContext2D.cpp | 15 +++
+ .../canvas/src/nsCanvasRenderingContext2DAzure.cpp | 15 +++
+ content/html/content/public/nsHTMLCanvasElement.h | 3 +
+ content/html/content/src/Makefile.in | 1 +
+ content/html/content/src/nsHTMLCanvasElement.cpp | 39 ++++++--
+ 14 files changed, 246 insertions(+), 9 deletions(-)
+
+diff --git a/browser/base/content/browser.css b/browser/base/content/browser.css
+index f033c2b..c709631 100644
+--- a/browser/base/content/browser.css
++++ b/browser/base/content/browser.css
+@@ -440,6 +440,7 @@ window[chromehidden~="toolbar"] toolbar:not(.toolbar-primary):not(.chromeclass-m
+ created with a null anchorID, so in that case use a default anchor icon. */
+ #notification-popup-box[anchorid="notification-popup-box"] > #default-notification-icon,
+ #notification-popup-box[anchorid="geo-notification-icon"] > #geo-notification-icon,
++#notification-popup-box[anchorid="canvas-notification-icon"] > #canvas-notification-icon,
+ #notification-popup-box[anchorid="indexedDB-notification-icon"] > #indexedDB-notification-icon,
+ #notification-popup-box[anchorid="addons-notification-icon"] > #addons-notification-icon,
+ #notification-popup-box[anchorid="password-notification-icon"] > #password-notification-icon {
+diff --git a/browser/base/content/browser.js b/browser/base/content/browser.js
+index 20e3666..0c6bd46 100644
+--- a/browser/base/content/browser.js
++++ b/browser/base/content/browser.js
+@@ -1522,6 +1522,7 @@ function delayedStartup(isLoadingBlank, mustLoadSidebar) {
+ BrowserOffline.init();
+ OfflineApps.init();
+ IndexedDBPromptHelper.init();
++ CanvasPermissionPromptHelper.init();
+ gFormSubmitObserver.init();
+ AddonManager.addAddonListener(AddonsMgrListener);
+
+@@ -1834,6 +1835,7 @@ function BrowserShutdown() {
+ BrowserOffline.uninit();
+ OfflineApps.uninit();
+ IndexedDBPromptHelper.uninit();
++ CanvasPermissionPromptHelper.uninit();
+ AddonManager.removeAddonListener(AddonsMgrListener);
+ }
+
+@@ -6656,6 +6658,106 @@ var IndexedDBPromptHelper = {
+ }
+ };
+
++var CanvasPermissionPromptHelper = {
++ _permissionsPrompt: "canvas-permissions-prompt",
++ _notificationIcon: "canvas-notification-icon",
++
++ init:
++ function CanvasPermissionPromptHelper_init() {
++ Services.obs.addObserver(this, this._permissionsPrompt, false);
++ },
++
++ uninit:
++ function CanvasPermissionPromptHelper_uninit() {
++ Services.obs.removeObserver(this, this._permissionsPrompt, false);
++ },
++
++ // aSubject is an nsIDOMWindow.
++ // aData is an URL string.
++ observe:
++ function CanvasPermissionPromptHelper_observe(aSubject, aTopic, aData) {
++ if ((aTopic != this._permissionsPrompt) || !aData)
++ throw new Error("Unexpected topic or missing URL");
++
++ var uri = makeURI(aData);
++ var contentWindow = aSubject.QueryInterface(Ci.nsIDOMWindow);
++ var contentDocument = contentWindow.document;
++ var browserWindow =
++ OfflineApps._getBrowserWindowForContentWindow(contentWindow);
++
++ if (browserWindow != window) {
++ // Must belong to some other window.
++ return;
++ }
++
++ // If canvas prompt is already displayed, just return. This is OK (and
++ // more efficient) since this permission is associated with the top
++ // browser's URL.
++ if (PopupNotifications.getNotification(aTopic, browser))
++ return;
++
++ var bundleSvc = Cc["@mozilla.org/intl/stringbundle;1"].
++ getService(Ci.nsIStringBundleService);
++ var torBtnBundle;
++ try {
++ torBtnBundle = bundleSvc.createBundle(
++ "chrome://torbutton/locale/torbutton.properties");
++ } catch (e) {}
++
++ var message = getLocalizedString("canvas.siteprompt", [ uri.asciiHost ]);
++
++ var mainAction = {
++ label: getLocalizedString("canvas.allow"),
++ accessKey: getLocalizedString("canvas.allowAccessKey"),
++ callback: function() {
++ setCanvasPermission(uri, Ci.nsIPermissionManager.ALLOW_ACTION);
++ }
++ };
++
++ var secondaryActions = [
++ {
++ label: getLocalizedString("canvas.never"),
++ accessKey: getLocalizedString("canvas.neverAccessKey"),
++ callback: function() {
++ setCanvasPermission(uri, Ci.nsIPermissionManager.DENY_ACTION);
++ }
++ }
++ ];
++
++ // Since we have a process in place to perform localization for the
++ // Torbutton extension, get our strings from the extension if possible.
++ function getLocalizedString(aID, aParams) {
++ var s;
++ if (torBtnBundle) try {
++ if (aParams)
++ s = torBtnBundle.formatStringFromName(aID, aParams, aParams.length);
++ else
++ s = torBtnBundle.GetStringFromName(aID);
++ } catch (e) {}
++
++ if (!s) {
++ if (aParams)
++ s = gNavigatorBundle.getFormattedString(aID, aParams);
++ else
++ s = gNavigatorBundle.getString(aID);
++ }
++
++ return s;
++ }
++
++ function setCanvasPermission(aURI, aPerm) {
++ Services.perms.add(aURI, "canvas/extractData", aPerm,
++ Ci.nsIPermissionManager.EXPIRE_NEVER);
++ }
++
++ var browser = OfflineApps._getBrowserForContentWindow(browserWindow,
++ contentWindow);
++ notification = PopupNotifications.show(browser, aTopic, message,
++ this._notificationIcon, mainAction,
++ secondaryActions, null);
++ }
++};
++
+ function WindowIsClosing()
+ {
+ if (TabView.isVisible()) {
+diff --git a/browser/base/content/browser.xul b/browser/base/content/browser.xul
+index ba2a7cb..1acea43 100644
+--- a/browser/base/content/browser.xul
++++ b/browser/base/content/browser.xul
+@@ -520,6 +520,7 @@
+ <image id="default-notification-icon" class="notification-anchor-icon" role="button"/>
+ <image id="geo-notification-icon" class="notification-anchor-icon" role="button"/>
+ <image id="addons-notification-icon" class="notification-anchor-icon" role="button"/>
++ <image id="canvas-notification-icon" class="notification-anchor-icon" role="button"/>
+ <image id="indexedDB-notification-icon" class="notification-anchor-icon" role="button"/>
+ <image id="password-notification-icon" class="notification-anchor-icon" role="button"/>
+ </box>
+diff --git a/browser/locales/en-US/chrome/browser/browser.properties b/browser/locales/en-US/chrome/browser/browser.properties
+index 380e3c3..98154d1 100644
+--- a/browser/locales/en-US/chrome/browser/browser.properties
++++ b/browser/locales/en-US/chrome/browser/browser.properties
+@@ -197,6 +197,13 @@ offlineApps.usage=This website (%S) is now storing more than %SMB of data on you
+ offlineApps.manageUsage=Show settings
+ offlineApps.manageUsageAccessKey=S
+
++# Canvas permission prompt
++canvas.siteprompt=This website (%S) attempted to access image data on a canvas. Blank (white) image data was returned this time.
++canvas.allow=Allow in the Future
++canvas.allowAccessKey=A
++canvas.never=Never for This Site
++canvas.neverAccessKey=e
++
+ # LOCALIZATION NOTE (indexedDB.usage): %1$S is the website host name
+ # %2$S a number of megabytes.
+ indexedDB.usage=This website (%1$S) is attempting to store more than %2$S MB of data on your computer for offline use.
+diff --git a/browser/themes/gnomestripe/browser/browser.css b/browser/themes/gnomestripe/browser/browser.css
+index edc0b72..8ba057e 100644
+--- a/browser/themes/gnomestripe/browser/browser.css
++++ b/browser/themes/gnomestripe/browser/browser.css
+@@ -1227,6 +1227,7 @@ toolbar[iconsize="small"] #feed-button {
+ list-style-image: url("moz-icon://stock/gtk-cancel?size=menu");
+ }
+
++.popup-notification-icon[popupid="canvas-permissions-prompt"],
+ .popup-notification-icon[popupid="indexedDB-permissions-prompt"],
+ .popup-notification-icon[popupid="indexedDB-quota-prompt"] {
+ list-style-image: url(chrome://global/skin/icons/question-64.png);
+@@ -1281,6 +1282,7 @@ toolbar[iconsize="small"] #feed-button {
+ list-style-image: url(chrome://mozapps/skin/extensions/extensionGeneric-16.png);
+ }
+
++#canvas-notification-icon,
+ #indexedDB-notification-icon {
+ list-style-image: url(chrome://global/skin/icons/question-16.png);
+ }
+diff --git a/browser/themes/pinstripe/browser/browser.css b/browser/themes/pinstripe/browser/browser.css
+index 2a96556..f94a6f2 100644
+--- a/browser/themes/pinstripe/browser/browser.css
++++ b/browser/themes/pinstripe/browser/browser.css
+@@ -2404,10 +2404,12 @@ toolbarbutton.chevron > .toolbarbutton-menu-dropmarker {
+ -moz-image-region: rect(0px, 48px, 16px, 32px);
+ }
+
++#canvas-notification-icon,
+ #indexedDB-notification-icon {
+ list-style-image: url(chrome://global/skin/icons/question-16.png);
+ }
+
++.popup-notification-icon[popupid="canvas-permissions-prompt"],
+ .popup-notification-icon[popupid="indexedDB-permissions-prompt"],
+ .popup-notification-icon[popupid="indexedDB-quota-prompt"] {
+ list-style-image: url(chrome://global/skin/icons/question-64.png);
+diff --git a/browser/themes/winstripe/browser/browser.css b/browser/themes/winstripe/browser/browser.css
+index 0103c79..d352790 100644
+--- a/browser/themes/winstripe/browser/browser.css
++++ b/browser/themes/winstripe/browser/browser.css
+@@ -2294,6 +2294,7 @@ toolbarbutton.bookmark-item[dragover="true"][open="true"] {
+ -moz-image-region: rect(32px, 32px, 48px, 16px);
+ }
+
++.popup-notification-icon[popupid="canvas-permissions-prompt"],
+ .popup-notification-icon[popupid="indexedDB-permissions-prompt"],
+ .popup-notification-icon[popupid="indexedDB-quota-prompt"] {
+ list-style-image: url(chrome://global/skin/icons/question-64.png);
+@@ -2346,6 +2347,7 @@ toolbarbutton.bookmark-item[dragover="true"][open="true"] {
+ list-style-image: url(chrome://mozapps/skin/extensions/extensionGeneric-16.png);
+ }
+
++#canvas-notification-icon,
+ #indexedDB-notification-icon {
+ list-style-image: url(chrome://global/skin/icons/question-16.png);
+ }
+diff --git a/content/canvas/src/CanvasUtils.cpp b/content/canvas/src/CanvasUtils.cpp
+index 2f822eb..d7d0591 100644
+--- a/content/canvas/src/CanvasUtils.cpp
++++ b/content/canvas/src/CanvasUtils.cpp
+@@ -59,6 +59,15 @@
+ #include "CanvasUtils.h"
+ #include "mozilla/gfx/Matrix.h"
+
++#include "nsIScriptObjectPrincipal.h"
++#include "nsIPermissionManager.h"
++#include "mozIThirdPartyUtil.h"
++#include "nsContentUtils.h"
++#include "nsUnicharUtils.h"
++
++#define TOPIC_CANVAS_PERMISSIONS_PROMPT "canvas-permissions-prompt"
++#define PERMISSION_CANVAS_EXTRACT_DATA "canvas/extractData"
++
+ namespace mozilla {
+ namespace CanvasUtils {
+
+@@ -101,6 +110,60 @@ DoDrawImageSecurityCheck(nsHTMLCanvasElement *aCanvasElement,
+ aCanvasElement->SetWriteOnly();
+ }
+
++// Check site-specific permission and display prompt if appropriate.
++bool
++IsImageExtractionAllowed(nsIDocument *aDocument)
++{
++ if (!aDocument)
++ return false;
++
++ nsPIDOMWindow *win = aDocument->GetWindow();
++ nsCOMPtr<nsIScriptObjectPrincipal> sop(do_QueryInterface(win));
++ if (sop && nsContentUtils::IsSystemPrincipal(sop->GetPrincipal()))
++ return true;
++
++ bool isAllowed = false;
++ nsCOMPtr<mozIThirdPartyUtil> thirdPartyUtil =
++ do_GetService(THIRDPARTYUTIL_CONTRACTID);
++ nsCOMPtr<nsIPermissionManager> permissionManager =
++ do_GetService(NS_PERMISSIONMANAGER_CONTRACTID);
++ if (thirdPartyUtil && permissionManager) {
++ nsCOMPtr<nsIURI> uri;
++ nsresult rv = thirdPartyUtil->GetFirstPartyURI(NULL, aDocument,
++ getter_AddRefs(uri));
++ uint32_t permission = nsIPermissionManager::UNKNOWN_ACTION;
++ if (NS_SUCCEEDED(rv)) {
++ // Allow local files to access canvas data; check content permissions
++ // for remote pages.
++ bool isFileURL = false;
++ (void)uri->SchemeIs("file", &isFileURL);
++ if (isFileURL)
++ permission = nsIPermissionManager::ALLOW_ACTION;
++ else {
++ rv = permissionManager->TestPermission(uri,
++ PERMISSION_CANVAS_EXTRACT_DATA, &permission);
++ }
++ }
++
++ if (NS_SUCCEEDED(rv)) {
++ isAllowed = (permission == nsIPermissionManager::ALLOW_ACTION);
++
++ if (!isAllowed && (permission != nsIPermissionManager::DENY_ACTION)) {
++ // Send notification so that a prompt is displayed.
++ nsCString spec;
++ rv = uri->GetSpec(spec);
++ NS_ENSURE_SUCCESS(rv, rv);
++ nsCOMPtr<nsIObserverService> obs =
++ mozilla::services::GetObserverService();
++ obs->NotifyObservers(win, TOPIC_CANVAS_PERMISSIONS_PROMPT,
++ NS_ConvertUTF8toUTF16(spec).get());
++ }
++ }
++ }
++
++ return isAllowed;
++}
++
+ void
+ LogMessage (const nsCString& errorString)
+ {
+diff --git a/content/canvas/src/CanvasUtils.h b/content/canvas/src/CanvasUtils.h
+index 36186dd..067ee46 100644
+--- a/content/canvas/src/CanvasUtils.h
++++ b/content/canvas/src/CanvasUtils.h
+@@ -77,6 +77,8 @@ void DoDrawImageSecurityCheck(nsHTMLCanvasElement *aCanvasElement,
+ bool forceWriteOnly,
+ bool CORSUsed);
+
++bool IsImageExtractionAllowed(nsIDocument *aDocument);
++
+ void LogMessage (const nsCString& errorString);
+ void LogMessagef (const char *fmt, ...);
+
+diff --git a/content/canvas/src/nsCanvasRenderingContext2D.cpp b/content/canvas/src/nsCanvasRenderingContext2D.cpp
+index 36389b0..0cf97ce 100644
+--- a/content/canvas/src/nsCanvasRenderingContext2D.cpp
++++ b/content/canvas/src/nsCanvasRenderingContext2D.cpp
+@@ -3886,6 +3886,21 @@ nsCanvasRenderingContext2D::GetImageData_explicit(PRInt32 x, PRInt32 y, PRUint32
+ if (!rightMost.valid() || !bottomMost.valid())
+ return NS_ERROR_DOM_SYNTAX_ERR;
+
++ // Check for site-specific permission and return all-white, opaque pixel
++ // data if no permission. This check is not needed if the canvas was
++ // created with a docshell (that is only done for special internal uses).
++ bool usePlaceholder = false;
++ if (mCanvasElement) {
++ nsCOMPtr<nsIDocument> ownerDoc = HTMLCanvasElement()->OwnerDoc();
++ usePlaceholder = !ownerDoc ||
++ !CanvasUtils::IsImageExtractionAllowed(ownerDoc);
++ }
++
++ if (usePlaceholder) {
++ memset(aData, 0xFF, aDataLen);
++ return NS_OK;
++ }
++
+ /* Copy the surface contents to the buffer */
+ nsRefPtr<gfxImageSurface> tmpsurf =
+ new gfxImageSurface(aData,
+diff --git a/content/canvas/src/nsCanvasRenderingContext2DAzure.cpp b/content/canvas/src/nsCanvasRenderingContext2DAzure.cpp
+index 13baaa5..e8dfb1e 100644
+--- a/content/canvas/src/nsCanvasRenderingContext2DAzure.cpp
++++ b/content/canvas/src/nsCanvasRenderingContext2DAzure.cpp
+@@ -4038,6 +4038,21 @@ nsCanvasRenderingContext2DAzure::GetImageData_explicit(PRInt32 x, PRInt32 y, PRU
+ return NS_OK;
+ }
+
++ // Check for site-specific permission and return all-white, opaque pixel
++ // data if no permission. This check is not needed if the canvas was
++ // created with a docshell (that is only done for special internal uses).
++ bool usePlaceholder = false;
++ if (mCanvasElement) {
++ nsCOMPtr<nsIDocument> ownerDoc = HTMLCanvasElement()->OwnerDoc();
++ usePlaceholder = !ownerDoc ||
++ !CanvasUtils::IsImageExtractionAllowed(ownerDoc);
++ }
++
++ if (usePlaceholder) {
++ memset(aData, 0xFF, aDataLen);
++ return NS_OK;
++ }
++
+ IntRect srcRect(0, 0, mWidth, mHeight);
+ IntRect destRect(x, y, w, h);
+
+diff --git a/content/html/content/public/nsHTMLCanvasElement.h b/content/html/content/public/nsHTMLCanvasElement.h
+index 86202a8..66176f2 100644
+--- a/content/html/content/public/nsHTMLCanvasElement.h
++++ b/content/html/content/public/nsHTMLCanvasElement.h
+@@ -188,13 +188,16 @@ protected:
+ nsresult UpdateContext(nsIPropertyBag *aNewContextOptions = nsnull);
+ nsresult ExtractData(const nsAString& aType,
+ const nsAString& aOptions,
++ bool aUsePlaceholder,
+ nsIInputStream** aStream,
+ bool& aFellBackToPNG);
+ nsresult ToDataURLImpl(const nsAString& aMimeType,
+ nsIVariant* aEncoderOptions,
++ bool aUsePlaceholder,
+ nsAString& aDataURL);
+ nsresult MozGetAsFileImpl(const nsAString& aName,
+ const nsAString& aType,
++ bool aUsePlaceholder,
+ nsIDOMFile** aResult);
+ nsresult GetContextHelper(const nsAString& aContextId,
+ bool aForceThebes,
+diff --git a/content/html/content/src/Makefile.in b/content/html/content/src/Makefile.in
+index 019d297..3db4f7c 100644
+--- a/content/html/content/src/Makefile.in
++++ b/content/html/content/src/Makefile.in
+@@ -138,6 +138,7 @@ INCLUDES += \
+ -I$(srcdir)/../../../events/src \
+ -I$(srcdir)/../../../xbl/src \
+ -I$(srcdir)/../../../xul/content/src \
++ -I$(srcdir)/../../../canvas/src/ \
+ -I$(srcdir)/../../../../layout/forms \
+ -I$(srcdir)/../../../../layout/style \
+ -I$(srcdir)/../../../../layout/tables \
+diff --git a/content/html/content/src/nsHTMLCanvasElement.cpp b/content/html/content/src/nsHTMLCanvasElement.cpp
+index a302f67..572a81b 100644
+--- a/content/html/content/src/nsHTMLCanvasElement.cpp
++++ b/content/html/content/src/nsHTMLCanvasElement.cpp
+@@ -60,6 +60,8 @@
+
+ #include "nsIWritablePropertyBag2.h"
+
++#include "CanvasUtils.h"
++
+ #define DEFAULT_CANVAS_WIDTH 300
+ #define DEFAULT_CANVAS_HEIGHT 150
+
+@@ -213,25 +215,36 @@ nsHTMLCanvasElement::ToDataURL(const nsAString& aType, nsIVariant* aParams,
+ return NS_ERROR_DOM_SECURITY_ERR;
+ }
+
+- return ToDataURLImpl(aType, aParams, aDataURL);
++ // Check site-specific permission and display prompt if appropriate.
++ // If no permission, return all-white, opaque image data.
++ bool usePlaceholder = !CanvasUtils::IsImageExtractionAllowed(OwnerDoc());
++ return ToDataURLImpl(aType, aParams, usePlaceholder, aDataURL);
+ }
+
++// TODO: on FF trunk, we also need to patch mozFetchAsStream().
+ nsresult
+ nsHTMLCanvasElement::ExtractData(const nsAString& aType,
+ const nsAString& aOptions,
++ bool aUsePlaceholder,
+ nsIInputStream** aStream,
+ bool& aFellBackToPNG)
+ {
+ // note that if we don't have a current context, the spec says we're
+ // supposed to just return transparent black pixels of the canvas
+ // dimensions.
++ // If placeholder data was requested, return all-white, opaque image data.
+ nsRefPtr<gfxImageSurface> emptyCanvas;
+ nsIntSize size = GetWidthHeight();
+- if (!mCurrentContext) {
++ if (aUsePlaceholder || !mCurrentContext) {
+ emptyCanvas = new gfxImageSurface(gfxIntSize(size.width, size.height), gfxASurface::ImageFormatARGB32);
+ if (emptyCanvas->CairoStatus()) {
+ return NS_ERROR_INVALID_ARG;
+ }
++
++ if (aUsePlaceholder) {
++ int32_t dataSize = emptyCanvas->GetDataSize();
++ memset(emptyCanvas->Data(), 0xFF, dataSize);
++ }
+ }
+
+ nsresult rv;
+@@ -241,12 +254,13 @@ nsHTMLCanvasElement::ExtractData(const nsAString& aType,
+ NS_ConvertUTF16toUTF8 encoderType(aType);
+
+ try_again:
+- if (mCurrentContext) {
++ if (!aUsePlaceholder && mCurrentContext) {
+ rv = mCurrentContext->GetInputStream(encoderType.get(),
+ nsPromiseFlatString(aOptions).get(),
+ getter_AddRefs(imgStream));
+ } else {
+- // no context, so we have to encode the empty image we created above
++ // Using placeholder or we have no context: encode the empty/white image
++ // we created above.
+ nsCString enccid("@mozilla.org/image/encoder;2?type=");
+ enccid += encoderType;
+
+@@ -284,6 +298,7 @@ nsHTMLCanvasElement::ExtractData(const nsAString& aType,
+ nsresult
+ nsHTMLCanvasElement::ToDataURLImpl(const nsAString& aMimeType,
+ nsIVariant* aEncoderOptions,
++ bool aUsePlaceholder,
+ nsAString& aDataURL)
+ {
+ bool fallbackToPNG = false;
+@@ -339,13 +354,15 @@ nsHTMLCanvasElement::ToDataURLImpl(const nsAString& aMimeType,
+ }
+
+ nsCOMPtr<nsIInputStream> stream;
+- rv = ExtractData(type, params, getter_AddRefs(stream), fallbackToPNG);
++ rv = ExtractData(type, params, aUsePlaceholder,
++ getter_AddRefs(stream), fallbackToPNG);
+
+ // If there are unrecognized custom parse options, we should fall back to
+ // the default values for the encoder without any options at all.
+ if (rv == NS_ERROR_INVALID_ARG && usingCustomParseOptions) {
+ fallbackToPNG = false;
+- rv = ExtractData(type, EmptyString(), getter_AddRefs(stream), fallbackToPNG);
++ rv = ExtractData(type, EmptyString(), aUsePlaceholder,
++ getter_AddRefs(stream), fallbackToPNG);
+ }
+
+ NS_ENSURE_SUCCESS(rv, rv);
+@@ -376,19 +393,23 @@ nsHTMLCanvasElement::MozGetAsFile(const nsAString& aName,
+ return NS_ERROR_DOM_SECURITY_ERR;
+ }
+
+- return MozGetAsFileImpl(aName, aType, aResult);
++ // Check site-speciifc permission and display prompt if appropriate.
++ // If no permission, return all-white, opaque image data.
++ bool usePlaceholder = !CanvasUtils::IsImageExtractionAllowed(OwnerDoc());
++ return MozGetAsFileImpl(aName, aType, usePlaceholder, aResult);
+ }
+
+ nsresult
+ nsHTMLCanvasElement::MozGetAsFileImpl(const nsAString& aName,
+ const nsAString& aType,
++ bool aUsePlaceholder,
+ nsIDOMFile** aResult)
+ {
+ bool fallbackToPNG = false;
+
+ nsCOMPtr<nsIInputStream> stream;
+- nsresult rv = ExtractData(aType, EmptyString(), getter_AddRefs(stream),
+- fallbackToPNG);
++ nsresult rv = ExtractData(aType, EmptyString(), aUsePlaceholder,
++ getter_AddRefs(stream), fallbackToPNG);
+ NS_ENSURE_SUCCESS(rv, rv);
+
+ nsAutoString type(aType);
+--
+1.7.5.4
+
diff --git a/src/current-patches/firefox/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..6da9c72
--- /dev/null
+++ b/src/current-patches/firefox/0022-Return-client-window-coordinates-for-mouse-event-scr.patch
@@ -0,0 +1,43 @@
+From 74215e38ba60b74df59216122c4f2cc068e33216 Mon Sep 17 00:00:00 2001
+From: Kathleen Brade <brade(a)pearlcrescent.com>
+Date: Tue, 9 Oct 2012 11:13:45 -0400
+Subject: [PATCH 22/24] Return client window coordinates for mouse event
+ screenX/Y (for dragend, 0,0 is returned).
+
+---
+ content/events/src/nsDOMUIEvent.cpp | 15 +++++++++++++++
+ 1 files changed, 15 insertions(+), 0 deletions(-)
+
+diff --git a/content/events/src/nsDOMUIEvent.cpp b/content/events/src/nsDOMUIEvent.cpp
+index fe57f52..d641f0d 100644
+--- a/content/events/src/nsDOMUIEvent.cpp
++++ b/content/events/src/nsDOMUIEvent.cpp
+@@ -135,10 +135,25 @@ nsDOMUIEvent::GetScreenPoint()
+ return nsIntPoint(0, 0);
+ }
+
++ bool isChrome = nsContentUtils::IsCallerChrome();
++
+ if (!((nsGUIEvent*)mEvent)->widget ) {
++ // For non-chrome callers, return 0,0 if there is no widget associated
++ // with this event, e.g., for dragend events. Since dragend is for the
++ // drag originator and not for the receiver, it is probably not widely
++ // used (receivers get a drop event). Therefore, returning 0,0 should
++ // not break many web pages. Also, a few years ago Firefox returned 0,0.
++ // See: https://bugzilla.mozilla.org/show_bug.cgi?id=466379
++ if (!isChrome)
++ return nsIntPoint(0, 0);
++
+ return mEvent->refPoint;
+ }
+
++ // For non-chrome callers, return client area coordinates instead.
++ if (!isChrome)
++ return GetClientPoint();
++
+ nsIntPoint offset = mEvent->refPoint +
+ ((nsGUIEvent*)mEvent)->widget->WidgetToScreenOffset();
+ nscoord factor = mPresContext->DeviceContext()->UnscaledAppUnitsPerDevPixel();
+--
+1.7.5.4
+
diff --git a/src/current-patches/firefox/0023-Do-not-expose-physical-screen-info.-via-window-and-w.patch b/src/current-patches/firefox/0023-Do-not-expose-physical-screen-info.-via-window-and-w.patch
new file mode 100644
index 0000000..1b925e0
--- /dev/null
+++ b/src/current-patches/firefox/0023-Do-not-expose-physical-screen-info.-via-window-and-w.patch
@@ -0,0 +1,312 @@
+From d944531b020848e09ac280af11d039d992ab6461 Mon Sep 17 00:00:00 2001
+From: Kathleen Brade <brade(a)pearlcrescent.com>
+Date: Wed, 3 Oct 2012 17:06:48 -0400
+Subject: [PATCH 23/24] Do not expose physical screen info. via window and
+ window.screen.
+
+---
+ dom/base/nsGlobalWindow.cpp | 46 +++++++++++++++++++++
+ dom/base/nsGlobalWindow.h | 2 +
+ dom/base/nsScreen.cpp | 92 +++++++++++++++++++++++++++++++++++++++++++
+ dom/base/nsScreen.h | 3 +
+ 4 files changed, 143 insertions(+), 0 deletions(-)
+
+diff --git a/dom/base/nsGlobalWindow.cpp b/dom/base/nsGlobalWindow.cpp
+index 2c99571..982d931 100644
+--- a/dom/base/nsGlobalWindow.cpp
++++ b/dom/base/nsGlobalWindow.cpp
+@@ -3817,6 +3817,10 @@ nsGlobalWindow::GetOuterWidth(PRInt32* aOuterWidth)
+ {
+ FORWARD_TO_OUTER(GetOuterWidth, (aOuterWidth), NS_ERROR_NOT_INITIALIZED);
+
++ // For non-chrome callers, return inner width to prevent fingerprinting.
++ if (!IsChrome())
++ return GetInnerWidth(aOuterWidth);
++
+ nsIntSize sizeCSSPixels;
+ nsresult rv = GetOuterSize(&sizeCSSPixels);
+ NS_ENSURE_SUCCESS(rv, rv);
+@@ -3830,6 +3834,10 @@ nsGlobalWindow::GetOuterHeight(PRInt32* aOuterHeight)
+ {
+ FORWARD_TO_OUTER(GetOuterHeight, (aOuterHeight), NS_ERROR_NOT_INITIALIZED);
+
++ // For non-chrome callers, return inner height to prevent fingerprinting.
++ if (!IsChrome())
++ return GetInnerHeight(aOuterHeight);
++
+ nsIntSize sizeCSSPixels;
+ nsresult rv = GetOuterSize(&sizeCSSPixels);
+ NS_ENSURE_SUCCESS(rv, rv);
+@@ -3892,6 +3900,12 @@ nsGlobalWindow::GetScreenX(PRInt32* aScreenX)
+ {
+ FORWARD_TO_OUTER(GetScreenX, (aScreenX), NS_ERROR_NOT_INITIALIZED);
+
++ // For non-chrome callers, always return 0 to prevent fingerprinting.
++ if (!IsChrome()) {
++ *aScreenX = 0;
++ return NS_OK;
++ }
++
+ nsCOMPtr<nsIBaseWindow> treeOwnerAsWin;
+ GetTreeOwner(getter_AddRefs(treeOwnerAsWin));
+ NS_ENSURE_TRUE(treeOwnerAsWin, NS_ERROR_FAILURE);
+@@ -3933,6 +3947,12 @@ nsGlobalWindow::GetMozInnerScreenX(float* aScreenX)
+ {
+ FORWARD_TO_OUTER(GetMozInnerScreenX, (aScreenX), NS_ERROR_NOT_INITIALIZED);
+
++ // For non-chrome callers, always return 0 to prevent fingerprinting.
++ if (!IsChrome()) {
++ *aScreenX = 0;
++ return NS_OK;
++ }
++
+ nsRect r = GetInnerScreenRect();
+ *aScreenX = nsPresContext::AppUnitsToFloatCSSPixels(r.x);
+ return NS_OK;
+@@ -3943,6 +3963,12 @@ nsGlobalWindow::GetMozInnerScreenY(float* aScreenY)
+ {
+ FORWARD_TO_OUTER(GetMozInnerScreenY, (aScreenY), NS_ERROR_NOT_INITIALIZED);
+
++ // For non-chrome callers, always return 0 to prevent fingerprinting.
++ if (!IsChrome()) {
++ *aScreenY = 0;
++ return NS_OK;
++ }
++
+ nsRect r = GetInnerScreenRect();
+ *aScreenY = nsPresContext::AppUnitsToFloatCSSPixels(r.y);
+ return NS_OK;
+@@ -4064,6 +4090,12 @@ nsGlobalWindow::GetScreenY(PRInt32* aScreenY)
+ {
+ FORWARD_TO_OUTER(GetScreenY, (aScreenY), NS_ERROR_NOT_INITIALIZED);
+
++ // For non-chrome callers, always return 0 to prevent fingerprinting.
++ if (!IsChrome()) {
++ *aScreenY = 0;
++ return NS_OK;
++ }
++
+ nsCOMPtr<nsIBaseWindow> treeOwnerAsWin;
+ GetTreeOwner(getter_AddRefs(treeOwnerAsWin));
+ NS_ENSURE_TRUE(treeOwnerAsWin, NS_ERROR_FAILURE);
+@@ -4110,6 +4142,20 @@ nsGlobalWindow::SetScreenY(PRInt32 aScreenY)
+ return NS_OK;
+ }
+
++bool
++nsGlobalWindow::IsChrome()
++{
++ bool isChrome = false;
++
++ if (mDocShell) {
++ nsRefPtr<nsPresContext> presContext;
++ mDocShell->GetPresContext(getter_AddRefs(presContext));
++ isChrome = (presContext && presContext->IsChrome());
++ }
++
++ return isChrome;
++}
++
+ // NOTE: Arguments to this function should have values scaled to
+ // CSS pixels, not device pixels.
+ nsresult
+diff --git a/dom/base/nsGlobalWindow.h b/dom/base/nsGlobalWindow.h
+index 2ffe4a7..863329c 100644
+--- a/dom/base/nsGlobalWindow.h
++++ b/dom/base/nsGlobalWindow.h
+@@ -744,6 +744,8 @@ protected:
+ nsresult SetOuterSize(PRInt32 aLengthCSSPixels, bool aIsWidth);
+ nsRect GetInnerScreenRect();
+
++ bool IsChrome();
++
+ bool IsFrame()
+ {
+ return GetParentInternal() != nsnull;
+diff --git a/dom/base/nsScreen.cpp b/dom/base/nsScreen.cpp
+index 33a03dc..29a3598 100644
+--- a/dom/base/nsScreen.cpp
++++ b/dom/base/nsScreen.cpp
+@@ -82,6 +82,12 @@ nsScreen::SetDocShell(nsIDocShell* aDocShell)
+ NS_IMETHODIMP
+ nsScreen::GetTop(PRInt32* aTop)
+ {
++ // For non-chrome callers, always return 0 to prevent fingerprinting.
++ if (!IsChrome()) {
++ *aTop = 0;
++ return NS_OK;
++ }
++
+ nsRect rect;
+ nsresult rv = GetRect(rect);
+
+@@ -94,6 +100,12 @@ nsScreen::GetTop(PRInt32* aTop)
+ NS_IMETHODIMP
+ nsScreen::GetLeft(PRInt32* aLeft)
+ {
++ // For non-chrome callers, always return 0 to prevent fingerprinting.
++ if (!IsChrome()) {
++ *aLeft = 0;
++ return NS_OK;
++ }
++
+ nsRect rect;
+ nsresult rv = GetRect(rect);
+
+@@ -106,6 +118,14 @@ nsScreen::GetLeft(PRInt32* aLeft)
+ NS_IMETHODIMP
+ nsScreen::GetWidth(PRInt32* aWidth)
+ {
++ // For non-chrome callers, return content width to prevent fingerprinting.
++ if (!IsChrome()) {
++ nsCOMPtr<nsIDOMWindow> win;
++ nsresult rv = GetDOMWindow(getter_AddRefs(win));
++ NS_ENSURE_SUCCESS(rv, rv);
++ return win->GetInnerWidth(aWidth);
++ }
++
+ nsRect rect;
+ nsresult rv = GetRect(rect);
+
+@@ -117,6 +137,14 @@ nsScreen::GetWidth(PRInt32* aWidth)
+ NS_IMETHODIMP
+ nsScreen::GetHeight(PRInt32* aHeight)
+ {
++ // For non-chrome callers, return content height to prevent fingerprinting.
++ if (!IsChrome()) {
++ nsCOMPtr<nsIDOMWindow> win;
++ nsresult rv = GetDOMWindow(getter_AddRefs(win));
++ NS_ENSURE_SUCCESS(rv, rv);
++ return win->GetInnerHeight(aHeight);
++ }
++
+ nsRect rect;
+ nsresult rv = GetRect(rect);
+
+@@ -128,6 +156,12 @@ nsScreen::GetHeight(PRInt32* aHeight)
+ NS_IMETHODIMP
+ nsScreen::GetPixelDepth(PRInt32* aPixelDepth)
+ {
++ // For non-chrome callers, always return 24 to prevent fingerprinting.
++ if (!IsChrome()) {
++ *aPixelDepth = 24;
++ return NS_OK;
++ }
++
+ nsDeviceContext* context = GetDeviceContext();
+
+ if (!context) {
+@@ -153,6 +187,14 @@ nsScreen::GetColorDepth(PRInt32* aColorDepth)
+ NS_IMETHODIMP
+ nsScreen::GetAvailWidth(PRInt32* aAvailWidth)
+ {
++ // For non-chrome callers, return content width to prevent fingerprinting.
++ if (!IsChrome()) {
++ nsCOMPtr<nsIDOMWindow> win;
++ nsresult rv = GetDOMWindow(getter_AddRefs(win));
++ NS_ENSURE_SUCCESS(rv, rv);
++ return win->GetInnerWidth(aAvailWidth);
++ }
++
+ nsRect rect;
+ nsresult rv = GetAvailRect(rect);
+
+@@ -164,6 +206,14 @@ nsScreen::GetAvailWidth(PRInt32* aAvailWidth)
+ NS_IMETHODIMP
+ nsScreen::GetAvailHeight(PRInt32* aAvailHeight)
+ {
++ // For non-chrome callers, return content height to prevent fingerprinting.
++ if (!IsChrome()) {
++ nsCOMPtr<nsIDOMWindow> win;
++ nsresult rv = GetDOMWindow(getter_AddRefs(win));
++ NS_ENSURE_SUCCESS(rv, rv);
++ return win->GetInnerHeight(aAvailHeight);
++ }
++
+ nsRect rect;
+ nsresult rv = GetAvailRect(rect);
+
+@@ -175,6 +225,12 @@ nsScreen::GetAvailHeight(PRInt32* aAvailHeight)
+ NS_IMETHODIMP
+ nsScreen::GetAvailLeft(PRInt32* aAvailLeft)
+ {
++ // For non-chrome callers, always return 0 to prevent fingerprinting.
++ if (!IsChrome()) {
++ *aAvailLeft = 0;
++ return NS_OK;
++ }
++
+ nsRect rect;
+ nsresult rv = GetAvailRect(rect);
+
+@@ -186,6 +242,12 @@ nsScreen::GetAvailLeft(PRInt32* aAvailLeft)
+ NS_IMETHODIMP
+ nsScreen::GetAvailTop(PRInt32* aAvailTop)
+ {
++ // For non-chrome callers, always return 0 to prevent fingerprinting.
++ if (!IsChrome()) {
++ *aAvailTop = 0;
++ return NS_OK;
++ }
++
+ nsRect rect;
+ nsresult rv = GetAvailRect(rect);
+
+@@ -237,3 +299,33 @@ nsScreen::GetAvailRect(nsRect& aRect)
+
+ return NS_OK;
+ }
++
++bool
++nsScreen::IsChrome()
++{
++ bool isChrome = false;
++ if (mDocShell) {
++ nsRefPtr<nsPresContext> presContext;
++ mDocShell->GetPresContext(getter_AddRefs(presContext));
++ if (presContext)
++ isChrome = presContext->IsChrome();
++ }
++
++ return isChrome;
++}
++
++nsresult
++nsScreen::GetDOMWindow(nsIDOMWindow **aResult)
++{
++ NS_ENSURE_ARG_POINTER(aResult);
++ *aResult = NULL;
++
++ if (!mDocShell)
++ return NS_ERROR_FAILURE;
++
++ nsCOMPtr<nsIDOMWindow> win = do_GetInterface(mDocShell);
++ NS_ENSURE_STATE(win);
++ win.swap(*aResult);
++
++ return NS_OK;
++}
+diff --git a/dom/base/nsScreen.h b/dom/base/nsScreen.h
+index 52eab29..d4edaa3 100644
+--- a/dom/base/nsScreen.h
++++ b/dom/base/nsScreen.h
+@@ -44,6 +44,7 @@
+
+ class nsIDocShell;
+ class nsDeviceContext;
++class nsIDOMWindow;
+ struct nsRect;
+
+ // Script "screen" object
+@@ -62,6 +63,8 @@ protected:
+ nsDeviceContext* GetDeviceContext();
+ nsresult GetRect(nsRect& aRect);
+ nsresult GetAvailRect(nsRect& aRect);
++ bool IsChrome();
++ nsresult GetDOMWindow(nsIDOMWindow **aResult);
+
+ nsIDocShell* mDocShell; // Weak Reference
+ };
+--
+1.7.5.4
+
diff --git a/src/current-patches/firefox/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..629a759
--- /dev/null
+++ b/src/current-patches/firefox/0024-Do-not-expose-system-colors-to-CSS-or-canvas.patch
@@ -0,0 +1,537 @@
+From 38a469e05779315cb2990be60c13fb167812e54d Mon Sep 17 00:00:00 2001
+From: Kathleen Brade <brade(a)pearlcrescent.com>
+Date: Thu, 4 Oct 2012 14:53:13 -0400
+Subject: [PATCH 24/24] Do not expose system colors to CSS or canvas.
+
+---
+ content/canvas/src/nsCanvasRenderingContext2D.cpp | 36 +++-
+ .../canvas/src/nsCanvasRenderingContext2DAzure.cpp | 51 ++++--
+ layout/style/nsCSSParser.cpp | 19 ++-
+ layout/style/nsRuleNode.cpp | 4 +-
+ widget/public/LookAndFeel.h | 9 +
+ widget/src/xpwidgets/nsXPLookAndFeel.cpp | 173 +++++++++++++++++++-
+ widget/src/xpwidgets/nsXPLookAndFeel.h | 5 +-
+ 7 files changed, 269 insertions(+), 28 deletions(-)
+
+diff --git a/content/canvas/src/nsCanvasRenderingContext2D.cpp b/content/canvas/src/nsCanvasRenderingContext2D.cpp
+index 0cf97ce..6c47821 100644
+--- a/content/canvas/src/nsCanvasRenderingContext2D.cpp
++++ b/content/canvas/src/nsCanvasRenderingContext2D.cpp
+@@ -186,8 +186,9 @@ class nsCanvasGradient : public nsIDOMCanvasGradient
+ public:
+ NS_DECLARE_STATIC_IID_ACCESSOR(NS_CANVASGRADIENT_PRIVATE_IID)
+
+- nsCanvasGradient(gfxPattern* pat)
+- : mPattern(pat)
++ nsCanvasGradient(mozilla::css::Loader* aLoader, gfxPattern* pat)
++ : mCSSLoader(aLoader)
++ , mPattern(pat)
+ {
+ }
+
+@@ -203,7 +204,7 @@ public:
+ return NS_ERROR_DOM_INDEX_SIZE_ERR;
+
+ nscolor color;
+- nsCSSParser parser;
++ nsCSSParser parser(mCSSLoader);
+ nsresult rv = parser.ParseColorString(nsString(colorstr),
+ nsnull, 0, &color);
+ if (NS_FAILED(rv))
+@@ -217,6 +218,7 @@ public:
+ NS_DECL_ISUPPORTS
+
+ protected:
++ mozilla::css::Loader* mCSSLoader; // not ref counted, it owns us
+ nsRefPtr<gfxPattern> mPattern;
+ };
+
+@@ -875,7 +877,9 @@ nsCanvasRenderingContext2D::SetStyleFromStringOrInterface(const nsAString& aStr,
+ HTMLCanvasElement()->OwnerDoc() : nsnull;
+
+ // Pass the CSS Loader object to the parser, to allow parser error
+- // reports to include the outer window ID.
++ // reports to include the outer window ID. The parser also uses it to
++ // detect whether the caller is chrome in order to avoid exposing
++ // system colors.
+ nsCSSParser parser(document ? document->CSSLoader() : nsnull);
+ rv = parser.ParseColorString(aStr, nsnull, 0, &color);
+ if (NS_FAILED(rv)) {
+@@ -1778,7 +1782,14 @@ nsCanvasRenderingContext2D::CreateLinearGradient(float x0, float y0, float x1, f
+ if (!gradpat)
+ return NS_ERROR_OUT_OF_MEMORY;
+
+- nsRefPtr<nsIDOMCanvasGradient> grad = new nsCanvasGradient(gradpat);
++ // Pass the CSS Loader object to the parser, to allow parser error reports
++ // to include the outer window ID. The parser also uses it to detect
++ // whether the caller is chrome in order to avoid exposing system colors.
++ nsIDocument* doc = mCanvasElement ? HTMLCanvasElement()->OwnerDoc()
++ : nsnull;
++ mozilla::css::Loader* cssLoader = doc ? doc->CSSLoader() : nsnull;
++ nsRefPtr<nsIDOMCanvasGradient> grad = new nsCanvasGradient(cssLoader,
++ gradpat);
+ if (!grad)
+ return NS_ERROR_OUT_OF_MEMORY;
+
+@@ -1800,7 +1811,14 @@ nsCanvasRenderingContext2D::CreateRadialGradient(float x0, float y0, float r0, f
+ if (!gradpat)
+ return NS_ERROR_OUT_OF_MEMORY;
+
+- nsRefPtr<nsIDOMCanvasGradient> grad = new nsCanvasGradient(gradpat);
++ // Pass the CSS Loader object to the parser, to allow parser error reports
++ // to include the outer window ID. The parser also uses it to detect
++ // whether the caller is chrome in order to avoid exposing system colors.
++ nsIDocument* doc = mCanvasElement ? HTMLCanvasElement()->OwnerDoc()
++ : nsnull;
++ mozilla::css::Loader* cssLoader = doc ? doc->CSSLoader() : nsnull;
++ nsRefPtr<nsIDOMCanvasGradient> grad = new nsCanvasGradient(cssLoader,
++ gradpat);
+ if (!grad)
+ return NS_ERROR_OUT_OF_MEMORY;
+
+@@ -1922,7 +1940,8 @@ nsCanvasRenderingContext2D::SetShadowColor(const nsAString& colorstr)
+ HTMLCanvasElement()->OwnerDoc() : nsnull;
+
+ // Pass the CSS Loader object to the parser, to allow parser error reports
+- // to include the outer window ID.
++ // to include the outer window ID. The parser also uses it to detect
++ // whether the caller is chrome in order to avoid exposing system colors.
+ nsCSSParser parser(document ? document->CSSLoader() : nsnull);
+ nscolor color;
+ nsresult rv = parser.ParseColorString(colorstr, nsnull, 0, &color);
+@@ -3694,7 +3713,8 @@ nsCanvasRenderingContext2D::DrawWindow(nsIDOMWindow* aWindow, float aX, float aY
+ HTMLCanvasElement()->OwnerDoc() : nsnull;
+
+ // Pass the CSS Loader object to the parser, to allow parser error reports
+- // to include the outer window ID.
++ // to include the outer window ID. The parser also uses it to detect
++ // whether the caller is chrome in order to avoid exposing system colors.
+ nsCSSParser parser(elementDoc ? elementDoc->CSSLoader() : nsnull);
+ nsresult rv = parser.ParseColorString(PromiseFlatString(aBGColor),
+ nsnull, 0, &bgColor);
+diff --git a/content/canvas/src/nsCanvasRenderingContext2DAzure.cpp b/content/canvas/src/nsCanvasRenderingContext2DAzure.cpp
+index e8dfb1e..cb5a5f5 100644
+--- a/content/canvas/src/nsCanvasRenderingContext2DAzure.cpp
++++ b/content/canvas/src/nsCanvasRenderingContext2DAzure.cpp
+@@ -201,7 +201,10 @@ public:
+ }
+
+ nscolor color;
+- nsCSSParser parser;
++ // Pass the CSS Loader object to the parser, to allow parser error reports
++ // to include the outer window ID. The parser also uses it to detect
++ // whether the caller is chrome in order to avoid exposing system colors.
++ nsCSSParser parser(mCSSLoader);;
+ nsresult rv = parser.ParseColorString(nsString(colorstr),
+ nsnull, 0, &color);
+ if (NS_FAILED(rv)) {
+@@ -221,20 +224,24 @@ public:
+ }
+
+ protected:
+- nsCanvasGradientAzure(Type aType) : mType(aType)
++ nsCanvasGradientAzure(mozilla::css::Loader* aLoader, Type aType)
++ : mCSSLoader(aLoader)
++ , mType(aType)
+ {}
+
+ nsTArray<GradientStop> mRawStops;
+ RefPtr<GradientStops> mStops;
++ mozilla::css::Loader* mCSSLoader; // not ref counted, it owns us
+ Type mType;
+ };
+
+ class nsCanvasRadialGradientAzure : public nsCanvasGradientAzure
+ {
+ public:
+- nsCanvasRadialGradientAzure(const Point &aBeginOrigin, Float aBeginRadius,
++ nsCanvasRadialGradientAzure(mozilla::css::Loader* aLoader,
++ const Point &aBeginOrigin, Float aBeginRadius,
+ const Point &aEndOrigin, Float aEndRadius)
+- : nsCanvasGradientAzure(RADIAL)
++ : nsCanvasGradientAzure(aLoader, RADIAL)
+ , mCenter1(aBeginOrigin)
+ , mCenter2(aEndOrigin)
+ , mRadius1(aBeginRadius)
+@@ -251,8 +258,9 @@ public:
+ class nsCanvasLinearGradientAzure : public nsCanvasGradientAzure
+ {
+ public:
+- nsCanvasLinearGradientAzure(const Point &aBegin, const Point &aEnd)
+- : nsCanvasGradientAzure(LINEAR)
++ nsCanvasLinearGradientAzure(mozilla::css::Loader* aLoader,
++ const Point &aBegin, const Point &aEnd)
++ : nsCanvasGradientAzure(aLoader, LINEAR)
+ , mBegin(aBegin)
+ , mEnd(aEnd)
+ {
+@@ -1066,8 +1074,9 @@ nsCanvasRenderingContext2DAzure::SetStyleFromStringOrInterface(const nsAString&
+ nsIDocument* document = mCanvasElement ?
+ HTMLCanvasElement()->OwnerDoc() : nsnull;
+
+- // Pass the CSS Loader object to the parser, to allow parser error
+- // reports to include the outer window ID.
++ // Pass the CSS Loader object to the parser, to allow parser error reports
++ // to include the outer window ID. The parser also uses it to detect
++ // whether the caller is chrome in order to avoid exposing system colors.
+ nsCSSParser parser(document ? document->CSSLoader() : nsnull);
+ rv = parser.ParseColorString(aStr, nsnull, 0, &color);
+ if (NS_FAILED(rv)) {
+@@ -1855,8 +1864,14 @@ nsCanvasRenderingContext2DAzure::CreateLinearGradient(float x0, float y0, float
+ return NS_ERROR_DOM_NOT_SUPPORTED_ERR;
+ }
+
+- nsRefPtr<nsIDOMCanvasGradient> grad =
+- new nsCanvasLinearGradientAzure(Point(x0, y0), Point(x1, y1));
++ // Pass the CSS Loader object to the parser, to allow parser error reports
++ // to include the outer window ID. The parser also uses it to detect
++ // whether the caller is chrome in order to avoid exposing system colors.
++ nsIDocument* doc = mCanvasElement ? HTMLCanvasElement()->OwnerDoc()
++ : nsnull;
++ mozilla::css::Loader* cssLoader = doc ? doc->CSSLoader() : nsnull;
++ nsRefPtr<nsIDOMCanvasGradient> grad = new nsCanvasLinearGradientAzure(
++ cssLoader, Point(x0, y0), Point(x1, y1));
+
+ *_retval = grad.forget().get();
+ return NS_OK;
+@@ -1875,8 +1890,14 @@ nsCanvasRenderingContext2DAzure::CreateRadialGradient(float x0, float y0, float
+ return NS_ERROR_DOM_INDEX_SIZE_ERR;
+ }
+
+- nsRefPtr<nsIDOMCanvasGradient> grad =
+- new nsCanvasRadialGradientAzure(Point(x0, y0), r0, Point(x1, y1), r1);
++ // Pass the CSS Loader object to the parser, to allow parser error reports
++ // to include the outer window ID. The parser also uses it to detect
++ // whether the caller is chrome in order to avoid exposing system colors.
++ nsIDocument* doc = mCanvasElement ? HTMLCanvasElement()->OwnerDoc()
++ : nsnull;
++ mozilla::css::Loader* cssLoader = doc ? doc->CSSLoader() : nsnull;
++ nsRefPtr<nsIDOMCanvasGradient> grad = new nsCanvasRadialGradientAzure(
++ cssLoader, Point(x0, y0), r0, Point(x1, y1), r1);
+
+ *_retval = grad.forget().get();
+ return NS_OK;
+@@ -2024,7 +2045,8 @@ nsCanvasRenderingContext2DAzure::SetShadowColor(const nsAString& colorstr)
+ HTMLCanvasElement()->OwnerDoc() : nsnull;
+
+ // Pass the CSS Loader object to the parser, to allow parser error reports
+- // to include the outer window ID.
++ // to include the outer window ID. The parser also uses it to detect
++ // whether the caller is chrome in order to avoid exposing system colors.
+ nsCSSParser parser(document ? document->CSSLoader() : nsnull);
+ nscolor color;
+ nsresult rv = parser.ParseColorString(colorstr, nsnull, 0, &color);
+@@ -3847,7 +3869,8 @@ nsCanvasRenderingContext2DAzure::DrawWindow(nsIDOMWindow* aWindow, float aX, flo
+ HTMLCanvasElement()->OwnerDoc() : nsnull;
+
+ // Pass the CSS Loader object to the parser, to allow parser error reports
+- // to include the outer window ID.
++ // to include the outer window ID. The parser also uses it to detect
++ // whether the caller is chrome in order to avoid exposing system colors.
+ nsCSSParser parser(elementDoc ? elementDoc->CSSLoader() : nsnull);
+ nsresult rv = parser.ParseColorString(PromiseFlatString(aBGColor),
+ nsnull, 0, &bgColor);
+diff --git a/layout/style/nsCSSParser.cpp b/layout/style/nsCSSParser.cpp
+index ae1a474..30e179c 100644
+--- a/layout/style/nsCSSParser.cpp
++++ b/layout/style/nsCSSParser.cpp
+@@ -1216,8 +1216,25 @@ CSSParserImpl::ParseColorString(const nsSubstring& aBuffer,
+ // Should remove this limitation at some point.
+ return NS_ERROR_FAILURE;
+ }
++
++ // We do not want to expose system/native colors to content. All callers
++ // who are working with content should ensure that they set the CSS
++ // loader (mChildLoader) so we can check here if the content is chrome.
++ bool isChrome = true;
++ if (mChildLoader) {
++ nsIDocument *doc = mChildLoader->GetDocument();
++ if (doc) {
++ nsIPresShell *presShell = doc->GetShell();
++ if (presShell) {
++ nsPresContext* presCtxt = presShell->GetPresContext();
++ if (presCtxt)
++ isChrome = presCtxt->IsChrome();
++ }
++ }
++ }
+ nscolor rgba;
+- nsresult rv = LookAndFeel::GetColor(LookAndFeel::ColorID(val), &rgba);
++ nsresult rv = LookAndFeel::GetColor(LookAndFeel::ColorID(val), !isChrome,
++ &rgba);
+ if (NS_FAILED(rv)) {
+ return rv;
+ }
+diff --git a/layout/style/nsRuleNode.cpp b/layout/style/nsRuleNode.cpp
+index 827585a..d19524e 100644
+--- a/layout/style/nsRuleNode.cpp
++++ b/layout/style/nsRuleNode.cpp
+@@ -768,7 +768,9 @@ static bool SetColor(const nsCSSValue& aValue, const nscolor aParentColor,
+ PRInt32 intValue = aValue.GetIntValue();
+ if (0 <= intValue) {
+ LookAndFeel::ColorID colorID = (LookAndFeel::ColorID) intValue;
+- if (NS_SUCCEEDED(LookAndFeel::GetColor(colorID, &aResult))) {
++ bool useStandinsForNativeColors = !aPresContext->IsChrome();
++ if (NS_SUCCEEDED(LookAndFeel::GetColor(colorID,
++ useStandinsForNativeColors, &aResult))) {
+ result = true;
+ }
+ }
+diff --git a/widget/public/LookAndFeel.h b/widget/public/LookAndFeel.h
+index aae3b28..bb7be3c 100644
+--- a/widget/public/LookAndFeel.h
++++ b/widget/public/LookAndFeel.h
+@@ -445,6 +445,15 @@ public:
+ static nsresult GetColor(ColorID aID, nscolor* aResult);
+
+ /**
++ * This variant of GetColor() take an extra Boolean parameter that allows
++ * the caller to ask that hard-coded color values be substituted for
++ * native colors (used when it is desireable to hide system colors to
++ * avoid system fingerprinting).
++ */
++ static nsresult GetColor(ColorID aID, bool aUseStandinsForNativeColors,
++ nscolor* aResult);
++
++ /**
+ * GetInt() and GetFloat() return a int or float value for aID. The result
+ * might be distance, time, some flags or a int value which has particular
+ * meaning. See each document at definition of each ID for the detail.
+diff --git a/widget/src/xpwidgets/nsXPLookAndFeel.cpp b/widget/src/xpwidgets/nsXPLookAndFeel.cpp
+index 8053432..96937ac 100644
+--- a/widget/src/xpwidgets/nsXPLookAndFeel.cpp
++++ b/widget/src/xpwidgets/nsXPLookAndFeel.cpp
+@@ -502,6 +502,155 @@ nsXPLookAndFeel::IsSpecialColor(ColorID aID, nscolor &aColor)
+ return false;
+ }
+
++bool
++nsXPLookAndFeel::ColorIsNotCSSAccessible(ColorID aID)
++{
++ bool result = false;
++
++ switch (aID) {
++ case eColorID_WindowBackground:
++ case eColorID_WindowForeground:
++ case eColorID_WidgetBackground:
++ case eColorID_WidgetForeground:
++ case eColorID_WidgetSelectBackground:
++ case eColorID_WidgetSelectForeground:
++ case eColorID_Widget3DHighlight:
++ case eColorID_Widget3DShadow:
++ case eColorID_TextBackground:
++ case eColorID_TextForeground:
++ case eColorID_TextSelectBackground:
++ case eColorID_TextSelectForeground:
++ case eColorID_TextSelectBackgroundDisabled:
++ case eColorID_TextSelectBackgroundAttention:
++ case eColorID_TextHighlightBackground:
++ case eColorID_TextHighlightForeground:
++ case eColorID_IMERawInputBackground:
++ case eColorID_IMERawInputForeground:
++ case eColorID_IMERawInputUnderline:
++ case eColorID_IMESelectedRawTextBackground:
++ case eColorID_IMESelectedRawTextForeground:
++ case eColorID_IMESelectedRawTextUnderline:
++ case eColorID_IMEConvertedTextBackground:
++ case eColorID_IMEConvertedTextForeground:
++ case eColorID_IMEConvertedTextUnderline:
++ case eColorID_IMESelectedConvertedTextBackground:
++ case eColorID_IMESelectedConvertedTextForeground:
++ case eColorID_IMESelectedConvertedTextUnderline:
++ case eColorID_SpellCheckerUnderline:
++ result = true;
++ break;
++ default:
++ break;
++ }
++
++ return result;
++}
++
++nscolor
++nsXPLookAndFeel::GetStandinForNativeColor(ColorID aID)
++{
++ nscolor result = NS_RGB(0xFF, 0xFF, 0xFF);
++
++ // The stand-in colors are taken from the Windows 7 Aero theme
++ // except Mac-specific colors which are taken from Mac OS 10.7.
++ switch (aID) {
++ // CSS 2 colors:
++ case eColorID_activeborder: result = NS_RGB(0xB4, 0xB4, 0xB4); break;
++ case eColorID_activecaption: result = NS_RGB(0x99, 0xB4, 0xD1); break;
++ case eColorID_appworkspace: result = NS_RGB(0xAB, 0xAB, 0xAB); break;
++ case eColorID_background: result = NS_RGB(0x00, 0x00, 0x00); break;
++ case eColorID_buttonface: result = NS_RGB(0xF0, 0xF0, 0xF0); break;
++ case eColorID_buttonhighlight: result = NS_RGB(0xFF, 0xFF, 0xFF); break;
++ case eColorID_buttonshadow: result = NS_RGB(0xA0, 0xA0, 0xA0); break;
++ case eColorID_buttontext: result = NS_RGB(0x00, 0x00, 0x00); break;
++ case eColorID_captiontext: result = NS_RGB(0x00, 0x00, 0x00); break;
++ case eColorID_graytext: result = NS_RGB(0x6D, 0x6D, 0x6D); break;
++ case eColorID_highlight: result = NS_RGB(0x33, 0x99, 0xFF); break;
++ case eColorID_highlighttext: result = NS_RGB(0xFF, 0xFF, 0xFF); break;
++ case eColorID_inactiveborder: result = NS_RGB(0xF4, 0xF7, 0xFC); break;
++ case eColorID_inactivecaption: result = NS_RGB(0xBF, 0xCD, 0xDB); break;
++ case eColorID_inactivecaptiontext:
++ result = NS_RGB(0x43, 0x4E, 0x54); break;
++ case eColorID_infobackground: result = NS_RGB(0xFF, 0xFF, 0xE1); break;
++ case eColorID_infotext: result = NS_RGB(0x00, 0x00, 0x00); break;
++ case eColorID_menu: result = NS_RGB(0xF0, 0xF0, 0xF0); break;
++ case eColorID_menutext: result = NS_RGB(0x00, 0x00, 0x00); break;
++ case eColorID_scrollbar: result = NS_RGB(0xC8, 0xC8, 0xC8); break;
++ case eColorID_threeddarkshadow: result = NS_RGB(0x69, 0x69, 0x69); break;
++ case eColorID_threedface: result = NS_RGB(0xF0, 0xF0, 0xF0); break;
++ case eColorID_threedhighlight: result = NS_RGB(0xFF, 0xFF, 0xFF); break;
++ case eColorID_threedlightshadow: result = NS_RGB(0xE3, 0xE3, 0xE3); break;
++ case eColorID_threedshadow: result = NS_RGB(0xA0, 0xA0, 0xA0); break;
++ case eColorID_window: result = NS_RGB(0xFF, 0xFF, 0xFF); break;
++ case eColorID_windowframe: result = NS_RGB(0x64, 0x64, 0x64); break;
++ case eColorID_windowtext: result = NS_RGB(0x00, 0x00, 0x00); break;
++ case eColorID__moz_buttondefault:
++ result = NS_RGB(0x69, 0x69, 0x69); break;
++ case eColorID__moz_field: result = NS_RGB(0xFF, 0xFF, 0xFF); break;
++ case eColorID__moz_fieldtext: result = NS_RGB(0x00, 0x00, 0x00); break;
++ case eColorID__moz_dialog: result = NS_RGB(0xF0, 0xF0, 0xF0); break;
++ case eColorID__moz_dialogtext: result = NS_RGB(0x00, 0x00, 0x00); break;
++ case eColorID__moz_dragtargetzone:
++ result = NS_RGB(0xFF, 0xFF, 0xFF); break;
++ case eColorID__moz_cellhighlight:
++ result = NS_RGB(0xF0, 0xF0, 0xF0); break;
++ case eColorID__moz_cellhighlighttext:
++ result = NS_RGB(0x00, 0x00, 0x00); break;
++ case eColorID__moz_html_cellhighlight:
++ result = NS_RGB(0x33, 0x99, 0xFF); break;
++ case eColorID__moz_html_cellhighlighttext:
++ result = NS_RGB(0xFF, 0xFF, 0xFF); break;
++ case eColorID__moz_buttonhoverface:
++ result = NS_RGB(0xF0, 0xF0, 0xF0); break;
++ case eColorID__moz_buttonhovertext:
++ result = NS_RGB(0x00, 0x00, 0x00); break;
++ case eColorID__moz_menuhover:
++ result = NS_RGB(0x33, 0x99, 0xFF); break;
++ case eColorID__moz_menuhovertext:
++ result = NS_RGB(0x00, 0x00, 0x00); break;
++ case eColorID__moz_menubartext:
++ result = NS_RGB(0x00, 0x00, 0x00); break;
++ case eColorID__moz_menubarhovertext:
++ result = NS_RGB(0x00, 0x00, 0x00); break;
++ case eColorID__moz_oddtreerow:
++ result = NS_RGB(0xFF, 0xFF, 0xFF); break;
++ case eColorID__moz_mac_chrome_active:
++ result = NS_RGB(0xB2, 0xB2, 0xB2); break;
++ case eColorID__moz_mac_chrome_inactive:
++ result = NS_RGB(0xE1, 0xE1, 0xE1); break;
++ case eColorID__moz_mac_focusring:
++ result = NS_RGB(0x60, 0x9D, 0xD7); break;
++ case eColorID__moz_mac_menuselect:
++ result = NS_RGB(0x38, 0x75, 0xD7); break;
++ case eColorID__moz_mac_menushadow:
++ result = NS_RGB(0xA3, 0xA3, 0xA3); break;
++ case eColorID__moz_mac_menutextdisable:
++ result = NS_RGB(0x88, 0x88, 0x88); break;
++ case eColorID__moz_mac_menutextselect:
++ result = NS_RGB(0xFF, 0xFF, 0xFF); break;
++ case eColorID__moz_mac_disabledtoolbartext:
++ result = NS_RGB(0x3F, 0x3F, 0x3F); break;
++ case eColorID__moz_mac_alternateprimaryhighlight:
++ result = NS_RGB(0x38, 0x75, 0xD7); break;
++ case eColorID__moz_mac_secondaryhighlight:
++ result = NS_RGB(0xD4, 0xD4, 0xD4); break;
++ case eColorID__moz_win_mediatext:
++ result = NS_RGB(0xFF, 0xFF, 0xFF); break;
++ case eColorID__moz_win_communicationstext:
++ result = NS_RGB(0xFF, 0xFF, 0xFF); break;
++ case eColorID__moz_nativehyperlinktext:
++ result = NS_RGB(0x00, 0x66, 0xCC); break;
++ case eColorID__moz_comboboxtext:
++ result = NS_RGB(0x00, 0x00, 0x00); break;
++ case eColorID__moz_combobox:
++ result = NS_RGB(0xFF, 0xFF, 0xFF); break;
++ default:
++ break;
++ }
++
++ return result;
++}
++
+ //
+ // All these routines will return NS_OK if they have a value,
+ // in which case the nsLookAndFeel should use that value;
+@@ -509,7 +658,8 @@ nsXPLookAndFeel::IsSpecialColor(ColorID aID, nscolor &aColor)
+ // platform-specific nsLookAndFeel should use its own values instead.
+ //
+ nsresult
+-nsXPLookAndFeel::GetColorImpl(ColorID aID, nscolor &aResult)
++nsXPLookAndFeel::GetColorImpl(ColorID aID, bool aUseStandinsForNativeColors,
++ nscolor &aResult)
+ {
+ if (!sInitialized)
+ Init();
+@@ -595,7 +745,10 @@ nsXPLookAndFeel::GetColorImpl(ColorID aID, nscolor &aResult)
+ }
+ #endif // DEBUG_SYSTEM_COLOR_USE
+
+- if (IS_COLOR_CACHED(aID)) {
++ if (aUseStandinsForNativeColors && ColorIsNotCSSAccessible(aID))
++ aUseStandinsForNativeColors = false;
++
++ if (!aUseStandinsForNativeColors && IS_COLOR_CACHED(aID)) {
+ aResult = sCachedColors[aID];
+ return NS_OK;
+ }
+@@ -629,6 +782,12 @@ nsXPLookAndFeel::GetColorImpl(ColorID aID, nscolor &aResult)
+ return NS_OK;
+ }
+
++ if (sUseNativeColors && aUseStandinsForNativeColors)
++ {
++ aResult = GetStandinForNativeColor(aID);
++ return NS_OK;
++ }
++
+ if (sUseNativeColors && NS_SUCCEEDED(NativeGetColor(aID, aResult))) {
+ if ((gfxPlatform::GetCMSMode() == eCMSMode_All) &&
+ !IsSpecialColor(aID, aResult)) {
+@@ -719,7 +878,15 @@ namespace mozilla {
+ nsresult
+ LookAndFeel::GetColor(ColorID aID, nscolor* aResult)
+ {
+- return nsLookAndFeel::GetInstance()->GetColorImpl(aID, *aResult);
++ return nsLookAndFeel::GetInstance()->GetColorImpl(aID, false, *aResult);
++}
++
++nsresult
++LookAndFeel::GetColor(ColorID aID, bool aUseStandinsForNativeColors,
++ nscolor* aResult)
++{
++ return nsLookAndFeel::GetInstance()->GetColorImpl(aID,
++ aUseStandinsForNativeColors, *aResult);
+ }
+
+ // static
+diff --git a/widget/src/xpwidgets/nsXPLookAndFeel.h b/widget/src/xpwidgets/nsXPLookAndFeel.h
+index ce06575..c0ecc32 100644
+--- a/widget/src/xpwidgets/nsXPLookAndFeel.h
++++ b/widget/src/xpwidgets/nsXPLookAndFeel.h
+@@ -84,7 +84,8 @@ public:
+ // otherwise we'll return NS_ERROR_NOT_AVAILABLE, in which case, the
+ // platform-specific nsLookAndFeel should use its own values instead.
+ //
+- nsresult GetColorImpl(ColorID aID, nscolor &aResult);
++ nsresult GetColorImpl(ColorID aID, bool aUseStandinsForNativeColors,
++ nscolor &aResult);
+ virtual nsresult GetIntImpl(IntID aID, PRInt32 &aResult);
+ virtual nsresult GetFloatImpl(FloatID aID, float &aResult);
+
+@@ -111,6 +112,8 @@ protected:
+ void InitColorFromPref(PRInt32 aIndex);
+ virtual nsresult NativeGetColor(ColorID aID, nscolor &aResult) = 0;
+ bool IsSpecialColor(ColorID aID, nscolor &aColor);
++ bool ColorIsNotCSSAccessible(ColorID aID);
++ nscolor GetStandinForNativeColor(ColorID aID);
+
+ static int OnPrefChanged(const char* aPref, void* aClosure);
+
+--
+1.7.5.4
+
1
0

24 Oct '12
commit 9d2b5c639160349d6aa02cc28c7df58fcf1bcd16
Merge: 8ff89c0 f550eda
Author: Erinn Clark <erinn(a)torproject.org>
Date: Wed Oct 24 16:33:09 2012 +0100
Merge branch 'maint-2.2' into maint-2.3
build-scripts/config/prefs.js | 1 +
1 files changed, 1 insertions(+), 0 deletions(-)
1
0
commit 09ea4a73a71aa67f842bcdf845f1b7d9fc7ff4ff
Author: Erinn Clark <erinn(a)torproject.org>
Date: Wed Oct 24 16:34:03 2012 +0100
update recommended-versions
---
build-scripts/recommended-versions | 18 +++++++++---------
1 files changed, 9 insertions(+), 9 deletions(-)
diff --git a/build-scripts/recommended-versions b/build-scripts/recommended-versions
index c252fbb..a63051a 100644
--- a/build-scripts/recommended-versions
+++ b/build-scripts/recommended-versions
@@ -1,11 +1,11 @@
[
-"2.2.39-3-MacOS-i386",
-"2.2.39-3-MacOS-x86_64",
-"2.2.39-3-Windows",
-"2.2.39-3-Linux-i686",
-"2.2.39-3-Linux-x86_64",
-"2.3.22-alpha-1-MacOS-i386",
-"2.3.22-alpha-1-Windows",
-"2.3.22-alpha-1-Linux-i386",
-"2.3.22-alpha-1-Linux-x86_64"
+"2.2.39-4-MacOS-i386",
+"2.2.39-4-MacOS-x86_64",
+"2.2.39-4-Windows",
+"2.2.39-4-Linux-i686",
+"2.2.39-4-Linux-x86_64",
+"2.3.23-alpha-1-MacOS-i386",
+"2.3.23-alpha-1-Windows",
+"2.3.23-alpha-1-Linux-i386",
+"2.3.23-alpha-1-Linux-x86_64"
]
1
0

24 Oct '12
commit 41056c205ca5628ad746570c6b23bec4f4533fe7
Merge: 9d2b5c6 09ea4a7
Author: Erinn Clark <erinn(a)torproject.org>
Date: Wed Oct 24 16:34:16 2012 +0100
Merge branch 'maint-2.2' into maint-2.3
build-scripts/recommended-versions | 18 +++++++++---------
1 files changed, 9 insertions(+), 9 deletions(-)
1
0