tor-commits
Threads by month
- ----- 2025 -----
- 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
August 2020
- 18 participants
- 1961 discussions

[tor-browser/tor-browser-80.0b2-10.0-1] fixup! TB4: Tor Browser's Firefox preference overrides.
by gk@torproject.org 17 Aug '20
by gk@torproject.org 17 Aug '20
17 Aug '20
commit 0e694a667dd14ea86857f89dd48c18ce94a5eb07
Author: Alex Catarineu <acat(a)torproject.org>
Date: Mon Aug 17 14:32:26 2020 +0200
fixup! TB4: Tor Browser's Firefox preference overrides.
---
browser/app/profile/000-tor-browser.js | 12 ++++++------
1 file changed, 6 insertions(+), 6 deletions(-)
diff --git a/browser/app/profile/000-tor-browser.js b/browser/app/profile/000-tor-browser.js
index 4990c3e4e3db..7e29c788b720 100644
--- a/browser/app/profile/000-tor-browser.js
+++ b/browser/app/profile/000-tor-browser.js
@@ -340,12 +340,6 @@ pref("browser.download.panel.shown", true);
// Treat .onions as secure
pref("dom.securecontext.whitelist_onions", true);
-// Onboarding.
-pref("browser.onboarding.tourset-version", 5);
-pref("browser.onboarding.newtour", "welcome,privacy,tor-network-9.0,circuit-display,security,expect-differences,onion-services,learn-more");
-pref("browser.onboarding.updatetour", "learn-more");
-pref("browser.onboarding.skip-tour-button.hide", true);
-
// Disable special URL bar behaviors
pref("browser.urlbar.suggest.topsites", false);
pref("browser.urlbar.update1.interventions", false);
@@ -355,6 +349,12 @@ pref("browser.urlbar.update1.searchTips", false);
// is only reported via telemetry (which is disabled).
pref("corroborator.enabled", false);
+// Onboarding.
+pref("browser.onboarding.tourset-version", 5);
+pref("browser.onboarding.newtour", "welcome,privacy,tor-network-9.0,circuit-display,security,expect-differences,onion-services,learn-more");
+pref("browser.onboarding.updatetour", "learn-more");
+pref("browser.onboarding.skip-tour-button.hide", true);
+
// prefs to disable jump-list entries in the taskbar on Windows (see bug #12885)
#ifdef XP_WIN
// this pref changes the app's set AUMID to be dependent on the profile path, rather than
1
0

[tor-browser/tor-browser-80.0b2-10.0-1] fixup! Bug 10760: Integrate TorButton to TorBrowser core
by gk@torproject.org 17 Aug '20
by gk@torproject.org 17 Aug '20
17 Aug '20
commit d9e55f2c6a7856976dbaf8ad48cf1d9f047b28cc
Author: Georg Koppen <gk(a)torproject.org>
Date: Mon Aug 17 12:58:28 2020 +0000
fixup! Bug 10760: Integrate TorButton to TorBrowser core
---
toolkit/torproject/torbutton | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/toolkit/torproject/torbutton b/toolkit/torproject/torbutton
index f55f5953c6ad..3dc1c58d6c49 160000
--- a/toolkit/torproject/torbutton
+++ b/toolkit/torproject/torbutton
@@ -1 +1 @@
-Subproject commit f55f5953c6adb6d75cad74fbb6c3b8fa2d617004
+Subproject commit 3dc1c58d6c494eeb5514ad84831b76661667ba2c
1
0

