From 44f7616238208200547c7df500d945752d7b6379 Mon Sep 17 00:00:00 2001 From: "mr. m" <91018726+mr-cheffy@users.noreply.github.com> Date: Tue, 30 Jun 2026 13:01:01 +0200 Subject: [PATCH] Merge commit from fork --- src/zen/glance/ZenGlanceManager.mjs | 32 ++++++++++++++++++++++++-- src/zen/split-view/ZenViewSplitter.mjs | 21 ++++++++++++++++- 2 files changed, 50 insertions(+), 3 deletions(-) diff --git a/src/zen/glance/ZenGlanceManager.mjs b/src/zen/glance/ZenGlanceManager.mjs index 9bb4d6e20..c5f503059 100644 --- a/src/zen/glance/ZenGlanceManager.mjs +++ b/src/zen/glance/ZenGlanceManager.mjs @@ -85,8 +85,7 @@ class nsZenGlanceManager extends nsZenDOMOperatedFeature { menuitem.addEventListener("command", () => this.openGlance({ url: gContextMenu.linkURL, - triggeringPrincipal: - Services.scriptSecurityManager.getSystemPrincipal(), + triggeringPrincipal: gContextMenu.principal, }) ); @@ -354,6 +353,28 @@ class nsZenGlanceManager extends nsZenDOMOperatedFeature { return this.#lastLinkClickData; } + /** + * Check whether a glance load is permitted for its triggering principal. + * + * @param {object} data - Glance data including URL and triggeringPrincipal + * @returns {boolean} Whether the load is allowed + */ + #isGlanceLoadAllowed(data) { + const { url, triggeringPrincipal } = data ?? {}; + if (typeof url !== "string" || !url.length || !triggeringPrincipal) { + return false; + } + try { + Services.scriptSecurityManager.checkLoadURIStrWithPrincipal( + triggeringPrincipal, + url + ); + } catch { + return false; + } + return true; + } + /** * Open a glance overlay with the specified data * @@ -371,6 +392,13 @@ class nsZenGlanceManager extends nsZenDOMOperatedFeature { return Promise.resolve(this.#currentTab); } + // Existing-tab glances perform no navigation and are exempt; for fresh + // loads, refuse any URL the triggering principal isn't allowed to load + // (e.g. a web page linking to file://). + if (!existingTab && !this.#isGlanceLoadAllowed(data)) { + return Promise.resolve(null); + } + if (!data.height || !data.width) { data = { ...data, diff --git a/src/zen/split-view/ZenViewSplitter.mjs b/src/zen/split-view/ZenViewSplitter.mjs index 094ddca99..bf8c489a9 100644 --- a/src/zen/split-view/ZenViewSplitter.mjs +++ b/src/zen/split-view/ZenViewSplitter.mjs @@ -1229,7 +1229,11 @@ class nsZenViewSplitter extends nsZenDOMOperatedFeature { const newTab = this.openAndSwitchToTab(url, { skipRoute: true, inBackground: false, + triggeringPrincipal: window.gContextMenu.principal, }); + if (!newTab) { + return; + } this.splitTabs([currentTab, newTab], undefined, 1); } @@ -1979,9 +1983,24 @@ class nsZenViewSplitter extends nsZenDOMOperatedFeature { * @returns {tab} The tab that was opened */ openAndSwitchToTab(url, options) { + const triggeringPrincipal = options?.triggeringPrincipal; + if (!triggeringPrincipal) { + return null; + } + try { + Services.scriptSecurityManager.checkLoadURIStrWithPrincipal( + triggeringPrincipal, + url + ); + } catch { + return null; + } const parentWindow = window.parent; const targetWindow = parentWindow || window; - const tab = targetWindow.gBrowser.addTrustedTab(url, options); + const tab = targetWindow.gBrowser.addTab(url, { + ...options, + triggeringPrincipal, + }); targetWindow.gBrowser.selectedTab = tab; return tab; }