[tor-commits] [tor-browser/tor-browser-78.15.0esr-10.5-1] Bug 16940: After update, load local change notes.

sysrqb at torproject.org sysrqb at torproject.org
Tue Sep 28 19:07:33 UTC 2021


commit b1242db21eea72a126a2ca6d59242e9caef67747
Author: Kathy Brade <brade at 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              |  53 ++++++++
 browser/actors/moz.build                           |   5 +
 .../base/content/abouttbupdate/aboutTBUpdate.css   |  74 ++++++++++++
 .../base/content/abouttbupdate/aboutTBUpdate.js    |  10 ++
 .../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                 |  25 ++++
 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 +
 browser/modules/AboutTBUpdate.jsm                  | 134 +++++++++++++++++++++
 browser/modules/moz.build                          |   5 +
 17 files changed, 420 insertions(+), 16 deletions(-)

diff --git a/browser/actors/AboutTBUpdateChild.jsm b/browser/actors/AboutTBUpdateChild.jsm
new file mode 100644
index 000000000000..91bb4dbba888
--- /dev/null
+++ b/browser/actors/AboutTBUpdateChild.jsm
@@ -0,0 +1,53 @@
+// Copyright (c) 2019, 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 {ActorChild} = ChromeUtils.import("resource://gre/modules/ActorChild.jsm");
+
+class AboutTBUpdateChild extends ActorChild {
+  receiveMessage(aMessage) {
+    if (aMessage.name == "AboutTBUpdate:Update")
+      this.onUpdate(aMessage.data);
+  }
+
+  handleEvent(aEvent) {
+    switch (aEvent.type) {
+      case "AboutTBUpdateLoad":
+        this.onPageLoad();
+        break;
+      case "pagehide":
+        this.onPageHide(aEvent);
+        break;
+    }
+  }
+
+  // aData may contain the following string properties:
+  //   version
+  //   releaseDate
+  //   moreInfoURL
+  //   releaseNotes
+  onUpdate(aData) {
+    let doc = this.content.document;
+    doc.getElementById("version-content").textContent = aData.version;
+    if (aData.releaseDate) {
+      doc.body.setAttribute("havereleasedate", "true");
+      doc.getElementById("releasedate-content").textContent = aData.releaseDate;
+    }
+    if (aData.moreInfoURL)
+      doc.getElementById("infolink").setAttribute("href", aData.moreInfoURL);
+    doc.getElementById("releasenotes-content").textContent = aData.releaseNotes;
+  }
+
+  onPageLoad() {
+    this.mm.sendAsyncMessage("AboutTBUpdate:RequestUpdate");
+  }
+
+  onPageHide(aEvent) {
+    if (aEvent.target.defaultView.frameElement) {
+      return;
+    }
+  }
+}
diff --git a/browser/actors/moz.build b/browser/actors/moz.build
index 4b903146699e..e70f0f09fe3a 100644
--- a/browser/actors/moz.build
+++ b/browser/actors/moz.build
@@ -74,3 +74,8 @@ FINAL_TARGET_FILES.actors += [
     'WebRTCChild.jsm',
     'WebRTCParent.jsm',
 ]
