tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

commit a581007def8ef5baf0f922046f338116eb69843c
parent cd7681f62c6a2ab2fa4cdf00a561db31f0c2126b
Author: hackademix <giorgio@maone.net>
Date:   Fri, 24 Mar 2023 19:40:19 +0100

BB 41695: Warn on window maximization without letterboxing in RFPHelper module

Diffstat:
Mbrowser/app/profile/001-base-profile.js | 2++
Mtoolkit/components/resistfingerprinting/RFPHelper.sys.mjs | 82+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
2 files changed, 84 insertions(+), 0 deletions(-)

diff --git a/browser/app/profile/001-base-profile.js b/browser/app/profile/001-base-profile.js @@ -529,6 +529,8 @@ pref("privacy.resistFingerprinting.letterboxing.vcenter", true); pref("privacy.resistFingerprinting.letterboxing.gradient", true); // tor-browser#41918: Should we reuse last window sizes if letterboxing is enabled pref("privacy.resistFingerprinting.letterboxing.rememberSize", false); +// tor-browser#41695: How many warnings we show if user closes them without restoring the window size +pref("privacy.resistFingerprinting.resizeWarnings", 3); // tor-browser#43402: Avoid a resize from the skeleton to the newwin size. // Should be fixed in ESR-140 with Bug 1448423. pref("browser.startup.blankWindow", false); diff --git a/toolkit/components/resistfingerprinting/RFPHelper.sys.mjs b/toolkit/components/resistfingerprinting/RFPHelper.sys.mjs @@ -30,6 +30,8 @@ const kTopicFullscreenNavToolbox = "fullscreen-nav-toolbox"; const kPrefVerticalTabs = "sidebar.verticalTabs"; +const kPrefResizeWarnings = "privacy.resistFingerprinting.resizeWarnings"; + const lazy = {}; ChromeUtils.defineESModuleGetters(lazy, { @@ -60,6 +62,84 @@ function forEachWindow(callback) { } } +async function windowResizeHandler(aEvent) { + if (RFPHelper.letterboxingEnabled || !RFPHelper.rfpEnabled) { + return; + } + if (Services.prefs.getIntPref(kPrefResizeWarnings) <= 0) { + return; + } + + const window = aEvent.currentTarget; + + // Wait for end of execution queue to ensure we have correct windowState. + await new Promise(resolve => window.setTimeout(resolve, 0)); + switch (window.windowState) { + case window.STATE_MAXIMIZED: + case window.STATE_FULLSCREEN: + break; + default: + return; + } + + // Do not add another notification if one is already showing. + const kNotificationName = "rfp-window-resize-notification"; + let box = window.gNotificationBox; + if (box.getNotificationWithValue(kNotificationName)) { + return; + } + + // Rate-limit showing our notification if needed. + if (Date.now() - (windowResizeHandler.timestamp || 0) < 1000) { + return; + } + windowResizeHandler.timestamp = Date.now(); + + const decreaseWarningsCount = () => { + const currentCount = Services.prefs.getIntPref(kPrefResizeWarnings); + if (currentCount > 0) { + Services.prefs.setIntPref(kPrefResizeWarnings, currentCount - 1); + } + }; + + const [label, accessKey] = await window.document.l10n.formatValues([ + { id: "basebrowser-rfp-restore-window-size-button-label" }, + { id: "basebrowser-rfp-restore-window-size-button-ak" }, + ]); + + const buttons = [ + { + label, + accessKey, + popup: null, + callback() { + // reset notification timer to work-around resize race conditions + windowResizeHandler.timestamp = Date.now(); + // restore the original (rounded) size we had stored on window startup + let { _rfpOriginalSize } = window; + window.setTimeout(() => { + window.resizeTo(_rfpOriginalSize.width, _rfpOriginalSize.height); + }, 0); + }, + }, + ]; + + box.appendNotification( + kNotificationName, + { + label: { "l10n-id": "basebrowser-rfp-maximize-warning-message" }, + priority: box.PRIORITY_WARNING_LOW, + eventCallback(event) { + if (event === "dismissed") { + // user manually dismissed the notification + decreaseWarningsCount(); + } + }, + }, + buttons + ); +} + class _RFPHelper { _resizeObservers = new WeakMap(); @@ -756,6 +836,7 @@ class _RFPHelper { _attachWindow(aWindow) { this._fixRounding(aWindow); + aWindow.addEventListener("sizemodechange", windowResizeHandler); aWindow.gBrowser.addTabsProgressListener(this); aWindow.addEventListener("TabOpen", this); let resizeObserver = new aWindow.ResizeObserver(entries => { @@ -1084,6 +1165,7 @@ class _RFPHelper { let browser = tab.linkedBrowser; this._resetContentSize(browser); } + aWindow.removeEventListener("sizemodechange", windowResizeHandler); aWindow.removeEventListener("nativethemechange", this); this._updateLetterboxingColors(aWindow, false);