Work-around for onload not being fired on XML documents in Tor Browser/ESR60.

This commit is contained in:
hackademix 2018-07-06 04:01:44 +02:00
parent 799d99bd10
commit 093b9d724e
2 changed files with 41 additions and 27 deletions

View File

@ -355,10 +355,11 @@ var RequestGuard = (() => {
async onHeadersReceived(request) { async onHeadersReceived(request) {
// called for main_frame, sub_frame and object // called for main_frame, sub_frame and object
debug("onHeadersReceived", request); debug("onHeadersReceived", request);
let {url, documentUrl, statusCode, tabId, responseHeaders} = request;
if (statusCode >= 300 && statusCode < 400) return;
try { try {
let header, blocker; let header, blocker;
let responseHeaders = request.responseHeaders;
let content = {} let content = {}
for (let h of responseHeaders) { for (let h of responseHeaders) {
if (CSP.isMine(h)) { if (CSP.isMine(h)) {
@ -370,11 +371,11 @@ var RequestGuard = (() => {
} }
if (ns.isEnforced(request.tabId)) { if (ns.isEnforced(tabId)) {
let policy = ns.policy; let policy = ns.policy;
let perms = policy.get(request.url, request.documentUrl).perms; let perms = policy.get(url, documentUrl).perms;
if (policy.autoAllowTop && request.frameId === 0 && perms === policy.DEFAULT) { if (policy.autoAllowTop && request.frameId === 0 && perms === policy.DEFAULT) {
policy.set(Sites.optimalKey(request.url), perms = policy.TRUSTED.tempTwin); policy.set(Sites.optimalKey(url), perms = policy.TRUSTED.tempTwin);
} }
let {capabilities} = perms; let {capabilities} = perms;
@ -422,7 +423,7 @@ var RequestGuard = (() => {
} }
} }
debug(`CSP blocker on %s:`, request.url, blocker); debug(`CSP blocker on %s:`, url, blocker);
if (blocker) { if (blocker) {
if (header) { if (header) {
header.value = CSP.inject(header.value, blocker); header.value = CSP.inject(header.value, blocker);

View File

@ -1,6 +1,8 @@
'use strict'; 'use strict';
{ {
let NULL = new Uint8Array();
let pendingRequests = new Map(); let pendingRequests = new Map();
let cleanup = r => { let cleanup = r => {
pendingRequests.delete(r.requestId); pendingRequests.delete(r.requestId);
}; };
@ -10,6 +12,24 @@
}; };
browser.webRequest.onCompleted.addListener(cleanup, filter); browser.webRequest.onCompleted.addListener(cleanup, filter);
browser.webRequest.onErrorOccurred.addListener(cleanup, filter); browser.webRequest.onErrorOccurred.addListener(cleanup, filter);
let executeAll = async (scripts, where) => {
let {url, tabId, frameId} = where;
for (let details of scripts.values()) {
details = Object.assign({
runAt: "document_start",
matchAboutBlank: true,
frameId,
}, details);
try {
await browser.tabs.executeScript(tabId, details);
debug("Execute on start OK", url, details);
} catch (e) {
error(e, "Execute on start failed", url, details);
}
}
};
var RequestUtil = { var RequestUtil = {
getContentMetaData(request) { getContentMetaData(request) {
@ -25,7 +45,8 @@
}, },
async executeOnStart(request, details) { async executeOnStart(request, details) {
let {requestId, tabId, frameId} = request; let {requestId, tabId, frameId, statusCode} = request;
if (statusCode >= 300 && statusCode < 400) return;
let scripts = pendingRequests.get(requestId); let scripts = pendingRequests.get(requestId);
let scriptKey = JSON.stringify(details); let scriptKey = JSON.stringify(details);
if (!scripts) { if (!scripts) {
@ -36,23 +57,15 @@
return; return;
} }
let content = this.getContentMetaData(request);
debug(request.url, content.type);
if (/\bxml\b/.test(content.type) && !/\bhtml\b/.test(content.type)) return;
let filter = browser.webRequest.filterResponseData(requestId); let filter = browser.webRequest.filterResponseData(requestId);
let buffer = []; let buffer = [];
let content = this.getContentMetaData(request);
let first = true; let first = true;
let execute = async () => { let runAndFlush = async () => {
for (let details of scripts.values()) { await executeAll(scripts, request);
details = Object.assign({
runAt: "document_start",
frameId,
}, details);
try {
await browser.tabs.executeScript(tabId, details);
debug("Execute on start OK", request.url, details);
} catch (e) {
error(e, "Execute on start failed", request.url, details);
}
}
if (buffer.length) { if (buffer.length) {
debug("Flushing %s buffer chunks", buffer.length); debug("Flushing %s buffer chunks", buffer.length);
for (let chunk of buffer) { for (let chunk of buffer) {
@ -62,24 +75,24 @@
buffer = null; buffer = null;
} }
}; };
filter.onstart = event => { filter.onstart = event => {
if (/ml$/i.test(content.type)) { filter.write(NULL);
filter.write(new Uint8Array()); // work-around for https://bugzilla.mozilla.org/show_bug.cgi?id=1410755
}
}
filter.ondata = event => {
if (first) {
execute();
first = false;
} }
filter.ondata = event => {
if (first) {
runAndFlush();
first = false;
}
if (buffer) { if (buffer) {
buffer.push(event.data); buffer.push(event.data);
return; return;
} }
filter.write(event.data); filter.write(event.data);
filter.disconnect(); filter.disconnect();
} };
} }
} }
} }