[tor-browser/tor-browser-80.0b2-10.0-1] Bug 40073: Disable remote Public Suffix List fetching
by gk@torproject.org 17 Aug '20
by gk@torproject.org 17 Aug '20
17 Aug '20
commit b912971d2367801ad7861e5cce8aaf4f35e1fba5
Author: Alex Catarineu <acat(a)torproject.org>
Date: Thu Aug 13 11:05:03 2020 +0200
Bug 40073: Disable remote Public Suffix List fetching
In https://bugzilla.mozilla.org/show_bug.cgi?id=1563246 Firefox implemented
fetching the Public Suffix List via RemoteSettings and replacing the default
one at runtime, which we do not want.
---
browser/components/BrowserGlue.jsm | 5 -----
1 file changed, 5 deletions(-)
diff --git a/browser/components/BrowserGlue.jsm b/browser/components/BrowserGlue.jsm
index f0b5a2f47ce1..21408e0413e9 100644
--- a/browser/components/BrowserGlue.jsm
+++ b/browser/components/BrowserGlue.jsm
@@ -740,7 +740,6 @@ XPCOMUtils.defineLazyModuleGetters(this, {
PluralForm: "resource://gre/modules/PluralForm.jsm",
PrivateBrowsingUtils: "resource://gre/modules/PrivateBrowsingUtils.jsm",
ProcessHangMonitor: "resource:///modules/ProcessHangMonitor.jsm",
- PublicSuffixList: "resource://gre/modules/netwerk-dns/PublicSuffixList.jsm",
RemoteSettings: "resource://services-settings/remote-settings.js",
RemoteSecuritySettings:
"resource://gre/modules/psm/RemoteSecuritySettings.jsm",
@@ -2642,10 +2641,6 @@ BrowserGlue.prototype = {
this._addBreachesSyncHandler();
},
- () => {
- PublicSuffixList.init();
- },
-
() => {
RemoteSecuritySettings.init();
},
1
0

[tor-browser/tor-browser-80.0b2-10.0-1] squash! Bug 31740: Remove some unnecessary RemoteSettings instances
by gk@torproject.org 17 Aug '20
by gk@torproject.org 17 Aug '20
17 Aug '20
commit 0439119ccb36ed1277465f7370ec65de37f986f3
Author: Alex Catarineu <acat(a)torproject.org>
Date: Wed Aug 5 22:53:46 2020 +0200
squash! Bug 31740: Remove some unnecessary RemoteSettings instances
Avoid creating instance for 'anti-tracking-url-decoration'.
If prefs are disabling their usage, avoid creating instances for
'cert-revocations' and 'intermediates'.
Do not ship JSON dumps for collections we do not expect to need. For
the ones in the 'main' bucket, this prevents them from being synced
unnecessarily (the code in remote-settings does so for collections
in the main bucket for which a dump or local data exists). For the
collections in the other buckets, we just save some size by not
shipping their dumps.
We also clear the collections database on the v2 -> v3 migration.
---
security/manager/ssl/RemoteSecuritySettings.jsm | 22 ++++++++++++++++++++++
services/settings/IDBHelpers.jsm | 4 ++++
services/settings/dumps/blocklists/moz.build | 8 +-------
services/settings/dumps/main/moz.build | 5 -----
services/settings/dumps/security-state/moz.build | 1 -
.../components/antitracking/antitracking.manifest | 2 +-
toolkit/components/antitracking/components.conf | 7 -------
7 files changed, 28 insertions(+), 21 deletions(-)
diff --git a/security/manager/ssl/RemoteSecuritySettings.jsm b/security/manager/ssl/RemoteSecuritySettings.jsm
index 3fedd43ed9be..fd2b69bc6a4f 100644
--- a/security/manager/ssl/RemoteSecuritySettings.jsm
+++ b/security/manager/ssl/RemoteSecuritySettings.jsm
@@ -350,6 +350,16 @@ var RemoteSecuritySettings = {
class IntermediatePreloads {
constructor() {
+ this.maybeInit();
+ }
+
+ maybeInit() {
+ if (
+ this.client ||
+ !Services.prefs.getBoolPref(INTERMEDIATES_ENABLED_PREF, true)
+ ) {
+ return;
+ }
this.client = RemoteSettings(
Services.prefs.getCharPref(INTERMEDIATES_COLLECTION_PREF),
{
@@ -379,6 +389,7 @@ class IntermediatePreloads {
);
return;
}
+ this.maybeInit();
// Download attachments that are awaiting download, up to a max.
const maxDownloadsPerRun = Services.prefs.getIntPref(
@@ -709,6 +720,16 @@ function compareFilters(filterA, filterB) {
class CRLiteFilters {
constructor() {
+ this.maybeInit();
+ }
+
+ maybeInit() {
+ if (
+ this.client ||
+ !Services.prefs.getBoolPref(CRLITE_FILTERS_ENABLED_PREF, true)
+ ) {
+ return;
+ }
this.client = RemoteSettings(
Services.prefs.getCharPref(CRLITE_FILTERS_COLLECTION_PREF),
{
@@ -734,6 +755,7 @@ class CRLiteFilters {
);
return;
}
+ this.maybeInit();
let current = await this.client.db.list();
let fullFilters = current.filter(filter => !filter.incremental);
if (fullFilters.length < 1) {
diff --git a/services/settings/IDBHelpers.jsm b/services/settings/IDBHelpers.jsm
index 5dc59c3687ef..010a5ea82987 100644
--- a/services/settings/IDBHelpers.jsm
+++ b/services/settings/IDBHelpers.jsm
@@ -188,6 +188,10 @@ async function openIDB(allowUpgrades = true) {
});
}
if (event.oldVersion < 3) {
+ // Clear existing stores for a fresh start
+ transaction.objectStore("records").clear();
+ transaction.objectStore("timestamps").clear();
+ transaction.objectStore("collections").clear();
// Attachment store
db.createObjectStore("attachments", {
keyPath: ["cid", "attachmentId"],
diff --git a/services/settings/dumps/blocklists/moz.build b/services/settings/dumps/blocklists/moz.build
index 1683ab6aafa4..3ba9ba4980a8 100644
--- a/services/settings/dumps/blocklists/moz.build
+++ b/services/settings/dumps/blocklists/moz.build
@@ -8,15 +8,9 @@ with Files('**'):
BUG_COMPONENT = ('Toolkit', 'Blocklist Implementation')
# The addons blocklist is also in mobile/android/installer/package-manifest.in
-FINAL_TARGET_FILES.defaults.settings.blocklists += ['addons-bloomfilters.json',
- 'addons.json',
+FINAL_TARGET_FILES.defaults.settings.blocklists += ['addons.json',
'gfx.json',
'plugins.json']
-FINAL_TARGET_FILES.defaults.settings.blocklists['addons-bloomfilters'] += [
- 'addons-bloomfilters/addons-mlbf.bin',
- 'addons-bloomfilters/addons-mlbf.bin.meta.json'
-]
-
if CONFIG['MOZ_BUILD_APP'] == 'browser':
DIST_SUBDIR = 'browser'
diff --git a/services/settings/dumps/main/moz.build b/services/settings/dumps/main/moz.build
index 3628fa00b5e6..e25fc4214042 100644
--- a/services/settings/dumps/main/moz.build
+++ b/services/settings/dumps/main/moz.build
@@ -3,15 +3,10 @@
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
FINAL_TARGET_FILES.defaults.settings.main += [
- 'anti-tracking-url-decoration.json',
'example.json',
'hijack-blocklists.json',
'language-dictionaries.json',
- 'onboarding.json',
- 'search-config.json',
'search-default-override-allowlist.json',
- 'sites-classification.json',
- 'url-classifier-skip-urls.json',
]
if CONFIG['MOZ_BUILD_APP'] == 'browser':
diff --git a/services/settings/dumps/security-state/moz.build b/services/settings/dumps/security-state/moz.build
index d8f8227a0278..37410d0fb054 100644
--- a/services/settings/dumps/security-state/moz.build
+++ b/services/settings/dumps/security-state/moz.build
@@ -3,7 +3,6 @@
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
FINAL_TARGET_FILES.defaults.settings['security-state'] += [
- 'intermediates.json',
'onecrl.json',
]
diff --git a/toolkit/components/antitracking/antitracking.manifest b/toolkit/components/antitracking/antitracking.manifest
index 5eb37f9a3f99..872e6af07575 100644
--- a/toolkit/components/antitracking/antitracking.manifest
+++ b/toolkit/components/antitracking/antitracking.manifest
@@ -1 +1 @@
-category profile-after-change URLDecorationAnnotationsService @mozilla.org/tracking-url-decoration-service;1 process=main
+# category profile-after-change URLDecorationAnnotationsService @mozilla.org/tracking-url-decoration-service;1 process=main
diff --git a/toolkit/components/antitracking/components.conf b/toolkit/components/antitracking/components.conf
index 74a8a21277d9..04b2ba1b815f 100644
--- a/toolkit/components/antitracking/components.conf
+++ b/toolkit/components/antitracking/components.conf
@@ -11,13 +11,6 @@ Classes = [
'jsm': 'resource://gre/modules/TrackingDBService.jsm',
'constructor': 'TrackingDBService',
},
- {
- 'cid': '{5874af6d-5719-4e1b-b155-ef4eae7fcb32}',
- 'contract_ids': ['@mozilla.org/tracking-url-decoration-service;1'],
- 'jsm': 'resource://gre/modules/URLDecorationAnnotationsService.jsm',
- 'constructor': 'URLDecorationAnnotationsService',
- 'processes': ProcessSelector.MAIN_PROCESS_ONLY,
- },
{
'cid': '{90d1fd17-2018-4e16-b73c-a04a26fa6dd4}',
'contract_ids': ['@mozilla.org/purge-tracker-service;1'],
1
0

[tor-browser/tor-browser-80.0b2-10.0-1] Bug 19273: Avoid JavaScript patching of the external app helper dialog.
by gk@torproject.org 17 Aug '20
by gk@torproject.org 17 Aug '20
17 Aug '20
commit 2d1d8739503a8ef795928088381455cb8f2e8ef1
Author: Kathy Brade <brade(a)pearlcrescent.com>
Date: Tue Jun 28 15:13:05 2016 -0400
Bug 19273: Avoid JavaScript patching of the external app helper dialog.
When handling an external URI or downloading a file, invoke Torbutton's
external app blocker component (which will present a download warning
dialog unless the user has checked the "Automatically download files
from now on" box).
For e10s compatibility, avoid using a modal dialog and instead use
a callback interface (nsIHelperAppWarningLauncher) to allow Torbutton
to indicate the user's desire to cancel or continue each request.
Other bugs fixed:
Bug 21766: Crash with e10s enabled while trying to download a file
Bug 21886: Download is stalled in non-e10s mode
Bug 22471: Downloading files via the PDF viewer download button is broken
Bug 22472: Fix FTP downloads when external helper app dialog is shown
Bug 22610: Avoid crashes when canceling external helper app downloads
Bug 22618: Downloading pdf file via file:/// is stalling
---
.../exthandler/nsExternalHelperAppService.cpp | 207 +++++++++++++++++----
uriloader/exthandler/nsExternalHelperAppService.h | 3 +
.../exthandler/nsIExternalHelperAppService.idl | 47 +++++
3 files changed, 222 insertions(+), 35 deletions(-)
diff --git a/uriloader/exthandler/nsExternalHelperAppService.cpp b/uriloader/exthandler/nsExternalHelperAppService.cpp
index 0ef1af1ffef7..c0f8e5bde0ce 100644
--- a/uriloader/exthandler/nsExternalHelperAppService.cpp
+++ b/uriloader/exthandler/nsExternalHelperAppService.cpp
@@ -133,6 +133,9 @@ static const char NEVER_ASK_FOR_SAVE_TO_DISK_PREF[] =
static const char NEVER_ASK_FOR_OPEN_FILE_PREF[] =
"browser.helperApps.neverAsk.openFile";
+static const char WARNING_DIALOG_CONTRACT_ID[] =
+ "@torproject.org/torbutton-extAppBlocker;1";
+
// Helper functions for Content-Disposition headers
/**
@@ -389,6 +392,22 @@ static nsresult GetDownloadDirectory(nsIFile** _directory,
return NS_OK;
}
+static already_AddRefed<nsIInterfaceRequestor> GetDialogParentAux(
+ BrowsingContext* aBrowsingContext, nsIInterfaceRequestor* aWindowContext) {
+ nsCOMPtr<nsIInterfaceRequestor> dialogParent = aWindowContext;
+
+ if (!dialogParent && aBrowsingContext) {
+ dialogParent = do_QueryInterface(aBrowsingContext->GetDOMWindow());
+ }
+ if (!dialogParent && aBrowsingContext && XRE_IsParentProcess()) {
+ RefPtr<Element> element = aBrowsingContext->Top()->GetEmbedderElement();
+ if (element) {
+ dialogParent = do_QueryInterface(element->OwnerDoc()->GetWindow());
+ }
+ }
+ return dialogParent.forget();
+}
+
/**
* Structure for storing extension->type mappings.
* @see defaultMimeEntries
@@ -545,6 +564,111 @@ static const nsDefaultMimeTypeEntry nonDecodableExtensions[] = {
{APPLICATION_COMPRESS, "z"},
{APPLICATION_GZIP, "svgz"}};
+//////////////////////////////////////////////////////////////////////////////////////////////////////
+// begin nsExternalLoadURIHandler class definition and implementation
+//////////////////////////////////////////////////////////////////////////////////////////////////////
+class nsExternalLoadURIHandler final : public nsIHelperAppWarningLauncher {
+ public:
+ NS_DECL_THREADSAFE_ISUPPORTS
+ NS_DECL_NSIHELPERAPPWARNINGLAUNCHER
+
+ nsExternalLoadURIHandler(nsIHandlerInfo* aHandlerInfo, nsIURI* aURI,
+ nsIPrincipal* aTriggeringPrincipal,
+ BrowsingContext* aBrowsingContext);
+
+ protected:
+ ~nsExternalLoadURIHandler();
+
+ nsCOMPtr<nsIHandlerInfo> mHandlerInfo;
+ nsCOMPtr<nsIURI> mURI;
+ nsCOMPtr<nsIPrincipal> mTriggeringPrincipal;
+ RefPtr<BrowsingContext> mBrowsingContext;
+ nsCOMPtr<nsIHelperAppWarningDialog> mWarningDialog;
+};
+
+NS_IMPL_ADDREF(nsExternalLoadURIHandler)
+NS_IMPL_RELEASE(nsExternalLoadURIHandler)
+
+NS_INTERFACE_MAP_BEGIN(nsExternalLoadURIHandler)
+ NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIHelperAppWarningLauncher)
+ NS_INTERFACE_MAP_ENTRY(nsIHelperAppWarningLauncher)
+NS_INTERFACE_MAP_END
+
+nsExternalLoadURIHandler::nsExternalLoadURIHandler(
+ nsIHandlerInfo* aHandlerInfo, nsIURI* aURI,
+ nsIPrincipal* aTriggeringPrincipal, BrowsingContext* aBrowsingContext)
+ : mHandlerInfo(aHandlerInfo),
+ mURI(aURI),
+ mTriggeringPrincipal(aTriggeringPrincipal),
+ mBrowsingContext(aBrowsingContext)
+
+{
+ nsresult rv = NS_OK;
+ mWarningDialog = do_CreateInstance(WARNING_DIALOG_CONTRACT_ID, &rv);
+ if (NS_SUCCEEDED(rv) && mWarningDialog) {
+ // This will create a reference cycle (the dialog holds a reference to us
+ // as nsIHelperAppWarningLauncher), which will be broken in ContinueRequest
+ // or CancelRequest.
+ nsCOMPtr<nsIInterfaceRequestor> dialogParent =
+ GetDialogParentAux(aBrowsingContext, nullptr);
+ rv = mWarningDialog->MaybeShow(this, dialogParent);
+ }
+
+ if (NS_FAILED(rv)) {
+ // If for some reason we could not open the download warning prompt,
+ // continue with the request.
+ ContinueRequest();
+ }
+}
+
+nsExternalLoadURIHandler::~nsExternalLoadURIHandler() {}
+
+NS_IMETHODIMP nsExternalLoadURIHandler::ContinueRequest() {
+ MOZ_ASSERT(mURI);
+ MOZ_ASSERT(mHandlerInfo);
+
+ // Break our reference cycle with the download warning dialog (set up in
+ // LoadURI).
+ mWarningDialog = nullptr;
+
+ nsHandlerInfoAction preferredAction;
+ mHandlerInfo->GetPreferredAction(&preferredAction);
+ bool alwaysAsk = true;
+ mHandlerInfo->GetAlwaysAskBeforeHandling(&alwaysAsk);
+
+ nsresult rv = NS_OK;
+ // If we are not supposed to ask, and the preferred action is to use
+ // a helper app or the system default, we just launch the URI.
+ if (!alwaysAsk && (preferredAction == nsIHandlerInfo::useHelperApp ||
+ preferredAction == nsIHandlerInfo::useSystemDefault)) {
+ rv = mHandlerInfo->LaunchWithURI(mURI, mBrowsingContext);
+ // We are not supposed to ask, but when file not found the user most likely
+ // uninstalled the application which handles the uri so we will continue
+ // by application chooser dialog.
+ if (rv != NS_ERROR_FILE_NOT_FOUND) {
+ return rv;
+ }
+ }
+
+ nsCOMPtr<nsIContentDispatchChooser> chooser =
+ do_CreateInstance("@mozilla.org/content-dispatch-chooser;1", &rv);
+ NS_ENSURE_SUCCESS(rv, rv);
+
+ return chooser->Ask(mHandlerInfo, mURI, mTriggeringPrincipal,
+ mBrowsingContext,
+ nsIContentDispatchChooser::REASON_CANNOT_HANDLE);
+}
+
+NS_IMETHODIMP nsExternalLoadURIHandler::CancelRequest(nsresult aReason) {
+ NS_ENSURE_ARG(NS_FAILED(aReason));
+
+ // Break our reference cycle with the download warning dialog (set up in
+ // LoadURI).
+ mWarningDialog = nullptr;
+
+ return NS_OK;
+}
+
static StaticRefPtr<nsExternalHelperAppService> sExtHelperAppSvcSingleton;
/**
@@ -571,6 +695,9 @@ nsExternalHelperAppService::GetSingleton() {
return do_AddRef(sExtHelperAppSvcSingleton);
}
+//////////////////////////////////////////////////////////////////////////////////////////////////////
+// nsExternalHelperAppService definition and implementation
+//////////////////////////////////////////////////////////////////////////////////////////////////////
NS_IMPL_ISUPPORTS(nsExternalHelperAppService, nsIExternalHelperAppService,
nsPIExternalAppLauncher, nsIExternalProtocolService,
nsIMIMEService, nsIObserver, nsISupportsWeakReference)
@@ -1016,30 +1143,13 @@ nsExternalHelperAppService::LoadURI(nsIURI* aURI,
rv = GetProtocolHandlerInfo(scheme, getter_AddRefs(handler));
NS_ENSURE_SUCCESS(rv, rv);
- nsHandlerInfoAction preferredAction;
- handler->GetPreferredAction(&preferredAction);
- bool alwaysAsk = true;
- handler->GetAlwaysAskBeforeHandling(&alwaysAsk);
-
- // if we are not supposed to ask, and the preferred action is to use
- // a helper app or the system default, we just launch the URI.
- if (!alwaysAsk && (preferredAction == nsIHandlerInfo::useHelperApp ||
- preferredAction == nsIHandlerInfo::useSystemDefault)) {
- rv = handler->LaunchWithURI(uri, aBrowsingContext);
- // We are not supposed to ask, but when file not found the user most likely
- // uninstalled the application which handles the uri so we will continue
- // by application chooser dialog.
- if (rv != NS_ERROR_FILE_NOT_FOUND) {
- return rv;
- }
+ RefPtr<nsExternalLoadURIHandler> h = new nsExternalLoadURIHandler(
+ handler, uri, aTriggeringPrincipal, aBrowsingContext);
+ if (!h) {
+ return NS_ERROR_OUT_OF_MEMORY;
}
- nsCOMPtr<nsIContentDispatchChooser> chooser =
- do_CreateInstance("@mozilla.org/content-dispatch-chooser;1", &rv);
- NS_ENSURE_SUCCESS(rv, rv);
-
- return chooser->Ask(handler, uri, aTriggeringPrincipal, aBrowsingContext,
- nsIContentDispatchChooser::REASON_CANNOT_HANDLE);
+ return NS_OK;
}
//////////////////////////////////////////////////////////////////////////////////////////////////////
@@ -1184,6 +1294,7 @@ NS_INTERFACE_MAP_BEGIN(nsExternalAppHandler)
NS_INTERFACE_MAP_ENTRY(nsIStreamListener)
NS_INTERFACE_MAP_ENTRY(nsIRequestObserver)
NS_INTERFACE_MAP_ENTRY(nsIHelperAppLauncher)
+ NS_INTERFACE_MAP_ENTRY(nsIHelperAppWarningLauncher)
NS_INTERFACE_MAP_ENTRY(nsICancelable)
NS_INTERFACE_MAP_ENTRY(nsIBackgroundFileSaverObserver)
NS_INTERFACE_MAP_ENTRY(nsINamed)
@@ -1545,18 +1656,7 @@ void nsExternalAppHandler::MaybeApplyDecodingForExtension(
already_AddRefed<nsIInterfaceRequestor>
nsExternalAppHandler::GetDialogParent() {
- nsCOMPtr<nsIInterfaceRequestor> dialogParent = mWindowContext;
-
- if (!dialogParent && mBrowsingContext) {
- dialogParent = do_QueryInterface(mBrowsingContext->GetDOMWindow());
- }
- if (!dialogParent && mBrowsingContext && XRE_IsParentProcess()) {
- RefPtr<Element> element = mBrowsingContext->Top()->GetEmbedderElement();
- if (element) {
- dialogParent = do_QueryInterface(element->OwnerDoc()->GetWindow());
- }
- }
- return dialogParent.forget();
+ return GetDialogParentAux(mBrowsingContext, mWindowContext);
}
NS_IMETHODIMP nsExternalAppHandler::OnStartRequest(nsIRequest* request) {
@@ -1673,6 +1773,34 @@ NS_IMETHODIMP nsExternalAppHandler::OnStartRequest(nsIRequest* request) {
MOZ_ASSERT(NS_SUCCEEDED(rv));
}
+ mWarningDialog = do_CreateInstance(WARNING_DIALOG_CONTRACT_ID, &rv);
+ if (NS_SUCCEEDED(rv) && mWarningDialog) {
+ // This will create a reference cycle (the dialog holds a reference to us
+ // as nsIHelperAppWarningLauncher), which will be broken in ContinueRequest
+ // or CancelRequest.
+ nsCOMPtr<nsIInterfaceRequestor> dialogParent = GetDialogParent();
+ rv = mWarningDialog->MaybeShow(this, dialogParent);
+ }
+
+ if (NS_FAILED(rv)) {
+ // If for some reason we could not open the download warning prompt,
+ // continue with the request.
+ ContinueRequest();
+ }
+
+ return NS_OK;
+}
+
+NS_IMETHODIMP nsExternalAppHandler::ContinueRequest() {
+ nsAutoCString MIMEType;
+ if (mMimeInfo) {
+ mMimeInfo->GetMIMEType(MIMEType);
+ }
+
+ // Break our reference cycle with the download warning dialog (set up in
+ // OnStartRequest).
+ mWarningDialog = nullptr;
+
// now that the temp file is set up, find out if we need to invoke a dialog
// asking the user what they want us to do with this content...
@@ -1756,6 +1884,7 @@ NS_IMETHODIMP nsExternalAppHandler::OnStartRequest(nsIRequest* request) {
action = nsIMIMEInfo::saveToDisk;
}
+ nsresult rv = NS_OK;
if (alwaysAsk) {
// Display the dialog
mDialog = do_CreateInstance(NS_HELPERAPPLAUNCHERDLG_CONTRACTID, &rv);
@@ -1813,6 +1942,14 @@ NS_IMETHODIMP nsExternalAppHandler::OnStartRequest(nsIRequest* request) {
return NS_OK;
}
+NS_IMETHODIMP nsExternalAppHandler::CancelRequest(nsresult aReason) {
+ // Break our reference cycle with the download warning dialog (set up in
+ // OnStartRequest).
+ mWarningDialog = nullptr;
+
+ return Cancel(aReason);
+}
+
// Convert error info into proper message text and send OnStatusChange
// notification to the dialog progress listener or nsITransfer implementation.
void nsExternalAppHandler::SendStatusChange(ErrorType type, nsresult rv,
@@ -2476,7 +2613,7 @@ NS_IMETHODIMP nsExternalAppHandler::Cancel(nsresult aReason) {
}
// Break our reference cycle with the helper app dialog (set up in
- // OnStartRequest)
+ // ContinueRequest)
mDialog = nullptr;
mRequest = nullptr;
diff --git a/uriloader/exthandler/nsExternalHelperAppService.h b/uriloader/exthandler/nsExternalHelperAppService.h
index f2bd67f64ccd..8c2d8817ac7b 100644
--- a/uriloader/exthandler/nsExternalHelperAppService.h
+++ b/uriloader/exthandler/nsExternalHelperAppService.h
@@ -203,6 +203,7 @@ class nsExternalHelperAppService : public nsIExternalHelperAppService,
*/
class nsExternalAppHandler final : public nsIStreamListener,
public nsIHelperAppLauncher,
+ public nsIHelperAppWarningLauncher,
public nsIBackgroundFileSaverObserver,
public nsINamed {
public:
@@ -210,6 +211,7 @@ class nsExternalAppHandler final : public nsIStreamListener,
NS_DECL_NSISTREAMLISTENER
NS_DECL_NSIREQUESTOBSERVER
NS_DECL_NSIHELPERAPPLAUNCHER
+ NS_DECL_NSIHELPERAPPWARNINGLAUNCHER
NS_DECL_NSICANCELABLE
NS_DECL_NSIBACKGROUNDFILESAVEROBSERVER
NS_DECL_NSINAMED
@@ -460,6 +462,7 @@ class nsExternalAppHandler final : public nsIStreamListener,
nsCOMPtr<nsITransfer> mTransfer;
nsCOMPtr<nsIHelperAppLauncherDialog> mDialog;
+ nsCOMPtr<nsIHelperAppWarningDialog> mWarningDialog;
/**
diff --git a/uriloader/exthandler/nsIExternalHelperAppService.idl b/uriloader/exthandler/nsIExternalHelperAppService.idl
index ea8b9b08f3e6..8b58671f7597 100644
--- a/uriloader/exthandler/nsIExternalHelperAppService.idl
+++ b/uriloader/exthandler/nsIExternalHelperAppService.idl
@@ -182,3 +182,50 @@ interface nsIHelperAppLauncher : nsICancelable
*/
readonly attribute uint64_t browsingContextId;
};
+
+/**
+ * nsIHelperAppWarningLauncher is implemented by two classes:
+ * nsExternalLoadURIHandler
+ * nsExternalAppHandler
+ */
+[scriptable, uuid(cffd508b-4aaf-43ad-99c6-671d35cbc558)]
+interface nsIHelperAppWarningLauncher : nsISupports
+{
+ /**
+ * Callback invoked by the external app warning dialog to continue the
+ * request.
+ * NOTE: This will release the reference to the nsIHelperAppWarningDialog.
+ */
+ void continueRequest();
+
+ /**
+ * Callback invoked by the external app warning dialog to cancel the request.
+ * NOTE: This will release the reference to the nsIHelperAppWarningDialog.
+ *
+ * @param aReason
+ * Pass a failure code to indicate the reason why this operation is
+ * being canceled. It is an error to pass a success code.
+ */
+ void cancelRequest(in nsresult aReason);
+};
+
+/**
+ * nsIHelperAppWarningDialog is implemented by Torbutton's external app
+ * blocker (src/components/external-app-blocker.js).
+ */
+[scriptable, uuid(f4899a3f-0df3-42cc-9db8-bdf599e5a208)]
+interface nsIHelperAppWarningDialog : nsISupports
+{
+ /**
+ * Possibly show a launch warning dialog (it will not be shown if the user
+ * has chosen to not see the warning again).
+ *
+ * @param aLauncher
+ * A nsIHelperAppWarningLauncher to be invoked after the user confirms
+ * or cancels the download.
+ * @param aWindowContext
+ * The window associated with the download.
+ */
+ void maybeShow(in nsIHelperAppWarningLauncher aLauncher,
+ in nsISupports aWindowContext);
+};
1
0

[tor-browser/tor-browser-80.0b2-10.0-1] Bug 16940: After update, load local change notes.
by gk@torproject.org 17 Aug '20
by gk@torproject.org 17 Aug '20
17 Aug '20
commit 0bde09eb82a7a65e694b171d0c1f56810eefecaf
Author: Kathy Brade <brade(a)pearlcrescent.com>
Date: Wed Nov 25 11:36:20 2015 -0500
Bug 16940: After update, load local change notes.
Add an about:tbupdate page that displays the first section from
TorBrowser/Docs/ChangeLog.txt and includes a link to the remote
post-update page (typically our blog entry for the release).
Always load about:tbupdate in a content process, but implement the
code that reads the file system (changelog) in the chrome process
for compatibility with future sandboxing efforts.
Also fix bug 29440. Now about:tbupdate is styled as a fairly simple
changelog page that is designed to be displayed via a link that is on
about:tor.
---
browser/actors/AboutTBUpdateChild.jsm | 12 +++
browser/actors/AboutTBUpdateParent.jsm | 120 +++++++++++++++++++++
browser/actors/moz.build | 6 ++
.../base/content/abouttbupdate/aboutTBUpdate.css | 74 +++++++++++++
.../base/content/abouttbupdate/aboutTBUpdate.js | 27 +++++
.../base/content/abouttbupdate/aboutTBUpdate.xhtml | 39 +++++++
browser/base/content/browser-siteIdentity.js | 2 +-
browser/base/content/browser.js | 4 +
browser/base/jar.mn | 5 +
browser/components/BrowserContentHandler.jsm | 55 +++++++---
browser/components/BrowserGlue.jsm | 15 +++
browser/components/about/AboutRedirector.cpp | 6 ++
browser/components/about/components.conf | 3 +
browser/components/moz.build | 5 +-
.../locales/en-US/chrome/browser/aboutTBUpdate.dtd | 8 ++
browser/locales/jar.mn | 3 +
toolkit/modules/RemotePageAccessManager.jsm | 5 +
17 files changed, 373 insertions(+), 16 deletions(-)
diff --git a/browser/actors/AboutTBUpdateChild.jsm b/browser/actors/AboutTBUpdateChild.jsm
new file mode 100644
index 000000000000..4670da19b3db
--- /dev/null
+++ b/browser/actors/AboutTBUpdateChild.jsm
@@ -0,0 +1,12 @@
+// Copyright (c) 2020, The Tor Project, Inc.
+// See LICENSE for licensing information.
+//
+// vim: set sw=2 sts=2 ts=8 et syntax=javascript:
+
+var EXPORTED_SYMBOLS = ["AboutTBUpdateChild"];
+
+const { RemotePageChild } = ChromeUtils.import(
+ "resource://gre/actors/RemotePageChild.jsm"
+);
+
+class AboutTBUpdateChild extends RemotePageChild {}
diff --git a/browser/actors/AboutTBUpdateParent.jsm b/browser/actors/AboutTBUpdateParent.jsm
new file mode 100644
index 000000000000..56a10394565a
--- /dev/null
+++ b/browser/actors/AboutTBUpdateParent.jsm
@@ -0,0 +1,120 @@
+// Copyright (c) 2020, The Tor Project, Inc.
+// See LICENSE for licensing information.
+//
+// vim: set sw=2 sts=2 ts=8 et syntax=javascript:
+
+"use strict";
+
+this.EXPORTED_SYMBOLS = ["AboutTBUpdateParent"];
+
+const { Services } = ChromeUtils.import("resource://gre/modules/Services.jsm");
+const { NetUtil } = ChromeUtils.import("resource://gre/modules/NetUtil.jsm");
+const { AppConstants } = ChromeUtils.import(
+ "resource://gre/modules/AppConstants.jsm"
+);
+
+const kRequestUpdateMessageName = "FetchUpdateData";
+
+/**
+ * This code provides services to the about:tbupdate page. Whenever
+ * about:tbupdate needs to do something chrome-privileged, it sends a
+ * message that's handled here. It is modeled after Mozilla's about:home
+ * implementation.
+ */
+class AboutTBUpdateParent extends JSWindowActorParent {
+ receiveMessage(aMessage) {
+ if (aMessage.name == kRequestUpdateMessageName) {
+ return this.releaseNoteInfo;
+ }
+ return undefined;
+ }
+
+ get moreInfoURL() {
+ try {
+ return Services.prefs.getCharPref("torbrowser.post_update.url");
+ } catch (e) {}
+
+ // Use the default URL as a fallback.
+ return Services.urlFormatter.formatURLPref("startup.homepage_override_url");
+ }
+
+ // Read the text from the beginning of the changelog file that is located
+ // at TorBrowser/Docs/ChangeLog.txt and return an object that contains
+ // the following properties:
+ // version e.g., Tor Browser 8.5
+ // releaseDate e.g., March 31 2019
+ // releaseNotes details of changes (lines 2 - end of ChangeLog.txt)
+ // We attempt to parse the first line of ChangeLog.txt to extract the
+ // version and releaseDate. If parsing fails, we return the entire first
+ // line in version and omit releaseDate.
+ //
+ // On Mac OS, when building with --enable-tor-browser-data-outside-app-dir
+ // to support Gatekeeper signing, the ChangeLog.txt file is located in
+ // TorBrowser.app/Contents/Resources/TorBrowser/Docs/.
+ get releaseNoteInfo() {
+ let info = { moreInfoURL: this.moreInfoURL };
+
+ try {
+ let f;
+ if (AppConstants.TOR_BROWSER_DATA_OUTSIDE_APP_DIR) {
+ // "XREExeF".parent is the directory that contains firefox, i.e.,
+ // Browser/ or, on Mac OS, TorBrowser.app/Contents/MacOS/.
+ f = Services.dirsvc.get("XREExeF", Ci.nsIFile).parent;
+ if (AppConstants.platform === "macosx") {
+ f = f.parent;
+ f.append("Resources");
+ }
+ f.append("TorBrowser");
+ } else {
+ // "DefProfRt" is .../TorBrowser/Data/Browser
+ f = Services.dirsvc.get("DefProfRt", Ci.nsIFile);
+ f = f.parent.parent; // Remove "Data/Browser"
+ }
+
+ f.append("Docs");
+ f.append("ChangeLog.txt");
+
+ let fs = Cc["@mozilla.org/network/file-input-stream;1"].createInstance(
+ Ci.nsIFileInputStream
+ );
+ fs.init(f, -1, 0, 0);
+ let s = NetUtil.readInputStreamToString(fs, fs.available());
+ fs.close();
+
+ // Truncate at the first empty line.
+ s = s.replace(/[\r\n][\r\n][\s\S]*$/m, "");
+
+ // Split into first line (version plus releaseDate) and
+ // remainder (releaseNotes).
+ // This first match() uses multiline mode with two capture groups:
+ // first line: (.*$)
+ // remaining lines: ([\s\S]+)
+ // [\s\S] matches all characters including end of line. This trick
+ // is needed because when using JavaScript regex in multiline mode,
+ // . does not match an end of line character.
+ let matchArray = s.match(/(.*$)\s*([\s\S]+)/m);
+ if (matchArray && matchArray.length == 3) {
+ info.releaseNotes = matchArray[2];
+ let line1 = matchArray[1];
+ // Extract the version and releaseDate. The first line looks like:
+ // Tor Browser 8.5 -- May 1 2019
+ // The regex uses two capture groups:
+ // text that does not include a hyphen: (^[^-]*)
+ // remaining text: (.*$)
+ // In between we match optional whitespace, one or more hyphens, and
+ // optional whitespace by using: \s*-+\s*
+ matchArray = line1.match(/(^[^-]*)\s*-+\s*(.*$)/);
+ if (matchArray && matchArray.length == 3) {
+ info.version = matchArray[1];
+ info.releaseDate = matchArray[2];
+ } else {
+ info.version = line1; // Match failed: return entire line in version.
+ }
+ } else {
+ info.releaseNotes = s; // Only one line: use as releaseNotes.
+ }
+ } catch (e) {}
+
+ return info;
+ }
+}
diff --git a/browser/actors/moz.build b/browser/actors/moz.build
index 09abb15b855d..e7c41036f768 100644
--- a/browser/actors/moz.build
+++ b/browser/actors/moz.build
@@ -80,3 +80,9 @@ FINAL_TARGET_FILES.actors += [
'WebRTCChild.jsm',
'WebRTCParent.jsm',
]
+
+if CONFIG['TOR_BROWSER_UPDATE']:
+ FINAL_TARGET_FILES.actors += [
+ 'AboutTBUpdateChild.jsm',
+ 'AboutTBUpdateParent.jsm',
+ ]
diff --git a/browser/base/content/abouttbupdate/aboutTBUpdate.css b/browser/base/content/abouttbupdate/aboutTBUpdate.css
new file mode 100644
index 000000000000..7c1a34b77f17
--- /dev/null
+++ b/browser/base/content/abouttbupdate/aboutTBUpdate.css
@@ -0,0 +1,74 @@
+/*
+ * Copyright (c) 2019, The Tor Project, Inc.
+ * See LICENSE for licensing information.
+ *
+ * vim: set sw=2 sts=2 ts=8 et syntax=css:
+ */
+
+:root {
+ --abouttor-text-color: white;
+ --abouttor-bg-toron-color: #420C5D;
+}
+
+body {
+ font-family: Helvetica, Arial, sans-serif;
+ color: var(--abouttor-text-color);
+ background-color: var(--abouttor-bg-toron-color);
+ background-attachment: fixed;
+ background-size: 100% 100%;
+}
+
+a {
+ color: var(--abouttor-text-color);
+}
+
+.two-column-grid {
+ display: inline-grid;
+ grid-template-columns: auto auto;
+ grid-column-gap: 50px;
+ margin: 10px 0px 0px 50px;
+}
+
+.two-column-grid div {
+ margin-top: 40px;
+ align-self: baseline; /* Align baseline of text across the row. */
+}
+
+.label-column {
+ font-size: 14px;
+ font-weight: 400;
+}
+
+/*
+ * Use a reduced top margin to bring the row that contains the
+ * "visit our website" link closer to the row that precedes it. This
+ * looks better because the "visit our website" row does not have a
+ * label in the left column.
+ */
+div.more-info-row {
+ margin-top: 5px;
+ font-size: 14px;
+}
+
+#version-content {
+ font-size: 50px;
+ font-weight: 300;
+}
+
+body:not([havereleasedate]) .release-date-cell {
+ display: none;
+}
+
+#releasedate-content {
+ font-size: 17px;
+}
+
+#releasenotes-label {
+ align-self: start; /* Anchor "Release Notes" label at the top. */
+}
+
+#releasenotes-content {
+ font-family: monospace;
+ font-size: 15px;
+ white-space: pre;
+}
diff --git a/browser/base/content/abouttbupdate/aboutTBUpdate.js b/browser/base/content/abouttbupdate/aboutTBUpdate.js
new file mode 100644
index 000000000000..ec070e2cb131
--- /dev/null
+++ b/browser/base/content/abouttbupdate/aboutTBUpdate.js
@@ -0,0 +1,27 @@
+// Copyright (c) 2020, The Tor Project, Inc.
+// See LICENSE for licensing information.
+//
+// vim: set sw=2 sts=2 ts=8 et syntax=javascript:
+
+/* eslint-env mozilla/frame-script */
+
+// aData may contain the following string properties:
+// version
+// releaseDate
+// moreInfoURL
+// releaseNotes
+function onUpdate(aData) {
+ document.getElementById("version-content").textContent = aData.version;
+ if (aData.releaseDate) {
+ document.body.setAttribute("havereleasedate", "true");
+ document.getElementById("releasedate-content").textContent =
+ aData.releaseDate;
+ }
+ if (aData.moreInfoURL) {
+ document.getElementById("infolink").setAttribute("href", aData.moreInfoURL);
+ }
+ document.getElementById("releasenotes-content").textContent =
+ aData.releaseNotes;
+}
+
+RPMSendQuery("FetchUpdateData").then(onUpdate);
diff --git a/browser/base/content/abouttbupdate/aboutTBUpdate.xhtml b/browser/base/content/abouttbupdate/aboutTBUpdate.xhtml
new file mode 100644
index 000000000000..8489cfef5083
--- /dev/null
+++ b/browser/base/content/abouttbupdate/aboutTBUpdate.xhtml
@@ -0,0 +1,39 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<!DOCTYPE html [
+ <!ENTITY % htmlDTD
+ PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
+ "DTD/xhtml1-strict.dtd">
+ %htmlDTD;
+ <!ENTITY % globalDTD SYSTEM "chrome://global/locale/global.dtd">
+ %globalDTD;
+ <!ENTITY % tbUpdateDTD SYSTEM "chrome://browser/locale/aboutTBUpdate.dtd">
+ %tbUpdateDTD;
+]>
+
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head>
+ <meta http-equiv="Content-Security-Policy" content="default-src chrome:; object-src 'none'" />
+ <title>&aboutTBUpdate.changelogTitle;</title>
+ <link rel="stylesheet" type="text/css"
+ href="chrome://browser/content/abouttbupdate/aboutTBUpdate.css"/>
+ <script src="chrome://browser/content/abouttbupdate/aboutTBUpdate.js"
+ type="text/javascript"/>
+</head>
+<body dir="&locale.dir;">
+<div class="two-column-grid">
+ <div class="label-column">&aboutTBUpdate.version;</div>
+ <div id="version-content"/>
+
+ <div class="label-column release-date-cell">&aboutTBUpdate.releaseDate;</div>
+ <div id="releasedate-content" class="release-date-cell"/>
+
+ <div class="more-info-row"/>
+ <div class="more-info-row">&aboutTBUpdate.linkPrefix;<a id="infolink">&aboutTBUpdate.linkLabel;</a>&aboutTBUpdate.linkSuffix;</div>
+
+ <div id="releasenotes-label"
+ class="label-column">&aboutTBUpdate.releaseNotes;</div>
+ <div id="releasenotes-content"></div>
+</div>
+</body>
+</html>
diff --git a/browser/base/content/browser-siteIdentity.js b/browser/base/content/browser-siteIdentity.js
index 017aac1fc6d8..ef8af841473f 100644
--- a/browser/base/content/browser-siteIdentity.js
+++ b/browser/base/content/browser-siteIdentity.js
@@ -57,7 +57,7 @@ var gIdentityHandler = {
* RegExp used to decide if an about url should be shown as being part of
* the browser UI.
*/
- _secureInternalPages: /^(?:accounts|addons|cache|certificate|config|crashes|downloads|license|logins|preferences|protections|rights|sessionrestore|support|welcomeback)(?:[?#]|$)/i,
+ _secureInternalPages: (AppConstants.TOR_BROWSER_UPDATE ? /^(?:accounts|addons|cache|certificate|config|crashes|downloads|license|logins|preferences|protections|rights|sessionrestore|support|welcomeback|tor|tbupdate)(?:[?#]|$)/i : /^(?:accounts|addons|cache|certificate|config|crashes|downloads|license|logins|preferences|protections|rights|sessionrestore|support|welcomeback|tor)(?:[?#]|$)/i),
/**
* Whether the established HTTPS connection is considered "broken".
diff --git a/browser/base/content/browser.js b/browser/base/content/browser.js
index 87666da1e5c5..303a3cc42889 100644
--- a/browser/base/content/browser.js
+++ b/browser/base/content/browser.js
@@ -630,6 +630,10 @@ var gInitialPages = [
"about:newinstall",
];
+if (AppConstants.TOR_BROWSER_UPDATE) {
+ gInitialPages.push("about:tbupdate");
+}
+
function isInitialPage(url) {
if (!(url instanceof Ci.nsIURI)) {
try {
diff --git a/browser/base/jar.mn b/browser/base/jar.mn
index 5520bb368095..743b2d38ae3e 100644
--- a/browser/base/jar.mn
+++ b/browser/base/jar.mn
@@ -30,6 +30,11 @@ browser.jar:
content/browser/aboutTabCrashed.css (content/aboutTabCrashed.css)
content/browser/aboutTabCrashed.js (content/aboutTabCrashed.js)
content/browser/aboutTabCrashed.xhtml (content/aboutTabCrashed.xhtml)
+#ifdef TOR_BROWSER_UPDATE
+ content/browser/abouttbupdate/aboutTBUpdate.xhtml (content/abouttbupdate/aboutTBUpdate.xhtml)
+ content/browser/abouttbupdate/aboutTBUpdate.js (content/abouttbupdate/aboutTBUpdate.js)
+ content/browser/abouttbupdate/aboutTBUpdate.css (content/abouttbupdate/aboutTBUpdate.css)
+#endif
* content/browser/browser.css (content/browser.css)
content/browser/browser.js (content/browser.js)
* content/browser/browser.xhtml (content/browser.xhtml)
diff --git a/browser/components/BrowserContentHandler.jsm b/browser/components/BrowserContentHandler.jsm
index 39ae2e7f5e2d..32d3dc80ee05 100644
--- a/browser/components/BrowserContentHandler.jsm
+++ b/browser/components/BrowserContentHandler.jsm
@@ -650,6 +650,23 @@ nsBrowserContentHandler.prototype = {
}
}
+ // Retrieve the home page early so we can compare it against about:tor
+ // to decide whether or not we need an override page (second tab) after
+ // an update was applied.
+ var startPage = "";
+ try {
+ var choice = prefb.getIntPref("browser.startup.page");
+ if (choice == 1 || choice == 3) {
+ startPage = HomePage.get();
+ }
+ } catch (e) {
+ Cu.reportError(e);
+ }
+
+ if (startPage == "about:blank") {
+ startPage = "";
+ }
+
var override;
var overridePage = "";
var additionalPage = "";
@@ -701,6 +718,16 @@ nsBrowserContentHandler.prototype = {
// into account because that requires waiting for the session file
// to be read. If a crash occurs after updating, before restarting,
// we may open the startPage in addition to restoring the session.
+ //
+ // Tor Browser: Instead of opening the post-update "override page"
+ // directly, we ensure that about:tor will be opened in a special
+ // mode that notifies the user that their browser was updated.
+ // The about:tor page will provide a link to the override page
+ // where the user can learn more about the update, as well as a
+ // link to the Tor Browser changelog page (about:tbupdate). The
+ // override page URL comes from the openURL attribute within the
+ // updates.xml file or, if no showURL action is present, from the
+ // startup.homepage_override_url pref.
willRestoreSession = SessionStartup.isAutomaticRestoreEnabled();
overridePage = Services.urlFormatter.formatURLPref(
@@ -720,6 +747,20 @@ nsBrowserContentHandler.prototype = {
overridePage = overridePage.replace("%OLD_VERSION%", old_mstone);
overridePage = overridePage.replace("%OLD_TOR_BROWSER_VERSION%",
old_tbversion);
+#ifdef TOR_BROWSER_UPDATE
+ if (overridePage)
+ {
+ prefb.setCharPref("torbrowser.post_update.url", overridePage);
+ prefb.setBoolPref("torbrowser.post_update.shouldNotify", true);
+ // If the user's homepage is about:tor, we will inform them
+ // about the update on that page; otherwise, we arrange to
+ // open about:tor in a secondary tab.
+ if (startPage === "about:tor")
+ overridePage = "";
+ else
+ overridePage = "about:tor";
+ }
+#endif
break;
case OVERRIDE_NEW_BUILD_ID:
if (UpdateManager.activeUpdate) {
@@ -792,20 +833,6 @@ nsBrowserContentHandler.prototype = {
}
}
- var startPage = "";
- try {
- var choice = prefb.getIntPref("browser.startup.page");
- if (choice == 1 || choice == 3) {
- startPage = HomePage.get();
- }
- } catch (e) {
- Cu.reportError(e);
- }
-
- if (startPage == "about:blank") {
- startPage = "";
- }
-
let skipStartPage =
(override == OVERRIDE_NEW_PROFILE ||
override == OVERRIDE_ALTERNATE_PROFILE) &&
diff --git a/browser/components/BrowserGlue.jsm b/browser/components/BrowserGlue.jsm
index 7ee2efc9f437..946f17131dda 100644
--- a/browser/components/BrowserGlue.jsm
+++ b/browser/components/BrowserGlue.jsm
@@ -600,6 +600,21 @@ let JSWINDOWACTORS = {
},
};
+if (AppConstants.TOR_BROWSER_UPDATE) {
+ JSWINDOWACTORS["AboutTBUpdate"] = {
+ parent: {
+ moduleURI: "resource:///actors/AboutTBUpdateParent.jsm",
+ },
+ child: {
+ moduleURI: "resource:///actors/AboutTBUpdateChild.jsm",
+ events: {
+ DOMWindowCreated: { capture: true },
+ },
+ },
+ matches: ["about:tbupdate"],
+ };
+}
+
(function earlyBlankFirstPaint() {
if (
AppConstants.platform == "macosx" ||
diff --git a/browser/components/about/AboutRedirector.cpp b/browser/components/about/AboutRedirector.cpp
index 9927a11420e7..5021846336aa 100644
--- a/browser/components/about/AboutRedirector.cpp
+++ b/browser/components/about/AboutRedirector.cpp
@@ -120,6 +120,12 @@ static const RedirEntry kRedirMap[] = {
nsIAboutModule::URI_CAN_LOAD_IN_PRIVILEGEDABOUT_PROCESS},
{"pioneer", "chrome://browser/content/pioneer.html",
nsIAboutModule::ALLOW_SCRIPT | nsIAboutModule::HIDE_FROM_ABOUTABOUT},
+#ifdef TOR_BROWSER_UPDATE
+ {"tbupdate", "chrome://browser/content/abouttbupdate/aboutTBUpdate.xhtml",
+ nsIAboutModule::URI_SAFE_FOR_UNTRUSTED_CONTENT |
+ nsIAboutModule::URI_MUST_LOAD_IN_CHILD | nsIAboutModule::ALLOW_SCRIPT |
+ nsIAboutModule::HIDE_FROM_ABOUTABOUT},
+#endif
};
static nsAutoCString GetAboutModuleName(nsIURI* aURI) {
diff --git a/browser/components/about/components.conf b/browser/components/about/components.conf
index bf0c6c096847..f31159d30e15 100644
--- a/browser/components/about/components.conf
+++ b/browser/components/about/components.conf
@@ -32,6 +32,9 @@ pages = [
'welcomeback',
]
+if defined('TOR_BROWSER_UPDATE'):
+ pages.append('tbupdate')
+
Classes = [
{
'cid': '{7e4bb6ad-2fc4-4dc6-89ef-23e8e5ccf980}',
diff --git a/browser/components/moz.build b/browser/components/moz.build
index c75c10b0c92d..cf3f566eba71 100644
--- a/browser/components/moz.build
+++ b/browser/components/moz.build
@@ -90,11 +90,14 @@ EXTRA_COMPONENTS += [
]
EXTRA_JS_MODULES += [
- 'BrowserContentHandler.jsm',
'BrowserGlue.jsm',
'distribution.js',
]
+EXTRA_PP_JS_MODULES += [
+ 'BrowserContentHandler.jsm',
+]
+
BROWSER_CHROME_MANIFESTS += [
'safebrowsing/content/test/browser.ini',
'tests/browser/browser.ini',
diff --git a/browser/locales/en-US/chrome/browser/aboutTBUpdate.dtd b/browser/locales/en-US/chrome/browser/aboutTBUpdate.dtd
new file mode 100644
index 000000000000..2d1e59b40eaf
--- /dev/null
+++ b/browser/locales/en-US/chrome/browser/aboutTBUpdate.dtd
@@ -0,0 +1,8 @@
+<!ENTITY aboutTBUpdate.changelogTitle "Tor Browser Changelog">
+<!ENTITY aboutTBUpdate.updated "Tor Browser has been updated.">
+<!ENTITY aboutTBUpdate.linkPrefix "For the most up-to-date information about this release, ">
+<!ENTITY aboutTBUpdate.linkLabel "visit our website">
+<!ENTITY aboutTBUpdate.linkSuffix ".">
+<!ENTITY aboutTBUpdate.version "Version">
+<!ENTITY aboutTBUpdate.releaseDate "Release Date">
+<!ENTITY aboutTBUpdate.releaseNotes "Release Notes">
diff --git a/browser/locales/jar.mn b/browser/locales/jar.mn
index 7bbfa54c91cb..7e0701deeb32 100644
--- a/browser/locales/jar.mn
+++ b/browser/locales/jar.mn
@@ -20,6 +20,9 @@
locale/browser/accounts.properties (%chrome/browser/accounts.properties)
locale/browser/app-extension-fields.properties (%chrome/browser/app-extension-fields.properties)
+#ifdef TOR_BROWSER_UPDATE
+ locale/browser/aboutTBUpdate.dtd (%chrome/browser/aboutTBUpdate.dtd)
+#endif
locale/browser/browser.dtd (%chrome/browser/browser.dtd)
locale/browser/baseMenuOverlay.dtd (%chrome/browser/baseMenuOverlay.dtd)
locale/browser/browser.properties (%chrome/browser/browser.properties)
diff --git a/toolkit/modules/RemotePageAccessManager.jsm b/toolkit/modules/RemotePageAccessManager.jsm
index ef9f9bd3ba98..076f1d211c0c 100644
--- a/toolkit/modules/RemotePageAccessManager.jsm
+++ b/toolkit/modules/RemotePageAccessManager.jsm
@@ -186,6 +186,11 @@ let RemotePageAccessManager = {
RPMAddMessageListener: ["*"],
RPMRemoveMessageListener: ["*"],
},
+ "about:tbupdate": {
+ RPMSendQuery: [
+ "FetchUpdateData",
+ ],
+ },
},
/**
1
0

[tor-browser/tor-browser-80.0b2-10.0-1] Bug 21431: Clean-up system extensions shipped in Firefox
by gk@torproject.org 17 Aug '20
by gk@torproject.org 17 Aug '20
17 Aug '20
commit c2fce6cbbaa9a67b8ba384bb5ea3a59618d2a60c
Author: Kathy Brade <brade(a)pearlcrescent.com>
Date: Tue May 23 17:05:29 2017 -0400
Bug 21431: Clean-up system extensions shipped in Firefox
Only ship the pdfjs extension.
---
browser/components/BrowserGlue.jsm | 6 ++++++
browser/extensions/moz.build | 5 -----
browser/installer/package-manifest.in | 1 -
browser/locales/Makefile.in | 8 --------
browser/locales/jar.mn | 7 -------
5 files changed, 6 insertions(+), 21 deletions(-)
diff --git a/browser/components/BrowserGlue.jsm b/browser/components/BrowserGlue.jsm
index 946f17131dda..99cf63baa19a 100644
--- a/browser/components/BrowserGlue.jsm
+++ b/browser/components/BrowserGlue.jsm
@@ -2060,6 +2060,9 @@ BrowserGlue.prototype = {
const ID = "screenshots(a)mozilla.org";
const _checkScreenshotsPref = async () => {
let addon = await AddonManager.getAddonByID(ID);
+ if (!addon) {
+ return;
+ }
let disabled = Services.prefs.getBoolPref(PREF, false);
if (disabled) {
await addon.disable({ allowSystemAddons: true });
@@ -2076,6 +2079,9 @@ BrowserGlue.prototype = {
const ID = "webcompat-reporter(a)mozilla.org";
Services.prefs.addObserver(PREF, async () => {
let addon = await AddonManager.getAddonByID(ID);
+ if (!addon) {
+ return;
+ }
let enabled = Services.prefs.getBoolPref(PREF, false);
if (enabled && !addon.isActive) {
await addon.enable({ allowSystemAddons: true });
diff --git a/browser/extensions/moz.build b/browser/extensions/moz.build
index 9787ecf81592..bdfc06cb6148 100644
--- a/browser/extensions/moz.build
+++ b/browser/extensions/moz.build
@@ -5,11 +5,6 @@
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
DIRS += [
- 'doh-rollout',
- 'formautofill',
- 'screenshots',
- 'webcompat',
- 'report-site-issue'
]
if not CONFIG['TOR_BROWSER_DISABLE_TOR_LAUNCHER']:
diff --git a/browser/installer/package-manifest.in b/browser/installer/package-manifest.in
index ff965bb07a07..6ab49b9a4a04 100644
--- a/browser/installer/package-manifest.in
+++ b/browser/installer/package-manifest.in
@@ -271,7 +271,6 @@
@RESPATH@/browser/chrome/icons/default/default64.png
@RESPATH@/browser/chrome/icons/default/default128.png
#endif
-@RESPATH@/browser/features/*
; [DevTools Startup Files]
@RESPATH@/browser/chrome/devtools-startup@JAREXT@
diff --git a/browser/locales/Makefile.in b/browser/locales/Makefile.in
index 496379c4306f..0946188813da 100644
--- a/browser/locales/Makefile.in
+++ b/browser/locales/Makefile.in
@@ -58,10 +58,6 @@ l10n-%:
@$(MAKE) -C ../../toolkit/locales l10n-$* XPI_ROOT_APPID='$(XPI_ROOT_APPID)'
@$(MAKE) -C ../../services/sync/locales AB_CD=$* XPI_NAME=locale-$*
@$(MAKE) -C ../../extensions/spellcheck/locales AB_CD=$* XPI_NAME=locale-$*
-ifneq (,$(wildcard ../extensions/formautofill/locales))
- @$(MAKE) -C ../extensions/formautofill/locales AB_CD=$* XPI_NAME=locale-$*
-endif
- @$(MAKE) -C ../extensions/report-site-issue/locales AB_CD=$* XPI_NAME=locale-$*
@$(MAKE) -C ../../devtools/client/locales AB_CD=$* XPI_NAME=locale-$* XPI_ROOT_APPID='$(XPI_ROOT_APPID)'
@$(MAKE) -C ../../devtools/startup/locales AB_CD=$* XPI_NAME=locale-$* XPI_ROOT_APPID='$(XPI_ROOT_APPID)'
@$(MAKE) l10n AB_CD=$* XPI_NAME=locale-$* PREF_DIR=$(PREF_DIR)
@@ -75,14 +71,10 @@ chrome-%:
@$(MAKE) -C ../../toolkit/locales chrome-$*
@$(MAKE) -C ../../services/sync/locales chrome AB_CD=$*
@$(MAKE) -C ../../extensions/spellcheck/locales chrome AB_CD=$*
-ifneq (,$(wildcard ../extensions/formautofill/locales))
- @$(MAKE) -C ../extensions/formautofill/locales chrome AB_CD=$*
-endif
@$(MAKE) -C ../../devtools/client/locales chrome AB_CD=$*
@$(MAKE) -C ../../devtools/startup/locales chrome AB_CD=$*
@$(MAKE) chrome AB_CD=$*
@$(MAKE) -C $(DEPTH)/$(MOZ_BRANDING_DIRECTORY)/locales chrome AB_CD=$*
- @$(MAKE) -C ../extensions/report-site-issue/locales chrome AB_CD=$*
package-win32-installer: $(SUBMAKEFILES)
$(MAKE) -C ../installer/windows CONFIG_DIR=l10ngen ZIP_IN='$(ZIP_OUT)' installer
diff --git a/browser/locales/jar.mn b/browser/locales/jar.mn
index 7e0701deeb32..1aeb2550cb3b 100644
--- a/browser/locales/jar.mn
+++ b/browser/locales/jar.mn
@@ -55,10 +55,3 @@
locale/browser/newInstall.dtd (%chrome/browser/newInstall.dtd)
locale/browser/brandings.dtd (%chrome/browser/brandings.dtd)
locale/browser/fxmonitor.properties (%chrome/browser/fxmonitor.properties)
-
-#ifdef XPI_NAME
-# Bug 1240628, restructure how l10n repacks work with feature addons
-# This is hacky, but ensures the chrome.manifest chain is complete
-[.] chrome.jar:
-% manifest features/chrome.manifest
-#endif
1
0

[tor-browser/tor-browser-80.0b2-10.0-1] Bug 21724: Make Firefox and Tor Browser distinct macOS apps
by gk@torproject.org 17 Aug '20
by gk@torproject.org 17 Aug '20
17 Aug '20
commit 7db5dc1351ac2e2e0e6ccc3e92552df6f3f2b565
Author: teor <teor2345(a)gmail.com>
Date: Mon Mar 13 23:06:23 2017 +1100
Bug 21724: Make Firefox and Tor Browser distinct macOS apps
When macOS opens a document or selects a default browser, it sometimes
uses the CFBundleSignature. Changing from the Firefox MOZB signature to
a different signature TORB allows macOS to distinguish between Firefox
and Tor Browser.
---
browser/app/Makefile.in | 2 +-
browser/app/macbuild/Contents/Info.plist.in | 2 +-
2 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/browser/app/Makefile.in b/browser/app/Makefile.in
index 1aec6541fc0f..6770319f1866 100644
--- a/browser/app/Makefile.in
+++ b/browser/app/Makefile.in
@@ -103,5 +103,5 @@ ifdef MOZ_UPDATER
mv -f '$(dist_dest)/Contents/MacOS/updater.app/Contents/MacOS/org.mozilla.updater' '$(dist_dest)/Contents/Library/LaunchServices'
ln -s ../../../../Library/LaunchServices/org.mozilla.updater '$(dist_dest)/Contents/MacOS/updater.app/Contents/MacOS/org.mozilla.updater'
endif
- printf APPLMOZB > '$(dist_dest)/Contents/PkgInfo'
+ printf APPLTORB > '$(dist_dest)/Contents/PkgInfo'
endif
diff --git a/browser/app/macbuild/Contents/Info.plist.in b/browser/app/macbuild/Contents/Info.plist.in
index 27969d6051df..61e6f3168475 100644
--- a/browser/app/macbuild/Contents/Info.plist.in
+++ b/browser/app/macbuild/Contents/Info.plist.in
@@ -179,7 +179,7 @@
<key>CFBundleShortVersionString</key>
<string>%APP_VERSION%</string>
<key>CFBundleSignature</key>
- <string>MOZB</string>
+ <string>TORB</string>
<key>CFBundleURLTypes</key>
<array>
<dict>
1
0

[tor-browser/tor-browser-80.0b2-10.0-1] Bug 11641: change TBB directory structure to be more like Firefox's
by gk@torproject.org 17 Aug '20
by gk@torproject.org 17 Aug '20
17 Aug '20
commit 1601a1e3568a2b1999b7553025da8b667763a5e4
Author: Kathy Brade <brade(a)pearlcrescent.com>
Date: Tue Apr 29 13:08:24 2014 -0400
Bug 11641: change TBB directory structure to be more like Firefox's
Unless the -osint command line flag is used, the browser now defaults
to the equivalent of -no-remote. There is a new -allow-remote flag that
may be used to restore the original (Firefox-like) default behavior.
---
toolkit/xre/nsAppRunner.cpp | 21 ++++++++++++++++-----
1 file changed, 16 insertions(+), 5 deletions(-)
diff --git a/toolkit/xre/nsAppRunner.cpp b/toolkit/xre/nsAppRunner.cpp
index 6547da9a2771..bda56973ad71 100644
--- a/toolkit/xre/nsAppRunner.cpp
+++ b/toolkit/xre/nsAppRunner.cpp
@@ -1445,8 +1445,10 @@ static void DumpHelp() {
" --migration Start with migration wizard.\n"
" --ProfileManager Start with ProfileManager.\n"
#ifdef MOZ_HAS_REMOTE
- " --no-remote Do not accept or send remote commands; implies\n"
+ " --no-remote (default) Do not accept or send remote commands; "
+ "implies\n"
" --new-instance.\n"
+ " --allow-remote Accept and send remote commands.\n"
" --new-instance Open new instance, not a new window in running "
"instance.\n"
#endif
@@ -3632,16 +3634,25 @@ int XREMain::XRE_mainInit(bool* aExitFlag) {
gSafeMode);
#if defined(MOZ_HAS_REMOTE)
+ // In Tor Browser, remoting is disabled by default unless -osint is used.
+ bool allowRemote = (CheckArg("allow-remote") == ARG_FOUND);
+ bool isOsint = (CheckArg("osint", nullptr, CheckArgFlag::None) == ARG_FOUND);
+ if (!allowRemote && !isOsint) {
+ SaveToEnv("MOZ_NO_REMOTE=1");
+ }
// Handle --no-remote and --new-instance command line arguments. Setup
// the environment to better accommodate other components and various
// restart scenarios.
ar = CheckArg("no-remote");
- if (ar == ARG_FOUND || EnvHasValue("MOZ_NO_REMOTE")) {
+ if ((ar == ARG_FOUND) && allowRemote) {
+ PR_fprintf(PR_STDERR,
+ "Error: argument --no-remote is invalid when argument "
+ "--allow-remote is specified\n");
+ return 1;
+ }
+ if (EnvHasValue("MOZ_NO_REMOTE")) {
mDisableRemoteClient = true;
mDisableRemoteServer = true;
- if (!EnvHasValue("MOZ_NO_REMOTE")) {
- SaveToEnv("MOZ_NO_REMOTE=1");
- }
}
ar = CheckArg("new-instance");
1
0

[tor-browser/tor-browser-80.0b2-10.0-1] Bug 4234: Use the Firefox Update Process for Tor Browser.
by gk@torproject.org 17 Aug '20
by gk@torproject.org 17 Aug '20
17 Aug '20
commit 2c202f5dddeec9844721875efdd3d93f5766801d
Author: Kathy Brade <brade(a)pearlcrescent.com>
Date: Fri Jan 13 11:40:24 2017 -0500
Bug 4234: Use the Firefox Update Process for Tor Browser.
The following files are never updated:
TorBrowser/Data/Browser/profiles.ini
TorBrowser/Data/Browser/profile.default/bookmarks.html
TorBrowser/Data/Tor/torrc
Mac OS: Store update metadata under TorBrowser/UpdateInfo.
Removed the %OS_VERSION% component from the update URL (13047) and
added support for minSupportedOSVersion, an attribute of the
<update> element that may be used to trigger Firefox's
"unsupported platform" behavior.
Hide the "What's new" links (set app.releaseNotesURL value to about:blank).
Windows: disable "runas" code path in updater (15201).
Windows: avoid writing to the registry (16236).
Also includes fixes for tickets 13047, 13301, 13356, 13594, 15406,
16014, 16909, 24476, and 25909.
Also fix Bug 26049: reduce the delay before the update prompt is displayed.
Instead of Firefox's 2 days, we use 1 hour (after which time the update
doorhanger will be displayed).
Also fix bug 27221: purge the startup cache if the Tor Browser
version changed (even if the Firefox version and build ID did
not change), e.g., after a minor Tor Browser update.
Also fix 32616: Disable GetSecureOutputDirectoryPath() functionality.
Bug 26048: potentially confusing "restart to update" message
Within the update doorhanger, remove the misleading message that mentions
that windows will be restored after an update is applied, and replace the
"Restart and Restore" button label with an existing
"Restart to update Tor Browser" string.
Bug 28885: notify users that update is downloading
Add a "Downloading Tor Browser update" item which appears in the
hamburger (app) menu while the update service is downloading a MAR
file. Before this change, the browser did not indicate to the user
that an update was in progress, which is especially confusing in
Tor Browser because downloads often take some time. If the user
clicks on the new menu item, the about dialog is opened to allow
the user to see download progress.
As part of this fix, the update service was changed to always show
update-related messages in the hamburger menu, even if the update
was started in the foreground via the about dialog or via the
"Check for Tor Browser Update" toolbar menu item. This change is
consistent with the Tor Browser goal of making sure users are
informed about the update process.
Removed #28885 parts of this patch which have been uplifted to Firefox.
---
browser/app/Makefile.in | 2 +
browser/app/profile/000-tor-browser.js | 16 +-
browser/app/profile/firefox.js | 10 +-
.../base/content/aboutDialog-appUpdater-legacy.js | 2 +-
browser/base/content/aboutDialog-appUpdater.js | 2 +-
browser/base/content/aboutDialog.js | 12 +-
browser/components/BrowserContentHandler.jsm | 39 ++-
.../customizableui/content/panelUI.inc.xhtml | 5 +-
browser/confvars.sh | 35 +--
browser/installer/package-manifest.in | 2 +
build/application.ini.in | 2 +-
build/moz.configure/init.configure | 3 +-
config/createprecomplete.py | 17 +-
.../client/aboutdebugging/src/actions/runtimes.js | 5 +
toolkit/modules/UpdateUtils.jsm | 34 +--
toolkit/mozapps/extensions/AddonManager.jsm | 24 ++
toolkit/mozapps/extensions/test/browser/head.js | 1 +
.../extensions/test/xpcshell/head_addons.js | 1 +
toolkit/mozapps/update/UpdateService.jsm | 127 +++++++-
toolkit/mozapps/update/UpdateServiceStub.jsm | 4 +
toolkit/mozapps/update/common/updatehelper.cpp | 8 +
toolkit/mozapps/update/moz.build | 5 +-
toolkit/mozapps/update/updater/launchchild_osx.mm | 2 +
toolkit/mozapps/update/updater/moz.build | 2 +-
toolkit/mozapps/update/updater/updater.cpp | 339 ++++++++++++++++++---
toolkit/xre/MacLaunchHelper.h | 2 +
toolkit/xre/MacLaunchHelper.mm | 2 +
toolkit/xre/nsAppRunner.cpp | 22 +-
toolkit/xre/nsUpdateDriver.cpp | 109 ++++++-
toolkit/xre/nsXREDirProvider.cpp | 42 ++-
tools/update-packaging/common.sh | 64 ++--
tools/update-packaging/make_full_update.sh | 38 +++
tools/update-packaging/make_incremental_update.sh | 141 ++++++++-
33 files changed, 963 insertions(+), 156 deletions(-)
diff --git a/browser/app/Makefile.in b/browser/app/Makefile.in
index 6770319f1866..7263b8e1dde7 100644
--- a/browser/app/Makefile.in
+++ b/browser/app/Makefile.in
@@ -98,10 +98,12 @@ tools repackage:: $(DIST)/bin/$(MOZ_APP_NAME)
rsync -aL $(DIST)/bin/$(MOZ_APP_NAME) '$(dist_dest)/Contents/MacOS'
cp -RL $(topsrcdir)/$(MOZ_BRANDING_DIRECTORY)/firefox.icns '$(dist_dest)/Contents/Resources/firefox.icns'
cp -RL $(topsrcdir)/$(MOZ_BRANDING_DIRECTORY)/document.icns '$(dist_dest)/Contents/Resources/document.icns'
+ifndef TOR_BROWSER_UPDATE
$(MKDIR) -p '$(dist_dest)/Contents/Library/LaunchServices'
ifdef MOZ_UPDATER
mv -f '$(dist_dest)/Contents/MacOS/updater.app/Contents/MacOS/org.mozilla.updater' '$(dist_dest)/Contents/Library/LaunchServices'
ln -s ../../../../Library/LaunchServices/org.mozilla.updater '$(dist_dest)/Contents/MacOS/updater.app/Contents/MacOS/org.mozilla.updater'
+endif
endif
printf APPLTORB > '$(dist_dest)/Contents/PkgInfo'
endif
diff --git a/browser/app/profile/000-tor-browser.js b/browser/app/profile/000-tor-browser.js
index 099f557a26f0..ab4cfba2ee50 100644
--- a/browser/app/profile/000-tor-browser.js
+++ b/browser/app/profile/000-tor-browser.js
@@ -7,7 +7,6 @@
// Disable initial homepage notifications
pref("browser.search.update", false);
pref("browser.rights.3.shown", true);
-pref("browser.startup.homepage_override.mstone", "ignore");
pref("startup.homepage_welcome_url", "");
pref("startup.homepage_welcome_url.additional", "");
@@ -20,9 +19,17 @@ pref("startup.homepage_override_url", "https://blog.torproject.org/category/tags
// Try to nag a bit more about updates: Pop up a restart dialog an hour after the initial dialog
pref("app.update.promptWaitTime", 3600);
-
-#ifdef XP_WIN
-// For now, disable staged updates on Windows (see #18292).
+pref("app.update.notifyDuringDownload", true);
+pref("app.update.url.manual", "https://www.torproject.org/download/languages/");
+pref("app.update.url.details", "https://www.torproject.org/download/");
+pref("app.update.badgeWaitTime", 0);
+pref("app.releaseNotesURL", "about:blank");
+
+#ifndef XP_MACOSX
+// Disable staged updates on platforms other than macOS.
+// Staged updates do not work on Windows due to #18292.
+// Also, on Windows and Linux any changes that are made to the browser profile
+// or Tor data after an update is staged will be lost.
pref("app.update.staging.enabled", false);
#endif
@@ -82,6 +89,7 @@ pref("datareporting.policy.dataSubmissionEnabled", false);
// Make sure Unified Telemetry is really disabled, see: #18738.
pref("toolkit.telemetry.unified", false);
pref("toolkit.telemetry.enabled", false);
+pref("toolkit.telemetry.updatePing.enabled", false); // Make sure updater telemetry is disabled; see #25909.
#ifdef XP_WIN
// Defense-in-depth: ensure that the Windows default browser agent will
// not ping Mozilla if it is somehow present (we omit it at build time).
diff --git a/browser/app/profile/firefox.js b/browser/app/profile/firefox.js
index 00042c2532ad..bf68a249cf8d 100644
--- a/browser/app/profile/firefox.js
+++ b/browser/app/profile/firefox.js
@@ -136,14 +136,8 @@ pref("app.update.elevation.promptMaxAttempts", 2);
pref("app.update.notifyDuringDownload", false);
// If set to true, the Update Service will automatically download updates if the
-// user can apply updates. This pref is no longer used on Windows, except as the
-// default value to migrate to the new location that this data is now stored
-// (which is in a file in the update directory). Because of this, this pref
-// should no longer be used directly. Instead, getAppUpdateAutoEnabled and
-// getAppUpdateAutoEnabled from UpdateUtils.jsm should be used.
-#ifndef XP_WIN
- pref("app.update.auto", true);
-#endif
+// user can apply updates.
+pref("app.update.auto", true);
// If set to true, the Update Service will apply updates in the background
// when it finishes downloading them.
diff --git a/browser/base/content/aboutDialog-appUpdater-legacy.js b/browser/base/content/aboutDialog-appUpdater-legacy.js
index 0629e8eaf41a..9f96e2263295 100644
--- a/browser/base/content/aboutDialog-appUpdater-legacy.js
+++ b/browser/base/content/aboutDialog-appUpdater-legacy.js
@@ -192,7 +192,7 @@ appUpdater.prototype = {
if (aChildID == "downloadAndInstall") {
let updateVersion = gAppUpdater.update.displayVersion;
// Include the build ID if this is an "a#" (nightly or aurora) build
- if (/a\d+$/.test(updateVersion)) {
+ if (!AppConstants.TOR_BROWSER_UPDATE && /a\d+$/.test(updateVersion)) {
let buildID = gAppUpdater.update.buildID;
let year = buildID.slice(0, 4);
let month = buildID.slice(4, 6);
diff --git a/browser/base/content/aboutDialog-appUpdater.js b/browser/base/content/aboutDialog-appUpdater.js
index 79828e5a279f..71de80626b89 100644
--- a/browser/base/content/aboutDialog-appUpdater.js
+++ b/browser/base/content/aboutDialog-appUpdater.js
@@ -147,7 +147,7 @@ appUpdater.prototype = {
if (aChildID == "downloadAndInstall") {
let updateVersion = gAppUpdater.update.displayVersion;
// Include the build ID if this is an "a#" (nightly or aurora) build
- if (/a\d+$/.test(updateVersion)) {
+ if (!AppConstants.TOR_BROWSER_UPDATE && /a\d+$/.test(updateVersion)) {
let buildID = gAppUpdater.update.buildID;
let year = buildID.slice(0, 4);
let month = buildID.slice(4, 6);
diff --git a/browser/base/content/aboutDialog.js b/browser/base/content/aboutDialog.js
index 19f0d6f16c6c..13dfe0e37ca2 100644
--- a/browser/base/content/aboutDialog.js
+++ b/browser/base/content/aboutDialog.js
@@ -50,15 +50,13 @@ async function init(aEvent) {
bits: Services.appinfo.is64Bit ? 64 : 32,
};
+ // Adjust version text to show the Tor Browser version
+ versionAttributes.version = AppConstants.TOR_BROWSER_VERSION +
+ " (based on Mozilla Firefox " +
+ AppConstants.MOZ_APP_VERSION_DISPLAY + ")";
+
let version = Services.appinfo.version;
if (/a\d+$/.test(version)) {
- versionId = "aboutDialog-version-nightly";
- let buildID = Services.appinfo.appBuildID;
- let year = buildID.slice(0, 4);
- let month = buildID.slice(4, 6);
- let day = buildID.slice(6, 8);
- versionAttributes.isodate = `${year}-${month}-${day}`;
-
document.getElementById("experimental").hidden = false;
document.getElementById("communityDesc").hidden = true;
}
diff --git a/browser/components/BrowserContentHandler.jsm b/browser/components/BrowserContentHandler.jsm
index 88512149e320..39ae2e7f5e2d 100644
--- a/browser/components/BrowserContentHandler.jsm
+++ b/browser/components/BrowserContentHandler.jsm
@@ -46,6 +46,8 @@ XPCOMUtils.defineLazyGlobalGetters(this, [URL]);
const NEWINSTALL_PAGE = "about:newinstall";
+const kTBSavedVersionPref = "browser.startup.homepage_override.torbrowser.version";
+
// One-time startup homepage override configurations
const ONCE_DOMAINS = ["mozilla.org", "firefox.com"];
const ONCE_PREF = "browser.startup.homepage_override.once";
@@ -105,7 +107,8 @@ const OVERRIDE_ALTERNATE_PROFILE = 4;
* Returns:
* OVERRIDE_NEW_PROFILE if this is the first run with a new profile.
* OVERRIDE_NEW_MSTONE if this is the first run with a build with a different
- * Gecko milestone (i.e. right after an upgrade).
+ * Gecko milestone or Tor Browser version (i.e. right
+ * after an upgrade).
* OVERRIDE_NEW_BUILD_ID if this is the first run with a new build ID of the
* same Gecko milestone (i.e. after a nightly upgrade).
* OVERRIDE_NONE otherwise.
@@ -128,6 +131,11 @@ function needHomepageOverride(prefb) {
var mstone = Services.appinfo.platformVersion;
+ var savedTBVersion = null;
+ try {
+ savedTBVersion = prefb.getCharPref(kTBSavedVersionPref);
+ } catch (e) {}
+
var savedBuildID = prefb.getCharPref(
"browser.startup.homepage_override.buildID",
""
@@ -146,7 +154,22 @@ function needHomepageOverride(prefb) {
prefb.setCharPref("browser.startup.homepage_override.mstone", mstone);
prefb.setCharPref("browser.startup.homepage_override.buildID", buildID);
- return savedmstone ? OVERRIDE_NEW_MSTONE : OVERRIDE_NEW_PROFILE;
+ prefb.setCharPref(kTBSavedVersionPref, AppConstants.TOR_BROWSER_VERSION);
+
+ // After an upgrade from an older release of Tor Browser (<= 5.5a1), the
+ // savedmstone will be undefined because those releases included the
+ // value "ignore" for the browser.startup.homepage_override.mstone pref.
+ // To correctly detect an upgrade vs. a new profile, we check for the
+ // presence of the "app.update.postupdate" pref.
+ let updated = prefb.prefHasUserValue("app.update.postupdate");
+ return (savedmstone || updated) ? OVERRIDE_NEW_MSTONE
+ : OVERRIDE_NEW_PROFILE;
+ }
+
+ if (AppConstants.TOR_BROWSER_VERSION != savedTBVersion) {
+ prefb.setCharPref("browser.startup.homepage_override.buildID", buildID);
+ prefb.setCharPref(kTBSavedVersionPref, AppConstants.TOR_BROWSER_VERSION);
+ return OVERRIDE_NEW_MSTONE;
}
if (buildID != savedBuildID) {
@@ -645,6 +668,13 @@ nsBrowserContentHandler.prototype = {
"browser.startup.homepage_override.buildID",
"unknown"
);
+
+ // We do the same for the Tor Browser version.
+ let old_tbversion = null;
+ try {
+ old_tbversion = prefb.getCharPref(kTBSavedVersionPref);
+ } catch (e) {}
+
override = needHomepageOverride(prefb);
if (override != OVERRIDE_NONE) {
switch (override) {
@@ -677,9 +707,10 @@ nsBrowserContentHandler.prototype = {
"startup.homepage_override_url"
);
let update = UpdateManager.activeUpdate;
+ let old_version = old_tbversion ? old_tbversion: old_mstone;
if (
update &&
- Services.vc.compare(update.appVersion, old_mstone) > 0
+ Services.vc.compare(update.appVersion, old_version) > 0
) {
overridePage = getPostUpdateOverridePage(update, overridePage);
// Send the update ping to signal that the update was successful.
@@ -687,6 +718,8 @@ nsBrowserContentHandler.prototype = {
}
overridePage = overridePage.replace("%OLD_VERSION%", old_mstone);
+ overridePage = overridePage.replace("%OLD_TOR_BROWSER_VERSION%",
+ old_tbversion);
break;
case OVERRIDE_NEW_BUILD_ID:
if (UpdateManager.activeUpdate) {
diff --git a/browser/components/customizableui/content/panelUI.inc.xhtml b/browser/components/customizableui/content/panelUI.inc.xhtml
index 8b326db72802..c84d5dd5c5a3 100644
--- a/browser/components/customizableui/content/panelUI.inc.xhtml
+++ b/browser/components/customizableui/content/panelUI.inc.xhtml
@@ -143,14 +143,15 @@
<popupnotification id="appMenu-update-restart-notification"
popupid="update-restart"
data-lazy-l10n-id="appmenu-update-restart"
- data-l10n-attrs="buttonlabel, buttonaccesskey, secondarybuttonlabel, secondarybuttonaccesskey"
+ data-l10n-attrs="buttonaccesskey, secondarybuttonlabel, secondarybuttonaccesskey"
+ buttonlabel="&updateRestart.panelUI.label2;"
closebuttonhidden="true"
dropmarkerhidden="true"
checkboxhidden="true"
buttonhighlight="true"
hidden="true">
<popupnotificationcontent id="update-restart-notification-content" orient="vertical">
- <description id="update-restart-description" data-lazy-l10n-id="appmenu-update-restart-message"></description>
+ <description id="update-restart-description"> </description>
</popupnotificationcontent>
</popupnotification>
diff --git a/browser/confvars.sh b/browser/confvars.sh
index 31f28736606d..f994783f9c65 100755
--- a/browser/confvars.sh
+++ b/browser/confvars.sh
@@ -7,26 +7,6 @@ MOZ_APP_BASENAME=Firefox
MOZ_APP_VENDOR=Mozilla
MOZ_UPDATER=1
-if test "$OS_ARCH" = "WINNT"; then
- if ! test "$HAVE_64BIT_BUILD"; then
- if test "$MOZ_UPDATE_CHANNEL" = "nightly" -o \
- "$MOZ_UPDATE_CHANNEL" = "nightly-try" -o \
- "$MOZ_UPDATE_CHANNEL" = "aurora" -o \
- "$MOZ_UPDATE_CHANNEL" = "beta" -o \
- "$MOZ_UPDATE_CHANNEL" = "release"; then
- if ! test "$MOZ_DEBUG"; then
- if ! test "$USE_STUB_INSTALLER"; then
- # Expect USE_STUB_INSTALLER from taskcluster for downstream task consistency
- echo "ERROR: STUB installer expected to be enabled but"
- echo "ERROR: USE_STUB_INSTALLER is not specified in the environment"
- exit 1
- fi
- MOZ_STUB_INSTALLER=1
- fi
- fi
- fi
-fi
-
BROWSER_CHROME_URL=chrome://browser/content/browser.xhtml
# MOZ_APP_DISPLAYNAME will be set by branding/configure.sh
@@ -39,6 +19,21 @@ MOZ_BRANDING_DIRECTORY=browser/branding/unofficial
MOZ_OFFICIAL_BRANDING_DIRECTORY=browser/branding/official
MOZ_APP_ID={ec8030f7-c20a-464f-9b0e-13a3a9e97384}
+# ACCEPTED_MAR_CHANNEL_IDS should usually be the same as the value MAR_CHANNEL_ID.
+# If more than one ID is needed, then you should use a comma separated list
+# of values.
+# The MAR_CHANNEL_ID must not contain the following 3 characters: ",\t "
+if test "$MOZ_UPDATE_CHANNEL" = "alpha"; then
+ ACCEPTED_MAR_CHANNEL_IDS=torbrowser-torproject-alpha
+ MAR_CHANNEL_ID=torbrowser-torproject-alpha
+elif test "$MOZ_UPDATE_CHANNEL" = "nightly"; then
+ ACCEPTED_MAR_CHANNEL_IDS=torbrowser-torproject-nightly
+ MAR_CHANNEL_ID=torbrowser-torproject-nightly
+else
+ ACCEPTED_MAR_CHANNEL_IDS=torbrowser-torproject-release
+ MAR_CHANNEL_ID=torbrowser-torproject-release
+fi
+
MOZ_PROFILE_MIGRATOR=1
# Include the DevTools client, not just the server (which is the default)
diff --git a/browser/installer/package-manifest.in b/browser/installer/package-manifest.in
index 133da76ee066..67f961dcd6f4 100644
--- a/browser/installer/package-manifest.in
+++ b/browser/installer/package-manifest.in
@@ -36,8 +36,10 @@
; Mac bundle stuff
@APPNAME@/Contents/Info.plist
#ifdef MOZ_UPDATER
+#ifndef TOR_BROWSER_UPDATE
@APPNAME@/Contents/Library/LaunchServices
#endif
+#endif
@APPNAME@/Contents/PkgInfo
@RESPATH@/firefox.icns
@RESPATH@/document.icns
diff --git a/build/application.ini.in b/build/application.ini.in
index a6141de0be15..96faf3775588 100644
--- a/build/application.ini.in
+++ b/build/application.ini.in
@@ -52,5 +52,5 @@ ServerURL=https://crash-reports.mozilla.com/submit?id=@MOZ_APP_ID@&version=…
#if MOZ_UPDATER
[AppUpdate]
-URL=https://@MOZ_APPUPDATE_HOST@/update/6/%PRODUCT%/%VERSION%/%BUILD_ID%/%BUILD_TARGET%/%LOCALE%/%CHANNEL%/%OS_VERSION%/%SYSTEM_CAPABILITIES%/%DISTRIBUTION%/%DISTRIBUTION_VERSION%/update.xml
+URL=https://aus1.torproject.org/torbrowser/update_3/%CHANNEL%/%BUILD_TARGET%/%VERSION%/%LOCALE%
#endif
diff --git a/build/moz.configure/init.configure b/build/moz.configure/init.configure
index 9345cb5e7f7d..7a1eeb98c848 100644
--- a/build/moz.configure/init.configure
+++ b/build/moz.configure/init.configure
@@ -1159,7 +1159,6 @@ def version_path(path):
# set RELEASE_OR_BETA and NIGHTLY_BUILD variables depending on the cycle we're in
# The logic works like this:
# - if we have "a1" in GRE_MILESTONE, we're building Nightly (define NIGHTLY_BUILD)
-# - otherwise, if we have "a" in GRE_MILESTONE, we're building Nightly or Aurora
# - otherwise, we're building Release/Beta (define RELEASE_OR_BETA)
@depends(check_build_environment, build_project, version_path, '--help')
@imports(_from='__builtin__', _import='open')
@@ -1206,7 +1205,7 @@ def milestone(build_env, build_project, version_path, _):
if 'a1' in milestone:
is_nightly = True
- elif 'a' not in milestone:
+ else:
is_release_or_beta = True
major_version = milestone.split('.')[0]
diff --git a/config/createprecomplete.py b/config/createprecomplete.py
index fadd796aa21f..73793c8e8b19 100644
--- a/config/createprecomplete.py
+++ b/config/createprecomplete.py
@@ -5,6 +5,7 @@
# update instructions which is used to remove files and directories that are no
# longer present in a complete update. The current working directory is used for
# the location to enumerate and to create the precomplete file.
+# For symlinks, remove instructions are always generated.
from __future__ import absolute_import
from __future__ import unicode_literals
@@ -13,9 +14,17 @@ import os
import io
+# TODO When TOR_BROWSER_DATA_OUTSIDE_APP_DIR is used on all platforms,
+# we should remove all lines in this file that contain:
+# TorBrowser/Data
+
def get_build_entries(root_path):
""" Iterates through the root_path, creating a list for each file and
directory. Excludes any file paths ending with channel-prefs.js.
+ To support Tor Browser updates, excludes:
+ TorBrowser/Data/Browser/profiles.ini
+ TorBrowser/Data/Browser/profile.default/bookmarks.html
+ TorBrowser/Data/Tor/torrc
"""
rel_file_path_set = set()
rel_dir_path_set = set()
@@ -26,6 +35,9 @@ def get_build_entries(root_path):
rel_path_file = rel_path_file.replace("\\", "/")
if not (rel_path_file.endswith("channel-prefs.js") or
rel_path_file.endswith("update-settings.ini") or
+ rel_path_file == "TorBrowser/Data/Browser/profiles.ini" or
+ rel_path_file == "TorBrowser/Data/Browser/profile.default/bookmarks.html" or
+ rel_path_file == "TorBrowser/Data/Tor/torrc" or
rel_path_file.find("distribution/") != -1):
rel_file_path_set.add(rel_path_file)
@@ -34,7 +46,10 @@ def get_build_entries(root_path):
rel_path_dir = os.path.join(parent_dir_rel_path, dir_name)
rel_path_dir = rel_path_dir.replace("\\", "/")+"/"
if rel_path_dir.find("distribution/") == -1:
- rel_dir_path_set.add(rel_path_dir)
+ if (os.path.islink(rel_path_dir[:-1])):
+ rel_file_path_set.add(rel_path_dir[:-1])
+ else:
+ rel_dir_path_set.add(rel_path_dir)
rel_file_path_list = list(rel_file_path_set)
rel_file_path_list.sort(reverse=True)
diff --git a/devtools/client/aboutdebugging/src/actions/runtimes.js b/devtools/client/aboutdebugging/src/actions/runtimes.js
index 6ac28b6b76a8..5ed1b7904952 100644
--- a/devtools/client/aboutdebugging/src/actions/runtimes.js
+++ b/devtools/client/aboutdebugging/src/actions/runtimes.js
@@ -67,6 +67,11 @@ async function getRuntimeIcon(runtime, channel) {
}
}
+ // Use the release build skin for devtools within Tor Browser alpha releases.
+ if (channel === "alpha") {
+ return "chrome://devtools/skin/images/aboutdebugging-firefox-release.svg";
+ }
+
return channel === "release" || channel === "beta" || channel === "aurora"
? `chrome://devtools/skin/images/aboutdebugging-firefox-${channel}.svg`
: "chrome://devtools/skin/images/aboutdebugging-firefox-nightly.svg";
diff --git a/toolkit/modules/UpdateUtils.jsm b/toolkit/modules/UpdateUtils.jsm
index d2b695b47442..883928472732 100644
--- a/toolkit/modules/UpdateUtils.jsm
+++ b/toolkit/modules/UpdateUtils.jsm
@@ -103,7 +103,7 @@ var UpdateUtils = {
case "PRODUCT":
return Services.appinfo.name;
case "VERSION":
- return Services.appinfo.version;
+ return AppConstants.TOR_BROWSER_VERSION;
case "BUILD_ID":
return Services.appinfo.appBuildID;
case "BUILD_TARGET":
@@ -167,25 +167,17 @@ var UpdateUtils = {
* downloads and installs updates. This corresponds to whether or not the user
* has selected "Automatically install updates" in about:preferences.
*
- * On Windows, this setting is shared across all profiles for the installation
+ * On Windows (except in Tor Browser), this setting is shared across all profiles
+ * for the installation
* and is read asynchronously from the file. On other operating systems, this
* setting is stored in a pref and is thus a per-profile setting.
*
* @return A Promise that resolves with a boolean.
*/
getAppUpdateAutoEnabled() {
- if (Services.policies) {
- if (!Services.policies.isAllowed("app-auto-updates-off")) {
- // We aren't allowed to turn off auto-update - it is forced on.
- return Promise.resolve(true);
- }
- if (!Services.policies.isAllowed("app-auto-updates-on")) {
- // We aren't allowed to turn on auto-update - it is forced off.
- return Promise.resolve(false);
- }
- }
- if (AppConstants.platform != "win") {
- // On platforms other than Windows the setting is stored in a preference.
+ if (AppConstants.TOR_BROWSER_UPDATE || (AppConstants.platform != "win")) {
+ // On platforms other than Windows and always in Tor Browser the setting
+ // is stored in a preference.
let prefValue = Services.prefs.getBoolPref(
PREF_APP_UPDATE_AUTO,
DEFAULT_APP_UPDATE_AUTO
@@ -256,7 +248,8 @@ var UpdateUtils = {
* updates" and "Check for updates but let you choose to install them" options
* in about:preferences.
*
- * On Windows, this setting is shared across all profiles for the installation
+ * On Windows (except in Tor Browser), this setting is shared across all profiles
+ * for the installation
* and is written asynchronously to the file. On other operating systems, this
* setting is stored in a pref and is thus a per-profile setting.
*
@@ -276,14 +269,9 @@ var UpdateUtils = {
* this operation simply sets a pref.
*/
setAppUpdateAutoEnabled(enabledValue) {
- if (this.appUpdateAutoSettingIsLocked()) {
- return Promise.reject(
- "setAppUpdateAutoEnabled: Unable to change value of setting because " +
- "it is locked by policy"
- );
- }
- if (AppConstants.platform != "win") {
- // Only in Windows do we store the update config in the update directory
+ if (AppConstants.TOR_BROWSER_UPDATE || (AppConstants.platform != "win")) {
+ // Only in Windows (but never for Tor Browser) do we store the update config
+ // in the update directory
let prefValue = !!enabledValue;
Services.prefs.setBoolPref(PREF_APP_UPDATE_AUTO, prefValue);
// Rather than call maybeUpdateAutoConfigChanged, a pref observer has
diff --git a/toolkit/mozapps/extensions/AddonManager.jsm b/toolkit/mozapps/extensions/AddonManager.jsm
index 2ef0232ab3bb..48876e3923e6 100644
--- a/toolkit/mozapps/extensions/AddonManager.jsm
+++ b/toolkit/mozapps/extensions/AddonManager.jsm
@@ -23,6 +23,7 @@ const { AppConstants } = ChromeUtils.import(
const MOZ_COMPATIBILITY_NIGHTLY = ![
"aurora",
+ "alpha",
"beta",
"release",
"esr",
@@ -37,6 +38,7 @@ const PREF_EM_AUTOUPDATE_DEFAULT = "extensions.update.autoUpdateDefault";
const PREF_EM_STRICT_COMPATIBILITY = "extensions.strictCompatibility";
const PREF_EM_CHECK_UPDATE_SECURITY = "extensions.checkUpdateSecurity";
const PREF_SYS_ADDON_UPDATE_ENABLED = "extensions.systemAddon.update.enabled";
+const PREF_EM_LAST_TORBROWSER_VERSION = "extensions.lastTorBrowserVersion";
const PREF_MIN_WEBEXT_PLATFORM_VERSION =
"extensions.webExtensionsMinPlatformVersion";
@@ -682,6 +684,28 @@ var AddonManagerInternal = {
);
}
+ // To ensure that extension and plugin code gets a chance to run
+ // after each browser update, set appChanged = true when the
+ // Tor Browser version has changed even if the Mozilla app
+ // version has not changed.
+ let tbChanged = undefined;
+ try {
+ tbChanged = AppConstants.TOR_BROWSER_VERSION !=
+ Services.prefs.getCharPref(PREF_EM_LAST_TORBROWSER_VERSION);
+ }
+ catch (e) { }
+ if (tbChanged !== false) {
+ // Because PREF_EM_LAST_TORBROWSER_VERSION was not present in older
+ // versions of Tor Browser, an app change is indicated when tbChanged
+ // is undefined or true.
+ if (appChanged === false) {
+ appChanged = true;
+ }
+
+ Services.prefs.setCharPref(PREF_EM_LAST_TORBROWSER_VERSION,
+ AppConstants.TOR_BROWSER_VERSION);
+ }
+
if (!MOZ_COMPATIBILITY_NIGHTLY) {
PREF_EM_CHECK_COMPATIBILITY =
PREF_EM_CHECK_COMPATIBILITY_BASE +
diff --git a/toolkit/mozapps/extensions/test/browser/head.js b/toolkit/mozapps/extensions/test/browser/head.js
index b7bfd6275d34..587319d92ce4 100644
--- a/toolkit/mozapps/extensions/test/browser/head.js
+++ b/toolkit/mozapps/extensions/test/browser/head.js
@@ -43,6 +43,7 @@ var PREF_CHECK_COMPATIBILITY;
var channel = Services.prefs.getCharPref("app.update.channel", "default");
if (
channel != "aurora" &&
+ channel != "alpha" &&
channel != "beta" &&
channel != "release" &&
channel != "esr"
diff --git a/toolkit/mozapps/extensions/test/xpcshell/head_addons.js b/toolkit/mozapps/extensions/test/xpcshell/head_addons.js
index 1cc9df5a0783..bebeff6b6ee2 100644
--- a/toolkit/mozapps/extensions/test/xpcshell/head_addons.js
+++ b/toolkit/mozapps/extensions/test/xpcshell/head_addons.js
@@ -390,6 +390,7 @@ function isNightlyChannel() {
return (
channel != "aurora" &&
+ channel != "alpha" &&
channel != "beta" &&
channel != "release" &&
channel != "esr"
diff --git a/toolkit/mozapps/update/UpdateService.jsm b/toolkit/mozapps/update/UpdateService.jsm
index 6c7de1de0be4..e9953032e1a2 100644
--- a/toolkit/mozapps/update/UpdateService.jsm
+++ b/toolkit/mozapps/update/UpdateService.jsm
@@ -32,11 +32,15 @@ XPCOMUtils.defineLazyGlobalGetters(this, ["DOMParser", "XMLHttpRequest"]);
XPCOMUtils.defineLazyModuleGetters(this, {
AsyncShutdown: "resource://gre/modules/AsyncShutdown.jsm",
CertUtils: "resource://gre/modules/CertUtils.jsm",
+#ifdef XP_WIN
ctypes: "resource://gre/modules/ctypes.jsm",
+#endif
DeferredTask: "resource://gre/modules/DeferredTask.jsm",
OS: "resource://gre/modules/osfile.jsm",
UpdateUtils: "resource://gre/modules/UpdateUtils.jsm",
+#if !defined(TOR_BROWSER_UPDATE)
WindowsRegistry: "resource://gre/modules/WindowsRegistry.jsm",
+#endif
});
const UPDATESERVICE_CID = Components.ID(
@@ -296,6 +300,7 @@ function testWriteAccess(updateTestFile, createDirectory) {
updateTestFile.remove(false);
}
+#ifdef XP_WIN
/**
* Windows only function that closes a Win32 handle.
*
@@ -388,6 +393,7 @@ function getPerInstallationMutexName(aGlobal = true) {
(aGlobal ? "Global\\" : "") + "MozillaUpdateMutex-" + hasher.finish(true)
);
}
+#endif
/**
* Whether or not the current instance has the update mutex. The update mutex
@@ -398,6 +404,7 @@ function getPerInstallationMutexName(aGlobal = true) {
* @return true if this instance holds the update mutex
*/
function hasUpdateMutex() {
+#ifdef XP_WIN
if (AppConstants.platform != "win") {
return true;
}
@@ -405,6 +412,9 @@ function hasUpdateMutex() {
gUpdateMutexHandle = createMutex(getPerInstallationMutexName(true), false);
}
return !!gUpdateMutexHandle;
+#else
+ return true;
+#endif
}
/**
@@ -435,6 +445,11 @@ function areDirectoryEntriesWriteable(aDir) {
* @return true if elevation is required, false otherwise
*/
function getElevationRequired() {
+#if defined(TOR_BROWSER_UPDATE)
+ // To avoid potential security holes associated with running the updater
+ // process with elevated privileges, Tor Browser does not support elevation.
+ return false;
+#else
if (AppConstants.platform != "macosx") {
return false;
}
@@ -469,6 +484,7 @@ function getElevationRequired() {
"not required"
);
return false;
+#endif
}
/**
@@ -501,6 +517,7 @@ function getCanApplyUpdates() {
return false;
}
+#if !defined(TOR_BROWSER_UPDATE)
if (AppConstants.platform == "macosx") {
LOG(
"getCanApplyUpdates - bypass the write since elevation can be used " +
@@ -516,6 +533,7 @@ function getCanApplyUpdates() {
);
return true;
}
+#endif
try {
if (AppConstants.platform == "win") {
@@ -1203,6 +1221,9 @@ function handleUpdateFailure(update, errorCode) {
cancelations++;
Services.prefs.setIntPref(PREF_APP_UPDATE_CANCELATIONS, cancelations);
if (AppConstants.platform == "macosx") {
+#if defined(TOR_BROWSER_UPDATE)
+ cleanupActiveUpdate();
+#else
let osxCancelations = Services.prefs.getIntPref(
PREF_APP_UPDATE_CANCELATIONS_OSX,
0
@@ -1226,6 +1247,7 @@ function handleUpdateFailure(update, errorCode) {
(update.state = STATE_PENDING_ELEVATE)
);
}
+#endif
update.statusText = gUpdateBundle.GetStringFromName("elevationFailure");
} else {
writeStatusFile(getUpdatesDir(), (update.state = STATE_PENDING));
@@ -1752,7 +1774,26 @@ function Update(update) {
this._patches.push(patch);
}
- if (!this._patches.length && !update.hasAttribute("unsupported")) {
+ if (update.hasAttribute("unsupported")) {
+ this.unsupported = ("true" == update.getAttribute("unsupported"));
+ } else if (update.hasAttribute("minSupportedOSVersion")) {
+ let minOSVersion = update.getAttribute("minSupportedOSVersion");
+ try {
+ let osVersion = Services.sysinfo.getProperty("version");
+ this.unsupported = (Services.vc.compare(osVersion, minOSVersion) < 0);
+ } catch (e) {}
+ }
+ if (!this.unsupported && update.hasAttribute("minSupportedInstructionSet")) {
+ let minInstructionSet = update.getAttribute("minSupportedInstructionSet");
+ if (['MMX', 'SSE', 'SSE2', 'SSE3',
+ 'SSE4A', 'SSE4_1', 'SSE4_2'].indexOf(minInstructionSet) >= 0) {
+ try {
+ this.unsupported = !Services.sysinfo.getProperty("has" + minInstructionSet);
+ } catch (e) {}
+ }
+ }
+
+ if (!this._patches.length && !this.unsupported) {
throw Components.Exception("", Cr.NS_ERROR_ILLEGAL_VALUE);
}
@@ -1790,9 +1831,7 @@ function Update(update) {
if (!isNaN(attr.value)) {
this.promptWaitTime = parseInt(attr.value);
}
- } else if (attr.name == "unsupported") {
- this.unsupported = attr.value == "true";
- } else {
+ } else if (attr.name != "unsupported") {
switch (attr.name) {
case "appVersion":
case "buildID":
@@ -1817,7 +1856,11 @@ function Update(update) {
}
if (!this.previousAppVersion) {
+#ifdef TOR_BROWSER_UPDATE
+ this.previousAppVersion = AppConstants.TOR_BROWSER_VERSION;
+#else
this.previousAppVersion = Services.appinfo.version;
+#endif
}
if (!this.elevationFailure) {
@@ -2200,6 +2243,7 @@ UpdateService.prototype = {
Services.obs.removeObserver(this, topic);
Services.prefs.removeObserver(PREF_APP_UPDATE_LOG, this);
+#ifdef XP_WIN
if (AppConstants.platform == "win" && gUpdateMutexHandle) {
// If we hold the update mutex, let it go!
// The OS would clean this up sometime after shutdown,
@@ -2207,6 +2251,7 @@ UpdateService.prototype = {
closeHandle(gUpdateMutexHandle);
gUpdateMutexHandle = null;
}
+#endif
if (this._retryTimer) {
this._retryTimer.cancel();
}
@@ -2240,6 +2285,7 @@ UpdateService.prototype = {
}
break;
case "test-close-handle-update-mutex":
+#ifdef XP_WIN
if (Cu.isInAutomation) {
if (AppConstants.platform == "win" && gUpdateMutexHandle) {
LOG("UpdateService:observe - closing mutex handle for testing");
@@ -2247,6 +2293,7 @@ UpdateService.prototype = {
gUpdateMutexHandle = null;
}
}
+#endif
break;
}
},
@@ -2268,6 +2315,9 @@ UpdateService.prototype = {
*/
_postUpdateProcessing: function AUS__postUpdateProcessing() {
gUpdateFileWriteInfo = { phase: "startup", failure: false };
+#if defined(TOR_BROWSER_UPDATE) && !defined(XP_MACOSX)
+ this._removeOrphanedTorBrowserFiles();
+#endif
if (!this.canCheckForUpdates) {
LOG(
"UpdateService:_postUpdateProcessing - unable to check for " +
@@ -2504,6 +2554,42 @@ UpdateService.prototype = {
}
},
+#if defined(TOR_BROWSER_UPDATE) && !defined(XP_MACOSX)
+ /**
+ * When updating from an earlier version to Tor Browser 6.0 or later, old
+ * update info files are left behind on Linux and Windows. Remove them.
+ */
+ _removeOrphanedTorBrowserFiles: function AUS__removeOrphanedTorBrowserFiles() {
+ try {
+ let oldUpdateInfoDir = getAppBaseDir(); // aka the Browser directory.
+
+#ifdef XP_WIN
+ // On Windows, the updater files were stored under
+ // Browser/TorBrowser/Data/Browser/Caches/firefox/
+ oldUpdateInfoDir.appendRelativePath(
+ "TorBrowser\\Data\\Browser\\Caches\\firefox");
+#endif
+
+ // Remove the updates directory.
+ let updatesDir = oldUpdateInfoDir.clone();
+ updatesDir.append("updates");
+ if (updatesDir.exists() && updatesDir.isDirectory()) {
+ updatesDir.remove(true);
+ }
+
+ // Remove files: active-update.xml and updates.xml
+ let filesToRemove = [ "active-update.xml", "updates.xml" ];
+ filesToRemove.forEach(function(aFileName) {
+ let f = oldUpdateInfoDir.clone();
+ f.append(aFileName);
+ if (f.exists()) {
+ f.remove(false);
+ }
+ });
+ } catch (e) {}
+ },
+#endif
+
/**
* Register an observer when the network comes online, so we can short-circuit
* the app.update.interval when there isn't connectivity
@@ -2859,9 +2945,14 @@ UpdateService.prototype = {
updates.forEach(function(aUpdate) {
// Ignore updates for older versions of the application and updates for
// the same version of the application with the same build ID.
- if (
- vc.compare(aUpdate.appVersion, Services.appinfo.version) < 0 ||
- (vc.compare(aUpdate.appVersion, Services.appinfo.version) == 0 &&
+#ifdef TOR_BROWSER_UPDATE
+ let compatVersion = AppConstants.TOR_BROWSER_VERSION;
+#else
+ let compatVersion = Services.appinfo.version;
+#endif
+ let rc = vc.compare(aUpdate.appVersion, compatVersion);
+ if (rc < 0 ||
+ (rc == 0 &&
aUpdate.buildID == Services.appinfo.appBuildID)
) {
LOG(
@@ -3214,20 +3305,32 @@ UpdateService.prototype = {
// current application's version or the update's version is the same as the
// application's version and the build ID is the same as the application's
// build ID.
+#ifdef TOR_BROWSER_UPDATE
+ let compatVersion = AppConstants.TOR_BROWSER_VERSION;
+#else
+ let compatVersion = Services.appinfo.version;
+#endif
if (
update.appVersion &&
- (Services.vc.compare(update.appVersion, Services.appinfo.version) < 0 ||
+ (Services.vc.compare(update.appVersion, compatVersion) < 0 ||
(update.buildID &&
update.buildID == Services.appinfo.appBuildID &&
- update.appVersion == Services.appinfo.version))
+ update.appVersion == compatVersion))
) {
LOG(
"UpdateService:downloadUpdate - canceling download of update since " +
"it is for an earlier or same application version and build ID.\n" +
+#ifdef TOR_BROWSER_UPDATE
+ "current Tor Browser version: " +
+ compatVersion +
+ "\n" +
+ "update Tor Browser version : " +
+#else
"current application version: " +
- Services.appinfo.version +
+ compatVersion +
"\n" +
"update application version : " +
+#endif
update.appVersion +
"\n" +
"current build ID: " +
@@ -3793,6 +3896,7 @@ Checker.prototype = {
*/
_callback: null,
+#if !defined(TOR_BROWSER_UPDATE)
_getCanMigrate: function UC__getCanMigrate() {
if (AppConstants.platform != "win") {
return false;
@@ -3862,6 +3966,7 @@ Checker.prototype = {
LOG("Checker:_getCanMigrate - no registry entries for this installation");
return false;
},
+#endif // !defined(TOR_BROWSER_UPDATE)
/**
* The URL of the update service XML file to connect to that contains details
@@ -3890,9 +3995,11 @@ Checker.prototype = {
url += (url.includes("?") ? "&" : "?") + "force=1";
}
+#if !defined(TOR_BROWSER_UPDATE)
if (this._getCanMigrate()) {
url += (url.includes("?") ? "&" : "?") + "mig64=1";
}
+#endif
LOG("Checker:getUpdateURL - update URL: " + url);
return url;
diff --git a/toolkit/mozapps/update/UpdateServiceStub.jsm b/toolkit/mozapps/update/UpdateServiceStub.jsm
index 3535131daa28..3ecfd97c8778 100644
--- a/toolkit/mozapps/update/UpdateServiceStub.jsm
+++ b/toolkit/mozapps/update/UpdateServiceStub.jsm
@@ -78,8 +78,12 @@ function UpdateServiceStub() {
// contains the status file's path
// We may need to migrate update data
+ // In Tor Browser we skip this because we do not use an update agent and we
+ // do not want to store any data outside of the browser installation directory.
+ // For more info, see https://bugzilla.mozilla.org/show_bug.cgi?id=1458314
if (
AppConstants.platform == "win" &&
+ !AppConstants.TOR_BROWSER_UPDATE &&
!Services.prefs.getBoolPref(prefUpdateDirMigrated, false)
) {
migrateUpdateDirectory();
diff --git a/toolkit/mozapps/update/common/updatehelper.cpp b/toolkit/mozapps/update/common/updatehelper.cpp
index b094d9eb75e9..c825d3c1ea8e 100644
--- a/toolkit/mozapps/update/common/updatehelper.cpp
+++ b/toolkit/mozapps/update/common/updatehelper.cpp
@@ -66,6 +66,13 @@ BOOL PathGetSiblingFilePath(LPWSTR destinationBuffer, LPCWSTR siblingFilePath,
* @return TRUE if successful
*/
BOOL GetSecureOutputDirectoryPath(LPWSTR outBuf) {
+#ifdef TOR_BROWSER_UPDATE
+ // This function is used to support the maintenance service and elevated
+ // updates and is therefore not called by Tor Browser's updater. We stub
+ // it out to avoid any chance that the Tor Browser updater will create
+ // files under C:\Program Files (x86)\ or a similar location.
+ return FALSE;
+#else
PWSTR progFilesX86;
if (FAILED(SHGetKnownFolderPath(FOLDERID_ProgramFilesX86, KF_FLAG_CREATE,
nullptr, &progFilesX86))) {
@@ -99,6 +106,7 @@ BOOL GetSecureOutputDirectoryPath(LPWSTR outBuf) {
}
return TRUE;
+#endif
}
/**
diff --git a/toolkit/mozapps/update/moz.build b/toolkit/mozapps/update/moz.build
index ddfda4571c31..d0c93895c1ec 100644
--- a/toolkit/mozapps/update/moz.build
+++ b/toolkit/mozapps/update/moz.build
@@ -22,11 +22,14 @@ EXTRA_COMPONENTS += [
EXTRA_JS_MODULES += [
'UpdateListener.jsm',
- 'UpdateService.jsm',
'UpdateServiceStub.jsm',
'UpdateTelemetry.jsm',
]
+EXTRA_PP_JS_MODULES += [
+ 'UpdateService.jsm',
+]
+
XPCOM_MANIFESTS += [
'components.conf',
]
diff --git a/toolkit/mozapps/update/updater/launchchild_osx.mm b/toolkit/mozapps/update/updater/launchchild_osx.mm
index 95c39f3d0e09..37677e8899f0 100644
--- a/toolkit/mozapps/update/updater/launchchild_osx.mm
+++ b/toolkit/mozapps/update/updater/launchchild_osx.mm
@@ -254,6 +254,7 @@ bool ObtainUpdaterArguments(int* argc, char*** argv) {
@end
+#ifndef TOR_BROWSER_UPDATE
bool ServeElevatedUpdate(int argc, const char** argv) {
MacAutoreleasePool pool;
@@ -269,6 +270,7 @@ bool ServeElevatedUpdate(int argc, const char** argv) {
[updater release];
return didSucceed;
}
+#endif
bool IsOwnedByGroupAdmin(const char* aAppBundle) {
MacAutoreleasePool pool;
diff --git a/toolkit/mozapps/update/updater/moz.build b/toolkit/mozapps/update/updater/moz.build
index a0eff9a3b7cd..ecc634c87037 100644
--- a/toolkit/mozapps/update/updater/moz.build
+++ b/toolkit/mozapps/update/updater/moz.build
@@ -49,7 +49,7 @@ xpcshell_cert.script = 'gen_cert_header.py:create_header'
dep1_cert.script = 'gen_cert_header.py:create_header'
dep2_cert.script = 'gen_cert_header.py:create_header'
-if CONFIG['MOZ_UPDATE_CHANNEL'] in ('beta', 'release', 'esr'):
+if CONFIG['MOZ_UPDATE_CHANNEL'] in ('alpha', 'beta', 'release', 'esr'):
primary_cert.inputs += ['release_primary.der']
secondary_cert.inputs += ['release_secondary.der']
elif CONFIG['MOZ_UPDATE_CHANNEL'] in ('nightly', 'aurora', 'nightly-elm',
diff --git a/toolkit/mozapps/update/updater/updater.cpp b/toolkit/mozapps/update/updater/updater.cpp
index 02e35ed81aa2..6e2e3a356b09 100644
--- a/toolkit/mozapps/update/updater/updater.cpp
+++ b/toolkit/mozapps/update/updater/updater.cpp
@@ -16,7 +16,7 @@
* updatev3.manifest
* -----------------
* method = "add" | "add-if" | "add-if-not" | "patch" | "patch-if" |
- * "remove" | "rmdir" | "rmrfdir" | type
+ * "remove" | "rmdir" | "rmrfdir" | "addsymlink" | type
*
* 'add-if-not' adds a file if it doesn't exist.
*
@@ -78,7 +78,9 @@ bool IsRecursivelyWritable(const char* aPath);
void LaunchChild(int argc, const char** argv);
void LaunchMacPostProcess(const char* aAppBundle);
bool ObtainUpdaterArguments(int* argc, char*** argv);
+# ifndef TOR_BROWSER_UPDATE
bool ServeElevatedUpdate(int argc, const char** argv);
+# endif
void SetGroupOwnershipAndPermissions(const char* aAppBundle);
struct UpdateServerThreadArgs {
int argc;
@@ -478,9 +480,12 @@ static const NS_tchar* get_relative_path(const NS_tchar* fullpath) {
* The line from the manifest that contains the path.
* @param isdir
* Whether the path is a directory path. Defaults to false.
+ * @param islinktarget
+ * Whether the path is a symbolic link target. Defaults to false.
* @return valid filesystem path or nullptr if the path checks fail.
*/
-static NS_tchar* get_valid_path(NS_tchar** line, bool isdir = false) {
+static NS_tchar* get_valid_path(NS_tchar** line, bool isdir = false,
+ bool islinktarget = false) {
NS_tchar* path = mstrtok(kQuote, line);
if (!path) {
LOG(("get_valid_path: unable to determine path: " LOG_S, *line));
@@ -516,10 +521,12 @@ static NS_tchar* get_valid_path(NS_tchar** line, bool isdir = false) {
path[NS_tstrlen(path) - 1] = NS_T('\0');
}
- // Don't allow relative paths that resolve to a parent directory.
- if (NS_tstrstr(path, NS_T("..")) != nullptr) {
- LOG(("get_valid_path: paths must not contain '..': " LOG_S, path));
- return nullptr;
+ if (!islinktarget) {
+ // Don't allow relative paths that resolve to a parent directory.
+ if (NS_tstrstr(path, NS_T("..")) != nullptr) {
+ LOG(("get_valid_path: paths must not contain '..': " LOG_S, path));
+ return nullptr;
+ }
}
return path;
@@ -559,7 +566,7 @@ static void ensure_write_permissions(const NS_tchar* path) {
(void)_wchmod(path, _S_IREAD | _S_IWRITE);
#else
struct stat fs;
- if (!stat(path, &fs) && !(fs.st_mode & S_IWUSR)) {
+ if (!lstat(path, &fs) && !S_ISLNK(fs.st_mode) && !(fs.st_mode & S_IWUSR)) {
(void)chmod(path, fs.st_mode | S_IWUSR);
}
#endif
@@ -746,11 +753,9 @@ static int ensure_copy(const NS_tchar* path, const NS_tchar* dest) {
return READ_ERROR;
}
-# ifdef XP_UNIX
if (S_ISLNK(ss.st_mode)) {
return ensure_copy_symlink(path, dest);
}
-# endif
AutoFile infile(ensure_open(path, NS_T("rb"), ss.st_mode));
if (!infile) {
@@ -837,12 +842,19 @@ static int ensure_copy_recursive(const NS_tchar* path, const NS_tchar* dest,
return READ_ERROR;
}
-#ifdef XP_UNIX
+#ifndef XP_WIN
if (S_ISLNK(sInfo.st_mode)) {
return ensure_copy_symlink(path, dest);
}
#endif
+#ifdef XP_UNIX
+ // Ignore Unix domain sockets. See #20691.
+ if (S_ISSOCK(sInfo.st_mode)) {
+ return 0;
+ }
+#endif
+
if (!S_ISDIR(sInfo.st_mode)) {
return ensure_copy(path, dest);
}
@@ -899,7 +911,7 @@ static int rename_file(const NS_tchar* spath, const NS_tchar* dpath,
}
struct NS_tstat_t spathInfo;
- rv = NS_tstat(spath, &spathInfo);
+ rv = NS_tlstat(spath, &spathInfo); // Get info about file or symlink.
if (rv) {
LOG(("rename_file: failed to read file status info: " LOG_S ", "
"err: %d",
@@ -907,7 +919,12 @@ static int rename_file(const NS_tchar* spath, const NS_tchar* dpath,
return READ_ERROR;
}
- if (!S_ISREG(spathInfo.st_mode)) {
+#ifdef XP_WIN
+ if (!S_ISREG(spathInfo.st_mode))
+#else
+ if (!S_ISREG(spathInfo.st_mode) && !S_ISLNK(spathInfo.st_mode))
+#endif
+ {
if (allowDirs && !S_ISDIR(spathInfo.st_mode)) {
LOG(("rename_file: path present, but not a file: " LOG_S ", err: %d",
spath, errno));
@@ -916,7 +933,12 @@ static int rename_file(const NS_tchar* spath, const NS_tchar* dpath,
LOG(("rename_file: proceeding to rename the directory"));
}
- if (!NS_taccess(dpath, F_OK)) {
+#ifdef XP_WIN
+ if (!NS_taccess(dpath, F_OK))
+#else
+ if (!S_ISLNK(spathInfo.st_mode) && !NS_taccess(dpath, F_OK))
+#endif
+ {
if (ensure_remove(dpath)) {
LOG(
("rename_file: destination file exists and could not be "
@@ -936,7 +958,7 @@ static int rename_file(const NS_tchar* spath, const NS_tchar* dpath,
return OK;
}
-#ifdef XP_WIN
+#if defined(XP_WIN) && !defined(TOR_BROWSER_UPDATE)
// Remove the directory pointed to by path and all of its files and
// sub-directories. If a file is in use move it to the tobedeleted directory
// and attempt to schedule removal of the file on reboot
@@ -1035,7 +1057,19 @@ static int backup_restore(const NS_tchar* path, const NS_tchar* relPath) {
NS_tsnprintf(relBackup, sizeof(relBackup) / sizeof(relBackup[0]),
NS_T("%s") BACKUP_EXT, relPath);
- if (NS_taccess(backup, F_OK)) {
+ bool isLink = false;
+#ifndef XP_WIN
+ struct stat linkInfo;
+ int rv = lstat(backup, &linkInfo);
+ if (rv) {
+ LOG(("backup_restore: cannot get info for backup file: " LOG_S ", err: %d",
+ relBackup, errno));
+ return OK;
+ }
+ isLink = S_ISLNK(linkInfo.st_mode);
+#endif
+
+ if (!isLink && NS_taccess(backup, F_OK)) {
LOG(("backup_restore: backup file doesn't exist: " LOG_S, relBackup));
return OK;
}
@@ -1053,8 +1087,18 @@ static int backup_discard(const NS_tchar* path, const NS_tchar* relPath) {
NS_tsnprintf(relBackup, sizeof(relBackup) / sizeof(relBackup[0]),
NS_T("%s") BACKUP_EXT, relPath);
+ bool isLink = false;
+#ifndef XP_WIN
+ struct stat linkInfo;
+ int rv2 = lstat(backup, &linkInfo);
+ if (rv2) {
+ return OK; // File does not exist; nothing to do.
+ }
+ isLink = S_ISLNK(linkInfo.st_mode);
+#endif
+
// Nothing to discard
- if (NS_taccess(backup, F_OK)) {
+ if (!isLink && NS_taccess(backup, F_OK)) {
return OK;
}
@@ -1069,6 +1113,8 @@ static int backup_discard(const NS_tchar* path, const NS_tchar* relPath) {
relBackup, relPath));
return WRITE_ERROR_DELETE_BACKUP;
}
+
+# if !defined(TOR_BROWSER_UPDATE)
// The MoveFileEx call to remove the file on OS reboot will fail if the
// process doesn't have write access to the HKEY_LOCAL_MACHINE registry key
// but this is ok since the installer / uninstaller will delete the
@@ -1085,6 +1131,7 @@ static int backup_discard(const NS_tchar* path, const NS_tchar* relPath) {
"file: " LOG_S,
relPath));
}
+# endif
}
#else
if (rv) {
@@ -1139,7 +1186,7 @@ class Action {
class RemoveFile : public Action {
public:
- RemoveFile() : mSkip(0) {}
+ RemoveFile() : mSkip(0), mIsLink(0) {}
int Parse(NS_tchar* line) override;
int Prepare() override;
@@ -1150,6 +1197,7 @@ class RemoveFile : public Action {
mozilla::UniquePtr<NS_tchar[]> mFile;
mozilla::UniquePtr<NS_tchar[]> mRelPath;
int mSkip;
+ int mIsLink;
};
int RemoveFile::Parse(NS_tchar* line) {
@@ -1172,28 +1220,39 @@ int RemoveFile::Parse(NS_tchar* line) {
}
int RemoveFile::Prepare() {
- // Skip the file if it already doesn't exist.
- int rv = NS_taccess(mFile.get(), F_OK);
- if (rv) {
- mSkip = 1;
- mProgressCost = 0;
- return OK;
+ int rv;
+#ifndef XP_WIN
+ struct stat linkInfo;
+ rv = lstat(mFile.get(), &linkInfo);
+ mIsLink = ((0 == rv) && S_ISLNK(linkInfo.st_mode));
+#endif
+
+ if (!mIsLink) {
+ // Skip the file if it already doesn't exist.
+ rv = NS_taccess(mFile.get(), F_OK);
+ if (rv) {
+ mSkip = 1;
+ mProgressCost = 0;
+ return OK;
+ }
}
LOG(("PREPARE REMOVEFILE " LOG_S, mRelPath.get()));
- // Make sure that we're actually a file...
- struct NS_tstat_t fileInfo;
- rv = NS_tstat(mFile.get(), &fileInfo);
- if (rv) {
- LOG(("failed to read file status info: " LOG_S ", err: %d", mFile.get(),
- errno));
- return READ_ERROR;
- }
+ if (!mIsLink) {
+ // Make sure that we're actually a file...
+ struct NS_tstat_t fileInfo;
+ rv = NS_tstat(mFile.get(), &fileInfo);
+ if (rv) {
+ LOG(("failed to read file status info: " LOG_S ", err: %d", mFile.get(),
+ errno));
+ return READ_ERROR;
+ }
- if (!S_ISREG(fileInfo.st_mode)) {
- LOG(("path present, but not a file: " LOG_S, mFile.get()));
- return DELETE_ERROR_EXPECTED_FILE;
+ if (!S_ISREG(fileInfo.st_mode)) {
+ LOG(("path present, but not a file: " LOG_S, mFile.get()));
+ return DELETE_ERROR_EXPECTED_FILE;
+ }
}
NS_tchar* slash = (NS_tchar*)NS_tstrrchr(mFile.get(), NS_T('/'));
@@ -1222,7 +1281,13 @@ int RemoveFile::Execute() {
// The file is checked for existence here and in Prepare since it might have
// been removed by a separate instruction: bug 311099.
- int rv = NS_taccess(mFile.get(), F_OK);
+ int rv = 0;
+ if (mIsLink) {
+ struct NS_tstat_t linkInfo;
+ rv = NS_tlstat(mFile.get(), &linkInfo);
+ } else {
+ rv = NS_taccess(mFile.get(), F_OK);
+ }
if (rv) {
LOG(("file cannot be removed because it does not exist; skipping"));
mSkip = 1;
@@ -1945,6 +2010,92 @@ void PatchIfFile::Finish(int status) {
PatchFile::Finish(status);
}
+#ifndef XP_WIN
+class AddSymlink : public Action {
+ public:
+ AddSymlink() : mAdded(false) {}
+
+ virtual int Parse(NS_tchar* line);
+ virtual int Prepare();
+ virtual int Execute();
+ virtual void Finish(int status);
+
+ private:
+ mozilla::UniquePtr<NS_tchar[]> mLinkPath;
+ mozilla::UniquePtr<NS_tchar[]> mRelPath;
+ mozilla::UniquePtr<NS_tchar[]> mTarget;
+ bool mAdded;
+};
+
+int AddSymlink::Parse(NS_tchar* line) {
+ // format "<linkname>" "target"
+
+ NS_tchar* validPath = get_valid_path(&line);
+ if (!validPath) return PARSE_ERROR;
+
+ mRelPath = mozilla::MakeUnique<NS_tchar[]>(MAXPATHLEN);
+ NS_tstrcpy(mRelPath.get(), validPath);
+ mLinkPath.reset(get_full_path(validPath));
+ if (!mLinkPath) {
+ return PARSE_ERROR;
+ }
+
+ // consume whitespace between args
+ NS_tchar* q = mstrtok(kQuote, &line);
+ if (!q) return PARSE_ERROR;
+
+ validPath = get_valid_path(&line, false, true);
+ if (!validPath) return PARSE_ERROR;
+
+ mTarget = mozilla::MakeUnique<NS_tchar[]>(MAXPATHLEN);
+ NS_tstrcpy(mTarget.get(), validPath);
+
+ return OK;
+}
+
+int AddSymlink::Prepare() {
+ LOG(("PREPARE ADDSYMLINK " LOG_S " -> " LOG_S, mRelPath.get(),
+ mTarget.get()));
+
+ return OK;
+}
+
+int AddSymlink::Execute() {
+ LOG(("EXECUTE ADDSYMLINK " LOG_S " -> " LOG_S, mRelPath.get(),
+ mTarget.get()));
+
+ // First make sure that we can actually get rid of any existing file or link.
+ struct stat linkInfo;
+ int rv = lstat(mLinkPath.get(), &linkInfo);
+ if ((0 == rv) && !S_ISLNK(linkInfo.st_mode)) {
+ rv = NS_taccess(mLinkPath.get(), F_OK);
+ }
+ if (rv == 0) {
+ rv = backup_create(mLinkPath.get());
+ if (rv) return rv;
+ } else {
+ rv = ensure_parent_dir(mLinkPath.get());
+ if (rv) return rv;
+ }
+
+ // Create the link.
+ rv = symlink(mTarget.get(), mLinkPath.get());
+ if (!rv) {
+ mAdded = true;
+ }
+
+ return rv;
+}
+
+void AddSymlink::Finish(int status) {
+ LOG(("FINISH ADDSYMLINK " LOG_S " -> " LOG_S, mRelPath.get(), mTarget.get()));
+ // When there is an update failure and a link has been added it is removed
+ // here since there might not be a backup to replace it.
+ if (status && mAdded) NS_tremove(mLinkPath.get());
+ backup_finish(mLinkPath.get(), mRelPath.get(), status);
+}
+#endif
+
//-----------------------------------------------------------------------------
#ifdef XP_WIN
@@ -2282,14 +2433,29 @@ static bool IsSecureUpdateStatusSucceeded(bool& isSucceeded) {
*/
static int CopyInstallDirToDestDir() {
// These files should not be copied over to the updated app
-#ifdef XP_WIN
-# define SKIPLIST_COUNT 3
-#elif XP_MACOSX
-# define SKIPLIST_COUNT 0
+#if defined(TOR_BROWSER_UPDATE) && !defined(TOR_BROWSER_DATA_OUTSIDE_APP_DIR)
+# ifdef XP_WIN
+# define SKIPLIST_COUNT 6
+# else
+# define SKIPLIST_COUNT 5
+# endif
#else
-# define SKIPLIST_COUNT 2
+# ifdef XP_WIN
+# define SKIPLIST_COUNT 3
+# elif XP_MACOSX
+# define SKIPLIST_COUNT 0
+# else
+# define SKIPLIST_COUNT 2
+# endif
#endif
copy_recursive_skiplist<SKIPLIST_COUNT> skiplist;
+#if defined(TOR_BROWSER_UPDATE) && !defined(TOR_BROWSER_DATA_OUTSIDE_APP_DIR)
+# ifdef XP_MACOSX
+ skiplist.append(0, gInstallDirPath, NS_T("Updated.app"));
+ skiplist.append(1, gInstallDirPath, NS_T("TorBrowser/UpdateInfo/updates/0"));
+# endif
+#endif
+
#ifndef XP_MACOSX
skiplist.append(0, gInstallDirPath, NS_T("updated"));
skiplist.append(1, gInstallDirPath, NS_T("updates/0"));
@@ -2298,6 +2464,19 @@ static int CopyInstallDirToDestDir() {
# endif
#endif
+#if defined(TOR_BROWSER_UPDATE) && !defined(TOR_BROWSER_DATA_OUTSIDE_APP_DIR)
+# ifdef XP_WIN
+ skiplist.append(SKIPLIST_COUNT - 3, gInstallDirPath,
+ NS_T("TorBrowser/Data/Browser/profile.default/parent.lock"));
+# else
+ skiplist.append(SKIPLIST_COUNT - 3, gInstallDirPath,
+ NS_T("TorBrowser/Data/Browser/profile.default/.parentlock"));
+# endif
+
+ skiplist.append(SKIPLIST_COUNT - 1, gInstallDirPath,
+ NS_T("TorBrowser/Data/Tor/lock"));
+#endif
+
return ensure_copy_recursive(gInstallDirPath, gWorkingDirPath, skiplist);
}
@@ -2435,7 +2614,9 @@ static int ProcessReplaceRequest() {
if (NS_taccess(deleteDir, F_OK)) {
NS_tmkdir(deleteDir, 0755);
}
+# if !defined(TOR_BROWSER_UPDATE)
remove_recursive_on_reboot(tmpDir, deleteDir);
+# endif
#endif
}
@@ -2443,8 +2624,45 @@ static int ProcessReplaceRequest() {
// On OS X, we we need to remove the staging directory after its Contents
// directory has been moved.
NS_tchar updatedAppDir[MAXPATHLEN];
+# if defined(TOR_BROWSER_UPDATE) && !defined(TOR_BROWSER_DATA_OUTSIDE_APP_DIR)
+ NS_tsnprintf(updatedAppDir, sizeof(updatedAppDir) / sizeof(updatedAppDir[0]),
+ NS_T("%s/Updated.app"), gInstallDirPath);
+ // For Tor Browser on OS X, we also need to copy everything else that is
+ // inside Updated.app.
+ NS_tDIR* dir = NS_topendir(updatedAppDir);
+ if (dir) {
+ NS_tdirent* entry;
+ while ((entry = NS_treaddir(dir)) != 0) {
+ if (NS_tstrcmp(entry->d_name, NS_T(".")) &&
+ NS_tstrcmp(entry->d_name, NS_T(".."))) {
+ NS_tchar childSrcPath[MAXPATHLEN];
+ NS_tsnprintf(childSrcPath,
+ sizeof(childSrcPath) / sizeof(childSrcPath[0]),
+ NS_T("%s/%s"), updatedAppDir, entry->d_name);
+ NS_tchar childDstPath[MAXPATHLEN];
+ NS_tsnprintf(childDstPath,
+ sizeof(childDstPath) / sizeof(childDstPath[0]),
+ NS_T("%s/%s"), gInstallDirPath, entry->d_name);
+ ensure_remove_recursive(childDstPath);
+ rv = rename_file(childSrcPath, childDstPath, true);
+ if (rv) {
+ LOG(("Moving " LOG_S " to " LOG_S " failed, err: %d", childSrcPath,
+ childDstPath, errno));
+ }
+ }
+ }
+
+ NS_tclosedir(dir);
+ } else {
+ LOG(("Updated.app dir can't be found: " LOG_S ", err: %d", updatedAppDir,
+ errno));
+ }
+# else
NS_tsnprintf(updatedAppDir, sizeof(updatedAppDir) / sizeof(updatedAppDir[0]),
NS_T("%s/Updated.app"), gPatchDirPath);
+# endif
+
+ // Remove the Updated.app directory.
ensure_remove_recursive(updatedAppDir);
#endif
@@ -2618,11 +2836,15 @@ static void UpdateThreadFunc(void* param) {
#ifdef XP_MACOSX
static void ServeElevatedUpdateThreadFunc(void* param) {
+# ifdef TOR_BROWSER_UPDATE
+ WriteStatusFile(ELEVATION_CANCELED);
+# else
UpdateServerThreadArgs* threadArgs = (UpdateServerThreadArgs*)param;
gSucceeded = ServeElevatedUpdate(threadArgs->argc, threadArgs->argv);
if (!gSucceeded) {
WriteStatusFile(ELEVATION_CANCELED);
}
+# endif
QuitProgressUI();
}
@@ -2646,7 +2868,7 @@ int LaunchCallbackAndPostProcessApps(int argc, NS_tchar** argv,
#endif
) {
if (argc > callbackIndex) {
-#if defined(XP_WIN)
+#if defined(XP_WIN) && !defined(TOR_BROWSER_UPDATE)
if (gSucceeded) {
if (!LaunchWinPostProcess(gInstallDirPath, gPatchDirPath)) {
fprintf(stderr, "The post update process was not launched");
@@ -2701,8 +2923,12 @@ int NS_main(int argc, NS_tchar** argv) {
UmaskContext umaskContext(0);
bool isElevated =
+# ifdef TOR_BROWSER_UPDATE
+ false;
+# else
strstr(argv[0], "/Library/PrivilegedHelperTools/org.mozilla.updater") !=
0;
+# endif
if (isElevated) {
if (!ObtainUpdaterArguments(&argc, &argv)) {
// Won't actually get here because ObtainUpdaterArguments will terminate
@@ -3346,6 +3572,26 @@ int NS_main(int argc, NS_tchar** argv) {
// using the service is because we are testing.
if (!useService && !noServiceFallback &&
updateLockFileHandle == INVALID_HANDLE_VALUE) {
+# ifdef TOR_BROWSER_UPDATE
+# ifdef TOR_BROWSER_DATA_OUTSIDE_APP_DIR
+ // Because the TorBrowser-Data directory that contains the user's
+ // profile is a sibling of the Tor Browser installation directory,
+ // the user probably has permission to apply updates. Therefore, to
+ // avoid potential security issues such as CVE-2015-0833, do not
+ // attempt to elevate privileges. Instead, write a "failed" message
+ // to the update status file (this function will return immediately
+ // after the CloseHandle(elevatedFileHandle) call below).
+# else
+ // Because the user profile is contained within the Tor Browser
+ // installation directory, the user almost certainly has permission to
+ // apply updates. Therefore, to avoid potential security issues such
+ // as CVE-2015-0833, do not attempt to elevate privileges. Instead,
+ // write a "failed" message to the update status file (this function
+ // will return immediately after the CloseHandle(elevatedFileHandle)
+ // call below).
+# endif
+ WriteStatusFile(WRITE_ERROR_ACCESS_DENIED);
+# else
// Get the secure ID before trying to update so it is possible to
// determine if the updater has created a new one.
char uuidStringBefore[UUID_LEN] = {'\0'};
@@ -3391,6 +3637,7 @@ int NS_main(int argc, NS_tchar** argv) {
gCopyOutputFiles = false;
WriteStatusFile(ELEVATION_CANCELED);
}
+# endif
}
// Note: The PostUpdate process is launched by the elevated updater which
@@ -3725,6 +3972,7 @@ int NS_main(int argc, NS_tchar** argv) {
if (!sStagedUpdate && !sReplaceRequest && _wrmdir(gDeleteDirPath)) {
LOG(("NS_main: unable to remove directory: " LOG_S ", err: %d", DELETE_DIR,
errno));
+# if !defined(TOR_BROWSER_UPDATE)
// The directory probably couldn't be removed due to it containing files
// that are in use and will be removed on OS reboot. The call to remove the
// directory on OS reboot is done after the calls to remove the files so the
@@ -3743,6 +3991,7 @@ int NS_main(int argc, NS_tchar** argv) {
"directory: " LOG_S,
DELETE_DIR));
}
+# endif
}
#endif /* XP_WIN */
@@ -4384,7 +4633,13 @@ int DoUpdate() {
action = new AddIfNotFile();
} else if (NS_tstrcmp(token, NS_T("patch-if")) == 0) { // Patch if exists
action = new PatchIfFile();
- } else {
+ }
+#ifndef XP_WIN
+ else if (NS_tstrcmp(token, NS_T("addsymlink")) == 0) {
+ action = new AddSymlink();
+ }
+#endif
+ else {
LOG(("DoUpdate: unknown token: " LOG_S, token));
free(buf);
return PARSE_ERROR;
diff --git a/toolkit/xre/MacLaunchHelper.h b/toolkit/xre/MacLaunchHelper.h
index f8dc75ee4d08..ce816acd83e2 100644
--- a/toolkit/xre/MacLaunchHelper.h
+++ b/toolkit/xre/MacLaunchHelper.h
@@ -17,7 +17,9 @@ extern "C" {
* pid of the terminated process to confirm that it executed successfully.
*/
void LaunchChildMac(int aArgc, char** aArgv, pid_t* aPid = 0);
+#ifndef TOR_BROWSER_UPDATE
bool LaunchElevatedUpdate(int aArgc, char** aArgv, pid_t* aPid = 0);
+#endif
}
#endif
diff --git a/toolkit/xre/MacLaunchHelper.mm b/toolkit/xre/MacLaunchHelper.mm
index ec570ffab124..da2917c2a99e 100644
--- a/toolkit/xre/MacLaunchHelper.mm
+++ b/toolkit/xre/MacLaunchHelper.mm
@@ -40,6 +40,7 @@ void LaunchChildMac(int aArgc, char** aArgv, pid_t* aPid) {
}
}
+#ifndef TOR_BROWSER_UPDATE
BOOL InstallPrivilegedHelper() {
AuthorizationRef authRef = NULL;
OSStatus status = AuthorizationCreate(
@@ -116,3 +117,4 @@ bool LaunchElevatedUpdate(int aArgc, char** aArgv, pid_t* aPid) {
}
return didSucceed;
}
+#endif
diff --git a/toolkit/xre/nsAppRunner.cpp b/toolkit/xre/nsAppRunner.cpp
index bda56973ad71..38932d126767 100644
--- a/toolkit/xre/nsAppRunner.cpp
+++ b/toolkit/xre/nsAppRunner.cpp
@@ -2754,6 +2754,11 @@ static bool CheckCompatibility(nsIFile* aProfileDir, const nsCString& aVersion,
gLastAppBuildID.Assign(gAppData->buildID);
nsAutoCString buf;
+
+ nsAutoCString tbVersion(TOR_BROWSER_VERSION_QUOTED);
+ rv = parser.GetString("Compatibility", "LastTorBrowserVersion", buf);
+ if (NS_FAILED(rv) || !tbVersion.Equals(buf)) return false;
+
rv = parser.GetString("Compatibility", "LastOSABI", buf);
if (NS_FAILED(rv) || !aOSABI.Equals(buf)) return false;
@@ -2839,6 +2844,12 @@ static void WriteVersion(nsIFile* aProfileDir, const nsCString& aVersion,
PR_Write(fd, kHeader, sizeof(kHeader) - 1);
PR_Write(fd, aVersion.get(), aVersion.Length());
+ nsAutoCString tbVersion(TOR_BROWSER_VERSION_QUOTED);
+ static const char kTorBrowserVersionHeader[] =
+ NS_LINEBREAK "LastTorBrowserVersion=";
+ PR_Write(fd, kTorBrowserVersionHeader, sizeof(kTorBrowserVersionHeader) - 1);
+ PR_Write(fd, tbVersion.get(), tbVersion.Length());
+
static const char kOSABIHeader[] = NS_LINEBREAK "LastOSABI=";
PR_Write(fd, kOSABIHeader, sizeof(kOSABIHeader) - 1);
PR_Write(fd, aOSABI.get(), aOSABI.Length());
@@ -4285,8 +4296,17 @@ int XREMain::XRE_mainStartup(bool* aExitFlag) {
if (CheckArg("test-process-updates")) {
SaveToEnv("MOZ_TEST_PROCESS_UPDATES=1");
}
+# ifdef TOR_BROWSER_UPDATE
+ nsAutoCString compatVersion(TOR_BROWSER_VERSION_QUOTED);
+# endif
ProcessUpdates(mDirProvider.GetGREDir(), exeDir, updRoot, gRestartArgc,
- gRestartArgv, mAppData->version);
+ gRestartArgv,
+# ifdef TOR_BROWSER_UPDATE
+ compatVersion.get()
+# else
+ mAppData->version
+# endif
+ );
if (EnvHasValue("MOZ_TEST_PROCESS_UPDATES")) {
SaveToEnv("MOZ_TEST_PROCESS_UPDATES=");
*aExitFlag = true;
diff --git a/toolkit/xre/nsUpdateDriver.cpp b/toolkit/xre/nsUpdateDriver.cpp
index 3694ec6f364c..20ad18b71dde 100644
--- a/toolkit/xre/nsUpdateDriver.cpp
+++ b/toolkit/xre/nsUpdateDriver.cpp
@@ -159,6 +159,13 @@ static nsresult GetInstallDirPath(nsIFile* appDir, nsACString& installDirPath) {
return NS_OK;
}
+#ifdef DEBUG
+static void dump_argv(const char* aPrefix, char** argv, int argc) {
+ printf("%s - %d args\n", aPrefix, argc);
+ for (int i = 0; i < argc; ++i) printf(" %d: %s\n", i, argv[i]);
+}
+#endif
+
static bool GetFile(nsIFile* dir, const nsACString& name,
nsCOMPtr<nsIFile>& result) {
nsresult rv;
@@ -220,6 +227,34 @@ typedef enum {
eAppliedService,
} UpdateStatus;
+#ifdef DEBUG
+static const char* UpdateStatusToString(UpdateStatus aStatus) {
+ const char* rv = "unknown";
+ switch (aStatus) {
+ case eNoUpdateAction:
+ rv = "NoUpdateAction";
+ break;
+ case ePendingUpdate:
+ rv = "PendingUpdate";
+ break;
+ case ePendingService:
+ rv = "PendingService";
+ break;
+ case ePendingElevate:
+ rv = "PendingElevate";
+ break;
+ case eAppliedUpdate:
+ rv = "AppliedUpdate";
+ break;
+ case eAppliedService:
+ rv = "AppliedService";
+ break;
+ }
+
+ return rv;
+}
+#endif
+
/**
* Returns a value indicating what needs to be done in order to handle an
* update.
@@ -292,9 +327,39 @@ static bool IsOlderVersion(nsIFile* versionFile, const char* appVersion) {
return false;
}
+#ifdef DEBUG
+ printf("IsOlderVersion checking appVersion %s against updateVersion %s\n",
+ appVersion, buf);
+#endif
+
return mozilla::Version(appVersion) > buf;
}
+#ifndef TOR_BROWSER_DATA_OUTSIDE_APP_DIR
+# if defined(TOR_BROWSER_UPDATE) && defined(XP_MACOSX)
+static nsresult GetUpdateDirFromAppDir(nsIFile* aAppDir, nsIFile** aResult) {
+ // On Mac OSX, we stage the update to an Updated.app directory that is
+ // directly below the main Tor Browser.app directory (two levels up from
+ // the appDir).
+ NS_ENSURE_ARG_POINTER(aAppDir);
+ NS_ENSURE_ARG_POINTER(aResult);
+ nsCOMPtr<nsIFile> parentDir1, parentDir2;
+ nsresult rv = aAppDir->GetParent(getter_AddRefs(parentDir1));
+ NS_ENSURE_SUCCESS(rv, rv);
+ rv = parentDir1->GetParent(getter_AddRefs(parentDir2));
+ NS_ENSURE_SUCCESS(rv, rv);
+
+ nsCOMPtr<nsIFile> updatedDir;
+ if (!GetFile(parentDir2, "Updated.app"_ns, updatedDir)) {
+ return NS_ERROR_FAILURE;
+ }
+
+ updatedDir.forget(aResult);
+ return NS_OK;
+}
+# endif
+#endif
+
/**
* Applies, switches, or stages an update.
*
@@ -442,7 +507,12 @@ static void ApplyUpdate(nsIFile* greDir, nsIFile* updateDir, nsIFile* appDir,
} else {
// Get the directory where the update is staged or will be staged.
#if defined(XP_MACOSX)
+# if defined(TOR_BROWSER_UPDATE) && !defined(TOR_BROWSER_DATA_OUTSIDE_APP_DIR)
+ rv = GetUpdateDirFromAppDir(appDir, getter_AddRefs(updatedDir));
+ if (NS_FAILED(rv)) {
+# else
if (!GetFile(updateDir, "Updated.app"_ns, updatedDir)) {
+# endif
#else
if (!GetFile(appDir, "updated"_ns, updatedDir)) {
#endif
@@ -537,6 +607,9 @@ static void ApplyUpdate(nsIFile* greDir, nsIFile* updateDir, nsIFile* appDir,
}
LOG(("spawning updater process [%s]\n", updaterPath.get()));
+#ifdef DEBUG
+ dump_argv("ApplyUpdate updater", argv, argc);
+#endif
#if defined(XP_UNIX) && !defined(XP_MACOSX)
// We use execv to spawn the updater process on all UNIX systems except Mac
@@ -574,6 +647,10 @@ static void ApplyUpdate(nsIFile* greDir, nsIFile* updateDir, nsIFile* appDir,
}
#elif defined(XP_MACOSX)
UpdateDriverSetupMacCommandLine(argc, argv, restart);
+# ifdef DEBUG
+dump_argv("ApplyUpdate after SetupMacCommandLine", argv, argc);
+# endif
+# ifndef TOR_BROWSER_UPDATE
// We need to detect whether elevation is required for this update. This can
// occur when an admin user installs the application, but another admin
// user attempts to update (see bug 394984).
@@ -586,6 +663,7 @@ if (restart && !IsRecursivelyWritable(installDirPath.get())) {
}
exit(0);
}
+# endif
if (isStaged) {
// Launch the updater to replace the installation with the staged updated.
@@ -656,9 +734,27 @@ static bool ProcessHasTerminated(ProcessType pt) {
nsresult ProcessUpdates(nsIFile* greDir, nsIFile* appDir, nsIFile* updRootDir,
int argc, char** argv, const char* appVersion,
bool restart, ProcessType* pid) {
+#if defined(XP_WIN) && defined(TOR_BROWSER_UPDATE)
+ // Try to remove the "tobedeleted" directory which, if present, contains
+ // files that could not be removed during a previous update (e.g., DLLs
+ // that were in use and therefore locked by Windows).
+ nsCOMPtr<nsIFile> deleteDir;
+ nsresult winrv = appDir->Clone(getter_AddRefs(deleteDir));
+ if (NS_SUCCEEDED(winrv)) {
+ winrv = deleteDir->AppendNative("tobedeleted"_ns);
+ if (NS_SUCCEEDED(winrv)) {
+ winrv = deleteDir->Remove(true);
+ }
+ }
+#endif
+
nsresult rv;
nsCOMPtr<nsIFile> updatesDir;
+#ifdef DEBUG
+ printf("ProcessUpdates updateRootDir: %s appVersion: %s\n",
+ updRootDir->HumanReadablePath().get(), appVersion);
+#endif
rv = updRootDir->Clone(getter_AddRefs(updatesDir));
NS_ENSURE_SUCCESS(rv, rv);
rv = updatesDir->AppendNative("updates"_ns);
@@ -678,6 +774,12 @@ nsresult ProcessUpdates(nsIFile* greDir, nsIFile* appDir, nsIFile* updRootDir,
nsCOMPtr<nsIFile> statusFile;
UpdateStatus status = GetUpdateStatus(updatesDir, statusFile);
+#ifdef DEBUG
+ printf("ProcessUpdates status: %s (%d)\n", UpdateStatusToString(status),
+ status);
+ printf("ProcessUpdates updatesDir: %s\n",
+ updatesDir->HumanReadablePath().get());
+#endif
switch (status) {
case ePendingUpdate:
case ePendingService: {
@@ -741,13 +843,16 @@ nsUpdateProcessor::ProcessUpdate() {
NS_ENSURE_SUCCESS(rv, rv);
}
+ nsAutoCString appVersion;
+#ifdef TOR_BROWSER_UPDATE
+ appVersion = TOR_BROWSER_VERSION_QUOTED;
+#else
nsCOMPtr<nsIXULAppInfo> appInfo =
do_GetService("@mozilla.org/xre/app-info;1", &rv);
NS_ENSURE_SUCCESS(rv, rv);
-
- nsAutoCString appVersion;
rv = appInfo->GetVersion(appVersion);
NS_ENSURE_SUCCESS(rv, rv);
+#endif
// Copy the parameters to the StagedUpdateInfo structure shared with the
// watcher thread.
diff --git a/toolkit/xre/nsXREDirProvider.cpp b/toolkit/xre/nsXREDirProvider.cpp
index b2ea009553ad..2ec6929b01a5 100644
--- a/toolkit/xre/nsXREDirProvider.cpp
+++ b/toolkit/xre/nsXREDirProvider.cpp
@@ -1256,6 +1256,41 @@ nsresult nsXREDirProvider::GetUpdateRootDir(nsIFile** aResult,
}
#endif
nsCOMPtr<nsIFile> updRoot;
+#if defined(TOR_BROWSER_UPDATE)
+ // For Tor Browser, we store update history, etc. within the UpdateInfo
+ // directory under the user data directory.
+ nsresult rv = GetTorBrowserUserDataDir(getter_AddRefs(updRoot));
+ NS_ENSURE_SUCCESS(rv, rv);
+ rv = updRoot->AppendNative("UpdateInfo"_ns);
+ NS_ENSURE_SUCCESS(rv, rv);
+# if defined(XP_MACOSX) && defined(TOR_BROWSER_DATA_OUTSIDE_APP_DIR)
+ // Since the TorBrowser-Data directory may be shared among different
+ // installations of the application, embed the app path in the update dir
+ // so that the update history is partitioned. This is much less likely to
+ // be an issue on Linux or Windows because the Tor Browser packages for
+ // those platforms include a "container" folder that provides partitioning
+ // by default, and we do not support use of a shared, OS-recommended area
+ // for user data on those platforms.
+ nsCOMPtr<nsIFile> appFile;
+ bool per = false;
+ rv = GetFile(XRE_EXECUTABLE_FILE, &per, getter_AddRefs(appFile));
+ NS_ENSURE_SUCCESS(rv, rv);
+ nsCOMPtr<nsIFile> appRootDirFile;
+ nsAutoString appDirPath;
+ if (NS_FAILED(appFile->GetParent(getter_AddRefs(appRootDirFile))) ||
+ NS_FAILED(appRootDirFile->GetPath(appDirPath))) {
+ return NS_ERROR_FAILURE;
+ }
+
+ int32_t dotIndex = appDirPath.RFind(".app");
+ if (dotIndex == kNotFound) {
+ dotIndex = appDirPath.Length();
+ }
+ appDirPath = Substring(appDirPath, 1, dotIndex - 1);
+ rv = updRoot->AppendRelativePath(appDirPath);
+ NS_ENSURE_SUCCESS(rv, rv);
+# endif
+#else // ! TOR_BROWSER_UPDATE
nsCOMPtr<nsIFile> appFile;
bool per = false;
nsresult rv = GetFile(XRE_EXECUTABLE_FILE, &per, getter_AddRefs(appFile));
@@ -1263,7 +1298,7 @@ nsresult nsXREDirProvider::GetUpdateRootDir(nsIFile** aResult,
rv = appFile->GetParent(getter_AddRefs(updRoot));
NS_ENSURE_SUCCESS(rv, rv);
-#ifdef XP_MACOSX
+# ifdef XP_MACOSX
nsCOMPtr<nsIFile> appRootDirFile;
nsCOMPtr<nsIFile> localDir;
nsAutoString appDirPath;
@@ -1297,7 +1332,7 @@ nsresult nsXREDirProvider::GetUpdateRootDir(nsIFile** aResult,
localDir.forget(aResult);
return NS_OK;
-#elif XP_WIN
+# elif XP_WIN
nsAutoString installPath;
rv = updRoot->GetPath(installPath);
NS_ENSURE_SUCCESS(rv, rv);
@@ -1326,7 +1361,8 @@ nsresult nsXREDirProvider::GetUpdateRootDir(nsIFile** aResult,
nsAutoString updatePathStr;
updatePathStr.Assign(updatePath.get());
updRoot->InitWithPath(updatePathStr);
-#endif // XP_WIN
+# endif // XP_WIN
+#endif // ! TOR_BROWSER_UPDATE
updRoot.forget(aResult);
return NS_OK;
}
diff --git a/tools/update-packaging/common.sh b/tools/update-packaging/common.sh
index 4b994f30169c..26eabbf31379 100755
--- a/tools/update-packaging/common.sh
+++ b/tools/update-packaging/common.sh
@@ -8,6 +8,10 @@
# Author: Darin Fisher
#
+# TODO When TOR_BROWSER_DATA_OUTSIDE_APP_DIR is used on all platforms,
+# we should remove all lines in this file that contain:
+# TorBrowser/Data
+
# -----------------------------------------------------------------------------
QUIET=0
@@ -76,17 +80,8 @@ make_add_instruction() {
forced=
fi
- is_extension=$(echo "$f" | grep -c 'distribution/extensions/.*/')
- if [ $is_extension = "1" ]; then
- # Use the subdirectory of the extensions folder as the file to test
- # before performing this add instruction.
- testdir=$(echo "$f" | sed 's/\(.*distribution\/extensions\/[^\/]*\)\/.*/\1/')
- verbose_notice " add-if \"$testdir\" \"$f\""
- echo "add-if \"$testdir\" \"$f\"" >> "$filev3"
- else
- verbose_notice " add \"$f\"$forced"
- echo "add \"$f\"" >> "$filev3"
- fi
+ verbose_notice " add \"$f\"$forced"
+ echo "add \"$f\"" >> "$filev3"
}
check_for_add_if_not_update() {
@@ -109,21 +104,21 @@ make_add_if_not_instruction() {
echo "add-if-not \"$f\" \"$f\"" >> "$filev3"
}
+make_addsymlink_instruction() {
+ link="$1"
+ target="$2"
+ filev3="$3"
+
+ verbose_notice " addsymlink: $link -> $target"
+ echo "addsymlink \"$link\" \"$target\"" >> "$filev3"
+}
+
make_patch_instruction() {
f="$1"
filev3="$2"
- is_extension=$(echo "$f" | grep -c 'distribution/extensions/.*/')
- if [ $is_extension = "1" ]; then
- # Use the subdirectory of the extensions folder as the file to test
- # before performing this add instruction.
- testdir=$(echo "$f" | sed 's/\(.*distribution\/extensions\/[^\/]*\)\/.*/\1/')
- verbose_notice " patch-if \"$testdir\" \"$f.patch\" \"$f\""
- echo "patch-if \"$testdir\" \"$f.patch\" \"$f\"" >> "$filev3"
- else
- verbose_notice " patch \"$f.patch\" \"$f\""
- echo "patch \"$f.patch\" \"$f\"" >> "$filev3"
- fi
+ verbose_notice " patch \"$f.patch\" \"$f\""
+ echo "patch \"$f.patch\" \"$f\"" >> "$filev3"
}
append_remove_instructions() {
@@ -168,6 +163,10 @@ append_remove_instructions() {
# List all files in the current directory, stripping leading "./"
# Pass a variable name and it will be filled as an array.
+# To support Tor Browser updates, skip the following files:
+# TorBrowser/Data/Browser/profiles.ini
+# TorBrowser/Data/Browser/profile.default/bookmarks.html
+# TorBrowser/Data/Tor/torrc
list_files() {
count=0
temp_filelist=$(mktemp)
@@ -178,6 +177,11 @@ list_files() {
| sed 's/\.\/\(.*\)/\1/' \
| sort -r > "${temp_filelist}"
while read file; do
+ if [ "$file" = "TorBrowser/Data/Browser/profiles.ini" -o \
+ "$file" = "TorBrowser/Data/Browser/profile.default/bookmarks.html" -o \
+ "$file" = "TorBrowser/Data/Tor/torrc" ]; then
+ continue;
+ fi
eval "${1}[$count]=\"$file\""
(( count++ ))
done < "${temp_filelist}"
@@ -199,3 +203,19 @@ list_dirs() {
done < "${temp_dirlist}"
rm "${temp_dirlist}"
}
+
+# List all symbolic links in the current directory, stripping leading "./"
+list_symlinks() {
+ count=0
+
+ find . -type l \
+ | sed 's/\.\/\(.*\)/\1/' \
+ | sort -r > "temp-symlinklist"
+ while read symlink; do
+ target=$(readlink "$symlink")
+ eval "${1}[$count]=\"$symlink\""
+ eval "${2}[$count]=\"$target\""
+ (( count++ ))
+ done < "temp-symlinklist"
+ rm "temp-symlinklist"
+}
diff --git a/tools/update-packaging/make_full_update.sh b/tools/update-packaging/make_full_update.sh
index db2c5898efdc..cc75a21dd51a 100755
--- a/tools/update-packaging/make_full_update.sh
+++ b/tools/update-packaging/make_full_update.sh
@@ -71,6 +71,20 @@ if [ ! -f "precomplete" ]; then
fi
list_files files
+list_symlinks symlinks symlink_targets
+
+# TODO When TOR_BROWSER_DATA_OUTSIDE_APP_DIR is used on all platforms,
+# we should remove the following lines (which remove entire directories
+# which, if present, contain old, unpacked copies of HTTPS Everywhere):
+# Make sure we delete the pre 5.1.0 HTTPS Everywhere as well in case it
+# exists. The extension ID got changed with the version bump to 5.1.0.
+ext_path='TorBrowser/Data/Browser/profile.default/extensions'
+if [ -d "$ext_dir" ]; then
+ directories_to_remove="$ext_path/https-everywhere(a)eff.org $ext_path/https-everywhere-eff(a)eff.org"
+else
+ directories_to_remove=""
+fi
+# END TOR_BROWSER_DATA_OUTSIDE_APP_DIR removal
popd
@@ -81,6 +95,21 @@ notice "Adding type instruction to update manifests"
notice " type complete"
echo "type \"complete\"" >> "$updatemanifestv3"
+# TODO When TOR_BROWSER_DATA_OUTSIDE_APP_DIR is used on all platforms,
+# we should remove the following lines:
+# If removal of any old, existing directories is desired, emit the appropriate
+# rmrfdir commands.
+notice ""
+notice "Adding directory removal instructions to update manifests"
+for dir_to_remove in $directories_to_remove; do
+ # rmrfdir requires a trailing slash; if slash is missing, add one.
+ if ! [[ "$dir_to_remove" =~ /$ ]]; then
+ dir_to_remove="${dir_to_remove}/"
+ fi
+ echo "rmrfdir \"$dir_to_remove\"" >> "$updatemanifestv3"
+done
+# END TOR_BROWSER_DATA_OUTSIDE_APP_DIR removal
+
notice ""
notice "Adding file add instructions to update manifests"
num_files=${#files[*]}
@@ -102,6 +131,15 @@ for ((i=0; $i<$num_files; i=$i+1)); do
targetfiles="$targetfiles \"$f\""
done
+notice ""
+notice "Adding symlink add instructions to update manifests"
+num_symlinks=${#symlinks[*]}
+for ((i=0; $i<$num_symlinks; i=$i+1)); do
+ link="${symlinks[$i]}"
+ target="${symlink_targets[$i]}"
+ make_addsymlink_instruction "$link" "$target" "$updatemanifestv3"
+done
+
# Append remove instructions for any dead files.
notice ""
notice "Adding file and directory remove instructions from file 'removed-files'"
diff --git a/tools/update-packaging/make_incremental_update.sh b/tools/update-packaging/make_incremental_update.sh
index 24d68616731a..2dd1e3077823 100755
--- a/tools/update-packaging/make_incremental_update.sh
+++ b/tools/update-packaging/make_incremental_update.sh
@@ -68,6 +68,21 @@ check_for_forced_update() {
## "true" *giggle*
return 0;
fi
+
+# TODO When TOR_BROWSER_DATA_OUTSIDE_APP_DIR is used on all platforms,
+# we should remove the following lines:
+ # If the file in the skip list ends with /*, do a prefix match.
+ # This allows TorBrowser/Data/Browser/profile.default/extensions/https-everywhere-eff(a)eff.org/*
+ # to be used to force all HTTPS Everywhere files to be updated.
+ f_suffix=${f##*/}
+ if [[ $f_suffix = "*" ]]; then
+ f_prefix="${f%\/\*}";
+ if [[ $forced_file_chk == $f_prefix* ]]; then
+ ## 0 means "true"
+ return 0;
+ fi
+ fi
+# END TOR_BROWSER_DATA_OUTSIDE_APP_DIR removal
done
## 'false'... because this is bash. Oh yay!
return 1;
@@ -78,7 +93,11 @@ if [ $# = 0 ]; then
exit 1
fi
-requested_forced_updates='Contents/MacOS/firefox'
+# Firefox uses requested_forced_updates='Contents/MacOS/firefox' due to
+# 770996 but in Tor Browser we do not need that fix.
+requested_forced_updates=""
+directories_to_remove=""
+extra_files_to_remove=""
while getopts "hqf:" flag
do
@@ -114,6 +133,83 @@ workdir="$(mktemp -d)"
updatemanifestv3="$workdir/updatev3.manifest"
archivefiles="updatev3.manifest"
+# TODO When TOR_BROWSER_DATA_OUTSIDE_APP_DIR is used on all platforms,
+# we should remove the following lines:
+# If the NoScript or HTTPS Everywhere extensions have changed between
+# releases, add them to the "force updates" list.
+ext_path='TorBrowser/Data/Browser/profile.default/extensions'
+if [ -d "$newdir/$ext_path" ]; then
+ https_everywhere_dir='https-everywhere-eff(a)eff.org'
+ https_everywhere_xpi='https-everywhere-eff(a)eff.org.xpi'
+ noscript='{73a6fe31-595d-460b-a920-fcc0f8843232}.xpi'
+
+ # NoScript is a packed extension, so we simply compare the old and the new
+ # .xpi files.
+ noscript_path="$ext_path/$noscript"
+ diff -a "$olddir/$noscript_path" "$newdir/$noscript_path" > /dev/null
+ rc=$?
+ if [ $rc -gt 1 ]; then
+ notice "Unexpected exit $rc from $noscript_path diff command"
+ exit 2
+ elif [ $rc -eq 1 ]; then
+ requested_forced_updates="$requested_forced_updates $noscript_path"
+ fi
+
+ # As of HTTPS Everywhere 5.1.0, the extension ID gained "-eff".
+ # As of HTTPS Everywhere 5.2.2, the extension is packed (i.e., it remains
+ # an .xpi after it is installed in the browser profile).
+ force_https_update=0
+ remove_unpacked_https_e_dirs=0
+ unpacked_https_e_install_rdf="$ext_path/$https_everywhere_dir/install.rdf"
+ packed_https_e_path="$ext_path/$https_everywhere_xpi"
+ if [ -d "$newdir/$ext_path/$https_everywhere_dir" ]; then
+ # The new HTTPS-E extension is unpacked, and presumably the old one is
+ # too. We need to determine if any of the unpacked files have changed.
+ # Since that is messy, we simply compare the old install.rdf file to the
+ # new one.
+ diff "$olddir/$unpacked_https_e_install_rdf" \
+ "$newdir/$unpacked_https_e_install_rdf" > /dev/null
+ rc=$?
+ if [ $rc -gt 1 -a -e "$olddir/$unpacked_https_e_install_rdf" ]; then
+ notice "Unexpected exit $rc from $unpacked_https_e_install_rdf diff command"
+ exit 2
+ elif [ $rc -ge 1 ]; then
+ force_https_update=1
+ remove_unpacked_https_e_dirs=1
+ # In case we still ship an unpacked HTTPS-E extension but the user has
+ # updated to a packed one, arrange for the packed one to be removed.
+ extra_files_to_remove="$extra_files_to_remove $packed_https_e_path"
+ fi
+ elif [ -d "$olddir/$ext_path/$https_everywhere_dir" ]; then
+ # The old HTTPS-E extension is unpacked but the new one is packed.
+ force_https_update=1
+ remove_unpacked_https_e_dirs=1
+ else
+ # Both the old and new HTTPS-E extensions are packed. In this case we can
+ # simply compare the .xpi files to determine if the extension has changed.
+ diff -a "$olddir/$packed_https_e_path" "$newdir/$packed_https_e_path" > /dev/null
+ rc=$?
+ if [ $rc -gt 1 ]; then
+ notice "Unexpected exit $rc from $packed_https_e_path diff command"
+ exit 2
+ elif [ $rc -eq 1 ]; then
+ force_https_update=1
+ fi
+ fi
+
+ if [ $force_https_update -ne 0 ]; then
+ requested_forced_updates="$requested_forced_updates $ext_path/$https_everywhere_dir/* $packed_https_e_path"
+ if [ "$remove_unpacked_https_e_dirs" -ne 0 ]; then
+ # The old version was unpacked, so remove the entire directory to ensure
+ # that the replace is "clean." Also, make sure we delete the pre 5.1.0
+ # HTTPS Everywhere as well in case it exists (the extension ID got
+ # changed with the version bump to 5.1.0).
+ directories_to_remove="$directories_to_remove $ext_path/https-everywhere(a)eff.org $ext_path/$https_everywhere_dir"
+ fi
+ fi
+fi
+# END TOR_BROWSER_DATA_OUTSIDE_APP_DIR removal
+
mkdir -p "$workdir"
# Generate a list of all files in the target directory.
@@ -124,6 +220,7 @@ fi
list_files oldfiles
list_dirs olddirs
+list_symlinks oldsymlinks oldsymlink_targets
popd
@@ -141,6 +238,7 @@ fi
list_dirs newdirs
list_files newfiles
+list_symlinks newsymlinks newsymlink_targets
popd
@@ -151,6 +249,22 @@ notice "Adding type instruction to update manifests"
notice " type partial"
echo "type \"partial\"" >> $updatemanifestv3
+# TODO When TOR_BROWSER_DATA_OUTSIDE_APP_DIR is used on all platforms,
+# we should remove the following lines:
+# If removal of any old, existing directories is desired, emit the appropriate
+# rmrfdir commands.
+notice ""
+notice "Adding directory removal instructions to update manifests"
+for dir_to_remove in $directories_to_remove; do
+ # rmrfdir requires a trailing slash, so add one if missing.
+ if ! [[ "$dir_to_remove" =~ /$ ]]; then
+ dir_to_remove="${dir_to_remove}/"
+ fi
+ echo "rmrfdir \"$dir_to_remove\"" >> "$updatemanifestv3"
+done
+# END TOR_BROWSER_DATA_OUTSIDE_APP_DIR removal
+
+
notice ""
notice "Adding file patch and add instructions to update manifests"
@@ -242,6 +356,23 @@ for ((i=0; $i<$num_oldfiles; i=$i+1)); do
fi
done
+# Remove and re-add symlinks
+notice ""
+notice "Adding symlink remove/add instructions to update manifests"
+num_oldsymlinks=${#oldsymlinks[*]}
+for ((i=0; $i<$num_oldsymlinks; i=$i+1)); do
+ link="${oldsymlinks[$i]}"
+ verbose_notice " remove: $link"
+ echo "remove \"$link\"" >> "$updatemanifestv3"
+done
+
+num_newsymlinks=${#newsymlinks[*]}
+for ((i=0; $i<$num_newsymlinks; i=$i+1)); do
+ link="${newsymlinks[$i]}"
+ target="${newsymlink_targets[$i]}"
+ make_addsymlink_instruction "$link" "$target" "$updatemanifestv3"
+done
+
# Newly added files
notice ""
notice "Adding file add instructions to update manifests"
@@ -286,6 +417,14 @@ notice ""
notice "Adding file and directory remove instructions from file 'removed-files'"
append_remove_instructions "$newdir" "$updatemanifestv3"
+# TODO When TOR_BROWSER_DATA_OUTSIDE_APP_DIR is used on all platforms,
+# we should remove the following lines:
+for f in $extra_files_to_remove; do
+ notice " remove \"$f\""
+ echo "remove \"$f\"" >> "$updatemanifestv3"
+done
+# END TOR_BROWSER_DATA_OUTSIDE_APP_DIR removal
+
notice ""
notice "Adding directory remove instructions for directories that no longer exist"
num_olddirs=${#olddirs[*]}
1
0