Undo interception in top windows

Fixes #431
This commit is contained in:
kkapsner 2020-01-23 13:56:14 +01:00
parent e2efb727b9
commit f3f6df229f
5 changed files with 122 additions and 58 deletions

View File

@ -90,5 +90,46 @@
}
};
const changedPropertiesByWindow = new WeakMap();
scope.changeProperty = function(window, group, {object, name, type, changed}){
let changedProperties = changedPropertiesByWindow.get(scope.getWrapped(window));
if (!changedProperties){
changedProperties = [];
changedPropertiesByWindow.set(scope.getWrapped(window), changedProperties);
}
const descriptor = Object.getOwnPropertyDescriptor(object, name);
const original = descriptor[type];
descriptor[type] = changed;
Object.defineProperty(object, name, descriptor);
changedProperties.push({group, object, name, type, original});
};
scope.revertProperties = function(window, group){
window = scope.getWrapped(window);
let changedProperties = changedPropertiesByWindow.get(window);
if (!changedProperties){
return;
}
if (group){
const remainingProperties = changedProperties.filter(function({group}){
return group !== group;
});
changedPropertiesByWindow.set(window, remainingProperties);
changedProperties = changedProperties.filter(function({group}){
return group === group;
});
}
else {
changedPropertiesByWindow.delete(window);
}
for (let i = changedProperties.length - 1; i >= 0; i -= 1){
const {object, name, type, original} = changedProperties[i];
logging.verbose("reverting", name, "on", object);
const descriptor = Object.getOwnPropertyDescriptor(object, name);
descriptor[type] = original;
Object.defineProperty(object, name, descriptor);
}
};
Object.seal(scope);
}());

View File

