Fixed externally handled resources opened in popups being broken by dynamic script injection.

This commit is contained in:
hackademix 2018-07-20 23:35:43 +02:00
parent 570cf0456c
commit 163467f82b
2 changed files with 37 additions and 20 deletions

View File

@ -367,7 +367,7 @@ var RequestGuard = (() => {
header = h; header = h;
h.value = CSP.inject(h.value, ""); h.value = CSP.inject(h.value, "");
} else if (/^\s*Content-(Type|Disposition)\s*$/i.test(h.name)) { } else if (/^\s*Content-(Type|Disposition)\s*$/i.test(h.name)) {
content[h.name.split("-")[1].trim().toLowerCase()] = h.value; content[RegExp.$1.toLowerCase()] = h.value;
} }
} }

View File

@ -16,17 +16,12 @@
reloadingTabs.delete(key); reloadingTabs.delete(key);
} }
}; };
let filter = {
urls: ["<all_urls>"], let executeAll = async request => {
types: ["main_frame", "sub_frame", "object"] let {url, tabId, frameId, requestId} = request;
}; let scripts = pendingRequests.get(requestId);
if (!scripts) return -1;
for (let event of ["onCompleted", "onErrorOccurred"]) pendingRequests.delete(requestId);
browser.webRequest[event].addListener(cleanup, filter);
let executeAll = async (scripts, where) => {
let {url, tabId, frameId} = where;
let count = 0; let count = 0;
for (let details of scripts.values()) { for (let details of scripts.values()) {
details = Object.assign({ details = Object.assign({
@ -44,7 +39,20 @@
} }
return count; return count;
}; };
{
let filter = {
urls: ["<all_urls>"],
types: ["main_frame", "sub_frame", "object"]
};
let wr = browser.webRequest;
for (let event of ["onCompleted", "onErrorOccurred"])
wr[event].addListener(cleanup, filter);
filter.types = ["main_frame"];
wr.onResponseStarted.addListener(executeAll, filter);
}
var RequestUtil = { var RequestUtil = {
getResponseMetaData(request) { getResponseMetaData(request) {
@ -66,11 +74,13 @@
let response = this.getResponseMetaData(request); let response = this.getResponseMetaData(request);
let {contentType, contentDisposition} = response; let {contentType, contentDisposition} = response;
if (contentDisposition) { if (contentDisposition ||
debug("Skipping execute on start of %s %o", url, response); xmlFeedOrImage.test(contentType) && !/\/svg\b/i.test(contentType)) {
debug("Skipping execute on start of %s %o.", url, response);
return; return;
} }
debug("Injecting script on start in %s (%o)", url, response);
debug("Injecting script on start in %s (%o).", url, response);
let scripts = pendingRequests.get(requestId); let scripts = pendingRequests.get(requestId);
let scriptKey = JSON.stringify(details); let scriptKey = JSON.stringify(details);
@ -81,12 +91,18 @@
scripts.set(scriptKey, details); scripts.set(scriptKey, details);
return; return;
} }
if (xmlFeedOrImage.test(contentType) && !/\/svg\b/i.test(contentType)) return; if (request.type === "main_frame"
&& /^(?:application|text)\//.test(contentType)
&& !/[^;]+\b(html|xml)\b/i.test(contentType)) {
debug("Not HTML, but top-level document: defer script to onResponseStarted for %s (%o)", url, response);
return;
}
if (typeof brokenXMLOnLoad === "undefined") { if (typeof brokenXMLOnLoad === "undefined") {
brokenXMLOnLoad = await (async () => parseInt((await browser.runtime.getBrowserInfo()).version) < 61)(); brokenXMLOnLoad = await (async () => parseInt((await browser.runtime.getBrowserInfo()).version) < 61)();
} }
let mustCheckFeed = brokenXMLOnLoad && frameId === 0 && rawXml.test(contentType); let mustCheckFeed = brokenXMLOnLoad && frameId === 0 && rawXml.test(contentType);
debug("mustCheckFeed = %s, brokenXMLOnLoad = %s", mustCheckFeed, brokenXMLOnLoad); debug("mustCheckFeed = %s, brokenXMLOnLoad = %s", mustCheckFeed, brokenXMLOnLoad);
let filter = browser.webRequest.filterResponseData(requestId); let filter = browser.webRequest.filterResponseData(requestId);
@ -95,7 +111,7 @@
let done = false; let done = false;
let mustReload = false; let mustReload = false;
let runAndFlush = async () => { let runAndFlush = async () => {
let scriptsRan = await executeAll(scripts, request); let scriptsRan = await executeAll(request);
if (mustCheckFeed && !scriptsRan) { if (mustCheckFeed && !scriptsRan) {
mustReload = true; mustReload = true;
debug(`Marking as "must reload"`, tabId, url); debug(`Marking as "must reload"`, tabId, url);
@ -120,6 +136,7 @@
first = false; first = false;
} }
if (buffer) { if (buffer) {
debug("buffering", url);
buffer.push(event.data); buffer.push(event.data);
return; return;
} }