Fix Intl.DateTimeFormat cross-compartment crash and Connection API robustness

OrigDateTimeFormat constructor called inside exportFunction callback failed
in Firefox compartment boundary. Moved construction to content-script-scope
helper. Also added addEventListener/removeEventListener to Connection override
to prevent crashes in real-time apps like Discord.
This commit is contained in:
sal
2026-03-04 22:03:12 -06:00
parent ac76f93fcb
commit 464a570201
3 changed files with 21 additions and 8 deletions

View File

@@ -1,5 +1,10 @@
# Changelog
## 0.5.2
- Fixed Discord crash caused by Intl.DateTimeFormat cross-compartment constructor failure
- Fixed Connection API override missing addEventListener (could crash real-time apps)
## 0.5.1
- Fixed Discord and other complex web apps crashing due to DOM dimension noise

View File

@@ -247,8 +247,12 @@
effectiveType: "4g",
downlink: 10,
rtt: 50,
saveData: false
}, pageWindow);
saveData: false,
addEventListener: function() {},
removeEventListener: function() {},
dispatchEvent: function() { return true; },
onchange: null
}, pageWindow, { cloneFunctions: true });
}, pageWindow),
configurable: true,
enumerable: true
@@ -330,10 +334,11 @@
const OrigDateTimeFormat = window.Intl.DateTimeFormat;
// Wrap the Intl.DateTimeFormat constructor to inject spoofed timezone
// when no explicit timeZone is provided. This ensures resolvedOptions()
// returns the spoofed timezone and all formatting uses it.
const wrappedDTF = exportFunction(function(locales, options) {
// Wrap the Intl.DateTimeFormat constructor to inject spoofed timezone.
// The wrapper creates the real instance in the content script scope
// (where OrigDateTimeFormat is a valid constructor) then returns it.
// Using a helper avoids cross-compartment constructor failures.
function createDateTimeFormat(locales, options) {
let opts;
if (options) {
try { opts = JSON.parse(JSON.stringify(options)); } catch(e) { opts = {}; }
@@ -341,8 +346,11 @@
opts = {};
}
if (!opts.timeZone) opts.timeZone = tzName;
// Support both `new Intl.DateTimeFormat()` and `Intl.DateTimeFormat()`
return new OrigDateTimeFormat(locales, opts);
}
const wrappedDTF = exportFunction(function(locales, options) {
return createDateTimeFormat(locales, options);
}, pageWindow);
try {

View File

@@ -1,7 +1,7 @@
{
"manifest_version": 2,
"name": "ContainSite",
"version": "0.5.1",
"version": "0.5.2",
"description": "Per-container fingerprint isolation — each container gets its own device identity",
"permissions": [
"contextualIdentities",