@ -45,13 +45,13 @@
let extensionSecret;
function computeExtensionSecret(){
function hashString(string){
return hashing(new Uint16Array(
string.split("").map(function(c){
return c.charCodeAt(0);
})
));
}
function hashString(string){
return hashing(new Uint16Array(
string.split("").map(function(c){
return c.charCodeAt(0);
})
));
}
const now = new Date();
const lastTenMinutes = Math.floor(now.getMinutes() / 10) * 10;
const nextRun = new Date(
@ -125,7 +125,6 @@
return settings.get(...args);
}
const interceptedWindows = new WeakMap();
function interceptWindow(window){
let wrappedTry;
@ -144,9 +143,15 @@
if (!enabled || interceptedWindows.get(wrappedWindow)){
return false;
}
if (wrappedWindow.matchMedia(extensionSecret[0]) === extensionSecret[1]){
interceptedWindows.set(wrappedWindow, true);
return false;
const canvasBlockerData = wrappedWindow.matchMedia(extensionSecret[0]);
if (canvasBlockerData.secret === extensionSecret[1]){
if (wrappedWindow.top === wrappedWindow){
canvasBlockerData.undoIntercept(extension.extensionID);
}
else {
interceptedWindows.set(wrappedWindow, true);
return false;
}
}
logging.message("intercepting window", window);
@ -168,17 +173,28 @@
const matchMediaDescriptor = Object.getOwnPropertyDescriptor(wrappedWindow, "matchMedia");
const originalMatchMedia = matchMediaDescriptor.value;
matchMediaDescriptor.value = extension.exportFunctionWithName(function matchMedia(query){
if (query === extensionSecret[0]){
return extensionSecret[1];
}
else {
return arguments.length > 1?
originalMatchMedia.call(this, ...arguments):
originalMatchMedia.call(this, query);
}
}, window, originalMatchMedia.name);
Object.defineProperty(wrappedWindow, "matchMedia", matchMediaDescriptor);
extension.changeProperty(window, "matchMedia", {
object: wrappedWindow,
name: "matchMedia",
type: "value",
changed: extension.exportFunctionWithName(function matchMedia(query){
if (query === extensionSecret[0]){
return {
secret: extensionSecret[1],
undoIntercept: function(token){
if (token === extension.extensionID){
extension.revertProperties(window);
}
}
};
}
else {
return arguments.length > 1?
originalMatchMedia.call(this, ...arguments):
originalMatchMedia.call(this, query);
}
}, window, originalMatchMedia.name)
});
interceptedWindows.set(wrappedWindow, true);
return true;

View File

@ -27,23 +27,12 @@
if ((typeof changed) === "function"){
changed = extension.exportFunctionWithName(changed, window, original.name);
}
descriptor[type] = changed;
Object.defineProperty(object, name, descriptor);
registerChangedProperty(object, name, descriptor, type, original);
}
const changedProperties = [];
// eslint-disable-next-line max-params
function registerChangedProperty(object, name, descriptor, type, original){
changedProperties.push({object, name, descriptor, type, original});
extension.changeProperty(window, "iframeProtection", {object, name, type, changed});
}
if (settings.isStillDefault){
settings.onloaded(function(){
if (isWhitelisted(window.location)){
changedProperties.forEach(function({object, name, descriptor, type, original}){
descriptor[type] = original;
Object.defineProperty(object, name, descriptor);
});
changedProperties.length = 0;
extension.revertProperties(window, "iframeProtection");
}
});
}

View File

@ -331,21 +331,22 @@
});
const descriptor = Object.getOwnPropertyDescriptor(object, name);
if (!descriptor) return;
if (descriptor.hasOwnProperty("value")){
const type = descriptor.hasOwnProperty("value")? "value": "get";
let changed;
if (type ==="value"){
if (changedFunction.fakeGenerator){
descriptor.value = extension.exportFunctionWithName(
changed = extension.exportFunctionWithName(
changedFunction.fakeGenerator(checker, original, windowToProcess),
windowToProcess,
original.name
);
}
else {
descriptor.value = null;
changed = null;
}
}
else {
descriptor.get = extension.exportFunctionWithName(function(){
changed = extension.exportFunctionWithName(function(){
return extension.exportFunctionWithName(
changedFunction.fakeGenerator(checker),
windowToProcess,
@ -353,7 +354,9 @@
);
}, windowToProcess, descriptor.get.name);
}
Object.defineProperty(object, name, descriptor);
extension.changeProperty(windowToProcess, changedFunction.api, {
object, name, type, changed
});
});
});
}
@ -378,7 +381,12 @@
window: windowToProcess, prefs, checkStack, ask, notify
});
const getter = changedGetter.getterGenerator(checker, original, windowToProcess);
descriptor.get = extension.exportFunctionWithName(getter, windowToProcess, original.name);
extension.changeProperty(windowToProcess, changedGetter.api,
{
object, name, type: "get",
changed: extension.exportFunctionWithName(getter, windowToProcess, original.name)
}
);
if (descriptor.hasOwnProperty("set") && descriptor.set && changedGetter.setterGenerator){
const original = descriptor.set;
@ -387,10 +395,14 @@
original,
prefs
);
descriptor.set = extension.exportFunctionWithName(setter, windowToProcess, original.name);
extension.changeProperty(windowToProcess, changedGetter.api,
{
object, name, type: "set",
changed: extension.exportFunctionWithName(setter, windowToProcess, original.name)
}
);
}
Object.defineProperty(object, name, descriptor);
}
else if (
changedGetter.valueGenerator &&
@ -405,21 +417,23 @@
}
switch (functionStatus.mode){
case "ask": case "block": case "fake":
descriptor.value = changedGetter.valueGenerator({
mode: functionStatus.mode,
original: descriptor.value,
notify: function notifyCallback(messageId){
notify({
url: getURL(windowToProcess),
errorStack: (new Error()).stack,
messageId,
timestamp: new Date(),
functionName: name,
api: changedGetter.api
});
}
extension.changeProperty(windowToProcess, changedGetter.api, {
object, name, type: "value",
changed: changedGetter.valueGenerator({
mode: functionStatus.mode,
original: descriptor.value,
notify: function notifyCallback(messageId){
notify({
url: getURL(windowToProcess),
errorStack: (new Error()).stack,
messageId,
timestamp: new Date(),
functionName: name,
api: changedGetter.api
});
}
})
});
Object.defineProperty(object, name, descriptor);
break;
}
}

View File

@ -109,6 +109,10 @@
{
"version": "1.1Alpha20192001",
"update_link": "https://canvasblocker.kkapsner.de/versions/canvasblocker_beta-1.1Alpha20192001-an+fx.xpi"
},
{
"version": "1.1Alpha20192301",
"update_link": "https://canvasblocker.kkapsner.de/versions/canvasblocker_beta-1.1Alpha20192301-an+fx.xpi"
}
]
}