tor-browser

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

commit 0c8136611b84cecbb6f470d14709788c4abbcb8f
parent 206592bdcb3d02b5369ab17eb3ca46419d28a23f
Author: Sandor Molnar <smolnar@mozilla.com>
Date:   Sat,  1 Nov 2025 02:30:02 +0200

Revert "Bug 1970743 - move strings for browser-utils to the right file, r=fluent-reviewers,bolsson" for causing bc failures @ browser_unknownContentType_blob.js

This reverts commit 53772e4cc4022d2cbeb4ba5427c8117010227805.

Revert "Bug 1970743 - consolidate DownloadUtils.getURIHost into BrowserUtils.formatURIForDisplay, r=mak"

This reverts commit 72fc2f83fe2979b1a7b0f1552555d77b63bbf891.

Diffstat:
Mbrowser/base/content/browser-fullScreenAndPointerLock.js | 7++++---
Mbrowser/components/downloads/DownloadsViewUI.sys.mjs | 9+--------
Mbrowser/components/firefoxview/fxview-tab-list.mjs | 4+---
Mbrowser/components/firefoxview/helpers.mjs | 4+---
Dpython/l10n/fluent_migrations/bug_1970743_browser_utils.py | 26--------------------------
Mtoolkit/locales/en-US/toolkit/downloads/downloadUtils.ftl | 7+++++++
Mtoolkit/locales/en-US/toolkit/global/browser-utils.ftl | 8--------
Mtoolkit/modules/BrowserUtils.sys.mjs | 56++++----------------------------------------------------
Mtoolkit/modules/tests/xpcshell/test_BrowserUtils_urlFormatting.js | 64+++-------------------------------------------------------------
Mtoolkit/mozapps/downloads/DownloadUtils.sys.mjs | 86+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Mtoolkit/mozapps/downloads/tests/unit/test_DownloadUtils.js | 31+++++++++++++++++++++++++++++++
11 files changed, 138 insertions(+), 164 deletions(-)

