From 5aa6a314ca1f1252116347e9dca22e5dd363aeac Mon Sep 17 00:00:00 2001 From: Kathy Brade <brade@pearlcrescent.com> Date: Fri, 13 Jan 2017 11:40:24 -0500 Subject: [PATCH] Bug 4234: Use the Firefox Update Process for Base Browser. 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 27221: purge the startup cache if the Base Browser version changed (even if the Firefox version and build ID did not change), e.g., after a minor Base 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 Base 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/base/content/aboutDialog.js | 6 +- browser/base/content/aboutDialog.xhtml | 1 + browser/base/moz.build | 3 + .../components/BrowserContentHandler.sys.mjs | 26 +++++- .../customizableui/content/panelUI.inc.xhtml | 2 +- browser/components/preferences/main.js | 2 +- browser/config/mozconfigs/base-browser | 1 + browser/confvars.sh | 15 ++++ browser/installer/Makefile.in | 4 + browser/installer/package-manifest.in | 2 + build/application.ini.in | 2 +- build/moz.build | 1 + build/moz.configure/init.configure | 15 ++-- build/moz.configure/update-programs.configure | 28 ++++++ mozconfig-linux-x86_64-dev | 1 + toolkit/modules/AppConstants.sys.mjs | 7 ++ toolkit/modules/UpdateUtils.sys.mjs | 31 ++++--- toolkit/modules/moz.build | 3 + .../mozapps/extensions/AddonManager.sys.mjs | 19 ++++ toolkit/mozapps/update/UpdateService.sys.mjs | 63 +++++++++++--- .../mozapps/update/UpdateServiceStub.sys.mjs | 5 ++ .../mozapps/update/common/updatehelper.cpp | 8 ++ .../mozapps/update/updater/launchchild_osx.mm | 2 + toolkit/mozapps/update/updater/updater.cpp | 42 ++++++++- toolkit/xre/MacLaunchHelper.h | 2 + toolkit/xre/MacLaunchHelper.mm | 2 + toolkit/xre/nsAppRunner.cpp | 23 ++++- toolkit/xre/nsUpdateDriver.cpp | 86 +++++++++++++++++-- toolkit/xre/nsXREDirProvider.cpp | 39 ++++++++- tools/update-packaging/common.sh | 26 +----- 31 files changed, 393 insertions(+), 76 deletions(-) diff --git a/browser/app/Makefile.in b/browser/app/Makefile.in index 54d6b43fe126f..5e66dede6b2ea 100644 --- a/browser/app/Makefile.in +++ b/browser/app/Makefile.in @@ -97,10 +97,12 @@ tools repackage:: $(DIST)/bin/$(MOZ_APP_NAME) $(objdir)/macbuild/Contents/MacOS- 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 BASE_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 APPLMOZB > '$(dist_dest)/Contents/PkgInfo' endif diff --git a/browser/base/content/aboutDialog.js b/browser/base/content/aboutDialog.js index fc0252ad1bd1c..209d9f3874950 100644 --- a/browser/base/content/aboutDialog.js +++ b/browser/base/content/aboutDialog.js @@ -43,10 +43,10 @@ function init() { } // Include the build ID and display warning if this is an "a#" (nightly or aurora) build - let versionId = "aboutDialog-version"; + let versionId = "basebrowser-about-dialog-version"; let versionAttributes = { - version: AppConstants.MOZ_APP_VERSION_DISPLAY, - bits: Services.appinfo.is64Bit ? 64 : 32, + version: AppConstants.BASE_BROWSER_VERSION, + firefoxVersion: AppConstants.MOZ_APP_VERSION_DISPLAY, }; let version = Services.appinfo.version; diff --git a/browser/base/content/aboutDialog.xhtml b/browser/base/content/aboutDialog.xhtml index 0824af6462593..69a85886336cd 100644 --- a/browser/base/content/aboutDialog.xhtml +++ b/browser/base/content/aboutDialog.xhtml @@ -30,6 +30,7 @@ <linkset> <html:link rel="localization" href="branding/brand.ftl"/> <html:link rel="localization" href="browser/aboutDialog.ftl"/> + <html:link rel="localization" href="browser/base-browser.ftl"/> </linkset> <html:div id="aboutDialogContainer"> diff --git a/browser/base/moz.build b/browser/base/moz.build index 8c6d23deb08f5..b2552f809e142 100644 --- a/browser/base/moz.build +++ b/browser/base/moz.build @@ -88,4 +88,7 @@ if CONFIG["OS_ARCH"] == "WINNT" and CONFIG["MOZ_DEFAULT_BROWSER_AGENT"]: # Impacts `/toolkit/content/license.html`. DEFINES["MOZ_DEFAULT_BROWSER_AGENT"] = True +if CONFIG["BASE_BROWSER_UPDATE"]: + DEFINES["BASE_BROWSER_UPDATE"] = True + JAR_MANIFESTS += ["jar.mn"] diff --git a/browser/components/BrowserContentHandler.sys.mjs b/browser/components/BrowserContentHandler.sys.mjs index 32ebdd4dcba5e..e8923e5c0089d 100644 --- a/browser/components/BrowserContentHandler.sys.mjs +++ b/browser/components/BrowserContentHandler.sys.mjs @@ -42,6 +42,9 @@ XPCOMUtils.defineLazyGetter(lazy, "gWindowsAlertsService", () => { ?.QueryInterface(Ci.nsIWindowsAlertsService); }); +const FORK_VERSION_PREF = + "browser.startup.homepage_override.basebrowser.version"; + // One-time startup homepage override configurations const ONCE_DOMAINS = ["mozilla.org", "firefox.com"]; const ONCE_PREF = "browser.startup.homepage_override.once"; @@ -105,7 +108,8 @@ const OVERRIDE_NEW_BUILD_ID = 3; * 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 fork 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. @@ -122,6 +126,8 @@ function needHomepageOverride(prefb) { var mstone = Services.appinfo.platformVersion; + var savedForkVersion = prefb.getCharPref(FORK_VERSION_PREF, null); + var savedBuildID = prefb.getCharPref( "browser.startup.homepage_override.buildID", "" @@ -143,9 +149,16 @@ function needHomepageOverride(prefb) { prefb.setCharPref("browser.startup.homepage_override.mstone", mstone); prefb.setCharPref("browser.startup.homepage_override.buildID", buildID); + prefb.setCharPref(FORK_VERSION_PREF, AppConstants.BASE_BROWSER_VERSION); return savedmstone ? OVERRIDE_NEW_MSTONE : OVERRIDE_NEW_PROFILE; } + if (AppConstants.BASE_BROWSER_VERSION != savedForkVersion) { + prefb.setCharPref("browser.startup.homepage_override.buildID", buildID); + prefb.setCharPref(FORK_VERSION_PREF, AppConstants.BASE_BROWSER_VERSION); + return OVERRIDE_NEW_MSTONE; + } + if (buildID != savedBuildID) { prefb.setCharPref("browser.startup.homepage_override.buildID", buildID); return OVERRIDE_NEW_BUILD_ID; @@ -671,6 +684,10 @@ nsBrowserContentHandler.prototype = { "browser.startup.homepage_override.buildID", "unknown" ); + + // We do the same for the fork version. + let old_forkVersion = prefb.getCharPref(FORK_VERSION_PREF, null); + override = needHomepageOverride(prefb); if (override != OVERRIDE_NONE) { switch (override) { @@ -702,9 +719,10 @@ nsBrowserContentHandler.prototype = { "startup.homepage_override_url" ); let update = lazy.UpdateManager.readyUpdate; + let old_version = old_forkVersion ? old_forkVersion : 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. @@ -712,6 +730,10 @@ nsBrowserContentHandler.prototype = { } overridePage = overridePage.replace("%OLD_VERSION%", old_mstone); + overridePage = overridePage.replace( + "%OLD_BASE_BROWSER_VERSION%", + old_forkVersion + ); break; case OVERRIDE_NEW_BUILD_ID: if (lazy.UpdateManager.readyUpdate) { diff --git a/browser/components/customizableui/content/panelUI.inc.xhtml b/browser/components/customizableui/content/panelUI.inc.xhtml index 4e93102bcfb22..8776e6c004c95 100644 --- a/browser/components/customizableui/content/panelUI.inc.xhtml +++ b/browser/components/customizableui/content/panelUI.inc.xhtml @@ -200,7 +200,7 @@ hasicon="true" hidden="true"> <popupnotificationcontent id="update-restart-notification-content" orient="vertical"> - <description id="update-restart-description" data-lazy-l10n-id="appmenu-update-restart-message2"></description> + <description id="update-restart-description"> </description> </popupnotificationcontent> </popupnotification> diff --git a/browser/components/preferences/main.js b/browser/components/preferences/main.js index 385254820ec38..273a0559563c0 100644 --- a/browser/components/preferences/main.js +++ b/browser/components/preferences/main.js @@ -549,7 +549,7 @@ var gMainPane = { .setAttribute("style", "display: none !important"); } // Initialize the Firefox Updates section. - let version = AppConstants.MOZ_APP_VERSION_DISPLAY; + let version = AppConstants.BASE_BROWSER_VERSION; // Include the build ID if this is an "a#" (nightly) build if (/a\d+$/.test(version)) { diff --git a/browser/config/mozconfigs/base-browser b/browser/config/mozconfigs/base-browser index 18838046558c7..37ed0949772a4 100644 --- a/browser/config/mozconfigs/base-browser +++ b/browser/config/mozconfigs/base-browser @@ -15,6 +15,7 @@ ac_add_options --enable-optimize ac_add_options --enable-rust-simd ac_add_options --disable-unverified-updates +ac_add_options --enable-base-browser-update ac_add_options --enable-bundled-fonts diff --git a/browser/confvars.sh b/browser/confvars.sh index 5143e486caf86..b4546aeac15a4 100755 --- a/browser/confvars.sh +++ b/browser/confvars.sh @@ -20,5 +20,20 @@ MOZ_APP_ID={ec8030f7-c20a-464f-9b0e-13a3a9e97384} # tor-browser#41577: Do not enable profile migration # MOZ_PROFILE_MIGRATOR=1 +# 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=basebrowser-torproject-alpha + MAR_CHANNEL_ID=basebrowser-torproject-alpha +elif test "$MOZ_UPDATE_CHANNEL" = "nightly"; then + ACCEPTED_MAR_CHANNEL_IDS=basebrowser-torproject-nightly + MAR_CHANNEL_ID=basebrowser-torproject-nightly +else + ACCEPTED_MAR_CHANNEL_IDS=basebrowser-torproject-release + MAR_CHANNEL_ID=basebrowser-torproject-release +fi + # Include the DevTools client, not just the server (which is the default) MOZ_DEVTOOLS=all diff --git a/browser/installer/Makefile.in b/browser/installer/Makefile.in index fc6d4808dca0c..b5b5e8ca29fdf 100644 --- a/browser/installer/Makefile.in +++ b/browser/installer/Makefile.in @@ -85,6 +85,10 @@ endif endif endif +ifdef BASE_BROWSER_UPDATE +DEFINES += -DBASE_BROWSER_UPDATE +endif + ifneq (,$(filter WINNT Darwin Android,$(OS_TARGET))) DEFINES += -DMOZ_SHARED_MOZGLUE=1 endif diff --git a/browser/installer/package-manifest.in b/browser/installer/package-manifest.in index 84fa4257f7aa6..c69f4eb1a96eb 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 BASE_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 6df13230a45b2..aa02201e619ff 100644 --- a/build/application.ini.in +++ b/build/application.ini.in @@ -52,5 +52,5 @@ ServerURL=@MOZ_CRASHREPORTER_URL@/submit?id=@MOZ_APP_ID@&version=@MOZ_APP_VERSIO #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=@BB_UPDATER_URL@/%CHANNEL%/%BUILD_TARGET%/%VERSION%/ALL #endif diff --git a/build/moz.build b/build/moz.build index 671e77e97b351..5662e29cae0da 100644 --- a/build/moz.build +++ b/build/moz.build @@ -75,6 +75,7 @@ if CONFIG["MOZ_APP_BASENAME"]: "MAR_CHANNEL_ID", "MOZ_APP_REMOTINGNAME", "MOZ_CRASHREPORTER_URL", + "BB_UPDATER_URL", ): appini_defines[var] = CONFIG[var] diff --git a/build/moz.configure/init.configure b/build/moz.configure/init.configure index 53bbc4203fcc8..3042fe0a7a678 100644 --- a/build/moz.configure/init.configure +++ b/build/moz.configure/init.configure @@ -1051,11 +1051,10 @@ option( ) -# 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) +# Firefox looks for "a" or "a1" in the milestone to detect whether nightly +# features should be enabled. We do not want them, because we want our nightly +# builds to be as close as possible to actual releases. +# So we set always is_release_or_beta to True. @depends( build_environment, build_project, @@ -1116,10 +1115,8 @@ def milestone(build_env, build_project, version_path, as_milestone, _): is_nightly = is_release_or_beta = None - if "a1" in milestone: - is_nightly = True - elif "a" not in milestone: - is_release_or_beta = True + # Do not enable extra nightly features + is_release_or_beta = True major_version = milestone.split(".")[0] m = re.search(r"([ab]\d+)", milestone) diff --git a/build/moz.configure/update-programs.configure b/build/moz.configure/update-programs.configure index bcdd457ad3397..213a95550861d 100644 --- a/build/moz.configure/update-programs.configure +++ b/build/moz.configure/update-programs.configure @@ -192,3 +192,31 @@ option( ) set_config("MOZ_NOTIFICATION_SERVER", True, when="--enable-notification-server") + + +# Enable updater customization for Base Browser-based browsers +# ============================================================================== + +option( + "--enable-base-browser-update", + help="Enable Base Browser update" +) + +set_config("BASE_BROWSER_UPDATE", True, when="--enable-base-browser-update") +set_define("BASE_BROWSER_UPDATE", True, when="--enable-base-browser-update") + + +# Updater URL +# ============================================================== + +option( + "--with-updater-url", + default="https://aus1.torproject.org/torbrowser/update_3/", + nargs=1, + help="Set the updater URL", +) + +set_config( + "BB_UPDATER_URL", + depends("--with-updater-url")(lambda x: x[0].rstrip("/")), +) diff --git a/mozconfig-linux-x86_64-dev b/mozconfig-linux-x86_64-dev index e9389eca5ef89..7d5d4d767a21f 100644 --- a/mozconfig-linux-x86_64-dev +++ b/mozconfig-linux-x86_64-dev @@ -12,3 +12,4 @@ ac_add_options --disable-strip ac_add_options --disable-install-strip ac_add_options --with-base-browser-version=dev-build +ac_add_options --disable-base-browser-update diff --git a/toolkit/modules/AppConstants.sys.mjs b/toolkit/modules/AppConstants.sys.mjs index 0d042cce879c4..abf490f990be3 100644 --- a/toolkit/modules/AppConstants.sys.mjs +++ b/toolkit/modules/AppConstants.sys.mjs @@ -466,6 +466,13 @@ export var AppConstants = Object.freeze({ false, #endif + BASE_BROWSER_UPDATE: +#ifdef BASE_BROWSER_UPDATE + true, +#else + false, +#endif + // Returns true for CN region build when distibution id set as 'MozillaOnline' isChinaRepack() { return ( diff --git a/toolkit/modules/UpdateUtils.sys.mjs b/toolkit/modules/UpdateUtils.sys.mjs index 3a86099aa81d2..a4be264a91ab3 100644 --- a/toolkit/modules/UpdateUtils.sys.mjs +++ b/toolkit/modules/UpdateUtils.sys.mjs @@ -82,7 +82,7 @@ export var UpdateUtils = { case "PRODUCT": return Services.appinfo.name; case "VERSION": - return Services.appinfo.version; + return AppConstants.BASE_BROWSER_VERSION; case "BUILD_ID": return Services.appinfo.appBuildID; case "BUILD_TARGET": @@ -161,7 +161,8 @@ export 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 Base Browser and derivatives), 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. * @@ -177,7 +178,8 @@ export 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 Base Browser and derivatives), 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. * @@ -249,7 +251,10 @@ export var UpdateUtils = { // setting is just to propagate it from a pref observer. This ensures that // the expected observers still get notified, even if a user manually // changes the pref value. - if (!UpdateUtils.PER_INSTALLATION_PREFS_SUPPORTED) { + if ( + AppConstants.BASE_BROWSER_UPDATE || + !UpdateUtils.PER_INSTALLATION_PREFS_SUPPORTED + ) { let initialConfig = {}; for (const [prefName, pref] of Object.entries( UpdateUtils.PER_INSTALLATION_PREFS @@ -318,7 +323,10 @@ export var UpdateUtils = { } } - if (!this.PER_INSTALLATION_PREFS_SUPPORTED) { + if ( + AppConstants.BASE_BROWSER_UPDATE || + !this.PER_INSTALLATION_PREFS_SUPPORTED + ) { // If we don't have per-installation prefs, we use regular preferences. let prefValue = prefTypeFns.getProfilePref(prefName, pref.defaultValue); return Promise.resolve(prefValue); @@ -413,7 +421,10 @@ export var UpdateUtils = { ); } - if (!this.PER_INSTALLATION_PREFS_SUPPORTED) { + if ( + AppConstants.BASE_BROWSER_UPDATE || + !this.PER_INSTALLATION_PREFS_SUPPORTED + ) { // If we don't have per-installation prefs, we use regular preferences. if (options.setDefaultOnly) { prefTypeFns.setProfileDefaultPref(prefName, value); @@ -549,14 +560,6 @@ UpdateUtils.PER_INSTALLATION_PREFS = { migrate: true, observerTopic: "auto-update-config-change", policyFn: () => { - if (!Services.policies.isAllowed("app-auto-updates-off")) { - // We aren't allowed to turn off auto-update - it is forced on. - return true; - } - if (!Services.policies.isAllowed("app-auto-updates-on")) { - // We aren't allowed to turn on auto-update - it is forced off. - return false; - } return null; }, }, diff --git a/toolkit/modules/moz.build b/toolkit/modules/moz.build index 858bfc466ef61..a3a8f3bafca41 100644 --- a/toolkit/modules/moz.build +++ b/toolkit/modules/moz.build @@ -297,6 +297,9 @@ for var in ( if CONFIG[var]: DEFINES[var] = True +if CONFIG["BASE_BROWSER_UPDATE"]: + DEFINES["BASE_BROWSER_UPDATE"] = True + JAR_MANIFESTS += ["jar.mn"] DEFINES["TOPOBJDIR"] = TOPOBJDIR diff --git a/toolkit/mozapps/extensions/AddonManager.sys.mjs b/toolkit/mozapps/extensions/AddonManager.sys.mjs index 2ae57f0b5201a..82e8429750b86 100644 --- a/toolkit/mozapps/extensions/AddonManager.sys.mjs +++ b/toolkit/mozapps/extensions/AddonManager.sys.mjs @@ -36,6 +36,7 @@ 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_REMOTESETTINGS_DISABLED = "extensions.remoteSettings.disabled"; +const PREF_EM_LAST_FORK_VERSION = "extensions.lastBaseBrowserVersion"; const PREF_MIN_WEBEXT_PLATFORM_VERSION = "extensions.webExtensionsMinPlatformVersion"; @@ -638,6 +639,24 @@ var AddonManagerInternal = { ); } + // To ensure that extension and plugin code gets a chance to run after + // each browser update, set appChanged = true when BASE_BROWSER_VERSION + // has changed even if the Mozilla app version has not changed. + const forkChanged = + AppConstants.BASE_BROWSER_VERSION !== + Services.prefs.getCharPref(PREF_EM_LAST_FORK_VERSION, ""); + if (forkChanged) { + // appChanged could be undefined (in case of a new profile) + if (appChanged === false) { + appChanged = true; + } + + Services.prefs.setCharPref( + PREF_EM_LAST_FORK_VERSION, + AppConstants.BASE_BROWSER_VERSION + ); + } + if (!MOZ_COMPATIBILITY_NIGHTLY) { PREF_EM_CHECK_COMPATIBILITY = PREF_EM_CHECK_COMPATIBILITY_BASE + diff --git a/toolkit/mozapps/update/UpdateService.sys.mjs b/toolkit/mozapps/update/UpdateService.sys.mjs index 5e9caf090e393..945146eade0c4 100644 --- a/toolkit/mozapps/update/UpdateService.sys.mjs +++ b/toolkit/mozapps/update/UpdateService.sys.mjs @@ -704,6 +704,11 @@ function areDirectoryEntriesWriteable(aDir) { * @return true if elevation is required, false otherwise */ function getElevationRequired() { + if (AppConstants.BASE_BROWSER_UPDATE) { + // To avoid potential security holes associated with running the updater + // process with elevated privileges, Tor Browser does not support elevation. + return false; + } if (AppConstants.platform != "macosx") { return false; } @@ -783,7 +788,7 @@ function getCanApplyUpdates() { return false; } - if (AppConstants.platform == "macosx") { + if (!AppConstants.BASE_BROWSER_UPDATE && AppConstants.platform == "macosx") { LOG( "getCanApplyUpdates - bypass the write since elevation can be used " + "on Mac OS X" @@ -791,7 +796,7 @@ function getCanApplyUpdates() { return true; } - if (shouldUseService()) { + if (!AppConstants.BASE_BROWSER_UPDATE && shouldUseService()) { LOG( "getCanApplyUpdates - bypass the write checks because the Windows " + "Maintenance Service can be used" @@ -1646,7 +1651,11 @@ function handleUpdateFailure(update) { ); cancelations++; Services.prefs.setIntPref(PREF_APP_UPDATE_CANCELATIONS, cancelations); - if (AppConstants.platform == "macosx") { + if (AppConstants.platform == "macosx" && AppConstants.BASE_BROWSER_UPDATE) { + cleanupActiveUpdates(); + update.statusText = + lazy.gUpdateBundle.GetStringFromName("elevationFailure"); + } else if (AppConstants.platform == "macosx") { let osxCancelations = Services.prefs.getIntPref( PREF_APP_UPDATE_CANCELATIONS_OSX, 0 @@ -1918,6 +1927,15 @@ function updateIsAtLeastAsOldAs(update, version, buildID) { ); } +/** + * This returns the current version of the browser to use to check updates. + */ +function getCompatVersion() { + return AppConstants.BASE_BROWSER_VERSION + ? AppConstants.BASE_BROWSER_VERSION + : Services.appinfo.version; +} + /** * This returns true if the passed update is the same version or older than * currently installed Firefox version. @@ -1925,7 +1943,7 @@ function updateIsAtLeastAsOldAs(update, version, buildID) { function updateIsAtLeastAsOldAsCurrentVersion(update) { return updateIsAtLeastAsOldAs( update, - Services.appinfo.version, + getCompatVersion(), Services.appinfo.appBuildID ); } @@ -2261,6 +2279,7 @@ UpdatePatch.prototype = { * @throws if the update contains no patches * @constructor */ +// eslint-disable-next-line complexity function Update(update) { this._patches = []; this._properties = {}; @@ -2296,7 +2315,31 @@ 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"].includes( + minInstructionSet + ) + ) { + try { + this.unsupported = !Services.sysinfo.getProperty( + "has" + minInstructionSet + ); + } catch (e) {} + } + } + + if (!this._patches.length && !this.unsupported) { throw Components.Exception("", Cr.NS_ERROR_ILLEGAL_VALUE); } @@ -2334,9 +2377,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": @@ -2361,7 +2402,7 @@ function Update(update) { } if (!this.previousAppVersion) { - this.previousAppVersion = Services.appinfo.version; + this.previousAppVersion = getCompatVersion(); } if (!this.elevationFailure) { @@ -4074,7 +4115,7 @@ UpdateService.prototype = { "UpdateService:downloadUpdate - Skipping download of update since " + "it is for an earlier or same application version and build ID.\n" + "current application version: " + - Services.appinfo.version + + getCompatVersion() + "\n" + "update application version : " + update.appVersion + @@ -4998,7 +5039,7 @@ export class CheckerService { } #getCanMigrate() { - if (AppConstants.platform != "win") { + if (AppConstants.platform != "win" || AppConstants.BASE_BROWSER_UPDATE) { return false; } diff --git a/toolkit/mozapps/update/UpdateServiceStub.sys.mjs b/toolkit/mozapps/update/UpdateServiceStub.sys.mjs index ae2d5b3f99618..958e5d46f4c33 100644 --- a/toolkit/mozapps/update/UpdateServiceStub.sys.mjs +++ b/toolkit/mozapps/update/UpdateServiceStub.sys.mjs @@ -76,8 +76,13 @@ export function UpdateServiceStub() { // contains the status file's path // We may need to migrate update data + // In Base Browser and derivatives, 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.BASE_BROWSER_UPDATE && !Services.prefs.getBoolPref(prefUpdateDirMigrated, false) ) { Services.prefs.setBoolPref(prefUpdateDirMigrated, true); diff --git a/toolkit/mozapps/update/common/updatehelper.cpp b/toolkit/mozapps/update/common/updatehelper.cpp index b094d9eb75e9d..0f4f4976a52e9 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 BASE_BROWSER_UPDATE + // This function is used to support the maintenance service and elevated + // updates and is therefore not called by Base Browser's updater. We stub + // it out to avoid any chance that the Base 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/updater/launchchild_osx.mm b/toolkit/mozapps/update/updater/launchchild_osx.mm index 3d28a064c72eb..c1e2d067a4475 100644 --- a/toolkit/mozapps/update/updater/launchchild_osx.mm +++ b/toolkit/mozapps/update/updater/launchchild_osx.mm @@ -372,6 +372,7 @@ bool ObtainUpdaterArguments(int* argc, char*** argv) { @end +#ifndef BASE_BROWSER_UPDATE bool ServeElevatedUpdate(int argc, const char** argv) { MacAutoreleasePool pool; @@ -387,6 +388,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/updater.cpp b/toolkit/mozapps/update/updater/updater.cpp index 446f1578eeb20..898b34e8b87dc 100644 --- a/toolkit/mozapps/update/updater/updater.cpp +++ b/toolkit/mozapps/update/updater/updater.cpp @@ -76,7 +76,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 BASE_BROWSER_UPDATE bool ServeElevatedUpdate(int argc, const char** argv); +# endif void SetGroupOwnershipAndPermissions(const char* aAppBundle); bool PerformInstallationFromDMG(int argc, char** argv); struct UpdateServerThreadArgs { @@ -852,6 +854,11 @@ static int ensure_copy_recursive(const NS_tchar* path, const NS_tchar* dest, if (S_ISLNK(sInfo.st_mode)) { return ensure_copy_symlink(path, dest); } + + // Ignore Unix domain sockets. See #20691. + if (S_ISSOCK(sInfo.st_mode)) { + return 0; + } #endif if (!S_ISDIR(sInfo.st_mode)) { @@ -947,7 +954,7 @@ static int rename_file(const NS_tchar* spath, const NS_tchar* dpath, return OK; } -#ifdef XP_WIN +#if defined(XP_WIN) && !defined(BASE_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 @@ -1080,6 +1087,8 @@ static int backup_discard(const NS_tchar* path, const NS_tchar* relPath) { relBackup, relPath)); return WRITE_ERROR_DELETE_BACKUP; } + +# if !defined(BASE_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 @@ -1096,6 +1105,7 @@ static int backup_discard(const NS_tchar* path, const NS_tchar* relPath) { "file: " LOG_S, relPath)); } +# endif } #else if (rv) { @@ -2564,7 +2574,9 @@ static int ProcessReplaceRequest() { if (NS_taccess(deleteDir, F_OK)) { NS_tmkdir(deleteDir, 0755); } +# if !defined(BASE_BROWSER_UPDATE) remove_recursive_on_reboot(tmpDir, deleteDir); +# endif #endif } @@ -2646,8 +2658,14 @@ static void UpdateThreadFunc(void* param) { if (ReadMARChannelIDs(updateSettingsPath, &MARStrings) != OK) { rv = UPDATE_SETTINGS_FILE_CHANNEL; } else { +# ifdef BASE_BROWSER_VERSION_QUOTED + // Use the base browser version to prevent downgrade attacks. + const char* appVersion = BASE_BROWSER_VERSION_QUOTED; +# else + const char* appVersion = MOZ_APP_VERSION; +# endif rv = gArchiveReader.VerifyProductInformation( - MARStrings.MARChannelID.get(), MOZ_APP_VERSION); + MARStrings.MARChannelID.get(), appVersion); } } #endif @@ -2751,11 +2769,15 @@ static void UpdateThreadFunc(void* param) { #ifdef XP_MACOSX static void ServeElevatedUpdateThreadFunc(void* param) { +# ifdef BASE_BROWSER_UPDATE + WriteStatusFile(ELEVATION_CANCELED); +# else UpdateServerThreadArgs* threadArgs = (UpdateServerThreadArgs*)param; gSucceeded = ServeElevatedUpdate(threadArgs->argc, threadArgs->argv); if (!gSucceeded) { WriteStatusFile(ELEVATION_CANCELED); } +# endif QuitProgressUI(); } @@ -2785,7 +2807,7 @@ int LaunchCallbackAndPostProcessApps(int argc, NS_tchar** argv, #endif if (argc > callbackIndex) { -#if defined(XP_WIN) +#if defined(XP_WIN) && !defined(BASE_BROWSER_UPDATE) if (gSucceeded) { if (!LaunchWinPostProcess(gInstallDirPath, gPatchDirPath)) { fprintf(stderr, "The post update process was not launched"); @@ -2868,8 +2890,12 @@ int NS_main(int argc, NS_tchar** argv) { mozilla::UniquePtr<UmaskContext> umaskContext(new UmaskContext(0)); bool isElevated = +# ifdef BASE_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 @@ -3607,6 +3633,13 @@ int NS_main(int argc, NS_tchar** argv) { if (!useService && !noServiceFallback && (updateLockFileHandle == INVALID_HANDLE_VALUE || forceServiceFallback)) { +# ifdef BASE_BROWSER_UPDATE + // 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). + 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'}; @@ -3676,6 +3709,7 @@ int NS_main(int argc, NS_tchar** argv) { gCopyOutputFiles = false; WriteStatusFile(ELEVATION_CANCELED); } +# endif /* BASE_BROWSER_UPDATE */ } // If we started the elevated updater, and it finished, check the secure @@ -4046,6 +4080,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(BASE_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 @@ -4065,6 +4100,7 @@ int NS_main(int argc, NS_tchar** argv) { "directory: " LOG_S, DELETE_DIR)); } +# endif /* BASE_BROWSER_UPDATE */ } #endif /* XP_WIN */ diff --git a/toolkit/xre/MacLaunchHelper.h b/toolkit/xre/MacLaunchHelper.h index a4a8fb16661a0..ce480c2f9c602 100644 --- a/toolkit/xre/MacLaunchHelper.h +++ b/toolkit/xre/MacLaunchHelper.h @@ -17,9 +17,11 @@ extern "C" { * pid of the terminated process to confirm that it executed successfully. */ void LaunchChildMac(int aArgc, char** aArgv, pid_t* aPid = 0); +#ifndef BASE_BROWSER_UPDATE bool LaunchElevatedUpdate(int aArgc, char** aArgv, pid_t* aPid = 0); bool InstallPrivilegedHelper(); void AbortElevatedUpdate(); +#endif } #endif diff --git a/toolkit/xre/MacLaunchHelper.mm b/toolkit/xre/MacLaunchHelper.mm index 555e15d08479f..56a574f4dc34f 100644 --- a/toolkit/xre/MacLaunchHelper.mm +++ b/toolkit/xre/MacLaunchHelper.mm @@ -39,6 +39,7 @@ void LaunchChildMac(int aArgc, char** aArgv, pid_t* aPid) { } } +#ifndef BASE_BROWSER_UPDATE bool InstallPrivilegedHelper() { AuthorizationRef authRef = NULL; OSStatus status = AuthorizationCreate( @@ -115,3 +116,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 b12187a9c259b..cd15676ad169f 100644 --- a/toolkit/xre/nsAppRunner.cpp +++ b/toolkit/xre/nsAppRunner.cpp @@ -3432,6 +3432,11 @@ static bool CheckCompatibility(nsIFile* aProfileDir, const nsCString& aVersion, gLastAppBuildID.Assign(gAppData->buildID); nsAutoCString buf; + + nsAutoCString forkVersion(BASE_BROWSER_VERSION_QUOTED); + rv = parser.GetString("Compatibility", "LastBaseBrowserVersion", buf); + if (NS_FAILED(rv) || !forkVersion.Equals(buf)) return false; + rv = parser.GetString("Compatibility", "LastOSABI", buf); if (NS_FAILED(rv) || !aOSABI.Equals(buf)) return false; @@ -3517,6 +3522,12 @@ static void WriteVersion(nsIFile* aProfileDir, const nsCString& aVersion, PR_Write(fd, kHeader, sizeof(kHeader) - 1); PR_Write(fd, aVersion.get(), aVersion.Length()); + nsAutoCString forkVersion(BASE_BROWSER_VERSION_QUOTED); + static const char kForkVersionHeader[] = + NS_LINEBREAK "LastBaseBrowserVersion="; + PR_Write(fd, kForkVersionHeader, sizeof(kForkVersionHeader) - 1); + PR_Write(fd, forkVersion.get(), forkVersion.Length()); + static const char kOSABIHeader[] = NS_LINEBREAK "LastOSABI="; PR_Write(fd, kOSABIHeader, sizeof(kOSABIHeader) - 1); PR_Write(fd, aOSABI.get(), aOSABI.Length()); @@ -4905,8 +4916,18 @@ int XREMain::XRE_mainStartup(bool* aExitFlag) { NS_ENSURE_SUCCESS(rv, 1); rv = exeFile->GetParent(getter_AddRefs(exeDir)); NS_ENSURE_SUCCESS(rv, 1); + +# ifdef BASE_BROWSER_VERSION_QUOTED + nsAutoCString compatVersion(BASE_BROWSER_VERSION_QUOTED); +# endif ProcessUpdates(mDirProvider.GetGREDir(), exeDir, updRoot, gRestartArgc, - gRestartArgv, mAppData->version); + gRestartArgv, +# ifdef BASE_BROWSER_VERSION_QUOTED + 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 c355741c76c97..b079f88f649c4 100644 --- a/toolkit/xre/nsUpdateDriver.cpp +++ b/toolkit/xre/nsUpdateDriver.cpp @@ -52,7 +52,6 @@ # include "commonupdatedir.h" # include "nsWindowsHelpers.h" # include "pathhash.h" -# include "WinUtils.h" # define getcwd(path, size) _getcwd(path, size) # define getpid() GetCurrentProcessId() #elif defined(XP_UNIX) @@ -161,6 +160,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; @@ -222,6 +228,34 @@ enum UpdateStatus { eAppliedService, }; +#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. @@ -294,6 +328,11 @@ 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; } @@ -443,6 +482,7 @@ static void ApplyUpdate(nsIFile* greDir, nsIFile* updateDir, nsIFile* appDir, gfxPlatformMac::WaitForFontRegistration(); } +# ifndef BASE_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). @@ -469,6 +509,7 @@ static void ApplyUpdate(nsIFile* greDir, nsIFile* updateDir, nsIFile* appDir, } } } +# endif #endif nsAutoCString applyToDirPath; @@ -577,6 +618,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 @@ -615,6 +659,13 @@ 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 BASE_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). if (restart && needElevation) { bool hasLaunched = LaunchElevatedUpdate(argc, argv, outpid); free(argv); @@ -624,6 +675,7 @@ if (restart && needElevation) { } exit(0); } +# endif if (isStaged) { // Launch the updater to replace the installation with the staged updated. @@ -694,14 +746,25 @@ nsresult ProcessUpdates(nsIFile* greDir, nsIFile* appDir, nsIFile* updRootDir, bool restart, ProcessType* pid) { nsresult rv; -#ifdef XP_WIN - // If we're in a package, we know any updates that we find are not for us. - if (mozilla::widget::WinUtils::HasPackageIdentity()) { - return NS_OK; +#if defined(XP_WIN) && defined(BASE_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 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); @@ -721,6 +784,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: { @@ -788,13 +857,16 @@ nsUpdateProcessor::ProcessUpdate() { NS_ENSURE_SUCCESS(rv, rv); } + nsAutoCString appVersion; +#ifdef BASE_BROWSER_VERSION_QUOTED + appVersion = BASE_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 // worker thread. diff --git a/toolkit/xre/nsXREDirProvider.cpp b/toolkit/xre/nsXREDirProvider.cpp index 566219fa303fc..ec9183ebc96e6 100644 --- a/toolkit/xre/nsXREDirProvider.cpp +++ b/toolkit/xre/nsXREDirProvider.cpp @@ -1100,7 +1100,44 @@ nsresult nsXREDirProvider::GetUpdateRootDir(nsIFile** aResult, rv = appFile->GetParent(getter_AddRefs(updRoot)); NS_ENSURE_SUCCESS(rv, rv); -#ifdef XP_MACOSX +#if defined(BASE_BROWSER_UPDATE) + // For Base Browser and derivatives, we store update history, etc. within the + // UpdateInfo directory under the user data directory. +# if defined(ANDROID) +# error "The Base Browser updater is not supported on Android." +# elif defined(XP_MACOSX) + rv = GetUserDataDirectory(getter_AddRefs(updRoot), false); + NS_ENSURE_SUCCESS(rv, rv); +# else + rv = GetUserDataDirectoryHome(getter_AddRefs(updRoot), false); + NS_ENSURE_SUCCESS(rv, rv); +# endif + rv = updRoot->AppendNative("UpdateInfo"_ns); + NS_ENSURE_SUCCESS(rv, rv); + +# if defined(XP_MACOSX) + // Since the 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 our 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. + nsAutoString appPath; + rv = appFile->GetPath(appPath); + NS_ENSURE_SUCCESS(rv, rv); + int32_t dotIndex = appPath.RFind(u".app"); + if (dotIndex == kNotFound) { + dotIndex = appPath.Length(); + } + appPath = Substring(appPath, 1, dotIndex - 1); + rv = updRoot->AppendRelativePath(appPath); + NS_ENSURE_SUCCESS(rv, rv); +# endif + + updRoot.forget(aResult); + return NS_OK; +// The rest of the function is for ! BASE_BROWSER_UPDATE +#elif defined(XP_MACOSX) nsCOMPtr<nsIFile> appRootDirFile; nsCOMPtr<nsIFile> localDir; nsAutoString appDirPath; diff --git a/tools/update-packaging/common.sh b/tools/update-packaging/common.sh index 4b994f30169c9..aef7c49c2b2a7 100755 --- a/tools/update-packaging/common.sh +++ b/tools/update-packaging/common.sh @@ -76,17 +76,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() { @@ -113,17 +104,8 @@ 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() { -- GitLab