More edge cases covered in dynamic script injection.

This commit is contained in:
hackademix 2018-07-26 19:33:46 +02:00
parent a8a6dd4c7b
commit d3cacf634f
4 changed files with 30 additions and 26 deletions

View File

@ -99,12 +99,14 @@ var RequestGuard = (() => {
} }
} }
let collection = records[what]; let collection = records[what];
if (type in collection) { if (collection) {
if (!collection[type].includes(requestKey)) { if (type in collection) {
collection[type].push(requestKey); if (!collection[type].includes(requestKey)) {
collection[type].push(requestKey);
}
} else {
collection[type] = [requestKey];
} }
} else {
collection[type] = [requestKey];
} }
return records; return records;
}, },
@ -425,12 +427,12 @@ var RequestGuard = (() => {
} }
if (!capabilities.has("media")) { if (!capabilities.has("media")) {
RequestUtil.executeOnStart(request, { RequestUtil.executeOnStart(request, {
code: "window.mediaBlocker = true;" code: "window.mediaBlocker = correctFrame();"
}); });
} }
RequestUtil.executeOnStart(request, { RequestUtil.executeOnStart(request, {
file: "content/media.js" file: "/content/media.js"
}); });
} else if (request.type === "main_frame" && !TabStatus.map.has(tabId)) { } else if (request.type === "main_frame" && !TabStatus.map.has(tabId)) {
debug("No TabStatus data yet for noscriptFrame", tabId); debug("No TabStatus data yet for noscriptFrame", tabId);

View File

@ -20,32 +20,39 @@
}; };
let executeAll = async request => { let executeAll = async request => {
let {url, tabId, frameId, requestId} = request; let {url, tabId, frameId, requestId, type} = request;
let scripts = pendingScripts.get(requestId); let scripts = pendingScripts.get(requestId);
if (!scripts) return -1; if (!scripts) return -1;
pendingScripts.delete(requestId); pendingScripts.delete(requestId);
let where = type === "object" ? {allFrames: true} : {frameId};
let count = 0; let count = 0;
await Promise.all([...scripts.values()].map(async details => { let run = async details => {
details = Object.assign({ details = Object.assign({
runAt: "document_start", runAt: "document_start",
matchAboutBlank: true, matchAboutBlank: true,
frameId, }, details, where);
}, details);
try { try {
let res;
for (let attempts = 10; attempts-- > 0;) { for (let attempts = 10; attempts-- > 0;) {
try { try {
await browser.tabs.executeScript(tabId, details); res = await browser.tabs.executeScript(tabId, details);
break;
} catch(e) { } catch(e) {
if (!/No matching message handler/.test(e.message)) throw e; if (!/No matching message handler/.test(e.message)) throw e;
debug("Couldn't inject script into %s: too early? Retrying up to %s times...", url, attempts); debug("Couldn't inject script into %s: too early? Retrying up to %s times...", url, attempts);
} }
} }
count++; count++;
debug("Execute on start OK", url, details); debug("Execute on start OK, result=%o", res, url, details);
} catch (e) { } catch (e) {
error(e, "Execute on start failed", url, details); error(e, "Execute on start failed", url, details);
} }
})); };
await run({code: `void(window.correctFrame = () => "${url}" === document.URL && document.readyState === "loading")`});
await Promise.all([...scripts.values()].map(run));
await run({code: `void(window.correctFrame = () => false)`});
return count; return count;
}; };
@ -59,7 +66,6 @@
wr[event].addListener(cleanup, filter); wr[event].addListener(cleanup, filter);
} }
filter.types = ["main_frame"];
wr.onResponseStarted.addListener(r => { wr.onResponseStarted.addListener(r => {
let scripts = pendingScripts.get(r.requestId); let scripts = pendingScripts.get(r.requestId);
if (scripts) scripts.runAndFlush(); if (scripts) scripts.runAndFlush();
@ -73,7 +79,7 @@
}, },
executeOnStart(request, details) { executeOnStart(request, details) {
let {requestId, url, tabId, frameId, statusCode} = request; let {requestId, url, tabId, frameId, statusCode, type} = request;
if (statusCode >= 300 && statusCode < 400) return; if (statusCode >= 300 && statusCode < 400) return;
if (frameId === 0) { if (frameId === 0) {

View File

@ -1,5 +1,5 @@
debug("Media Hook (blocked %s)", !!window.mediaBlocker, document.URL, document.documentElement && document.documentElement.innerHTML); if (correctFrame()) {
try { debug("Media Hook (blocked %s)", !!window.mediaBlocker, document.URL, document.documentElement && document.documentElement.innerHTML);
(() => { (() => {
let unpatched = new Map(); let unpatched = new Map();
function patch(obj, methodName, replacement) { function patch(obj, methodName, replacement) {
@ -56,6 +56,5 @@ try {
}); });
})(); })();
} catch (e) { document.URL;
error(e, "Cannot patch MediaSource");
} }

View File

@ -1,5 +1,5 @@
debug("WebGL Hook", document.URL, document.documentElement && document.documentElement.innerHTML); if (correctFrame()) {
try { debug("WebGL Hook", document.URL, document.documentElement && document.documentElement.innerHTML);
let proto = HTMLCanvasElement.prototype; let proto = HTMLCanvasElement.prototype;
let getContext = proto.getContext; let getContext = proto.getContext;
exportFunction(function(type, ...rest) { exportFunction(function(type, ...rest) {
@ -24,8 +24,5 @@ try {
} }
return getContext.call(this, type, ...rest); return getContext.call(this, type, ...rest);
}, proto, {defineAs: "getContext"}); }, proto, {defineAs: "getContext"});
} catch (e) { document.URL;
console.error(e);
} }
null;