mirror of https://github.com/gorhill/uBlock.git
fix #2014
This commit is contained in:
parent
40f574537b
commit
95ec573141
|
@ -19,12 +19,18 @@
|
|||
Home: https://github.com/gorhill/uBlock
|
||||
*/
|
||||
|
||||
/* exported processObserver */
|
||||
|
||||
'use strict';
|
||||
|
||||
/******************************************************************************/
|
||||
|
||||
// https://github.com/gorhill/uBlock/issues/800
|
||||
this.EXPORTED_SYMBOLS = ['contentObserver', 'LocationChangeListener'];
|
||||
this.EXPORTED_SYMBOLS = [
|
||||
'contentObserver',
|
||||
'processObserver',
|
||||
'LocationChangeListener'
|
||||
];
|
||||
|
||||
const {interfaces: Ci, utils: Cu} = Components;
|
||||
const {Services} = Cu.import('resource://gre/modules/Services.jsm', null);
|
||||
|
@ -64,20 +70,94 @@ const getMessageManager = function(win) {
|
|||
|
||||
/******************************************************************************/
|
||||
|
||||
const getChildProcessMessageManager = function() {
|
||||
var svc = Services;
|
||||
if ( !svc ) {
|
||||
return;
|
||||
}
|
||||
var cpmm = svc.cpmm;
|
||||
if ( cpmm ) {
|
||||
return cpmm;
|
||||
}
|
||||
cpmm = Components.classes['@mozilla.org/childprocessmessagemanager;1'];
|
||||
if ( cpmm ) {
|
||||
return cpmm.getService(Ci.nsISyncMessageSender);
|
||||
}
|
||||
};
|
||||
// https://github.com/gorhill/uBlock/issues/2014
|
||||
// Have a dictionary of hostnames for which there are script tag filters. This
|
||||
// allow for coarse-testing before firing a synchronous message to the
|
||||
// parent process. Script tag filters are not very common, so this allows
|
||||
// to skip the blocking of the child process most of the time.
|
||||
|
||||
var scriptTagFilterer = (function() {
|
||||
var scriptTagHostnames;
|
||||
|
||||
var getCpmm = function() {
|
||||
var svc = Services;
|
||||
if ( !svc ) { return; }
|
||||
var cpmm = svc.cpmm;
|
||||
if ( cpmm ) { return cpmm; }
|
||||
cpmm = Components.classes['@mozilla.org/childprocessmessagemanager;1'];
|
||||
if ( cpmm ) { return cpmm.getService(Ci.nsISyncMessageSender); }
|
||||
};
|
||||
|
||||
var listener = function(message) {
|
||||
var details;
|
||||
try {
|
||||
details = JSON.parse(message.data);
|
||||
} catch (ex) {
|
||||
}
|
||||
if ( !details || !details.msg ) { return; }
|
||||
if (details.msg.what === 'staticFilteringDataChanged' ) {
|
||||
reset();
|
||||
}
|
||||
};
|
||||
|
||||
var getScriptTagHostnames = function() {
|
||||
if ( scriptTagHostnames ) {
|
||||
return scriptTagHostnames;
|
||||
}
|
||||
var cpmm = getCpmm();
|
||||
if ( !cpmm ) { return; }
|
||||
var r = cpmm.sendSyncMessage(rpcEmitterName, { fnName: 'getScriptTagHostnames' });
|
||||
if ( Array.isArray(r) && Array.isArray(r[0]) ) {
|
||||
scriptTagHostnames = new Set(r[0]);
|
||||
}
|
||||
return scriptTagHostnames;
|
||||
};
|
||||
|
||||
var getScriptTagFilters = function(details) {
|
||||
let cpmm = getCpmm();
|
||||
if ( !cpmm ) { return; }
|
||||
let r = cpmm.sendSyncMessage(rpcEmitterName, {
|
||||
fnName: 'getScriptTagFilters',
|
||||
rootURL: details.rootURL,
|
||||
frameURL: details.frameURL,
|
||||
frameHostname: details.frameHostname
|
||||
});
|
||||
if ( Array.isArray(r) ) {
|
||||
return r[0];
|
||||
}
|
||||
};
|
||||
|
||||
var regexFromHostname = function(details) {
|
||||
// If target hostname has no script tag filter, no point querying
|
||||
// chrome process.
|
||||
var hostnames = getScriptTagHostnames();
|
||||
if ( !hostnames ) { return; }
|
||||
var hn = details.frameHostname, pos, entity;
|
||||
for (;;) {
|
||||
if ( hostnames.has(hn) ) {
|
||||
return getScriptTagFilters(details);
|
||||
}
|
||||
pos = hn.indexOf('.');
|
||||
if ( pos === -1 ) { break; }
|
||||
entity = hn.slice(0, pos) + '.*';
|
||||
if ( hostnames.has(entity) ) {
|
||||
return getScriptTagFilters(details);
|
||||
}
|
||||
hn = hn.slice(pos + 1);
|
||||
if ( hn === '' ) { break; }
|
||||
}
|
||||
};
|
||||
|
||||
var reset = function() {
|
||||
scriptTagHostnames = undefined;
|
||||
};
|
||||
|
||||
return {
|
||||
get: regexFromHostname,
|
||||
listener: listener,
|
||||
reset: reset
|
||||
};
|
||||
})();
|
||||
|
||||
/******************************************************************************/
|
||||
|
||||
|
@ -305,18 +385,9 @@ var contentObserver = {
|
|||
wantXHRConstructor: false
|
||||
});
|
||||
|
||||
if ( getChildProcessMessageManager() ) {
|
||||
sandbox.rpc = function(details) {
|
||||
var cpmm = getChildProcessMessageManager();
|
||||
if ( !cpmm ) { return; }
|
||||
var r = cpmm.sendSyncMessage(rpcEmitterName, details);
|
||||
if ( Array.isArray(r) ) {
|
||||
return r[0];
|
||||
}
|
||||
};
|
||||
} else {
|
||||
sandbox.rpc = function() {};
|
||||
}
|
||||
sandbox.getScriptTagFilters = function(details) {
|
||||
return scriptTagFilterer.get(details);
|
||||
};
|
||||
|
||||
sandbox.injectScript = function(script) {
|
||||
let svc = Services;
|
||||
|
@ -344,6 +415,8 @@ var contentObserver = {
|
|||
}
|
||||
};
|
||||
|
||||
sandbox.topContentScript = win === win.top;
|
||||
|
||||
// The goal is to have content scripts removed from web pages. This
|
||||
// helps remove traces of uBlock from memory when disabling/removing
|
||||
// the addon.
|
||||
|
@ -353,15 +426,15 @@ var contentObserver = {
|
|||
sandbox.outerShutdown = function() {
|
||||
sandbox.removeMessageListener();
|
||||
sandbox.addMessageListener =
|
||||
sandbox.getScriptTagFilters =
|
||||
sandbox.injectCSS =
|
||||
sandbox.injectScript =
|
||||
sandbox.outerShutdown =
|
||||
sandbox.removeCSS =
|
||||
sandbox.removeMessageListener =
|
||||
sandbox.rpc =
|
||||
sandbox.sendAsyncMessage = function(){};
|
||||
sandbox.vAPI = {};
|
||||
messager = null;
|
||||
messager = sandbox = null;
|
||||
};
|
||||
}
|
||||
else {
|
||||
|
@ -380,13 +453,21 @@ var contentObserver = {
|
|||
callback(message.data);
|
||||
};
|
||||
|
||||
sandbox._broadcastListener_ = function(message) {
|
||||
// https://github.com/gorhill/uBlock/issues/2014
|
||||
if ( sandbox.topContentScript ) {
|
||||
scriptTagFilterer.listener(message);
|
||||
}
|
||||
callback(message.data);
|
||||
};
|
||||
|
||||
messager.addMessageListener(
|
||||
sandbox._sandboxId_,
|
||||
sandbox._messageListener_
|
||||
);
|
||||
messager.addMessageListener(
|
||||
hostName + ':broadcast',
|
||||
sandbox._messageListener_
|
||||
sandbox._broadcastListener_
|
||||
);
|
||||
};
|
||||
|
||||
|
@ -401,13 +482,13 @@ var contentObserver = {
|
|||
);
|
||||
messager.removeMessageListener(
|
||||
hostName + ':broadcast',
|
||||
sandbox._messageListener_
|
||||
sandbox._broadcastListener_
|
||||
);
|
||||
} catch (ex) {
|
||||
// It throws sometimes, mostly when the popup closes
|
||||
}
|
||||
|
||||
sandbox._messageListener_ = null;
|
||||
sandbox._messageListener_ = sandbox._broadcastListener_ = null;
|
||||
};
|
||||
|
||||
return sandbox;
|
||||
|
@ -498,6 +579,14 @@ var contentObserver = {
|
|||
|
||||
/******************************************************************************/
|
||||
|
||||
var processObserver = {
|
||||
start: function() {
|
||||
scriptTagFilterer.reset();
|
||||
}
|
||||
};
|
||||
|
||||
/******************************************************************************/
|
||||
|
||||
var LocationChangeListener = function(docShell, webProgress) {
|
||||
var mm = docShell.QueryInterface(Ci.nsIInterfaceRequestor)
|
||||
.getInterface(Ci.nsIContentFrameMessageManager);
|
||||
|
|
|
@ -23,21 +23,16 @@
|
|||
|
||||
// https://developer.mozilla.org/en-US/Firefox/Multiprocess_Firefox/Frame_script_environment
|
||||
|
||||
(function() {
|
||||
(function(context) {
|
||||
'use strict';
|
||||
|
||||
let {LocationChangeListener} = Components.utils.import(
|
||||
Components.stack.filename.replace('Script', 'Module'),
|
||||
null
|
||||
);
|
||||
|
||||
if ( !this.docShell ) {
|
||||
if ( !context.docShell ) {
|
||||
return;
|
||||
}
|
||||
|
||||
let webProgress = this.docShell
|
||||
.QueryInterface(Components.interfaces.nsIInterfaceRequestor)
|
||||
.getInterface(Components.interfaces.nsIWebProgress);
|
||||
let webProgress = context.docShell
|
||||
.QueryInterface(Components.interfaces.nsIInterfaceRequestor)
|
||||
.getInterface(Components.interfaces.nsIWebProgress);
|
||||
if ( !webProgress ) {
|
||||
return;
|
||||
}
|
||||
|
@ -49,11 +44,19 @@
|
|||
return;
|
||||
}
|
||||
|
||||
let {LocationChangeListener} = Components.utils.import(
|
||||
Components.stack.filename.replace('Script', 'Module'),
|
||||
null
|
||||
);
|
||||
|
||||
// https://github.com/gorhill/uBlock/issues/1444
|
||||
// Apparently, on older versions of Firefox (31 and less), the same context
|
||||
// is used for all extensions, hence we must use a unique variable name to
|
||||
// ensure no collision.
|
||||
this.ublock0LocationChangeListener = new LocationChangeListener(this.docShell, webProgress);
|
||||
}).call(this);
|
||||
// is used for all frame scripts, hence we must use a unique variable name
|
||||
// to ensure no collision.
|
||||
context.ublock0LocationChangeListener = new LocationChangeListener(
|
||||
context.docShell,
|
||||
webProgress
|
||||
);
|
||||
})(this);
|
||||
|
||||
/******************************************************************************/
|
||||
|
|
|
@ -1760,16 +1760,15 @@ vAPI.messaging.setup = function(defaultHandler) {
|
|||
}
|
||||
this.defaultHandler = defaultHandler;
|
||||
|
||||
this.globalMessageManager.addMessageListener(
|
||||
var gmm = this.globalMessageManager;
|
||||
gmm.addMessageListener(
|
||||
location.host + ':background',
|
||||
this.onMessage
|
||||
);
|
||||
|
||||
this.globalMessageManager.loadFrameScript(this.frameScriptURL, true);
|
||||
gmm.loadFrameScript(this.frameScriptURL, true);
|
||||
|
||||
cleanupTasks.push(function() {
|
||||
var gmm = vAPI.messaging.globalMessageManager;
|
||||
|
||||
gmm.broadcastAsyncMessage(
|
||||
location.host + ':broadcast',
|
||||
JSON.stringify({
|
||||
|
@ -1778,13 +1777,11 @@ vAPI.messaging.setup = function(defaultHandler) {
|
|||
msg: { cmd: 'shutdownSandbox' }
|
||||
})
|
||||
);
|
||||
|
||||
gmm.removeDelayedFrameScript(vAPI.messaging.frameScriptURL);
|
||||
gmm.removeMessageListener(
|
||||
location.host + ':background',
|
||||
vAPI.messaging.onMessage
|
||||
);
|
||||
|
||||
vAPI.messaging.defaultHandler = null;
|
||||
});
|
||||
};
|
||||
|
@ -1820,8 +1817,9 @@ vAPI.messaging.broadcast = function(message) {
|
|||
// https://developer.mozilla.org/en-US/Firefox/Multiprocess_Firefox/Message_Manager/Message_manager_overview#Content_frame_message_manager
|
||||
|
||||
vAPI.rpcReceiver = (function() {
|
||||
var calls = Object.create(null);
|
||||
var childProcessMessageName = location.host + ':child-process-message';
|
||||
var calls = Object.create(null),
|
||||
childProcessMessageName = location.host + ':child-process-message',
|
||||
processScriptURL = vAPI.getURL('processScript.js');
|
||||
|
||||
var onChildProcessMessage = function(ev) {
|
||||
var msg = ev.data;
|
||||
|
@ -1838,22 +1836,31 @@ vAPI.rpcReceiver = (function() {
|
|||
if ( ppmm ) {
|
||||
ppmm = ppmm.getService(Ci.nsIMessageListenerManager);
|
||||
}
|
||||
if ( !ppmm ) {
|
||||
return calls;
|
||||
}
|
||||
}
|
||||
|
||||
if ( ppmm ) {
|
||||
ppmm.addMessageListener(
|
||||
// https://github.com/gorhill/uBlock/issues/2014
|
||||
// Not supported on older versions of Firefox.
|
||||
if ( ppmm.loadProcessScript instanceof Function ) {
|
||||
ppmm.loadProcessScript(processScriptURL, true);
|
||||
}
|
||||
|
||||
ppmm.addMessageListener(
|
||||
childProcessMessageName,
|
||||
onChildProcessMessage
|
||||
);
|
||||
|
||||
cleanupTasks.push(function() {
|
||||
if ( ppmm.removeDelayedProcessScript instanceof Function ) {
|
||||
ppmm.removeDelayedProcessScript(processScriptURL);
|
||||
}
|
||||
|
||||
ppmm.removeMessageListener(
|
||||
childProcessMessageName,
|
||||
onChildProcessMessage
|
||||
);
|
||||
}
|
||||
|
||||
cleanupTasks.push(function() {
|
||||
if ( ppmm ) {
|
||||
ppmm.removeMessageListener(
|
||||
childProcessMessageName,
|
||||
onChildProcessMessage
|
||||
);
|
||||
}
|
||||
});
|
||||
|
||||
return calls;
|
||||
|
|
|
@ -45,13 +45,6 @@ if ( document instanceof HTMLDocument === false ) {
|
|||
|
||||
/******************************************************************************/
|
||||
|
||||
// Not all sandboxes are given an rpc function, so assign a dummy one if it is
|
||||
// missing -- this avoids the need for testing before use.
|
||||
|
||||
self.rpc = self.rpc || function(){};
|
||||
|
||||
/******************************************************************************/
|
||||
|
||||
var vAPI = self.vAPI = self.vAPI || {};
|
||||
|
||||
/******************************************************************************/
|
||||
|
@ -154,12 +147,14 @@ vAPI.shutdown = (function() {
|
|||
/******************************************************************************/
|
||||
|
||||
(function() {
|
||||
if ( !self.getScriptTagFilters ) {
|
||||
return;
|
||||
}
|
||||
var hostname = location.hostname;
|
||||
if ( !hostname ) {
|
||||
return;
|
||||
}
|
||||
var filters = self.rpc({
|
||||
fnName: 'getScriptTagFilters',
|
||||
var filters = self.getScriptTagFilters({
|
||||
rootURL: self.location.href,
|
||||
frameURL: self.location.href,
|
||||
frameHostname: hostname
|
||||
|
|
|
@ -42,7 +42,7 @@ var hasCachedContent = false;
|
|||
|
||||
var onMessage = function(msg) {
|
||||
switch ( msg.what ) {
|
||||
case 'allFilterListsReloaded':
|
||||
case 'staticFilteringDataChanged':
|
||||
renderFilterLists();
|
||||
break;
|
||||
|
||||
|
|
|
@ -1237,6 +1237,12 @@ FilterContainer.prototype.createScriptTagFilter = function(hash, hostname, selec
|
|||
|
||||
/******************************************************************************/
|
||||
|
||||
FilterContainer.prototype.retrieveScriptTagHostnames = function() {
|
||||
return Object.keys(this.scriptTagFilters);
|
||||
};
|
||||
|
||||
/******************************************************************************/
|
||||
|
||||
FilterContainer.prototype.retrieveScriptTagRegex = function(domain, hostname) {
|
||||
if ( this.scriptTagFilterCount === 0 ) {
|
||||
return;
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
/*******************************************************************************
|
||||
|
||||
uBlock Origin - a browser extension to block requests.
|
||||
Copyright (C) 2015 Raymond Hill
|
||||
Copyright (C) 2015-2016 Raymond Hill
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
|
@ -19,14 +19,12 @@
|
|||
Home: https://github.com/gorhill/uBlock
|
||||
*/
|
||||
|
||||
/* global vAPI, µBlock */
|
||||
'use strict';
|
||||
|
||||
/******************************************************************************/
|
||||
|
||||
(function() {
|
||||
|
||||
'use strict';
|
||||
|
||||
/******************************************************************************/
|
||||
|
||||
if ( typeof vAPI.rpcReceiver !== 'object' ) {
|
||||
|
@ -35,12 +33,19 @@ if ( typeof vAPI.rpcReceiver !== 'object' ) {
|
|||
|
||||
/******************************************************************************/
|
||||
|
||||
vAPI.rpcReceiver.getScriptTagHostnames = function() {
|
||||
var µb = µBlock;
|
||||
var cfe = µb.cosmeticFilteringEngine;
|
||||
if ( !cfe ) { return; }
|
||||
return cfe.retrieveScriptTagHostnames();
|
||||
};
|
||||
|
||||
/******************************************************************************/
|
||||
|
||||
vAPI.rpcReceiver.getScriptTagFilters = function(details) {
|
||||
var µb = µBlock;
|
||||
var cfe = µb.cosmeticFilteringEngine;
|
||||
if ( !cfe ) {
|
||||
return;
|
||||
}
|
||||
if ( !cfe ) { return; }
|
||||
// Fetching the script tag filters first: assuming it is faster than
|
||||
// checking whether the site is whitelisted.
|
||||
var hostname = details.frameHostname;
|
||||
|
|
|
@ -406,7 +406,8 @@
|
|||
|
||||
//quickProfiler.stop(0);
|
||||
|
||||
vAPI.messaging.broadcast({ what: 'allFilterListsReloaded' });
|
||||
vAPI.messaging.broadcast({ what: 'staticFilteringDataChanged' });
|
||||
|
||||
callback();
|
||||
|
||||
µb.selfieManager.create();
|
||||
|
|
|
@ -25,6 +25,7 @@ cp platform/firefox/css/* $DES/css/
|
|||
cp platform/firefox/polyfill.js $DES/js/
|
||||
cp platform/firefox/vapi-*.js $DES/js/
|
||||
cp platform/firefox/bootstrap.js $DES/
|
||||
cp platform/firefox/processScript.js $DES/
|
||||
cp platform/firefox/frame*.js $DES/
|
||||
cp -R platform/firefox/img $DES/
|
||||
cp platform/firefox/chrome.manifest $DES/
|
||||
|
|
Loading…
Reference in New Issue