
Pier Angelo Vendrame pushed to branch tor-browser-140.2.0esr-15.0-1 at The Tor Project / Applications / Tor Browser Commits: d5582e87 by Pier Angelo Vendrame at 2025-09-08T12:03:34+02:00 fixup! BB 42019: Empty browser's clipboard on browser shutdown BB 43770: Follow upstream's BrowserGlue simplifications. ClipboardPrivacy to its own file and initialize it from the manifest, rather than from BrowserGlue. - - - - - d4c6e7a4 by Pier Angelo Vendrame at 2025-09-08T12:03:35+02:00 fixup! BB 40925: Implemented the Security Level component BB 43770: Follow upstream's BrowserGlue simplifications. Initialize the security level notification from the manifest. Also, since it was the only occurrence of the file path, move it to the moz-src:// scheme. - - - - - 8eccdc93 by Pier Angelo Vendrame at 2025-09-08T12:03:35+02:00 fixup! TB 40933: Add tor-launcher functionality BB 43770: Follow upstream's BrowserGlue simplifications. Moved the call to firstWindowLoaded to the manifest. - - - - - 167c0116 by Pier Angelo Vendrame at 2025-09-08T12:03:36+02:00 fixup! TB 8324: Prevent DNS proxy bypasses caused by Drag&Drop BB 43770: Follow upstream's BrowserGlue simplifications. - - - - - b45bb7f1 by Pier Angelo Vendrame at 2025-09-08T12:03:37+02:00 fixup! TB 43405: Show a prompt whenever we fail to apply Tor settings. BB 43770: Follow upstream's BrowserGlue simplifications. - - - - - ad267a06 by Pier Angelo Vendrame at 2025-09-08T12:03:37+02:00 fixup! TB 40458: Implement .tor.onion aliases Use proper private method and members. - - - - - a05bd724 by Pier Angelo Vendrame at 2025-09-08T12:03:38+02:00 fixup! TB 40458: Implement .tor.onion aliases BB 43770: Follow upstream's BrowserGlue simplifications. - - - - - a857af7e by Pier Angelo Vendrame at 2025-09-08T12:03:38+02:00 fixup! BB 42027: Base Browser migration procedures. BB 43770: Follow upstream's BrowserGlue simplifications. - - - - - 51ca3bdf by Pier Angelo Vendrame at 2025-09-08T12:03:39+02:00 fixup! TB 41435: Add a Tor Browser migration function BB 43770: Follow upstream's BrowserGlue simplifications. - - - - - 12 changed files: - browser/components/BrowserComponents.manifest - browser/components/BrowserGlue.sys.mjs - browser/components/ProfileDataUpgrader.sys.mjs - browser/components/onionservices/OnionAliasStore.sys.mjs - browser/components/onionservices/moz.build - browser/components/rulesets/RulesetsParent.sys.mjs - + browser/modules/ClipboardPrivacy.sys.mjs - browser/modules/moz.build - dom/base/ContentAreaDropListener.sys.mjs - toolkit/components/places/PlacesUtils.sys.mjs - toolkit/components/tor-launcher/tor-launcher.manifest - toolkit/modules/moz.build Changes: ===================================== browser/components/BrowserComponents.manifest ===================================== @@ -51,6 +51,11 @@ category browser-first-window-ready resource://gre/modules/CaptchaDetectionPingU category browser-first-window-ready resource://gre/modules/SandboxUtils.sys.mjs SandboxUtils.maybeWarnAboutMissingUserNamespaces #endif #endif +category browser-first-window-ready moz-src:///browser/modules/ClipboardPrivacy.sys.mjs ClipboardPrivacy.init +category browser-first-window-ready moz-src:///browser/modules/SecurityLevelRestartNotification.sys.mjs SecurityLevelRestartNotification.ready +category browser-first-window-ready moz-src:///toolkit/modules/DragDropFilter.sys.mjs DragDropFilter.init +category browser-first-window-ready moz-src:///browser/modules/TorSettingsNotification.sys.mjs TorSettingsNotification.ready +category browser-first-window-ready moz-src:///browser/components/onionservices/OnionAliasStore.sys.mjs OnionAliasStore.init category browser-idle-startup resource:///modules/PlacesUIUtils.sys.mjs PlacesUIUtils.unblockToolbars category browser-idle-startup resource:///modules/BuiltInThemes.sys.mjs BuiltInThemes.ensureBuiltInThemes @@ -94,5 +99,6 @@ category browser-quit-application-granted moz-src:///browser/components/search/S category browser-quit-application-granted resource://gre/modules/UpdateListener.sys.mjs UpdateListener.reset #endif category browser-quit-application-granted resource:///modules/UrlbarSearchTermsPersistence.sys.mjs UrlbarSearchTermsPersistence.uninit +category browser-quit-application-granted moz-src:///browser/components/onionservices/OnionAliasStore.sys.mjs OnionAliasStore.uninit category search-service-notification moz-src:///browser/components/search/SearchUIUtils.sys.mjs SearchUIUtils.showSearchServiceNotification ===================================== browser/components/BrowserGlue.sys.mjs ===================================== @@ -12,7 +12,6 @@ ChromeUtils.defineESModuleGetters(lazy, { AWToolbarButton: "resource:///modules/aboutwelcome/AWToolbarUtils.sys.mjs", ASRouter: "resource:///modules/asrouter/ASRouter.sys.mjs", AddonManager: "resource://gre/modules/AddonManager.sys.mjs", - AsyncShutdown: "resource://gre/modules/AsyncShutdown.sys.mjs", BackupService: "resource:///modules/backup/BackupService.sys.mjs", BrowserSearchTelemetry: "moz-src:///browser/components/search/BrowserSearchTelemetry.sys.mjs", @@ -31,7 +30,6 @@ ChromeUtils.defineESModuleGetters(lazy, { DistributionManagement: "resource:///modules/distribution.sys.mjs", DownloadsViewableInternally: "resource:///modules/DownloadsViewableInternally.sys.mjs", - DragDropFilter: "resource://gre/modules/DragDropFilter.sys.mjs", ExtensionsUI: "resource:///modules/ExtensionsUI.sys.mjs", // FilePickerCrashed is used by the `listeners` object below. // eslint-disable-next-line mozilla/valid-lazy @@ -42,7 +40,6 @@ ChromeUtils.defineESModuleGetters(lazy, { LoginHelper: "resource://gre/modules/LoginHelper.sys.mjs", MigrationUtils: "resource:///modules/MigrationUtils.sys.mjs", NimbusFeatures: "resource://nimbus/ExperimentAPI.sys.mjs", - OnionAliasStore: "resource:///modules/OnionAliasStore.sys.mjs", OnboardingMessageProvider: "resource:///modules/asrouter/OnboardingMessageProvider.sys.mjs", PageDataService: "resource:///modules/pagedata/PageDataService.sys.mjs", @@ -63,8 +60,6 @@ ChromeUtils.defineESModuleGetters(lazy, { ScreenshotsUtils: "resource:///modules/ScreenshotsUtils.sys.mjs", SearchSERPTelemetry: "moz-src:///browser/components/search/SearchSERPTelemetry.sys.mjs", - SecurityLevelRestartNotification: - "resource:///modules/SecurityLevelRestartNotification.sys.mjs", SessionStartup: "resource:///modules/sessionstore/SessionStartup.sys.mjs", SessionStore: "resource:///modules/sessionstore/SessionStore.sys.mjs", ShortcutUtils: "resource://gre/modules/ShortcutUtils.sys.mjs", @@ -75,11 +70,6 @@ ChromeUtils.defineESModuleGetters(lazy, { TelemetryReportingPolicy: "resource://gre/modules/TelemetryReportingPolicy.sys.mjs", TRRRacer: "resource:///modules/TRRPerformance.sys.mjs", - TorConnect: "resource://gre/modules/TorConnect.sys.mjs", - TorConnectTopics: "resource://gre/modules/TorConnect.sys.mjs", - TorProviderBuilder: "resource://gre/modules/TorProviderBuilder.sys.mjs", - TorSettingsNotification: - "resource:///modules/TorSettingsNotification.sys.mjs", WebChannel: "resource://gre/modules/WebChannel.sys.mjs", WebProtocolHandlerRegistrar: "resource:///modules/WebProtocolHandlerRegistrar.sys.mjs", @@ -113,170 +103,6 @@ if (AppConstants.ENABLE_WEBDRIVER) { const PREF_PDFJS_ISDEFAULT_CACHE_STATE = "pdfjs.enabledCache.state"; -// Empty clipboard content from private windows on exit -// (tor-browser#42154) -const ClipboardPrivacy = { - _lastClipboardHash: null, - _globalActivation: false, - _isPrivateClipboard: false, - _hasher: null, - _shuttingDown: false, - _log: null, - - _createTransferable() { - const trans = Cc["@mozilla.org/widget/transferable;1"].createInstance( - Ci.nsITransferable - ); - trans.init(null); - return trans; - }, - _computeClipboardHash() { - const flavors = ["text/x-moz-url", "text/plain"]; - if ( - !Services.clipboard.hasDataMatchingFlavors( - flavors, - Ci.nsIClipboard.kGlobalClipboard - ) - ) { - return null; - } - const trans = this._createTransferable(); - flavors.forEach(trans.addDataFlavor); - try { - Services.clipboard.getData(trans, Ci.nsIClipboard.kGlobalClipboard); - const clipboardContent = {}; - trans.getAnyTransferData({}, clipboardContent); - const { data } = clipboardContent.value.QueryInterface( - Ci.nsISupportsString - ); - const bytes = new TextEncoder().encode(data); - const hasher = (this._hasher ||= Cc[ - "@mozilla.org/security/hash;1" - ].createInstance(Ci.nsICryptoHash)); - hasher.init(hasher.SHA256); - hasher.update(bytes, bytes.length); - return hasher.finish(true); - } catch (e) {} - return null; - }, - - startup() { - this._log = console.createInstance({ - prefix: "ClipboardPrivacy", - }); - this._lastClipboardHash = this._computeClipboardHash(); - - // Here we track changes in active window / application, - // by filtering focus events and window closures. - const handleActivation = (win, activation) => { - if (activation) { - if (!this._globalActivation) { - // focus changed within this window, bail out. - return; - } - this._globalActivation = false; - } else if (!Services.focus.activeWindow) { - // focus is leaving this window: - // let's track whether it remains within the browser. - lazy.setTimeout(() => { - this._globalActivation = !Services.focus.activeWindow; - }, 100); - } - - const checkClipboardContent = () => { - const clipboardHash = this._computeClipboardHash(); - if (clipboardHash !== this._lastClipboardHash) { - this._isPrivateClipboard = - !activation && - (lazy.PrivateBrowsingUtils.permanentPrivateBrowsing || - lazy.PrivateBrowsingUtils.isWindowPrivate(win)); - this._lastClipboardHash = clipboardHash; - this._log.debug( - `Clipboard changed: private ${this._isPrivateClipboard}, hash ${clipboardHash}.` - ); - } - }; - - if (win.closed) { - checkClipboardContent(); - } else { - // defer clipboard access on DOM events to work-around tor-browser#42306 - lazy.setTimeout(checkClipboardContent, 0); - } - }; - const focusListener = e => - e.isTrusted && handleActivation(e.currentTarget, e.type === "focusin"); - const initWindow = win => { - for (const e of ["focusin", "focusout"]) { - win.addEventListener(e, focusListener); - } - }; - for (const w of Services.ww.getWindowEnumerator()) { - initWindow(w); - } - Services.ww.registerNotification((win, event) => { - switch (event) { - case "domwindowopened": - initWindow(win); - break; - case "domwindowclosed": - handleActivation(win, false); - if ( - this._isPrivateClipboard && - lazy.PrivateBrowsingUtils.isWindowPrivate(win) && - (this._shuttingDown || - !Array.from(Services.ww.getWindowEnumerator()).find( - w => - lazy.PrivateBrowsingUtils.isWindowPrivate(w) && - // We need to filter out the HIDDEN WebExtensions window, - // which might be private as well but is not UI-relevant. - !w.location.href.startsWith("chrome://extensions/") - )) - ) { - // no more private windows, empty private content if needed - this.emptyPrivate(); - } - } - }); - - lazy.AsyncShutdown.quitApplicationGranted.addBlocker( - "ClipboardPrivacy: removing private data", - () => { - this._shuttingDown = true; - this.emptyPrivate(); - } - ); - }, - emptyPrivate() { - if ( - this._isPrivateClipboard && - !Services.prefs.getBoolPref( - "browser.privatebrowsing.preserveClipboard", - false - ) && - this._lastClipboardHash === this._computeClipboardHash() - ) { - // nsIClipboard.emptyClipboard() does nothing in Wayland: - // we'll set an empty string as a work-around. - const trans = this._createTransferable(); - const flavor = "text/plain"; - trans.addDataFlavor(flavor); - const emptyString = Cc["@mozilla.org/supports-string;1"].createInstance( - Ci.nsISupportsString - ); - emptyString.data = ""; - trans.setTransferData(flavor, emptyString); - const { clipboard } = Services, - { kGlobalClipboard } = clipboard; - clipboard.setData(trans, null, kGlobalClipboard); - clipboard.emptyClipboard(kGlobalClipboard); - this._lastClipboardHash = null; - this._isPrivateClipboard = false; - this._log.info("Private clipboard emptied."); - } - }, -}; - ChromeUtils.defineLazyGetter( lazy, "WeaveService", @@ -603,13 +429,8 @@ BrowserGlue.prototype = { // handle any UI migration this._migrateUI(); - - // Base Browser-specific version of _migrateUI. - this._migrateUIBB(); - - // Handle any TBB-specific migration before showing the UI. Keep after - // _migrateUI to make sure this._isNewProfile has been defined. - this._migrateUITBB(); + lazy.ProfileDataUpgrader.upgradeBB(this._isNewProfile); + lazy.ProfileDataUpgrader.upgradeTB(this._isNewProfile); if (!Services.prefs.prefHasUserValue(PREF_PDFJS_ISDEFAULT_CACHE_STATE)) { lazy.PdfJs.checkIsDefault(this._isNewProfile); @@ -995,16 +816,6 @@ BrowserGlue.prototype = { lazy.WeaveService.init(); } - lazy.SecurityLevelRestartNotification.ready(); - - lazy.DragDropFilter.init(); - - lazy.TorProviderBuilder.firstWindowLoaded(); - - lazy.TorSettingsNotification.ready(); - - ClipboardPrivacy.startup(); - lazy.BrowserUtils.callModulesFromCategory( { categoryName: "browser-first-window-ready", @@ -1104,7 +915,6 @@ BrowserGlue.prototype = { // can perform at-shutdown tasks later in shutdown. Services.fog; }, - () => lazy.OnionAliasStore.uninit(), ]; for (let task of tasks) { @@ -1375,30 +1185,6 @@ BrowserGlue.prototype = { }, }, - { - task: () => { - if (!lazy.TorConnect.shouldShowTorConnect) { - // we will take this path when the user is using the legacy tor launcher or - // when Tor Browser didn't launch its own tor. - lazy.OnionAliasStore.init(); - } else { - // this path is taken when using about:torconnect, we wait to init - // after we are bootstrapped and connected to tor - const topic = lazy.TorConnectTopics.BootstrapComplete; - let bootstrapObserver = { - observe(aSubject, aTopic) { - if (aTopic === topic) { - lazy.OnionAliasStore.init(); - // we only need to init once, so remove ourselves as an obvserver - Services.obs.removeObserver(this, topic); - } - }, - }; - Services.obs.addObserver(bootstrapObserver, topic); - } - }, - }, - // Run TRR performance measurements for DoH. { name: "doh-rollout.trrRacer.run", @@ -1865,208 +1651,6 @@ BrowserGlue.prototype = { } }, - _migrateUIBB() { - // Version 1: 13.0a3. Reset layout.css.prefers-color-scheme.content-override - // for tor-browser#41739. - // Version 2: 14.0a5: Reset the privacy tracking headers preferences since - // the UI is hidden. tor-browser#42777. - // Also, do not set - // dom.security.https_only_mode_send_http_background_request in - // the security level anymore (tor-browser#42149). - // Also, reset security.xfocsp.errorReporting.automatic since we - // hid its neterror checkbox. tor-browser#42653. - // Version 3: 14.0a7: Reset general.smoothScroll. tor-browser#42070. - // Version 4: 15.0a2: Drop ML components. tor-browser#44045. - const MIGRATION_VERSION = 4; - const MIGRATION_PREF = "basebrowser.migration.version"; - if (this._isNewProfile) { - // Do not migrate fresh profiles - Services.prefs.setIntPref(MIGRATION_PREF, MIGRATION_VERSION); - return; - } else if (this._isNewProfile === undefined) { - // If this happens, check if upstream updated their function and do not - // set this member anymore! - console.error("_migrateUIBB: this._isNewProfile is undefined."); - } - // We do not care whether this is a new or old profile, since in version 1 - // we just quickly clear a user preference, which should not do anything to - // new profiles. - // Shall we ever raise the version number and have a watershed, we can add - // a check easily (any version > 0 will be an old profile). - const currentVersion = Services.prefs.getIntPref(MIGRATION_PREF, 0); - if (currentVersion < 1) { - Services.prefs.clearUserPref( - "layout.css.prefers-color-scheme.content-override" - ); - } - if (currentVersion < 2) { - for (const prefName of [ - "privacy.globalprivacycontrol.enabled", - "privacy.donottrackheader.enabled", - // Telemetry preference for if the user changed the value. - "privacy.globalprivacycontrol.was_ever_enabled", - // The next two preferences have no corresponding UI, but are related. - "privacy.globalprivacycontrol.functionality.enabled", - "privacy.globalprivacycontrol.pbmode.enabled", - "dom.security.https_only_mode_send_http_background_request", - "security.xfocsp.errorReporting.automatic", - ]) { - Services.prefs.clearUserPref(prefName); - } - } - if (currentVersion < 3) { - Services.prefs.clearUserPref("general.smoothScroll"); - } - if (currentVersion < 4) { - for (const prefName of [ - "browser.translations.enable", - "browser.ml.enable", - "browser.ml.chat.enabled", - "browser.ml.linkPreview.enabled", - "browser.tabs.groups.smart.enabled", - "browser.tabs.groups.smart.userEnabled", - "extensions.ml.enabled", - "pdfjs.enableAltText", - "pdfjs.enableAltTextForEnglish", - "pdfjs.enableGuessAltText", - "pdfjs.enableAltTextModelDownload", - "browser.urlbar.quicksuggest.mlEnabled", - "places.semanticHistory.featureGate", - ]) { - // Preferences are locked. Do not want user values to linger in the - // user's profile and become active if these preferences become unlocked - // in the future. - Services.prefs.clearUserPref(prefName); - } - } - Services.prefs.setIntPref(MIGRATION_PREF, MIGRATION_VERSION); - }, - - // Use this method for any TBB migration that can be run just before showing - // the UI. - // Anything that critically needs to be migrated earlier should not use this. - async _migrateUITBB() { - // Version 1: Tor Browser 12.0. We use it to remove langpacks, after the - // migration to packaged locales. - // Version 2: Tor Browser 13.0/13.0a1: tor-browser#41845. Also, removed some - // torbutton preferences that are not used anymore. - // Version 3: Tor Browser 13.0.7/13.5a3: Remove blockchair - // (tor-browser#42283). - // Version 4: Tor Browser 14.0a4 (2024-09-02): Remove Twitter, Yahoo and - // YouTube search engines (tor-browser#41835). - // Version 5: Tor Browser 14.0a5: Clear user preference for CFR settings - // since we hid the UI (tor-browser#43118). - // Version 6: Tor Browser 14.5a3: Clear preference for TorSettings that is - // no longer used (tor-browser#41921). - // Drop unused TorConnect setting (tor-browser#43462). - // Version 7: Tor Browser 14.5a6: Clear home page update url preference - // (tor-browser#43567). - // Version 8: Tor Browser 15.0a2: Remove legacy search addons - // (tor-browser#43111). - const TBB_MIGRATION_VERSION = 8; - const MIGRATION_PREF = "torbrowser.migration.version"; - - // If we decide to force updating users to pass through any version - // following 12.0, we can remove this check, and check only whether - // MIGRATION_PREF has a user value, like Mozilla does. - if (this._isNewProfile) { - // Do not migrate fresh profiles - Services.prefs.setIntPref(MIGRATION_PREF, TBB_MIGRATION_VERSION); - return; - } else if (this._isNewProfile === undefined) { - // If this happens, check if upstream updated their function and do not - // set this member anymore! - console.error("_migrateUITBB: this._isNewProfile is undefined."); - } - - const currentVersion = Services.prefs.getIntPref(MIGRATION_PREF, 0); - const removeLangpacks = async () => { - for (const addon of await AddonManager.getAddonsByTypes(["locale"])) { - await addon.uninstall(); - } - }; - if (currentVersion < 1) { - try { - await removeLangpacks(); - } catch (err) { - console.error("Could not remove langpacks", err); - } - } - if (currentVersion < 2) { - const prefToClear = [ - // tor-browser#41845: We were forcing these value by check the value of - // automatic PBM. We decided not to change - "browser.cache.disk.enable", - "places.history.enabled", - "security.nocertdb", - "permissions.memory_only", - // Old torbutton preferences not used anymore. - "extensions.torbutton.loglevel", - "extensions.torbutton.logmethod", - "extensions.torbutton.pref_fixup_version", - "extensions.torbutton.resize_new_windows", - "extensions.torbutton.startup", - "extensions.torlauncher.prompt_for_locale", - "extensions.torlauncher.loglevel", - "extensions.torlauncher.logmethod", - "extensions.torlauncher.torrc_fixup_version", - ]; - for (const pref of prefToClear) { - if (Services.prefs.prefHasUserValue(pref)) { - Services.prefs.clearUserPref(pref); - } - } - } - const dropAddons = async list => { - for (const id of list) { - try { - const engine = await lazy.AddonManager.getAddonByID(id); - await engine?.uninstall(); - } catch {} - } - }; - if (currentVersion < 3) { - await dropAddons([ - "blockchair@search.mozilla.org", - "blockchair-onion@search.mozilla.org", - ]); - } - if (currentVersion < 4) { - await dropAddons([ - "twitter@search.mozilla.org", - "yahoo@search.mozilla.org", - "youtube@search.mozilla.org", - ]); - } - if (currentVersion < 5) { - for (const pref of [ - "browser.newtabpage.activity-stream.asrouter.userprefs.cfr.addons", - "browser.newtabpage.activity-stream.asrouter.userprefs.cfr.features", - ]) { - Services.prefs.clearUserPref(pref); - } - } - if (currentVersion < 6) { - Services.prefs.clearUserPref("torbrowser.settings.enabled"); - Services.prefs.clearUserPref("torbrowser.bootstrap.allow_internet_test"); - } - if (currentVersion < 7) { - Services.prefs.clearUserPref("torbrowser.post_update.url"); - } - if (currentVersion < 8) { - await dropAddons([ - "ddg@search.mozilla.org", - "ddg-onion@search.mozilla.org", - "google@search.mozilla.org", - "startpage@search.mozilla.org", - "startpage-onion@search.mozilla.org", - "wikipedia@search.mozilla.org", - ]); - } - - Services.prefs.setIntPref(MIGRATION_PREF, TBB_MIGRATION_VERSION); - }, - async _showUpgradeDialog() { const data = await lazy.OnboardingMessageProvider.getUpgradeMessage(); const { gBrowser } = lazy.BrowserWindowTracker.getTopWindow(); ===================================== browser/components/ProfileDataUpgrader.sys.mjs ===================================== @@ -900,4 +900,200 @@ export let ProfileDataUpgrader = { // Update the migration version. Services.prefs.setIntPref("browser.migration.version", newVersion); }, + + upgradeBB(isNewProfile) { + // Version 1: 13.0a3. Reset layout.css.prefers-color-scheme.content-override + // for tor-browser#41739. + // Version 2: 14.0a5: Reset the privacy tracking headers preferences since + // the UI is hidden. tor-browser#42777. + // Also, do not set + // dom.security.https_only_mode_send_http_background_request in + // the security level anymore (tor-browser#42149). + // Also, reset security.xfocsp.errorReporting.automatic since we + // hid its neterror checkbox. tor-browser#42653. + // Version 3: 14.0a7: Reset general.smoothScroll. tor-browser#42070. + // Version 4: 15.0a2: Drop ML components. tor-browser#44045. + const MIGRATION_VERSION = 4; + const MIGRATION_PREF = "basebrowser.migration.version"; + + if (isNewProfile) { + // Do not migrate fresh profiles + Services.prefs.setIntPref(MIGRATION_PREF, MIGRATION_VERSION); + return; + } else if (isNewProfile === undefined) { + // If this happens, check if upstream updated their function and do not + // set this member anymore! + console.error("upgradeBB: isNewProfile is undefined."); + } + + const currentVersion = Services.prefs.getIntPref(MIGRATION_PREF, 0); + if (currentVersion < 1) { + Services.prefs.clearUserPref( + "layout.css.prefers-color-scheme.content-override" + ); + } + if (currentVersion < 2) { + for (const prefName of [ + "privacy.globalprivacycontrol.enabled", + "privacy.donottrackheader.enabled", + // Telemetry preference for if the user changed the value. + "privacy.globalprivacycontrol.was_ever_enabled", + // The next two preferences have no corresponding UI, but are related. + "privacy.globalprivacycontrol.functionality.enabled", + "privacy.globalprivacycontrol.pbmode.enabled", + "dom.security.https_only_mode_send_http_background_request", + "security.xfocsp.errorReporting.automatic", + ]) { + Services.prefs.clearUserPref(prefName); + } + } + if (currentVersion < 3) { + Services.prefs.clearUserPref("general.smoothScroll"); + } + if (currentVersion < 4) { + for (const prefName of [ + "browser.translations.enable", + "browser.ml.enable", + "browser.ml.chat.enabled", + "browser.ml.linkPreview.enabled", + "browser.tabs.groups.smart.enabled", + "browser.tabs.groups.smart.userEnabled", + "extensions.ml.enabled", + "pdfjs.enableAltText", + "pdfjs.enableAltTextForEnglish", + "pdfjs.enableGuessAltText", + "pdfjs.enableAltTextModelDownload", + "browser.urlbar.quicksuggest.mlEnabled", + "places.semanticHistory.featureGate", + ]) { + // Preferences are locked. Do not want user values to linger in the + // user's profile and become active if these preferences become unlocked + // in the future. + Services.prefs.clearUserPref(prefName); + } + } + Services.prefs.setIntPref(MIGRATION_PREF, MIGRATION_VERSION); + }, + + async upgradeTB(isNewProfile) { + // Version 1: Tor Browser 12.0. We use it to remove langpacks, after the + // migration to packaged locales. + // Version 2: Tor Browser 13.0/13.0a1: tor-browser#41845. Also, removed some + // torbutton preferences that are not used anymore. + // Version 3: Tor Browser 13.0.7/13.5a3: Remove blockchair + // (tor-browser#42283). + // Version 4: Tor Browser 14.0a4 (2024-09-02): Remove Twitter, Yahoo and + // YouTube search engines (tor-browser#41835). + // Version 5: Tor Browser 14.0a5: Clear user preference for CFR settings + // since we hid the UI (tor-browser#43118). + // Version 6: Tor Browser 14.5a3: Clear preference for TorSettings that is + // no longer used (tor-browser#41921). + // Drop unused TorConnect setting (tor-browser#43462). + // Version 7: Tor Browser 14.5a6: Clear home page update url preference + // (tor-browser#43567). + // Version 8: Tor Browser 15.0a2: Remove legacy search addons + // (tor-browser#43111). + const TBB_MIGRATION_VERSION = 8; + const MIGRATION_PREF = "torbrowser.migration.version"; + + // If we decide to force updating users to pass through any version + // following 12.0, we can remove this check, and check only whether + // MIGRATION_PREF has a user value, like Mozilla does. + if (isNewProfile) { + // Do not migrate fresh profiles + Services.prefs.setIntPref(MIGRATION_PREF, TBB_MIGRATION_VERSION); + return; + } else if (isNewProfile === undefined) { + // If this happens, check if upstream updated their function and do not + // set this member anymore! + console.error("upgradeTB: isNewProfile is undefined."); + } + + const currentVersion = Services.prefs.getIntPref(MIGRATION_PREF, 0); + const removeLangpacks = async () => { + for (const addon of await AddonManager.getAddonsByTypes(["locale"])) { + await addon.uninstall(); + } + }; + if (currentVersion < 1) { + try { + await removeLangpacks(); + } catch (err) { + console.error("Could not remove langpacks", err); + } + } + if (currentVersion < 2) { + const prefToClear = [ + // tor-browser#41845: We were forcing these value by check the value of + // automatic PBM. We decided not to change + "browser.cache.disk.enable", + "places.history.enabled", + "security.nocertdb", + "permissions.memory_only", + // Old torbutton preferences not used anymore. + "extensions.torbutton.loglevel", + "extensions.torbutton.logmethod", + "extensions.torbutton.pref_fixup_version", + "extensions.torbutton.resize_new_windows", + "extensions.torbutton.startup", + "extensions.torlauncher.prompt_for_locale", + "extensions.torlauncher.loglevel", + "extensions.torlauncher.logmethod", + "extensions.torlauncher.torrc_fixup_version", + ]; + for (const pref of prefToClear) { + if (Services.prefs.prefHasUserValue(pref)) { + Services.prefs.clearUserPref(pref); + } + } + } + const dropAddons = async list => { + for (const id of list) { + try { + const engine = await lazy.AddonManager.getAddonByID(id); + await engine?.uninstall(); + } catch {} + } + }; + if (currentVersion < 3) { + await dropAddons([ + "blockchair@search.mozilla.org", + "blockchair-onion@search.mozilla.org", + ]); + } + if (currentVersion < 4) { + await dropAddons([ + "twitter@search.mozilla.org", + "yahoo@search.mozilla.org", + "youtube@search.mozilla.org", + ]); + } + if (currentVersion < 5) { + for (const pref of [ + "browser.newtabpage.activity-stream.asrouter.userprefs.cfr.addons", + "browser.newtabpage.activity-stream.asrouter.userprefs.cfr.features", + ]) { + Services.prefs.clearUserPref(pref); + } + } + if (currentVersion < 6) { + Services.prefs.clearUserPref("torbrowser.settings.enabled"); + Services.prefs.clearUserPref("torbrowser.bootstrap.allow_internet_test"); + } + if (currentVersion < 7) { + Services.prefs.clearUserPref("torbrowser.post_update.url"); + } + if (currentVersion < 8) { + await dropAddons([ + "ddg@search.mozilla.org", + "ddg-onion@search.mozilla.org", + "google@search.mozilla.org", + "startpage@search.mozilla.org", + "startpage-onion@search.mozilla.org", + "wikipedia@search.mozilla.org", + ]); + } + + Services.prefs.setIntPref(MIGRATION_PREF, TBB_MIGRATION_VERSION); + }, }; ===================================== browser/components/onionservices/OnionAliasStore.sys.mjs ===================================== @@ -1,4 +1,6 @@ -// Copyright (c) 2022, The Tor Project, Inc. +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ import { setTimeout, clearTimeout } from "resource://gre/modules/Timer.sys.mjs"; @@ -6,7 +8,10 @@ const lazy = {}; ChromeUtils.defineESModuleGetters(lazy, { JSONFile: "resource://gre/modules/JSONFile.sys.mjs", - TorRequestWatch: "resource:///modules/TorRequestWatch.sys.mjs", + TorConnect: "resource://gre/modules/TorConnect.sys.mjs", + TorConnectTopics: "resource://gre/modules/TorConnect.sys.mjs", + TorRequestWatch: + "moz-src:///browser/components/onionservices/TorRequestWatch.sys.mjs", }); /* OnionAliasStore observer topics */ @@ -84,12 +89,14 @@ class Channel { }; } + #enabled; + constructor(name, pathPrefix, jwk, scope, enabled) { this.name = name; this.pathPrefix = pathPrefix; this.jwk = jwk; this.scope = scope; - this._enabled = enabled; + this.#enabled = enabled; this.mappings = []; this.currentTimestamp = 0; @@ -158,10 +165,10 @@ class Channel { log.debug( `Downloaded and verified rules for ${this.name}, now uncompressing` ); - this._makeMappings(JSON.parse(await gunzip(rulesGz))); + this.#makeMappings(JSON.parse(await gunzip(rulesGz))); } - _makeMappings(rules) { + #makeMappings(rules) { const toTest = /^https?:\/\/[a-zA-Z0-9\.]{56}\.onion$/; const mappings = []; rules.rulesets.forEach(rule => { @@ -210,7 +217,7 @@ class Channel { async updateMappings(force) { force = force === undefined ? false : !!force; - if (!this._enabled && !force) { + if (!this.#enabled && !force) { return; } await this.updateLatestTimestamp(); @@ -224,10 +231,10 @@ class Channel { } get enabled() { - return this._enabled; + return this.#enabled; } set enabled(enabled) { - this._enabled = enabled; + this.#enabled = enabled; if (!enabled) { this.mappings = []; this.currentTimestamp = 0; @@ -243,7 +250,7 @@ class Channel { pathPrefix: this.pathPrefix, jwk: this.jwk, scope, - enabled: this._enabled, + enabled: this.#enabled, mappings: this.mappings, currentTimestamp: this.currentTimestamp, }; @@ -277,37 +284,40 @@ class _OnionAliasStore { return 86400 * 1000; // 1 day, like HTTPS-Everywhere } - constructor() { - this._channels = new Map(); - this._rulesetTimeout = null; - this._lastCheck = 0; - this._storage = null; - } + #channels = new Map(); + #rulesetTimeout = null; + #lastCheck = 0; + #storage = null; async init() { lazy.TorRequestWatch.start(); - await this._loadSettings(); - if (this.enabled) { - await this._startUpdates(); + await this.#loadSettings(); + if (this.enabled && !lazy.TorConnect.shouldShowTorConnect) { + await this.#startUpdates(); + } else { + Services.obs.addObserver(this, lazy.TorConnectTopics.BootstrapComplete); } Services.prefs.addObserver(kPrefOnionAliasEnabled, this); } uninit() { - this._clear(); - if (this._rulesetTimeout) { - clearTimeout(this._rulesetTimeout); + this.#clear(); + if (this.#rulesetTimeout) { + clearTimeout(this.#rulesetTimeout); } - this._rulesetTimeout = null; + this.#rulesetTimeout = null; + + Services.obs.removeObserver(this, lazy.TorConnectTopics.BootstrapComplete); Services.prefs.removeObserver(kPrefOnionAliasEnabled, this); + lazy.TorRequestWatch.stop(); } async getChannels() { - if (this._storage === null) { - await this._loadSettings(); + if (this.#storage === null) { + await this.#loadSettings(); } - return Array.from(this._channels.values(), ch => ch.toJSON()); + return Array.from(this.#channels.values(), ch => ch.toJSON()); } async setChannel(chanData) { @@ -328,20 +338,20 @@ class _OnionAliasStore { ); // Call makeKey to make it throw if the key is invalid await ch.makeKey(); - this._channels.set(name, ch); - this._applyMappings(); - this._saveSettings(); - setTimeout(this._notifyChanges.bind(this), 1); + this.#channels.set(name, ch); + this.#applyMappings(); + this.#saveSettings(); + setTimeout(this.#notifyChanges.bind(this), 1); return ch; } enableChannel(name, enabled) { - const channel = this._channels.get(name); + const channel = this.#channels.get(name); if (channel !== null) { channel.enabled = enabled; - this._applyMappings(); - this._saveSettings(); - this._notifyChanges(); + this.#applyMappings(); + this.#saveSettings(); + this.#notifyChanges(); if (this.enabled && enabled && !channel.currentTimestamp) { this.updateChannel(name); } @@ -352,46 +362,46 @@ class _OnionAliasStore { if (!this.enabled) { throw Error("Onion Aliases are disabled"); } - const channel = this._channels.get(name); + const channel = this.#channels.get(name); if (channel === null) { throw Error("Channel not found"); } await channel.updateMappings(true); - this._saveSettings(); - this._applyMappings(); - setTimeout(this._notifyChanges.bind(this), 1); + this.#saveSettings(); + this.#applyMappings(); + setTimeout(this.#notifyChanges.bind(this), 1); return channel; } deleteChannel(name) { - if (this._channels.delete(name)) { - this._saveSettings(); - this._applyMappings(); - this._notifyChanges(); + if (this.#channels.delete(name)) { + this.#saveSettings(); + this.#applyMappings(); + this.#notifyChanges(); } } - async _loadSettings() { - if (this._storage !== null) { + async #loadSettings() { + if (this.#storage !== null) { return; } - this._channels = new Map(); - this._storage = new lazy.JSONFile({ + this.#channels = new Map(); + this.#storage = new lazy.JSONFile({ path: PathUtils.join( Services.dirsvc.get("ProfD", Ci.nsIFile).path, "onion-aliases.json" ), - dataPostProcessor: this._settingsProcessor.bind(this), + dataPostProcessor: this.#settingsProcessor.bind(this), }); - await this._storage.load(); - log.debug("Loaded settings", this._storage.data, this._storage.path); - this._applyMappings(); - this._notifyChanges(); + await this.#storage.load(); + log.debug("Loaded settings", this.#storage.data, this.#storage.path); + this.#applyMappings(); + this.#notifyChanges(); } - _settingsProcessor(data) { + #settingsProcessor(data) { if ("lastCheck" in data) { - this._lastCheck = data.lastCheck; + this.#lastCheck = data.lastCheck; } else { data.lastCheck = 0; } @@ -410,56 +420,56 @@ class _OnionAliasStore { } return true; }); - this._channels = channels; + this.#channels = channels; return data; } - _saveSettings() { - if (this._storage === null) { + #saveSettings() { + if (this.#storage === null) { throw Error("Settings have not been loaded"); } - this._storage.data.lastCheck = this._lastCheck; - this._storage.data.channels = Array.from(this._channels.values(), ch => + this.#storage.data.lastCheck = this.#lastCheck; + this.#storage.data.channels = Array.from(this.#channels.values(), ch => ch.toJSON() ); - this._storage.saveSoon(); + this.#storage.saveSoon(); } - _addMapping(shortOnionHost, longOnionHost) { + #addMapping(shortOnionHost, longOnionHost) { const service = Cc["@torproject.org/onion-alias-service;1"].getService( Ci.IOnionAliasService ); service.addOnionAlias(shortOnionHost, longOnionHost); } - _clear() { + #clear() { const service = Cc["@torproject.org/onion-alias-service;1"].getService( Ci.IOnionAliasService ); service.clearOnionAliases(); } - _applyMappings() { - this._clear(); - for (const ch of this._channels.values()) { + #applyMappings() { + this.#clear(); + for (const ch of this.#channels.values()) { if (!ch.enabled) { continue; } for (const [short, long] of ch.mappings) { - this._addMapping(short, long); + this.#addMapping(short, long); } } } - async _periodicRulesetCheck() { + async #periodicRulesetCheck() { if (!this.enabled) { log.debug("Onion Aliases are disabled, not updating rulesets."); return; } log.debug("Begin scheduled ruleset update"); - this._lastCheck = Date.now(); + this.#lastCheck = Date.now(); let anyUpdated = false; - for (const ch of this._channels.values()) { + for (const ch of this.#channels.values()) { if (!ch.enabled) { log.debug(`Not updating ${ch.name} because not enabled`); continue; @@ -473,22 +483,22 @@ class _OnionAliasStore { } } if (anyUpdated) { - this._saveSettings(); - this._applyMappings(); - this._notifyChanges(); + this.#saveSettings(); + this.#applyMappings(); + this.#notifyChanges(); } else { log.debug("No channel has been updated, avoid saving"); } - this._scheduleCheck(_OnionAliasStore.RULESET_CHECK_INTERVAL); + this.#scheduleCheck(_OnionAliasStore.RULESET_CHECK_INTERVAL); } - async _startUpdates() { - // This is a "private" function, so we expect the callers to verify wheter + async #startUpdates() { + // This is a private function, so we expect the callers to verify whether // onion aliases are enabled. // Callees will also do, so we avoid an additional check here. - const dt = Date.now() - this._lastCheck; + const dt = Date.now() - this.#lastCheck; let force = false; - for (const ch of this._channels.values()) { + for (const ch of this.#channels.values()) { if (ch.enabled && !ch.currentTimestamp) { // Edited while being offline or some other error happened force = true; @@ -499,34 +509,34 @@ class _OnionAliasStore { log.debug( `Mappings are stale (${dt}), or force check requested (${force}), checking them immediately` ); - await this._periodicRulesetCheck(); + await this.#periodicRulesetCheck(); } else { - this._scheduleCheck(_OnionAliasStore.RULESET_CHECK_INTERVAL - dt); + this.#scheduleCheck(_OnionAliasStore.RULESET_CHECK_INTERVAL - dt); } } - _scheduleCheck(dt) { - if (this._rulesetTimeout) { + #scheduleCheck(dt) { + if (this.#rulesetTimeout) { log.warn("The previous update timeout was not null"); - clearTimeout(this._rulesetTimeout); + clearTimeout(this.#rulesetTimeout); } if (!this.enabled) { log.warn( "Ignoring the scheduling of a new check because the Onion Alias feature is currently disabled." ); - this._rulesetTimeout = null; + this.#rulesetTimeout = null; return; } log.debug(`Scheduling ruleset update in ${dt}`); - this._rulesetTimeout = setTimeout(() => { - this._rulesetTimeout = null; - this._periodicRulesetCheck(); + this.#rulesetTimeout = setTimeout(() => { + this.#rulesetTimeout = null; + this.#periodicRulesetCheck(); }, dt); } - _notifyChanges() { + #notifyChanges() { Services.obs.notifyObservers( - Array.from(this._channels.values(), ch => ch.toJSON()), + Array.from(this.#channels.values(), ch => ch.toJSON()), OnionAliasStoreTopics.ChannelsChanged ); } @@ -538,11 +548,16 @@ class _OnionAliasStore { observe(aSubject, aTopic) { if (aTopic === "nsPref:changed") { if (this.enabled) { - this._startUpdates(); - } else if (this._rulesetTimeout) { - clearTimeout(this._rulesetTimeout); - this._rulesetTimeout = null; + this.#startUpdates(); + } else if (this.#rulesetTimeout) { + clearTimeout(this.#rulesetTimeout); + this.#rulesetTimeout = null; } + } else if ( + aTopic === lazy.TorConnectTopics.BootstrapComplete && + this.enabled + ) { + this.#startUpdates(); } } } ===================================== browser/components/onionservices/moz.build ===================================== @@ -1,8 +1,11 @@ JAR_MANIFESTS += ["jar.mn"] EXTRA_JS_MODULES += [ - "OnionAliasStore.sys.mjs", "OnionLocationChild.sys.mjs", "OnionLocationParent.sys.mjs", +] + +MOZ_SRC_FILES += [ + "OnionAliasStore.sys.mjs", "TorRequestWatch.sys.mjs", ] ===================================== browser/components/rulesets/RulesetsParent.sys.mjs ===================================== @@ -1,9 +1,11 @@ -// Copyright (c) 2022, The Tor Project, Inc. +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ import { OnionAliasStore, OnionAliasStoreTopics, -} from "resource:///modules/OnionAliasStore.sys.mjs"; +} from "moz-src:///browser/components/onionservices/OnionAliasStore.sys.mjs"; const kShowWarningPref = "torbrowser.rulesets.show_warning"; @@ -56,9 +58,10 @@ export class RulesetsParent extends JSWindowActorParent { return { showWarning: Services.prefs.getBoolPref(kShowWarningPref, true), }; - case "rulesets:set-channel": + case "rulesets:set-channel": { const ch = await OnionAliasStore.setChannel(message.data); return ch; + } case "rulesets:update-channel": // We need to catch any error in this way, because in case of an // exception, RPMSendQuery does not return on the other side ===================================== browser/modules/ClipboardPrivacy.sys.mjs ===================================== @@ -0,0 +1,178 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +const lazy = {}; + +ChromeUtils.defineESModuleGetters(lazy, { + AsyncShutdown: "resource://gre/modules/AsyncShutdown.sys.mjs", + PrivateBrowsingUtils: "resource://gre/modules/PrivateBrowsingUtils.sys.mjs", + setTimeout: "resource://gre/modules/Timer.sys.mjs", +}); + +/** + * Empty clipboard content from private windows on exit. + * + * See tor-browser#42154. + */ +export const ClipboardPrivacy = { + _lastClipboardHash: null, + _globalActivation: false, + _isPrivateClipboard: false, + _hasher: null, + _shuttingDown: false, + _log: null, + + _createTransferable() { + const trans = Cc["@mozilla.org/widget/transferable;1"].createInstance( + Ci.nsITransferable + ); + trans.init(null); + return trans; + }, + _computeClipboardHash() { + const flavors = ["text/x-moz-url", "text/plain"]; + if ( + !Services.clipboard.hasDataMatchingFlavors( + flavors, + Ci.nsIClipboard.kGlobalClipboard + ) + ) { + return null; + } + const trans = this._createTransferable(); + flavors.forEach(trans.addDataFlavor); + try { + Services.clipboard.getData(trans, Ci.nsIClipboard.kGlobalClipboard); + const clipboardContent = {}; + trans.getAnyTransferData({}, clipboardContent); + const { data } = clipboardContent.value.QueryInterface( + Ci.nsISupportsString + ); + const bytes = new TextEncoder().encode(data); + const hasher = (this._hasher ||= Cc[ + "@mozilla.org/security/hash;1" + ].createInstance(Ci.nsICryptoHash)); + hasher.init(hasher.SHA256); + hasher.update(bytes, bytes.length); + return hasher.finish(true); + } catch (e) {} + return null; + }, + + init() { + this._log = console.createInstance({ + prefix: "ClipboardPrivacy", + }); + this._lastClipboardHash = this._computeClipboardHash(); + + // Here we track changes in active window / application, + // by filtering focus events and window closures. + const handleActivation = (win, activation) => { + if (activation) { + if (!this._globalActivation) { + // focus changed within this window, bail out. + return; + } + this._globalActivation = false; + } else if (!Services.focus.activeWindow) { + // focus is leaving this window: + // let's track whether it remains within the browser. + lazy.setTimeout(() => { + this._globalActivation = !Services.focus.activeWindow; + }, 100); + } + + const checkClipboardContent = () => { + const clipboardHash = this._computeClipboardHash(); + if (clipboardHash !== this._lastClipboardHash) { + this._isPrivateClipboard = + !activation && + (lazy.PrivateBrowsingUtils.permanentPrivateBrowsing || + lazy.PrivateBrowsingUtils.isWindowPrivate(win)); + this._lastClipboardHash = clipboardHash; + this._log.debug( + `Clipboard changed: private ${this._isPrivateClipboard}, hash ${clipboardHash}.` + ); + } + }; + + if (win.closed) { + checkClipboardContent(); + } else { + // defer clipboard access on DOM events to work-around tor-browser#42306 + lazy.setTimeout(checkClipboardContent, 0); + } + }; + const focusListener = e => + e.isTrusted && handleActivation(e.currentTarget, e.type === "focusin"); + const initWindow = win => { + for (const e of ["focusin", "focusout"]) { + win.addEventListener(e, focusListener); + } + }; + for (const w of Services.ww.getWindowEnumerator()) { + initWindow(w); + } + Services.ww.registerNotification((win, event) => { + switch (event) { + case "domwindowopened": + initWindow(win); + break; + case "domwindowclosed": + handleActivation(win, false); + if ( + this._isPrivateClipboard && + lazy.PrivateBrowsingUtils.isWindowPrivate(win) && + (this._shuttingDown || + !Array.from(Services.ww.getWindowEnumerator()).find( + w => + lazy.PrivateBrowsingUtils.isWindowPrivate(w) && + // We need to filter out the HIDDEN WebExtensions window, + // which might be private as well but is not UI-relevant. + !w.location.href.startsWith("chrome://extensions/") + )) + ) { + // no more private windows, empty private content if needed + this.emptyPrivate(); + } + } + }); + + lazy.AsyncShutdown.quitApplicationGranted.addBlocker( + "ClipboardPrivacy: removing private data", + () => { + this._shuttingDown = true; + this.emptyPrivate(); + } + ); + }, + emptyPrivate() { + if ( + this._isPrivateClipboard && + !Services.prefs.getBoolPref( + "browser.privatebrowsing.preserveClipboard", + false + ) && + this._lastClipboardHash === this._computeClipboardHash() + ) { + // nsIClipboard.emptyClipboard() does nothing in Wayland: + // we'll set an empty string as a work-around. + const trans = this._createTransferable(); + const flavor = "text/plain"; + trans.addDataFlavor(flavor); + const emptyString = Cc["@mozilla.org/supports-string;1"].createInstance( + Ci.nsISupportsString + ); + emptyString.data = ""; + trans.setTransferData(flavor, emptyString); + const { clipboard } = Services, + { kGlobalClipboard } = clipboard; + clipboard.setData(trans, null, kGlobalClipboard); + clipboard.emptyClipboard(kGlobalClipboard); + this._lastClipboardHash = null; + this._isPrivateClipboard = false; + this._log.info("Private clipboard emptied."); + } + }, +}; ===================================== browser/modules/moz.build ===================================== @@ -136,12 +136,10 @@ EXTRA_JS_MODULES += [ "PopupBlockerObserver.sys.mjs", "ProcessHangMonitor.sys.mjs", "Sanitizer.sys.mjs", - "SecurityLevelRestartNotification.sys.mjs", "SelectionChangedMenulist.sys.mjs", "SharingUtils.sys.mjs", "SiteDataManager.sys.mjs", "SitePermissions.sys.mjs", - "TorSettingsNotification.sys.mjs", "TorUIUtils.sys.mjs", "TransientPrefs.sys.mjs", "URILoadingHelper.sys.mjs", @@ -151,6 +149,9 @@ EXTRA_JS_MODULES += [ MOZ_SRC_FILES += [ "ContextId.sys.mjs", + "ClipboardPrivacy.sys.mjs", + "SecurityLevelRestartNotification.sys.mjs", + "TorSettingsNotification.sys.mjs", ] if CONFIG["MOZ_WIDGET_TOOLKIT"] == "windows": ===================================== dom/base/ContentAreaDropListener.sys.mjs ===================================== @@ -5,7 +5,7 @@ const lazy = {}; ChromeUtils.defineESModuleGetters(lazy, { - OpaqueDrag: "resource://gre/modules/DragDropFilter.sys.mjs", + OpaqueDrag: "moz-src:///toolkit/modules/DragDropFilter.sys.mjs", }); // This component is used for handling dragover and drop of urls. ===================================== toolkit/components/places/PlacesUtils.sys.mjs ===================================== @@ -12,7 +12,7 @@ const lazy = {}; ChromeUtils.defineESModuleGetters(lazy, { Bookmarks: "resource://gre/modules/Bookmarks.sys.mjs", History: "resource://gre/modules/History.sys.mjs", - OpaqueDrag: "resource://gre/modules/DragDropFilter.sys.mjs", + OpaqueDrag: "moz-src:///toolkit/modules/DragDropFilter.sys.mjs", PlacesSyncUtils: "resource://gre/modules/PlacesSyncUtils.sys.mjs", Sqlite: "resource://gre/modules/Sqlite.sys.mjs", }); ===================================== toolkit/components/tor-launcher/tor-launcher.manifest ===================================== @@ -1 +1,2 @@ category profile-after-change TorStartupService @torproject.org/tor-startup-service;1 +category browser-first-window-ready resource://gre/modules/TorProviderBuilder.sys.mjs TorProviderBuilder.firstWindowLoaded ===================================== toolkit/modules/moz.build ===================================== @@ -164,7 +164,6 @@ EXTRA_JS_MODULES += [ "DateTimePickerPanel.sys.mjs", "DeferredTask.sys.mjs", "DomainFrontedRequests.sys.mjs", - "DragDropFilter.sys.mjs", "E10SUtils.sys.mjs", "EventEmitter.sys.mjs", "FileUtils.sys.mjs", @@ -220,6 +219,10 @@ EXTRA_JS_MODULES += [ "WebChannel.sys.mjs", ] +MOZ_SRC_FILES += [ + "DragDropFilter.sys.mjs", +] + if CONFIG["MOZ_ASAN_REPORTER"]: EXTRA_JS_MODULES += [ "AsanReporter.sys.mjs", View it on GitLab: https://gitlab.torproject.org/tpo/applications/tor-browser/-/compare/d28d9f4... -- View it on GitLab: https://gitlab.torproject.org/tpo/applications/tor-browser/-/compare/d28d9f4... You're receiving this email because of your account on gitlab.torproject.org.
participants (1)
-
Pier Angelo Vendrame (@pierov)