Skip to content

Commit 6d2b337

Browse files
committed
Mind that BroadcastChannel contructor can throw in Firefox
BroadcastChannel constructor throws in Firefox when Enhanced Tracking Protection is set to "strict". This behavior could cause scriptlet injection to wholly break when uBO's logger was opened, as BroadcastChannel() is used by scriptlets to report information to the logger. This commit ensures that exceptions from BroadcastChannel constructor are properly handled. The scriptlets will fall back to report at the console should they be unable to report to the logger through BroadcastChannel.
1 parent 4169340 commit 6d2b337

File tree

2 files changed

+60
-46
lines changed

2 files changed

+60
-46
lines changed

assets/resources/scriptlets.js

Lines changed: 39 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -173,13 +173,11 @@ function safeSelf() {
173173
scriptletGlobals.safeSelf = safe;
174174
if ( scriptletGlobals.bcSecret === undefined ) { return safe; }
175175
// This is executed only when the logger is opened
176-
const bc = new self.BroadcastChannel(scriptletGlobals.bcSecret);
177-
let bcBuffer = [];
178176
safe.logLevel = scriptletGlobals.logLevel || 1;
179177
let lastLogType = '';
180178
let lastLogText = '';
181179
let lastLogTime = 0;
182-
safe.sendToLogger = (type, ...args) => {
180+
safe.toLogText = (type, ...args) => {
183181
if ( args.length === 0 ) { return; }
184182
const text = `[${document.location.hostname || document.location.href}]${args.join(' ')}`;
185183
if ( text === lastLogText && type === lastLogType ) {
@@ -188,30 +186,45 @@ function safeSelf() {
188186
lastLogType = type;
189187
lastLogText = text;
190188
lastLogTime = Date.now();
191-
if ( bcBuffer === undefined ) {
192-
return bc.postMessage({ what: 'messageToLogger', type, text });
193-
}
194-
bcBuffer.push({ type, text });
195-
};
196-
bc.onmessage = ev => {
197-
const msg = ev.data;
198-
switch ( msg ) {
199-
case 'iamready!':
200-
if ( bcBuffer === undefined ) { break; }
201-
bcBuffer.forEach(({ type, text }) =>
202-
bc.postMessage({ what: 'messageToLogger', type, text })
203-
);
204-
bcBuffer = undefined;
205-
break;
206-
case 'setScriptletLogLevelToOne':
207-
safe.logLevel = 1;
208-
break;
209-
case 'setScriptletLogLevelToTwo':
210-
safe.logLevel = 2;
211-
break;
212-
}
189+
return text;
213190
};
214-
bc.postMessage('areyouready?');
191+
try {
192+
const bc = new self.BroadcastChannel(scriptletGlobals.bcSecret);
193+
let bcBuffer = [];
194+
safe.sendToLogger = (type, ...args) => {
195+
const text = safe.toLogText(type, ...args);
196+
if ( text === undefined ) { return; }
197+
if ( bcBuffer === undefined ) {
198+
return bc.postMessage({ what: 'messageToLogger', type, text });
199+
}
200+
bcBuffer.push({ type, text });
201+
};
202+
bc.onmessage = ev => {
203+
const msg = ev.data;
204+
switch ( msg ) {
205+
case 'iamready!':
206+
if ( bcBuffer === undefined ) { break; }
207+
bcBuffer.forEach(({ type, text }) =>
208+
bc.postMessage({ what: 'messageToLogger', type, text })
209+
);
210+
bcBuffer = undefined;
211+
break;
212+
case 'setScriptletLogLevelToOne':
213+
safe.logLevel = 1;
214+
break;
215+
case 'setScriptletLogLevelToTwo':
216+
safe.logLevel = 2;
217+
break;
218+
}
219+
};
220+
bc.postMessage('areyouready?');
221+
} catch(_) {
222+
safe.sendToLogger = (type, ...args) => {
223+
const text = safe.toLogText(type, ...args);
224+
if ( text === undefined ) { return; }
225+
console.log(`uBO${text}`);
226+
};
227+
}
215228
return safe;
216229
}
217230

@@ -5144,7 +5157,6 @@ function trustedPreventXhr(...args) {
51445157
}
51455158

51465159
/**
5147-
*
51485160
* @trustedScriptlet trusted-prevent-dom-bypass
51495161
*
51505162
* @description
@@ -5219,7 +5231,6 @@ function trustedPreventDomBypass(
52195231
}
52205232

52215233
/**
5222-
*
52235234
* @trustedScriptlet trusted-override-element-method
52245235
*
52255236
* @description

src/js/scriptlet-filtering.js

Lines changed: 21 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -176,25 +176,28 @@ const onScriptletMessageInjector = (( ) => {
176176
'(',
177177
function(name) {
178178
if ( self.uBO_bcSecret ) { return; }
179-
const bcSecret = new self.BroadcastChannel(name);
180-
bcSecret.onmessage = ev => {
181-
const msg = ev.data;
182-
switch ( typeof msg ) {
183-
case 'string':
184-
if ( msg !== 'areyouready?' ) { break; }
185-
bcSecret.postMessage('iamready!');
186-
break;
187-
case 'object':
188-
if ( self.vAPI && self.vAPI.messaging ) {
189-
self.vAPI.messaging.send('contentscript', msg);
190-
} else {
191-
console.log(`[uBO][${msg.type}]${msg.text}`);
179+
try {
180+
const bcSecret = new self.BroadcastChannel(name);
181+
bcSecret.onmessage = ev => {
182+
const msg = ev.data;
183+
switch ( typeof msg ) {
184+
case 'string':
185+
if ( msg !== 'areyouready?' ) { break; }
186+
bcSecret.postMessage('iamready!');
187+
break;
188+
case 'object':
189+
if ( self.vAPI && self.vAPI.messaging ) {
190+
self.vAPI.messaging.send('contentscript', msg);
191+
} else {
192+
console.log(`[uBO][${msg.type}]${msg.text}`);
193+
}
194+
break;
192195
}
193-
break;
194-
}
195-
};
196-
bcSecret.postMessage('iamready!');
197-
self.uBO_bcSecret = bcSecret;
196+
};
197+
bcSecret.postMessage('iamready!');
198+
self.uBO_bcSecret = bcSecret;
199+
} catch(_) {
200+
}
198201
}.toString(),
199202
')(',
200203
'bcSecret-slot',

0 commit comments

Comments
 (0)