+
+if CONFIG['TOR_BROWSER_UPDATE']:
+    FINAL_TARGET_FILES.actors += [
+        'AboutTBUpdateChild.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..da7553f0ae81
--- /dev/null
+++ b/browser/base/content/abouttbupdate/aboutTBUpdate.js
@@ -0,0 +1,10 @@
+// Copyright (c) 2019, The Tor Project, Inc.
+// See LICENSE for licensing information.
+//
+// vim: set sw=2 sts=2 ts=8 et syntax=javascript:
+
+
+addEventListener("load", () => {
+  let event = new CustomEvent("AboutTBUpdateLoad", { bubbles: true });
+  document.dispatchEvent(event);
+});
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 29f95ae4129f..1d6f9555b33f 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.
    */
-  _secureInternalUIWhitelist: /^(?:accounts|addons|cache|certificate|config|crashes|downloads|license|logins|preferences|protections|rights|sessionrestore|support|welcomeback)(?:[?#]|$)/i,
+  _secureInternalUIWhitelist: (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 3c342dedd5d4..036d92e131da 100644
--- a/browser/base/content/browser.js
+++ b/browser/base/content/browser.js
@@ -631,6 +631,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 a2e1f9c259d2..df65349796b5 100644
--- a/browser/base/jar.mn
+++ b/browser/base/jar.mn
@@ -29,6 +29,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 9f5b6ab0218c..1cc1015414fc 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 0a3555f26432..3b7d8d6e0309 100644
--- a/browser/components/BrowserGlue.jsm
+++ b/browser/components/BrowserGlue.jsm
@@ -560,6 +560,22 @@ let LEGACY_ACTORS = {
   },
 };
 
+if (AppConstants.TOR_BROWSER_UPDATE) {
+  LEGACY_ACTORS["AboutTBUpdate"] = {
+    child: {
+      module: "resource:///actors/AboutTBUpdateChild.jsm",
+      events: {
+        "AboutTBUpdateLoad": {wantUntrusted: true},
+        "pagehide": {capture: true},
+      },
+      matches: ["about:tbupdate"],
+      messages: [
+        "AboutTBUpdate:Update",
+      ],
+    }
+  };
+}
+
 (function earlyBlankFirstPaint() {
   if (
     AppConstants.platform == "macosx" ||
@@ -747,6 +763,11 @@ if (AppConstants.MOZ_CRASHREPORTER) {
   });
 }
 
+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"
@@ -2200,6 +2221,10 @@ BrowserGlue.prototype = {
       AsanReporter.init();
     }
 
+    if (AppConstants.TOR_BROWSER_UPDATE) {
+      AboutTBUpdate.init();
+    }
+
     Sanitizer.onStartup();
     this._scheduleStartupIdleTasks();
     this._lateTasksIdleObserver = (idleService, topic, data) => {
diff --git a/browser/components/about/AboutRedirector.cpp b/browser/components/about/AboutRedirector.cpp
index 1471e10bf0db..933d519bd959 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 ca892a187adf..31e2d3d870e6 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/browser/modules/AboutTBUpdate.jsm b/browser/modules/AboutTBUpdate.jsm
new file mode 100644
index 000000000000..996e2e8394aa
--- /dev/null
+++ b/browser/modules/AboutTBUpdate.jsm
@@ -0,0 +1,134 @@
+// Copyright (c) 2019, 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";
+
+#expand const TOR_BROWSER_VERSION = __TOR_BROWSER_VERSION_QUOTED__;
+
+/**
+ * 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() {
+    Services.mm.addMessageListener(kRequestUpdateMessageName, this);
+  },
+
+  receiveMessage: function(aMessage) {
+    if (aMessage.name == kRequestUpdateMessageName)
+      this.sendAboutTBUpdateData(aMessage.target);
+  },
+
+  sendAboutTBUpdateData: function(aTarget) {
+    let data = this.releaseNoteInfo;
+    data.moreInfoURL = this.moreInfoURL;
+    if (aTarget && aTarget.messageManager) {
+      aTarget.messageManager.sendAsyncMessage(kSendUpdateMessageName, data);
+    } else {
+      Services.mm.broadcastAsyncMessage(kSendUpdateMessageName, data);
+    }
+  },
+
+  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 = {};
+
+    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.
+      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/modules/moz.build b/browser/modules/moz.build
index 88f2a55d6f49..61fe5371e48f 100644
--- a/browser/modules/moz.build
+++ b/browser/modules/moz.build
@@ -160,6 +160,11 @@ EXTRA_JS_MODULES += [
     'ZoomUI.jsm',
 ]
 
+if CONFIG['TOR_BROWSER_UPDATE']:
+    EXTRA_PP_JS_MODULES += [
+        'AboutTBUpdate.jsm',
+    ]
+
 if CONFIG['MOZ_ASAN_REPORTER']:
     EXTRA_JS_MODULES += [
         'AsanReporter.jsm',





More information about the tor-commits mailing list