commit 7719a132533d0e245602b9aee496875a8cb03cd5
Author: Kathy Brade <brade(a)pearlcrescent.com>
Date: Wed Jan 17 14:01:51 2018 -0500
fixup! Bug 16940: After update, load local change notes.
Always load about:tbupdate in a content process.
To improve compatiblity with future sandboxing efforts, relocate the
code that accesses the file system (changelog) to the chrome process.
Avoid using a query string to pass the "more info" link to the
about:tbupdate page.
Remove obsolete flag nsIAboutModule::MAKE_UNLINKABLE (about: pages
are unlinkable by default).
---
browser/base/content/browser.js | 22 +++--
browser/base/content/tab-content.js | 104 ++++++++----------------
browser/base/jar.mn | 2 +-
browser/base/moz.build | 3 +
browser/components/about/AboutRedirector.cpp | 2 +-
browser/components/nsBrowserContentHandler.js | 5 +-
browser/components/nsBrowserGlue.js | 9 +++
browser/modules/AboutTBUpdate.jsm | 111 ++++++++++++++++++++++++++
browser/modules/moz.build | 5 ++
toolkit/modules/AppConstants.jsm | 7 ++
toolkit/modules/moz.build | 3 +
11 files changed, 186 insertions(+), 87 deletions(-)
diff --git a/browser/base/content/browser.js b/browser/base/content/browser.js
index 5c0d9a4d7161..5eabd3373b71 100755
--- a/browser/base/content/browser.js
+++ b/browser/base/content/browser.js
@@ -215,9 +215,6 @@ this.__defineSetter__("AddonManager", function (val) {
var gInitialPages = [
"about:tor",
-#ifdef TOR_BROWSER_UPDATE
- "about:tbupdate",
-#endif
"about:blank",
"about:newtab",
"about:home",
@@ -225,6 +222,9 @@ var gInitialPages = [
"about:welcomeback",
"about:sessionrestore"
];
+if (AppConstants.TOR_BROWSER_UPDATE) {
+ gInitialPages.push("about:tbupdate");
+}
function* browserWindows() {
let windows = Services.wm.getEnumerator("navigator:browser");
@@ -2420,13 +2420,8 @@ function URLBarSetURI(aURI) {
// 2. if remote newtab is enabled and it's the default remote newtab page
let defaultRemoteURL = gAboutNewTabService.remoteEnabled &&
uri.spec === gAboutNewTabService.newTabURL;
-#ifdef TOR_BROWSER_UPDATE
- if ((gInitialPages.includes(uri.spec.split('?')[0]) || defaultRemoteURL) &&
- checkEmptyPageOrigin(gBrowser.selectedBrowser, uri))
-#else
if ((gInitialPages.includes(uri.spec) || defaultRemoteURL) &&
checkEmptyPageOrigin(gBrowser.selectedBrowser, uri))
-#endif
{
value = "";
} else {
@@ -7453,11 +7448,12 @@ var gIdentityHandler = {
this._uriHasHost = false;
}
-#ifdef TOR_BROWSER_UPDATE
- let whitelist = /^(?:accounts|addons|cache|config|crashes|customizing|downloads|healthreport|home|license|newaddon|permissions|preferences|privatebrowsing|rights|searchreset|sessionrestore|support|welcomeback|tor|tbupdate)(?:[?#]|$)/i;
-#else
- let whitelist = /^(?:accounts|addons|cache|config|crashes|customizing|downloads|healthreport|home|license|newaddon|permissions|preferences|privatebrowsing|rights|searchreset|sessionrestore|support|welcomeback|tor)(?:[?#]|$)/i;
-#endif
+ let whitelist;
+ if (AppConstants.TOR_BROWSER_UPDATE) {
+ whitelist = /^(?:accounts|addons|cache|config|crashes|customizing|downloads|healthreport|home|license|newaddon|permissions|preferences|privatebrowsing|rights|searchreset|sessionrestore|support|welcomeback|tor|tbupdate)(?:[?#]|$)/i;
+ } else {
+ whitelist = /^(?:accounts|addons|cache|config|crashes|customizing|downloads|healthreport|home|license|newaddon|permissions|preferences|privatebrowsing|rights|searchreset|sessionrestore|support|welcomeback|tor)(?:[?#]|$)/i;
+ }
this._isSecureInternalUI = uri.schemeIs("about") && whitelist.test(uri.path);
// Create a channel for the sole purpose of getting the resolved URI
diff --git a/browser/base/content/tab-content.js b/browser/base/content/tab-content.js
index d7d565ec50de..9aefa567fbae 100644
--- a/browser/base/content/tab-content.js
+++ b/browser/base/content/tab-content.js
@@ -5,19 +5,11 @@
/* This content script contains code that requires a tab browser. */
-#ifdef TOR_BROWSER_VERSION
-# Add double-quotes back on (stripped by JarMaker.py).
-#expand const TOR_BROWSER_VERSION = "__TOR_BROWSER_VERSION__";
-#endif
-
var {classes: Cc, interfaces: Ci, utils: Cu, results: Cr} = Components;
Cu.import("resource://gre/modules/XPCOMUtils.jsm");
Cu.import("resource://gre/modules/Services.jsm");
Cu.import("resource://gre/modules/ExtensionContent.jsm");
-#ifdef TOR_BROWSER_UPDATE
-Cu.import("resource://gre/modules/NetUtil.jsm");
-#endif
XPCOMUtils.defineLazyModuleGetter(this, "E10SUtils",
"resource:///modules/E10SUtils.jsm");
@@ -408,80 +400,50 @@ let AboutTBUpdateListener = {
},
get isAboutTBUpdate() {
- return content.document.documentURI.split('?')[0].toLowerCase()
- == "about:tbupdate";
+ return content.document.documentURI.toLowerCase() == "about:tbupdate";
},
handleEvent: function(aEvent) {
- if (this.isAboutTBUpdate && (aEvent.type == "AboutTBUpdateLoad"))
- this.onPageLoad();
- },
+ if (!this.isAboutTBUpdate)
+ return;
- onPageLoad: function() {
- let doc = content.document;
- doc.getElementById("infolink").setAttribute("href", this.getPostUpdateURL());
- doc.getElementById("changelog").textContent = this.getChangeLogText();
-
- const kBrandBundle = "chrome://branding/locale/brand.properties";
- let brandBundle = Cc["@mozilla.org/intl/stringbundle;1"]
- .getService(Ci.nsIStringBundleService)
- .createBundle(kBrandBundle);
- let productName = brandBundle.GetStringFromName("brandFullName");
- doc.getElementById("torbrowser-version").textContent = productName + "\n"
- + TOR_BROWSER_VERSION;
+ switch (aEvent.type) {
+ case "AboutTBUpdateLoad":
+ this.onPageLoad();
+ break;
+ case "pagehide":
+ this.onPageHide(aEvent);
+ break;
+ }
},
- // Extract the post update URL from this page's query string.
- getPostUpdateURL: function() {
- let idx = content.document.documentURI.indexOf('?');
- if (idx > 0)
- return decodeURIComponent(content.document.documentURI.substring(idx+1));
-
- // No query string: use the default URL.
- return Services.urlFormatter.formatURLPref("startup.homepage_override_url");
+ receiveMessage: function(aMessage) {
+ if (this.isAboutTBUpdate && (aMessage.name == "AboutTBUpdate:Update"))
+ this.onUpdate(aMessage.data);
},
- // Read and return the text from the beginning of the changelog file that is
- // located at TorBrowser/Docs/ChangeLog.txt.
- // On Mac OS, when building with --enable-tor-browser-data-outside-app-dir
- // to support Gatekeeper signing, the file is located in
- // TorBrowser.app/Contents/Resources/TorBrowser/Docs/.
- //
- // When electrolysis is enabled we will need to adopt an architecture that is
- // more similar to the one that is used for about:home (see AboutHomeListener
- // in this file and browser/modules/AboutHome.jsm).
- getChangeLogText: function() {
- try {
-#ifdef 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/.
- let f = Services.dirsvc.get("XREExeF", Ci.nsIFile).parent;
-#ifdef XP_MACOSX
- f = f.parent;
- f.append("Resources");
-#endif
- f.append("TorBrowser");
-#else
- // "DefProfRt" is .../TorBrowser/Data/Browser
- let f = Cc["@mozilla.org/file/directory_service;1"]
- .getService(Ci.nsIProperties).get("DefProfRt", Ci.nsIFile);
- f = f.parent.parent; // Remove "Data/Browser"
-#endif
- 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();
+ onUpdate: function(aData) {
+ let doc = content.document;
+ doc.getElementById("torbrowser-version").textContent = aData.productInfo;
+ if (aData.moreInfoURL)
+ doc.getElementById("infolink").setAttribute("href", aData.moreInfoURL);
+ doc.getElementById("changelog").textContent = aData.changeLog;
+ },
- // Truncate at the first empty line.
- return s.replace(/[\r\n][\r\n][\s\S]*$/m, "");
- } catch (e) {}
+ onPageLoad: function() {
+ addMessageListener("AboutTBUpdate:Update", this);
+ addEventListener("pagehide", this, true);
+ sendAsyncMessage("AboutTBUpdate:RequestUpdate");
+ },
- return "";
+ onPageHide: function(aEvent) {
+ if (aEvent.target.defaultView.frameElement) {
+ return;
+ }
+ removeMessageListener("AboutTBUpdate:Update", this);
+ removeEventListener("pagehide", this, true);
},
+
};
AboutTBUpdateListener.init(this);
#endif
diff --git a/browser/base/jar.mn b/browser/base/jar.mn
index 2b0f744b42cb..9d2f100a9717 100644
--- a/browser/base/jar.mn
+++ b/browser/base/jar.mn
@@ -75,7 +75,7 @@ browser.jar:
content/browser/abouttbupdate/aboutTBUpdateLogo.png (content/abouttbupdate/aboutTBUpdateLogo.png)
#endif
* content/browser/browser.css (content/browser.css)
-* content/browser/browser.js (content/browser.js)
+ content/browser/browser.js (content/browser.js)
* content/browser/browser.xul (content/browser.xul)
content/browser/browser-addons.js (content/browser-addons.js)
content/browser/browser-captivePortal.js (content/browser-captivePortal.js)
diff --git a/browser/base/moz.build b/browser/base/moz.build
index 46634999261c..dc15e2902bb8 100644
--- a/browser/base/moz.build
+++ b/browser/base/moz.build
@@ -47,4 +47,7 @@ if CONFIG['MOZ_WIDGET_TOOLKIT'] in ('windows', 'cocoa'):
if CONFIG['MOZ_WIDGET_TOOLKIT'] in ('windows', 'gtk2', 'gtk3'):
DEFINES['MENUBAR_CAN_AUTOHIDE'] = 1
+if CONFIG['TOR_BROWSER_UPDATE']:
+ DEFINES['TOR_BROWSER_UPDATE'] = 1
+
JAR_MANIFESTS += ['jar.mn']
diff --git a/browser/components/about/AboutRedirector.cpp b/browser/components/about/AboutRedirector.cpp
index 016d75cb68c7..364f78d46957 100644
--- a/browser/components/about/AboutRedirector.cpp
+++ b/browser/components/about/AboutRedirector.cpp
@@ -107,8 +107,8 @@ static RedirEntry kRedirMap[] = {
#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::MAKE_UNLINKABLE |
nsIAboutModule::HIDE_FROM_ABOUTABOUT },
#endif
};
diff --git a/browser/components/nsBrowserContentHandler.js b/browser/components/nsBrowserContentHandler.js
index ee0c6a5a4a7a..583010e937ed 100644
--- a/browser/components/nsBrowserContentHandler.js
+++ b/browser/components/nsBrowserContentHandler.js
@@ -576,7 +576,10 @@ nsBrowserContentHandler.prototype = {
#ifdef TOR_BROWSER_UPDATE
if (overridePage)
- overridePage = "about:tbupdate?" + encodeURIComponent(overridePage);
+ {
+ prefb.setCharPref("torbrowser.post_update.url", overridePage);
+ overridePage = "about:tbupdate"
+ }
#endif
break;
}
diff --git a/browser/components/nsBrowserGlue.js b/browser/components/nsBrowserGlue.js
index bb2351d41014..562ca20e19a4 100644
--- a/browser/components/nsBrowserGlue.js
+++ b/browser/components/nsBrowserGlue.js
@@ -78,6 +78,11 @@ if (AppConstants.MOZ_CRASHREPORTER) {
"resource://gre/modules/CrashSubmit.jsm");
}
+if (AppConstants.TOR_BROWSER_UPDATE) {
+ XPCOMUtils.defineLazyModuleGetter(this, "AboutTBUpdate",
+ "resource:///modules/AboutTBUpdate.jsm");
+}
+
XPCOMUtils.defineLazyGetter(this, "gBrandBundle", function() {
return Services.strings.createBundle('chrome://branding/locale/brand.properties');
});
@@ -714,6 +719,10 @@ BrowserGlue.prototype = {
UnsubmittedCrashHandler.init();
}
+ if (AppConstants.TOR_BROWSER_UPDATE) {
+ AboutTBUpdate.init();
+ }
+
Services.obs.notifyObservers(null, "browser-ui-startup-complete", "");
},
diff --git a/browser/modules/AboutTBUpdate.jsm b/browser/modules/AboutTBUpdate.jsm
new file mode 100644
index 000000000000..49d9d9b0e18d
--- /dev/null
+++ b/browser/modules/AboutTBUpdate.jsm
@@ -0,0 +1,111 @@
+// Copyright (c) 2018, The Tor Project, Inc.
+// See LICENSE for licensing information.
+//
+// vim: set sw=2 sts=2 ts=8 et syntax=javascript:
+
+"use strict";
+
+var Cc = Components.classes;
+var Ci = Components.interfaces;
+var Cu = Components.utils;
+
+this.EXPORTED_SYMBOLS = [ "AboutTBUpdate" ];
+
+Cu.import("resource://gre/modules/Services.jsm");
+Cu.import("resource://gre/modules/NetUtil.jsm");
+
+const kRequestUpdateMessageName = "AboutTBUpdate:RequestUpdate";
+const kSendUpdateMessageName = "AboutTBUpdate:Update";
+
+#ifdef TOR_BROWSER_VERSION
+#expand const TOR_BROWSER_VERSION = __TOR_BROWSER_VERSION__;
+#endif
+
+/**
+ * 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.
+ */
+var AboutTBUpdate = {
+ init: function() {
+ let mm = Cc["@mozilla.org/globalmessagemanager;1"]
+ .getService(Ci.nsIMessageListenerManager);
+ mm.addMessageListener(kRequestUpdateMessageName, this);
+ },
+
+ receiveMessage: function(aMessage) {
+ if (aMessage.name == kRequestUpdateMessageName)
+ this.sendAboutTBUpdateData(aMessage.target);
+ },
+
+ sendAboutTBUpdateData: function(aTarget) {
+ let data = { productInfo: this.productInfo,
+ moreInfoURL: this.moreInfoURL,
+ changeLog: this.changeLog };
+
+ if (aTarget && aTarget.messageManager) {
+ aTarget.messageManager.sendAsyncMessage(kSendUpdateMessageName, data);
+ } else {
+ let mm = Cc["@mozilla.org/globalmessagemanager;1"]
+ .getService(Ci.nsIMessageListenerManager);
+ mm.broadcastAsyncMessage(kSendUpdateMessageName, data);
+ }
+ },
+
+ get productInfo() {
+ const kBrandBundle = "chrome://branding/locale/brand.properties";
+ let brandBundle = Cc["@mozilla.org/intl/stringbundle;1"]
+ .getService(Ci.nsIStringBundleService)
+ .createBundle(kBrandBundle);
+ return brandBundle.GetStringFromName("brandFullName")
+ + "\n" + TOR_BROWSER_VERSION;
+ },
+
+ 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 and return the text from the beginning of the changelog file that is
+ // located at TorBrowser/Docs/ChangeLog.txt.
+ // On Mac OS, when building with --enable-tor-browser-data-outside-app-dir
+ // to support Gatekeeper signing, the file is located in
+ // TorBrowser.app/Contents/Resources/TorBrowser/Docs/.
+ get changeLog() {
+ try {
+#ifdef 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/.
+ let f = Services.dirsvc.get("XREExeF", Ci.nsIFile).parent;
+#ifdef XP_MACOSX
+ f = f.parent;
+ f.append("Resources");
+#endif
+ f.append("TorBrowser");
+#else
+ // "DefProfRt" is .../TorBrowser/Data/Browser
+ let f = Cc["@mozilla.org/file/directory_service;1"]
+ .getService(Ci.nsIProperties).get("DefProfRt", Ci.nsIFile);
+ f = f.parent.parent; // Remove "Data/Browser"
+#endif
+ 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.
+ return s.replace(/[\r\n][\r\n][\s\S]*$/m, "");
+ } catch (e) {}
+
+ return "";
+ },
+};
diff --git a/browser/modules/moz.build b/browser/modules/moz.build
index 2526272249e8..4fe8adeb6c49 100644
--- a/browser/modules/moz.build
+++ b/browser/modules/moz.build
@@ -52,6 +52,11 @@ if not CONFIG['TOR_BROWSER_VERSION']:
'CastingApps.jsm',
]
+if CONFIG['TOR_BROWSER_UPDATE']:
+ EXTRA_PP_JS_MODULES += [
+ 'AboutTBUpdate.jsm',
+ ]
+
if CONFIG['MOZ_WIDGET_TOOLKIT'] == 'windows':
EXTRA_JS_MODULES += [
'Windows8WindowFrameColor.jsm',
diff --git a/toolkit/modules/AppConstants.jsm b/toolkit/modules/AppConstants.jsm
index 7ce8e1f09af4..82e5753be12a 100644
--- a/toolkit/modules/AppConstants.jsm
+++ b/toolkit/modules/AppConstants.jsm
@@ -340,4 +340,11 @@ this.AppConstants = Object.freeze({
#else
false,
#endif
+
+ TOR_BROWSER_UPDATE:
+#ifdef TOR_BROWSER_UPDATE
+ true,
+#else
+ false,
+#endif
});
diff --git a/toolkit/modules/moz.build b/toolkit/modules/moz.build
index 7d4b0f3fa713..6c3d273804fc 100644
--- a/toolkit/modules/moz.build
+++ b/toolkit/modules/moz.build
@@ -159,4 +159,7 @@ for var in ('MOZ_TOOLKIT_SEARCH',
if CONFIG[var]:
DEFINES[var] = True
+if CONFIG['TOR_BROWSER_UPDATE']:
+ DEFINES['TOR_BROWSER_UPDATE'] = 1
+
DEFINES['TOPOBJDIR'] = TOPOBJDIR