diff --git a/browser/base/content/browser-fullScreenAndPointerLock.js b/browser/base/content/browser-fullScreenAndPointerLock.js @@ -100,9 +100,10 @@ var PointerlockFsWarning = { } else { textElem.removeAttribute("hidden"); // Document's principal's URI has a host. Display a warning including it. - let displayHost = BrowserUtils.formatURIForDisplay(uri, { - onlyBaseDomain: true, - }); + let { DownloadUtils } = ChromeUtils.importESModule( + "resource://gre/modules/DownloadUtils.sys.mjs" + ); + let displayHost = DownloadUtils.getURIHost(uri.spec)[0]; let l10nString = { "fullscreen-warning": "fullscreen-warning-domain", "pointerlock-warning": "pointerlock-warning-domain", diff --git a/browser/components/downloads/DownloadsViewUI.sys.mjs b/browser/components/downloads/DownloadsViewUI.sys.mjs @@ -12,7 +12,6 @@ import { XPCOMUtils } from "resource://gre/modules/XPCOMUtils.sys.mjs"; const lazy = {}; ChromeUtils.defineESModuleGetters(lazy, { - BrowserUtils: "resource://gre/modules/BrowserUtils.sys.mjs", BrowserWindowTracker: "resource:///modules/BrowserWindowTracker.sys.mjs", DownloadUtils: "resource://gre/modules/DownloadUtils.sys.mjs", Downloads: "resource://gre/modules/Downloads.sys.mjs", @@ -604,13 +603,7 @@ DownloadsViewUI.DownloadElementShell.prototype = { this.showStatus(stateLabel, hoverStatus); return; } - let uri = URL.parse(this.download.source.url)?.URI; - let displayHost = uri - ? lazy.BrowserUtils.formatURIForDisplay(uri, { - onlyBaseDomain: true, - }) - : ""; - + let [displayHost] = lazy.DownloadUtils.getURIHost(this.download.source.url); let [displayDate] = lazy.DownloadUtils.getReadableDates( new Date(this.download.endTime) ); diff --git a/browser/components/firefoxview/fxview-tab-list.mjs b/browser/components/firefoxview/fxview-tab-list.mjs @@ -517,9 +517,7 @@ export class FxviewTabRowBase extends MozLitElement { formatURIForDisplay(uriString) { return !window.IS_STORYBOOK - ? lazy.BrowserUtils.formatURIStringForDisplay(uriString, { - showFilenameForLocalURIs: true, - }) + ? lazy.BrowserUtils.formatURIStringForDisplay(uriString) : uriString; } diff --git a/browser/components/firefoxview/helpers.mjs b/browser/components/firefoxview/helpers.mjs @@ -24,9 +24,7 @@ export const LOGGING_PREF = "browser.tabs.firefox-view.logLevel"; export const MAX_TABS_FOR_RECENT_BROWSING = 5; export function formatURIForDisplay(uriString) { - return lazy.BrowserUtils.formatURIStringForDisplay(uriString, { - showFilenameForLocalURIs: true, - }); + return lazy.BrowserUtils.formatURIStringForDisplay(uriString); } export function convertTimestamp( diff --git a/python/l10n/fluent_migrations/bug_1970743_browser_utils.py b/python/l10n/fluent_migrations/bug_1970743_browser_utils.py @@ -1,26 +0,0 @@ -# Any copyright is dedicated to the Public Domain. -# http://creativecommons.org/publicdomain/zero/1.0/ - -import fluent.syntax.ast as FTL -from fluent.migrate import COPY_PATTERN -from fluent.migrate.helpers import transforms_from -from fluent.migrate.transforms import COPY - - -def migrate(ctx): - """Bug 1970743 - move some download strings to browser-utils.ftl, part {index}.""" - source = "toolkit/toolkit/downloads/downloadUtils.ftl" - target = "toolkit/toolkit/global/browser-utils.ftl" - - ctx.add_transforms( - target, - target, - transforms_from( - """ -browser-utils-file-scheme = {COPY_PATTERN(from_path, "download-utils-done-file-scheme")} - -browser-utils-url-scheme = {COPY_PATTERN(from_path, "download-utils-done-scheme")} -""", - from_path=source, - ), - ) diff --git a/toolkit/locales/en-US/toolkit/downloads/downloadUtils.ftl b/toolkit/locales/en-US/toolkit/downloads/downloadUtils.ftl @@ -95,5 +95,12 @@ download-utils-time-left-double = { $time1 } { $time2 } left download-utils-time-few-seconds = A few seconds left download-utils-time-unknown = Unknown time left +# Variables: +# $scheme (string) - URI scheme like data: jar: about: +download-utils-done-scheme = { $scheme } resource +# Special case of done-scheme for file: +# This is used as an eTLD replacement for local files, so make it lower case +download-utils-done-file-scheme = local file + # Displayed time for files finished yesterday download-utils-yesterday = Yesterday diff --git a/toolkit/locales/en-US/toolkit/global/browser-utils.ftl b/toolkit/locales/en-US/toolkit/global/browser-utils.ftl @@ -5,14 +5,6 @@ # Used for data: URLs where we don't have any useful origin information browser-utils-url-data = (data) -# Variables: -# $scheme (string) - URI scheme like jar: about: -browser-utils-url-scheme = { $scheme } resource -# Special case of done-scheme for file: -# This is used as an eTLD replacement for local files, so make it lower case -browser-utils-file-scheme = local file - - # Used for extension URLs # Variables: # $extension (string) - Name of the extension that generated the URL diff --git a/toolkit/modules/BrowserUtils.sys.mjs b/toolkit/modules/BrowserUtils.sys.mjs @@ -246,36 +246,8 @@ export var BrowserUtils = { } }, - /** - * Show a URI in the UI in a user-friendly (but security-sensitive) way. - * - * @param {nsIURI} uri - * @param {object} [options={}] - * @param {boolean} [options.showInsecureHTTP=false] - * Whether to show "http://" for insecure HTTP URLs. - * @param {boolean} [options.showWWW=false] - * Whether to show "www." for URLs that have it. - * @param {boolean} [options.onlyBaseDomain=false] - * Whether to show only the base domain (eTLD+1) for HTTP(S) URLs. - * @param {boolean} [options.showFilenameForLocalURIs=false] - * If false (default), will show a protocol-specific label for local - * URIs (file:, chrome:, resource:, moz-src:, jar:). - * Otherwise, will show the filename for such URIs. Only use 'true' if - * the context in which the URI is being represented is not security- - * critical. - */ formatURIForDisplay(uri, options = {}) { - let { - showInsecureHTTP = false, - showWWW = false, - onlyBaseDomain = false, - showFilenameForLocalURIs = false, - } = options; - // For moz-icon and jar etc. which wrap nsIURLs, if we want to show the - // actual filename, unwrap: - if (uri && uri instanceof Ci.nsINestedURI && showFilenameForLocalURIs) { - return this.formatURIForDisplay(uri.innermostURI, options); - } + let { showInsecureHTTP = false } = options; switch (uri.scheme) { case "view-source": { let innerURI = uri.spec.substring("view-source:".length); @@ -285,14 +257,8 @@ export var BrowserUtils = { // Fall through. case "https": { let host = uri.displayHostPort; - let removeSubdomains = - !showInsecureHTTP && - (onlyBaseDomain || (!showWWW && host.startsWith("www."))); - if (removeSubdomains) { + if (!showInsecureHTTP && host.startsWith("www.")) { host = Services.eTLD.getSchemelessSite(uri); - if (uri.port != -1) { - host += ":" + uri.port; - } } if (showInsecureHTTP && uri.scheme == "http") { return "http://" + host; @@ -303,7 +269,7 @@ export var BrowserUtils = { return "about:" + uri.filePath; case "blob": try { - let url = URL.fromURI(uri); + let url = new URL(uri.specIgnoringRef); // _If_ we find a non-null origin, report that. if (url.origin && url.origin != "null") { return this.formatURIStringForDisplay(url.origin, options); @@ -325,22 +291,8 @@ export var BrowserUtils = { } case "chrome": case "resource": - case "moz-icon": - case "moz-src": case "jar": case "file": - if (!showFilenameForLocalURIs) { - if (uri.scheme == "file") { - return lazy.gLocalization.formatValueSync( - "browser-utils-file-scheme" - ); - } - return lazy.gLocalization.formatValueSync( - "browser-utils-url-scheme", - { scheme: uri.scheme } - ); - } - // Otherwise, fall through to show filename... default: try { let url = uri.QueryInterface(Ci.nsIURL); @@ -366,7 +318,7 @@ export var BrowserUtils = { console.error(ex); } } - return uri.spec; + return uri.asciiHost || uri.spec; }, // Given a URL returns a (possibly transformed) URL suitable for sharing, or null if diff --git a/toolkit/modules/tests/xpcshell/test_BrowserUtils_urlFormatting.js b/toolkit/modules/tests/xpcshell/test_BrowserUtils_urlFormatting.js @@ -19,10 +19,6 @@ const EXTENSION_URL_EXPECTED_STRING = gL10n.formatValueSync( { extension: EXTENSION_NAME } ); -const FILE_URL_EXPECTED_STRING = gL10n.formatValueSync( - "browser-utils-file-scheme" -); - const { AddonTestUtils } = ChromeUtils.importESModule( "resource://testing-common/AddonTestUtils.sys.mjs" ); @@ -92,7 +88,7 @@ const HTTP_TESTS = [ output: "www.co.uk", }, - // Other subdomains should be kept: + // Other sudomains should be kept: { input: "https://webmail.example.co.uk", output: "webmail.example.co.uk", @@ -162,15 +158,6 @@ const TESTS = [ input: "data:text/html,42", output: DATA_URL_EXPECTED_STRING, }, - - { - input: `moz-icon:${Services.io.newFileURI(tempFile).spec}`, - output: tempFile.leafName, - }, - { - input: "moz-icon://.extension?size=16", - output: "moz-icon://.extension?size=16", - }, ]; add_setup(async () => { @@ -233,9 +220,7 @@ const { BrowserUtils } = ChromeUtils.importESModule( add_task(async function test_checkStringFormatting() { for (let { input, output } of TESTS) { Assert.equal( - BrowserUtils.formatURIStringForDisplay(input, { - showFilenameForLocalURIs: true, - }), + BrowserUtils.formatURIStringForDisplay(input), output, `String ${input} formatted for output should match` ); @@ -246,56 +231,13 @@ add_task(async function test_checkURIFormatting() { for (let { input, output } of TESTS) { let uri = Services.io.newURI(input); Assert.equal( - BrowserUtils.formatURIForDisplay(uri, { - showFilenameForLocalURIs: true, - }), - output, - `URI ${input} formatted for output should match` - ); - } -}); - -add_task(async function test_checkOnlyBaseDomain() { - for (let { input, output } of [ - { input: "https://subdomain.example.com/", output: "example.com" }, - { - input: "http://www.city.mikasa.hokkaido.jp/", - output: "city.mikasa.hokkaido.jp", - }, - { input: "https://www.example.co.uk/", output: "example.co.uk" }, - { - input: "mailto:example@subdomain.example.com", - output: "mailto:example@subdomain.example.com", - }, - ]) { - let uri = Services.io.newURI(input); - Assert.equal( - BrowserUtils.formatURIForDisplay(uri, { onlyBaseDomain: true }), + BrowserUtils.formatURIForDisplay(uri), output, `URI ${input} formatted for output should match` ); } }); -add_task(async function test_checkLocalFileFormatting() { - for (let { input } of TESTS) { - let uri = Services.io.newURI(input); - if ( - ["file", "chrome", "moz-icon", "resource", "jar"].includes(uri.scheme) - ) { - Assert.equal( - BrowserUtils.formatURIForDisplay(uri, { - showFilenameForLocalURIs: false, - }), - uri.scheme == "file" - ? FILE_URL_EXPECTED_STRING - : `${uri.scheme} resource`, - `URI ${input} formatted for output should match` - ); - } - } -}); - add_task(async function test_checkViewSourceFormatting() { for (let { input, output } of HTTP_TESTS) { Assert.equal( diff --git a/toolkit/mozapps/downloads/DownloadUtils.sys.mjs b/toolkit/mozapps/downloads/DownloadUtils.sys.mjs @@ -3,6 +3,8 @@ * 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 { XPCOMUtils } from "resource://gre/modules/XPCOMUtils.sys.mjs"; + /** * This module provides the DownloadUtils object which contains useful methods * for downloads such as displaying file sizes, transfer times, and download @@ -53,6 +55,14 @@ const TIME_UNITS = [ // with TIME_UNITS without the last item const TIME_SIZES = [60, 60, 24]; +const lazy = {}; +XPCOMUtils.defineLazyServiceGetter( + lazy, + "IDNService", + "@mozilla.org/network/idn-service;1", + Ci.nsIIDNService +); + var localeNumberFormatCache = new Map(); function getLocaleNumberFormat(fractionDigits) { if (!localeNumberFormatCache.has(fractionDigits)) { @@ -377,6 +387,82 @@ export var DownloadUtils = { }, /** + * Get the appropriate display host string for a URI string depending on if + * the URI has an eTLD + 1, is an IP address, a local file, or other protocol + * + * @param aURIString + * The URI string to try getting an eTLD + 1, etc. + * @return A pair: [display host for the URI string, full host name] + */ + getURIHost: function DU_getURIHost(aURIString) { + // Get a URI that knows about its components + let uri = URL.parse(aURIString)?.URI; + if (!uri) { + return ["", ""]; + } + + // Get the inner-most uri for schemes like jar: + if (uri instanceof Ci.nsINestedURI) { + uri = uri.innermostURI; + } + + if (uri.schemeIs("blob")) { + let origin = URL.fromURI(uri).origin; + // Origin can be "null" for blob URIs from a sandbox. + if (origin != "null") { + // `newURI` can throw (like for null) and throwing here breaks... + // a lot of stuff. So let's avoid doing that in case there are other + // edgecases we're missing here. + try { + uri = Services.io.newURI(origin); + } catch (ex) { + console.error(ex); + } + } + } + + let fullHost; + try { + // Get the full host name; some special URIs fail (data: jar:) + fullHost = uri.host; + } catch (e) { + fullHost = ""; + } + + let displayHost; + try { + // This might fail if it's an IP address or doesn't have more than 1 part + let baseDomain = Services.eTLD.getBaseDomain(uri); + + // Convert base domain for display + displayHost = lazy.IDNService.convertToDisplayIDN(baseDomain); + } catch (e) { + // Default to the host name + displayHost = fullHost; + } + + // Check if we need to show something else for the host + if (uri.schemeIs("file")) { + // Display special text for file protocol + displayHost = l10n.formatValueSync("download-utils-done-file-scheme"); + fullHost = displayHost; + } else if (!displayHost.length) { + // Got nothing; show the scheme (data: about: moz-icon:) + displayHost = l10n.formatValueSync("download-utils-done-scheme", { + scheme: uri.scheme, + }); + fullHost = displayHost; + } else if (uri.port != -1) { + // Tack on the port if it's not the default port + let port = ":" + uri.port; + displayHost += port; + fullHost += port; + } + + return [displayHost, fullHost]; + }, + + /** * Converts a number of bytes to the appropriate unit that results in an * internationalized number that needs fewer than 4 digits. * diff --git a/toolkit/mozapps/downloads/tests/unit/test_DownloadUtils.js b/toolkit/mozapps/downloads/tests/unit/test_DownloadUtils.js @@ -83,6 +83,16 @@ function testFormattedTimeStatus(aSec, aExpected) { Assert.equal(status.l10n.id, aExpected); } +function testURI(aURI, aDisp, aHost) { + dump("URI Test: " + [aURI, aDisp, aHost] + "\n"); + + let [disp, host] = DownloadUtils.getURIHost(aURI); + + // Make sure we have the right display host and full host + Assert.equal(disp, aDisp); + Assert.equal(host, aHost); +} + function testGetReadableDates(aDate, aCompactValue) { const now = new Date(2000, 11, 31, 11, 59, 59); @@ -363,5 +373,26 @@ function run_test() { testFormattedTimeStatus(0, "downloading-file-opens-in-seconds-2"); testFormattedTimeStatus(30, "downloading-file-opens-in-seconds-2"); + testURI("http://www.mozilla.org/", "mozilla.org", "www.mozilla.org"); + testURI( + "http://www.city.mikasa.hokkaido.jp/", + "city.mikasa.hokkaido.jp", + "www.city.mikasa.hokkaido.jp" + ); + testURI("data:text/html,Hello World", "data resource", "data resource"); + testURI( + "jar:http://www.mozilla.com/file!/magic", + "mozilla.com", + "www.mozilla.com" + ); + testURI("file:///C:/Cool/Stuff/", "local file", "local file"); + // Don't test for moz-icon if we don't have a protocol handler for it (e.g. b2g): + if ("@mozilla.org/network/protocol;1?name=moz-icon" in Cc) { + testURI("moz-icon:file:///test.extension", "local file", "local file"); + testURI("moz-icon://.extension", "moz-icon resource", "moz-icon resource"); + } + testURI("about:config", "about resource", "about resource"); + testURI("invalid.uri", "", ""); + testAllGetReadableDates(); }