brizental pushed to branch tor-browser-140.2.0esr-15.0-1 at The Tor Project / Applications / Tor Browser
Commits:
-
40fe2123
by Beatriz Rizental at 2025-08-21T14:45:59+02:00
-
ca116af7
by Beatriz Rizental at 2025-08-21T14:45:59+02:00
-
61f37354
by Beatriz Rizental at 2025-08-21T14:46:00+02:00
-
db2882b1
by Beatriz Rizental at 2025-08-21T14:46:00+02:00
-
2e686601
by Beatriz Rizental at 2025-08-21T14:46:00+02:00
-
3e500e35
by Beatriz Rizental at 2025-08-21T14:46:01+02:00
-
1b623002
by Beatriz Rizental at 2025-08-21T14:46:01+02:00
9 changed files:
- browser/base/content/pageinfo/security.js
- browser/components/abouttor/content/aboutTor.js
- browser/components/newidentity/content/newidentity.js
- browser/components/onionservices/OnionAliasStore.sys.mjs
- browser/components/onionservices/OnionLocationChild.sys.mjs
- browser/components/onionservices/TorRequestWatch.sys.mjs
- browser/components/rulesets/content/aboutRulesets.js
- toolkit/components/torconnect/TorConnectChild.sys.mjs
- toolkit/modules/DragDropFilter.sys.mjs
Changes:
... | ... | @@ -57,15 +57,15 @@ var security = { |
57 | 57 | (Ci.nsIWebProgressListener.STATE_LOADED_MIXED_ACTIVE_CONTENT |
|
58 | 58 | Ci.nsIWebProgressListener.STATE_LOADED_MIXED_DISPLAY_CONTENT);
|
59 | 59 | var isEV = ui.state & Ci.nsIWebProgressListener.STATE_IDENTITY_EV_TOPLEVEL;
|
60 | - let uriInformation = new URL(gDocInfo.documentURIObject.spec);
|
|
60 | + let uriInformation = URL.parse(gDocInfo.documentURIObject.spec);
|
|
61 | 61 | // If the Onion site could not be loaded, the view-source will be also be
|
62 | 62 | // about:neterror.
|
63 | - if (uriInformation.protocol == "view-source:") {
|
|
64 | - uriInformation = new URL(uriInformation.pathname);
|
|
63 | + if (uriInformation?.protocol == "view-source:") {
|
|
64 | + uriInformation = URL.parse(uriInformation.pathname);
|
|
65 | 65 | }
|
66 | 66 | const isOnion =
|
67 | - ["http:", "https:"].includes(uriInformation.protocol) &&
|
|
68 | - uriInformation.hostname.endsWith(".onion");
|
|
67 | + ["http:", "https:"].includes(uriInformation?.protocol) &&
|
|
68 | + uriInformation?.hostname.endsWith(".onion");
|
|
69 | 69 | |
70 | 70 | let retval = {
|
71 | 71 | cAName: "",
|
... | ... | @@ -298,10 +298,11 @@ const SurveyArea = { |
298 | 298 | */
|
299 | 299 | init() {
|
300 | 300 | document.getElementById("survey-launch").addEventListener("click", () => {
|
301 | - if (!this._localeData) {
|
|
301 | + const url = URL.parse(this._urlBase);
|
|
302 | + if (!url || !this._localeData) {
|
|
302 | 303 | return;
|
303 | 304 | }
|
304 | - const url = new URL(this._urlBase);
|
|
305 | + |
|
305 | 306 | url.searchParams.append("lang", this._localeData.urlCode);
|
306 | 307 | open(url.href);
|
307 | 308 | });
|
... | ... | @@ -418,22 +418,21 @@ ChromeUtils.defineLazyGetter(this, "NewIdentityButton", () => { |
418 | 418 | tbl.onLocationChange = (...args) => {
|
419 | 419 | tbl.onLocationChange = onLocationChange;
|
420 | 420 | tbl.onLocationChange(...args);
|
421 | - let displayAddress;
|
|
422 | - try {
|
|
423 | - const url = new URL(homeURL);
|
|
424 | - displayAddress = url.hostname;
|
|
425 | - if (!displayAddress) {
|
|
426 | - // no host, use full address and truncate if too long
|
|
427 | - const MAX_LEN = 32;
|
|
428 | - displayAddress = url.href;
|
|
429 | - if (displayAddress.length > MAX_LEN) {
|
|
430 | - displayAddress = `${displayAddress.substring(0, MAX_LEN)}…`;
|
|
431 | - }
|
|
432 | - }
|
|
433 | - } catch (e) {
|
|
421 | + const url = URL.parse(homeURL);
|
|
422 | + if (!url) {
|
|
434 | 423 | // malformed URL, bail out
|
435 | 424 | return;
|
436 | 425 | }
|
426 | + |
|
427 | + let displayAddress = url.hostname;
|
|
428 | + if (!displayAddress) {
|
|
429 | + // no host, use full address and truncate if too long
|
|
430 | + const MAX_LEN = 32;
|
|
431 | + displayAddress = url.href;
|
|
432 | + if (displayAddress.length > MAX_LEN) {
|
|
433 | + displayAddress = `${displayAddress.substring(0, MAX_LEN)}…`;
|
|
434 | + }
|
|
435 | + }
|
|
437 | 436 | const callback = () => {
|
438 | 437 | Services.prefs.setStringPref(trustedHomePref, homeURL);
|
439 | 438 | win.BrowserHome();
|
... | ... | @@ -175,17 +175,15 @@ class Channel { |
175 | 175 | );
|
176 | 176 | return;
|
177 | 177 | }
|
178 | - let toHostname;
|
|
179 | - try {
|
|
180 | - const toUrl = new URL(rule.rule[0].to);
|
|
181 | - toHostname = toUrl.hostname;
|
|
182 | - } catch (err) {
|
|
178 | + const toHostname = URL.parse(rule.rule[0].to)?.hostname;
|
|
179 | + if (!toHostname) {
|
|
183 | 180 | log.error(
|
184 | - "Cannot detect the hostname from the to rule",
|
|
185 | - rule.rule[0].to,
|
|
186 | - err
|
|
181 | + "Unable to parse the URL and the hostname from the to rule",
|
|
182 | + rule.rule[0].to
|
|
187 | 183 | );
|
184 | + return;
|
|
188 | 185 | }
|
186 | + |
|
189 | 187 | let fromRe;
|
190 | 188 | try {
|
191 | 189 | fromRe = new RegExp(rule.rule[0].from);
|
... | ... | @@ -318,6 +316,7 @@ class _OnionAliasStore { |
318 | 316 | throw Error("Name cannot be empty");
|
319 | 317 | }
|
320 | 318 | |
319 | + // This will throw if the URL is invalid.
|
|
321 | 320 | new URL(chanData.pathPrefix);
|
322 | 321 | const scope = new RegExp(chanData.scope);
|
323 | 322 | const ch = new Channel(
|
... | ... | @@ -25,12 +25,12 @@ export class OnionLocationChild extends JSWindowActorChild { |
25 | 25 | let onionLocationURI = doc.onionLocationURI;
|
26 | 26 | const refreshURI = docShell.QueryInterface(Ci.nsIRefreshURI);
|
27 | 27 | if (onionLocationURI && refreshURI) {
|
28 | - const docUrl = new URL(doc.URL);
|
|
29 | - let onionUrl = new URL(onionLocationURI.asciiSpec);
|
|
28 | + const docUrl = URL.parse(doc.URL);
|
|
29 | + let onionUrl = URL.parse(onionLocationURI.asciiSpec);
|
|
30 | 30 | // Keep consistent with Location
|
31 | - if (!onionUrl.hash && docUrl.hash) {
|
|
31 | + if (!onionUrl?.hash && docUrl?.hash) {
|
|
32 | 32 | onionUrl.hash = docUrl.hash;
|
33 | - onionLocationURI = Services.io.newURI(onionUrl.toString());
|
|
33 | + onionLocationURI = Services.io.newURI(onionUrl?.toString() || "");
|
|
34 | 34 | }
|
35 | 35 | refreshURI.refreshURI(
|
36 | 36 | onionLocationURI,
|
... | ... | @@ -79,7 +79,14 @@ class RequestObserver { |
79 | 79 | }
|
80 | 80 | |
81 | 81 | isCrossOrigin(url1, url2) {
|
82 | - return new URL(url1).origin !== new URL(url2).origin;
|
|
82 | + const origin1 = URL.parse(url1)?.origin;
|
|
83 | + const origin2 = URL.parse(url2)?.origin;
|
|
84 | + |
|
85 | + if (!origin1 || !origin2) {
|
|
86 | + return true;
|
|
87 | + }
|
|
88 | + |
|
89 | + return origin1 !== origin2;
|
|
83 | 90 | }
|
84 | 91 | shouldBlindCrossOrigin(uri) {
|
85 | 92 | try {
|
... | ... | @@ -210,8 +210,8 @@ class EditState { |
210 | 210 | |
211 | 211 | const pathPrefix = elements.pathPrefixInput.value.trim();
|
212 | 212 | try {
|
213 | - const url = new URL(pathPrefix);
|
|
214 | - if (url.protocol !== "http:" && url.protocol !== "https:") {
|
|
213 | + const url = URL.parse(pathPrefix);
|
|
214 | + if (url?.protocol !== "http:" && url?.protocol !== "https:") {
|
|
215 | 215 | elements.pathPrefixInput.setCustomValidity(
|
216 | 216 | await document.l10n.formatValue("rulesets-details-path-input-invalid")
|
217 | 217 | );
|
... | ... | @@ -30,20 +30,21 @@ export class TorConnectChild extends RemotePageChild { |
30 | 30 | this.#redirected = true;
|
31 | 31 | |
32 | 32 | const redirect = new URLSearchParams(
|
33 | - new URL(this.contentWindow.document.location.href).search
|
|
33 | + URL.parse(this.contentWindow.document.location.href)?.search
|
|
34 | 34 | ).get("redirect");
|
35 | 35 | |
36 | 36 | // Fallback in error cases:
|
37 | 37 | let replaceURI = "about:tor";
|
38 | - try {
|
|
39 | - const url = new URL(
|
|
40 | - redirect
|
|
41 | - ? decodeURIComponent(redirect)
|
|
42 | - : // NOTE: We expect no redirect when address is entered manually, or
|
|
43 | - // about:torconnect is opened from preferences or urlbar.
|
|
44 | - // Go to the home page.
|
|
45 | - await this.sendQuery("torconnect:home-page")
|
|
46 | - );
|
|
38 | + const url = URL.parse(
|
|
39 | + redirect
|
|
40 | + ? decodeURIComponent(redirect)
|
|
41 | + : // NOTE: We expect no redirect when address is entered manually, or
|
|
42 | + // about:torconnect is opened from preferences or urlbar.
|
|
43 | + // Go to the home page.
|
|
44 | + await this.sendQuery("torconnect:home-page")
|
|
45 | + );
|
|
46 | + |
|
47 | + if (url) {
|
|
47 | 48 | // Do not allow javascript URI. See tor-browser#41766
|
48 | 49 | if (
|
49 | 50 | ["about:", "file:", "https:", "http:"].includes(url.protocol) ||
|
... | ... | @@ -55,8 +56,8 @@ export class TorConnectChild extends RemotePageChild { |
55 | 56 | } else {
|
56 | 57 | console.error(`Scheme is not allowed "${redirect}"`);
|
57 | 58 | }
|
58 | - } catch (e) {
|
|
59 | - console.error(`Invalid redirect URL "${redirect}"`, e);
|
|
59 | + } else {
|
|
60 | + console.error(`Invalid redirect URL "${redirect}"`);
|
|
60 | 61 | }
|
61 | 62 | |
62 | 63 | // Replace the destination to prevent "about:torconnect" entering the
|
... | ... | @@ -97,11 +97,7 @@ export const DragDropFilter = { |
97 | 97 | const links = aDataTransfer.mozGetDataAt(urlType, i);
|
98 | 98 | // Skip DNS-safe URLs (no hostname, e.g. RFC 3966 tel:)
|
99 | 99 | const mayLeakDNS = links.split("\n").some(link => {
|
100 | - try {
|
|
101 | - return new URL(link).hostname;
|
|
102 | - } catch (e) {
|
|
103 | - return false;
|
|
104 | - }
|
|
100 | + return URL.parse(link)?.hostname ?? false;
|
|
105 | 101 | });
|
106 | 102 | if (!mayLeakDNS) {
|
107 | 103 | continue;
|