From 3f10f6cfc58ab78b8b83c5179e67f0ab5070c5c1 Mon Sep 17 00:00:00 2001 From: wuggy Date: Mon, 14 Sep 2026 15:25:18 -0700 Subject: [PATCH 1/4] fix ubO pt.3 --- dom/indexedDB/IDBObjectStore.cpp | 4 +- .../test/unit/test_cache_record_roundtrip.js | 49 +++++++++++++++++++ dom/indexedDB/test/unit/xpcshell-shared.ini | 1 + 3 files changed, 53 insertions(+), 1 deletion(-) create mode 100644 dom/indexedDB/test/unit/test_cache_record_roundtrip.js diff --git a/dom/indexedDB/IDBObjectStore.cpp b/dom/indexedDB/IDBObjectStore.cpp index 0aa9d06649..e0e3db0ed0 100644 --- a/dom/indexedDB/IDBObjectStore.cpp +++ b/dom/indexedDB/IDBObjectStore.cpp @@ -68,7 +68,9 @@ struct IDBObjectStore::StructuredCloneWriteInfo uint64_t mOffsetToKeyProp; explicit StructuredCloneWriteInfo(IDBDatabase* aDatabase) - : mCloneBuffer(JS::StructuredCloneScope::DifferentProcessForIndexedDB, nullptr, + // DifferentProcessForIndexedDB is a read-only compatibility mode. New + // records must use the durable, cross-process serialization format. + : mCloneBuffer(JS::StructuredCloneScope::DifferentProcess, nullptr, nullptr) , mDatabase(aDatabase) , mOffsetToKeyProp(0) diff --git a/dom/indexedDB/test/unit/test_cache_record_roundtrip.js b/dom/indexedDB/test/unit/test_cache_record_roundtrip.js new file mode 100644 index 0000000000..7fa7c283d7 --- /dev/null +++ b/dom/indexedDB/test/unit/test_cache_record_roundtrip.js @@ -0,0 +1,49 @@ +/** + * Any copyright is dedicated to the Public Domain. + * http://creativecommons.org/publicdomain/zero/1.0/ + */ + +var testGenerator = testSteps(); + +function* testSteps() { + const name = "cache-record-roundtrip"; + let request = indexedDB.open(name, 1); + request.onerror = errorHandler; + request.onupgradeneeded = event => { + event.target.result.createObjectStore("cache", {keyPath: "key"}); + }; + request.onsuccess = grabEventAndContinueHandler; + let event = yield undefined; + let db = event.target.result; + let transaction = db.transaction("cache", "readwrite"); + transaction.onabort = errorHandler; + transaction.oncomplete = grabEventAndContinueHandler; + let store = transaction.objectStore("cache"); + store.put({key: "text", value: "compiled filter data"}); + store.put({key: "bytes", value: new Uint8Array([0, 1, 127, 255])}); + store.put({key: "empty", value: new ArrayBuffer(0)}); + yield undefined; + db.close(); + + // Reopen after committing: test the serialized database records, rather than + // just observing successful writes or values still held by the caller. + request = indexedDB.open(name, 1); + request.onerror = errorHandler; + request.onsuccess = grabEventAndContinueHandler; + event = yield undefined; + db = event.target.result; + request = db.transaction("cache").objectStore("cache").getAll(); + request.onerror = errorHandler; + request.onsuccess = grabEventAndContinueHandler; + event = yield undefined; + let records = event.target.result; + is(records.length, 3, "All committed records are readable"); + is(records[0].key, "bytes", "Records retain their keys"); + ok(records[0].value instanceof Uint8Array, "Typed array type survives storage"); + is(Array.from(records[0].value).join(), "0,1,127,255", "Bytes survive storage"); + is(records[1].value.byteLength, 0, "Empty buffers survive storage"); + is(records[2].value, "compiled filter data", "Strings survive storage"); + db.close(); + finishTest(); + yield undefined; +} diff --git a/dom/indexedDB/test/unit/xpcshell-shared.ini b/dom/indexedDB/test/unit/xpcshell-shared.ini index 05359097bd..8a4db0f4f9 100644 --- a/dom/indexedDB/test/unit/xpcshell-shared.ini +++ b/dom/indexedDB/test/unit/xpcshell-shared.ini @@ -10,6 +10,7 @@ [test_autoIncrement.js] [test_autoIncrement_indexes.js] [test_blocked_order.js] +[test_cache_record_roundtrip.js] [test_clear.js] [test_complex_keyPaths.js] [test_count.js] From e134fea1ba3fe5b058014911ccbb90b87d41e12b Mon Sep 17 00:00:00 2001 From: wuggy Date: Mon, 14 Sep 2026 15:39:45 -0700 Subject: [PATCH 2/4] fix ubO pt.4 --- browser/components/webextensions/ext-browserAction.js | 9 ++++++++- .../components/webextensions/schemas/browser_action.json | 5 +++++ toolkit/components/webextensions/schemas/manifest.json | 3 +++ 3 files changed, 16 insertions(+), 1 deletion(-) diff --git a/browser/components/webextensions/ext-browserAction.js b/browser/components/webextensions/ext-browserAction.js index 2c82ac701a..e370cb205a 100644 --- a/browser/components/webextensions/ext-browserAction.js +++ b/browser/components/webextensions/ext-browserAction.js @@ -76,6 +76,12 @@ function BrowserAction(options, extension) { BrowserAction.prototype = { build() { + let areas = { + navbar: CustomizableUI.AREA_NAVBAR, + menupanel: CustomizableUI.AREA_PANEL, + tabstrip: CustomizableUI.AREA_TABSTRIP, + personaltoolbar: CustomizableUI.AREA_BOOKMARKS, + }; let widget = CustomizableUI.createWidget({ id: this.id, viewId: this.viewId, @@ -83,7 +89,8 @@ BrowserAction.prototype = { removable: true, label: this.defaults.title || this.extension.name, tooltiptext: this.defaults.title || "", - defaultArea: CustomizableUI.AREA_NAVBAR, + defaultArea: areas[this.extension.manifest.browser_action.default_area] || + CustomizableUI.AREA_NAVBAR, onBeforeCreated: document => { let view = document.createElementNS(XUL_NS, "panelview"); diff --git a/browser/components/webextensions/schemas/browser_action.json b/browser/components/webextensions/schemas/browser_action.json index 1a7da956a1..854a3bebbf 100644 --- a/browser/components/webextensions/schemas/browser_action.json +++ b/browser/components/webextensions/schemas/browser_action.json @@ -31,6 +31,11 @@ "browser_style": { "type": "boolean", "optional": true + }, + "default_area": { + "type": "string", + "enum": ["navbar", "menupanel", "tabstrip", "personaltoolbar"], + "optional": true } }, "optional": true diff --git a/toolkit/components/webextensions/schemas/manifest.json b/toolkit/components/webextensions/schemas/manifest.json index 636575dc04..291e668323 100644 --- a/toolkit/components/webextensions/schemas/manifest.json +++ b/toolkit/components/webextensions/schemas/manifest.json @@ -218,9 +218,12 @@ "enum": [ "alarms", "clipboardWrite", + "dns", "idle", "notifications", + "privacy", "storage" + ,"unlimitedStorage" ] }, { "$ref": "MatchPattern" } From ae54ac8e28f0da4299e4307c111b73d5f8ce1aa4 Mon Sep 17 00:00:00 2001 From: wuggy Date: Mon, 14 Sep 2026 15:57:30 -0700 Subject: [PATCH 3/4] fix ubO pt.5 --- browser/components/nsBrowserGlue.js | 4 +- .../webextensions/schemas/context_menus.json | 5 ++- js/src/vm/StructuredClone.cpp | 7 +++- toolkit/components/webextensions/ext-dns.js | 41 +++++++++++++++++++ .../webextensions/extensions-toolkit.manifest | 2 + .../components/webextensions/schemas/dns.json | 4 ++ toolkit/content/widgets/browser.xml | 2 +- toolkit/modules/addons/MatchPattern.jsm | 4 +- 8 files changed, 63 insertions(+), 6 deletions(-) create mode 100644 toolkit/components/webextensions/ext-dns.js create mode 100644 toolkit/components/webextensions/schemas/dns.json diff --git a/browser/components/nsBrowserGlue.js b/browser/components/nsBrowserGlue.js index a9d95bb0cf..af8a33570a 100644 --- a/browser/components/nsBrowserGlue.js +++ b/browser/components/nsBrowserGlue.js @@ -922,7 +922,9 @@ BrowserGlue.prototype = { AutoCompletePopup.init(); DateTimePickerHelper.init(); - this._firstWindowLoaded(); + if (typeof this._firstWindowLoaded == "function") { + this._firstWindowLoaded(); + } }, /** diff --git a/browser/components/webextensions/schemas/context_menus.json b/browser/components/webextensions/schemas/context_menus.json index b31af51f3f..7f9702fa55 100644 --- a/browser/components/webextensions/schemas/context_menus.json +++ b/browser/components/webextensions/schemas/context_menus.json @@ -11,7 +11,8 @@ "choices": [{ "type": "string", "enum": [ - "contextMenus" + "contextMenus", + "menus" ] }] } @@ -20,7 +21,7 @@ { "namespace": "contextMenus", "description": "Use the browser.contextMenus API to add items to the browser's context menu. You can choose what types of objects your context menu additions apply to, such as images, hyperlinks, and pages.", - "permissions": ["contextMenus"], + "permissions": ["contextMenus", "menus"], "properties": { "ACTION_MENU_TOP_LEVEL_LIMIT": { "value": 6, diff --git a/js/src/vm/StructuredClone.cpp b/js/src/vm/StructuredClone.cpp index 50e6162923..6a3ca514b9 100644 --- a/js/src/vm/StructuredClone.cpp +++ b/js/src/vm/StructuredClone.cpp @@ -2323,11 +2323,16 @@ JSStructuredCloneReader::readHeader() return false; } + // Some older IndexedDB writers stored the compatibility marker in the + // header. Read those records as durable cross-process data. + if (storedScope == JS::StructuredCloneScope::DifferentProcessForIndexedDB) { + storedScope = JS::StructuredCloneScope::DifferentProcess; + } + if (allowedScope == JS::StructuredCloneScope::DifferentProcessForIndexedDB) { // Bug 1434308 and bug 1458320 - the scopes stored in old IndexedDB // clones are incorrect. Treat them as if they were DifferentProcess. allowedScope = JS::StructuredCloneScope::DifferentProcess; - return true; } if (storedScope < allowedScope) { diff --git a/toolkit/components/webextensions/ext-dns.js b/toolkit/components/webextensions/ext-dns.js new file mode 100644 index 0000000000..b131d0b6e5 --- /dev/null +++ b/toolkit/components/webextensions/ext-dns.js @@ -0,0 +1,41 @@ +"use strict"; + +var {classes: Cc, interfaces: Ci, utils: Cu, results: Cr} = Components; +Cu.import("resource://gre/modules/Services.jsm"); +Cu.import("resource://gre/modules/XPCOMUtils.jsm"); + +function dnsResolve(hostname, flags = []) { + let mask = 0; + for (let flag of flags) { + switch (flag) { + case "bypass_cache": mask |= Ci.nsIDNSService.RESOLVE_BYPASS_CACHE; break; + case "canonical_name": mask |= Ci.nsIDNSService.RESOLVE_CANONICAL_NAME; break; + case "disable_ipv4": mask |= Ci.nsIDNSService.RESOLVE_DISABLE_IPV4; break; + case "disable_ipv6": mask |= Ci.nsIDNSService.RESOLVE_DISABLE_IPV6; break; + case "offline": mask |= Ci.nsIDNSService.RESOLVE_OFFLINE; break; + case "priority_low": mask |= Ci.nsIDNSService.RESOLVE_PRIORITY_LOW; break; + case "priority_medium": mask |= Ci.nsIDNSService.RESOLVE_PRIORITY_MEDIUM; break; + case "allow_name_collisions": mask |= Ci.nsIDNSService.RESOLVE_ALLOW_NAME_COLLISION; break; + } + } + let dns = Cc["@mozilla.org/network/dns-service;1"].getService(Ci.nsIDNSService); + return new Promise((resolve, reject) => { + let listener = { + onLookupComplete(request, record, status) { + if (Components.isSuccessCode(status)) { + let addresses = []; + try { record.rewind(); while (record.hasMore()) addresses.push(record.getNextAddrAsString()); } catch (e) {} + resolve({addresses, canonicalName: record.canonicalName || undefined, isTRR: false}); + } else { + reject(Components.Exception("DNS resolution failed", status)); + } + }, + QueryInterface: XPCOMUtils.generateQI([Ci.nsIDNSListener]), + }; + dns.asyncResolve(hostname, mask, listener, Services.tm.mainThread); + }); +} + +extensions.registerSchemaAPI("dns", "addon_parent", () => ({ + dns: { resolve: dnsResolve }, +})); diff --git a/toolkit/components/webextensions/extensions-toolkit.manifest b/toolkit/components/webextensions/extensions-toolkit.manifest index 4ec65a9844..5a5151aea6 100644 --- a/toolkit/components/webextensions/extensions-toolkit.manifest +++ b/toolkit/components/webextensions/extensions-toolkit.manifest @@ -8,6 +8,7 @@ category webextension-scripts notifications chrome://extensions/content/ext-noti category webextension-scripts i18n chrome://extensions/content/ext-i18n.js category webextension-scripts idle chrome://extensions/content/ext-idle.js category webextension-scripts webRequest chrome://extensions/content/ext-webRequest.js +category webextension-scripts dns chrome://extensions/content/ext-dns.js category webextension-scripts webNavigation chrome://extensions/content/ext-webNavigation.js category webextension-scripts runtime chrome://extensions/content/ext-runtime.js category webextension-scripts extension chrome://extensions/content/ext-extension.js @@ -47,3 +48,4 @@ category webextension-schemas test chrome://extensions/content/schemas/test.json category webextension-schemas top_sites chrome://extensions/content/schemas/top_sites.json category webextension-schemas web_navigation chrome://extensions/content/schemas/web_navigation.json category webextension-schemas web_request chrome://extensions/content/schemas/web_request.json +category webextension-schemas dns chrome://extensions/content/schemas/dns.json diff --git a/toolkit/components/webextensions/schemas/dns.json b/toolkit/components/webextensions/schemas/dns.json new file mode 100644 index 0000000000..7484656e59 --- /dev/null +++ b/toolkit/components/webextensions/schemas/dns.json @@ -0,0 +1,4 @@ +[ + {"namespace":"manifest","types":[{"$extend":"Permission","choices":[{"type":"string","enum":["dns"]}]}]}, + {"namespace":"dns","permissions":["dns"],"types":[{"id":"DNSRecord","type":"object","properties":{"addresses":{"type":"array","items":{"type":"string"}},"canonicalName":{"type":"string","optional":true},"isTRR":{"type":"boolean"}}}],"functions":[{"name":"resolve","type":"function","async":"promise","parameters":[{"name":"hostname","type":"string"},{"name":"flags","type":"array","items":{"type":"string"},"optional":true}],"returns":{"$ref":"DNSRecord"}}]} +] diff --git a/toolkit/content/widgets/browser.xml b/toolkit/content/widgets/browser.xml index 839b0551c7..db9f1051f6 100644 --- a/toolkit/content/widgets/browser.xml +++ b/toolkit/content/widgets/browser.xml @@ -457,7 +457,7 @@ + onget="return this.docShell && this.docShell.QueryInterface(Components.interfaces.nsIInterfaceRequestor).getInterface(Components.interfaces.nsIWebProgress);"/> null diff --git a/toolkit/modules/addons/MatchPattern.jsm b/toolkit/modules/addons/MatchPattern.jsm index 4dff81fd23..fd46e1e786 100644 --- a/toolkit/modules/addons/MatchPattern.jsm +++ b/toolkit/modules/addons/MatchPattern.jsm @@ -18,7 +18,9 @@ this.EXPORTED_SYMBOLS = ["MatchPattern", "MatchGlobs", "MatchURLFilters"]; /* globals MatchPattern, MatchGlobs */ -const PERMITTED_SCHEMES = ["http", "https", "file", "ftp", "data"]; +// WebExtensions also use WebSocket URLs for request filtering and +// moz-extension URLs internally when validating web-accessible resources. +const PERMITTED_SCHEMES = ["http", "https", "file", "ftp", "data", "ws", "wss", "moz-extension"]; const PERMITTED_SCHEMES_REGEXP = PERMITTED_SCHEMES.join("|"); // This function converts a glob pattern (containing * and possibly ? From e0fe6706d1c8961049d62f253d65893ed5f1e7f8 Mon Sep 17 00:00:00 2001 From: wuggy Date: Mon, 14 Sep 2026 16:11:09 -0700 Subject: [PATCH 4/4] AAAAAAAAAAAAAAAAAAAAAAAAAAA --- browser/components/nsBrowserGlue.js | 4 +--- browser/components/webextensions/ext-browserAction.js | 9 +-------- .../components/webextensions/schemas/browser_action.json | 5 ----- js/src/vm/StructuredClone.cpp | 7 +------ .../components/webextensions/extensions-toolkit.manifest | 1 - toolkit/content/widgets/browser.xml | 2 +- 6 files changed, 4 insertions(+), 24 deletions(-) diff --git a/browser/components/nsBrowserGlue.js b/browser/components/nsBrowserGlue.js index af8a33570a..a9d95bb0cf 100644 --- a/browser/components/nsBrowserGlue.js +++ b/browser/components/nsBrowserGlue.js @@ -922,9 +922,7 @@ BrowserGlue.prototype = { AutoCompletePopup.init(); DateTimePickerHelper.init(); - if (typeof this._firstWindowLoaded == "function") { - this._firstWindowLoaded(); - } + this._firstWindowLoaded(); }, /** diff --git a/browser/components/webextensions/ext-browserAction.js b/browser/components/webextensions/ext-browserAction.js index e370cb205a..2c82ac701a 100644 --- a/browser/components/webextensions/ext-browserAction.js +++ b/browser/components/webextensions/ext-browserAction.js @@ -76,12 +76,6 @@ function BrowserAction(options, extension) { BrowserAction.prototype = { build() { - let areas = { - navbar: CustomizableUI.AREA_NAVBAR, - menupanel: CustomizableUI.AREA_PANEL, - tabstrip: CustomizableUI.AREA_TABSTRIP, - personaltoolbar: CustomizableUI.AREA_BOOKMARKS, - }; let widget = CustomizableUI.createWidget({ id: this.id, viewId: this.viewId, @@ -89,8 +83,7 @@ BrowserAction.prototype = { removable: true, label: this.defaults.title || this.extension.name, tooltiptext: this.defaults.title || "", - defaultArea: areas[this.extension.manifest.browser_action.default_area] || - CustomizableUI.AREA_NAVBAR, + defaultArea: CustomizableUI.AREA_NAVBAR, onBeforeCreated: document => { let view = document.createElementNS(XUL_NS, "panelview"); diff --git a/browser/components/webextensions/schemas/browser_action.json b/browser/components/webextensions/schemas/browser_action.json index 854a3bebbf..1a7da956a1 100644 --- a/browser/components/webextensions/schemas/browser_action.json +++ b/browser/components/webextensions/schemas/browser_action.json @@ -31,11 +31,6 @@ "browser_style": { "type": "boolean", "optional": true - }, - "default_area": { - "type": "string", - "enum": ["navbar", "menupanel", "tabstrip", "personaltoolbar"], - "optional": true } }, "optional": true diff --git a/js/src/vm/StructuredClone.cpp b/js/src/vm/StructuredClone.cpp index 6a3ca514b9..50e6162923 100644 --- a/js/src/vm/StructuredClone.cpp +++ b/js/src/vm/StructuredClone.cpp @@ -2323,16 +2323,11 @@ JSStructuredCloneReader::readHeader() return false; } - // Some older IndexedDB writers stored the compatibility marker in the - // header. Read those records as durable cross-process data. - if (storedScope == JS::StructuredCloneScope::DifferentProcessForIndexedDB) { - storedScope = JS::StructuredCloneScope::DifferentProcess; - } - if (allowedScope == JS::StructuredCloneScope::DifferentProcessForIndexedDB) { // Bug 1434308 and bug 1458320 - the scopes stored in old IndexedDB // clones are incorrect. Treat them as if they were DifferentProcess. allowedScope = JS::StructuredCloneScope::DifferentProcess; + return true; } if (storedScope < allowedScope) { diff --git a/toolkit/components/webextensions/extensions-toolkit.manifest b/toolkit/components/webextensions/extensions-toolkit.manifest index 5a5151aea6..a86c6778a6 100644 --- a/toolkit/components/webextensions/extensions-toolkit.manifest +++ b/toolkit/components/webextensions/extensions-toolkit.manifest @@ -8,7 +8,6 @@ category webextension-scripts notifications chrome://extensions/content/ext-noti category webextension-scripts i18n chrome://extensions/content/ext-i18n.js category webextension-scripts idle chrome://extensions/content/ext-idle.js category webextension-scripts webRequest chrome://extensions/content/ext-webRequest.js -category webextension-scripts dns chrome://extensions/content/ext-dns.js category webextension-scripts webNavigation chrome://extensions/content/ext-webNavigation.js category webextension-scripts runtime chrome://extensions/content/ext-runtime.js category webextension-scripts extension chrome://extensions/content/ext-extension.js diff --git a/toolkit/content/widgets/browser.xml b/toolkit/content/widgets/browser.xml index db9f1051f6..839b0551c7 100644 --- a/toolkit/content/widgets/browser.xml +++ b/toolkit/content/widgets/browser.xml @@ -457,7 +457,7 @@ + onget="return this.docShell.QueryInterface(Components.interfaces.nsIInterfaceRequestor).getInterface(Components.interfaces.nsIWebProgress);"/> null