More efficient window.name persistence for tab-scoped permissions.
This commit is contained in:
parent
b60cbbd49e
commit
4f7d8579af
|
@ -102,7 +102,7 @@
|
||||||
let preamble = info ? `${marker} + ${JSON.stringify(JSON.stringify([info]))} + ${marker} + "," + ` : "";
|
let preamble = info ? `${marker} + ${JSON.stringify(JSON.stringify([info]))} + ${marker} + "," + ` : "";
|
||||||
await browser.tabs.executeScript(tabId, {
|
await browser.tabs.executeScript(tabId, {
|
||||||
code: `window.name = ${preamble}window.name.split(${marker} + ",").pop();`,
|
code: `window.name = ${preamble}window.name.split(${marker} + ",").pop();`,
|
||||||
allFrames: false,
|
allFrames: true,
|
||||||
matchAboutBlank: true,
|
matchAboutBlank: true,
|
||||||
runAt: "document_start",
|
runAt: "document_start",
|
||||||
});
|
});
|
||||||
|
|
|
@ -317,6 +317,10 @@ var RequestGuard = (() => {
|
||||||
await ChildPolicies.update(policy);
|
await ChildPolicies.update(policy);
|
||||||
}
|
}
|
||||||
capabilities = perms.capabilities;
|
capabilities = perms.capabilities;
|
||||||
|
} else {
|
||||||
|
if (!isMainFrame && type === "sub_frame") {
|
||||||
|
await Settings.enforceTabRestrictions(tabId);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if (isMainFrame && !TabStatus.map.has(tabId)) {
|
if (isMainFrame && !TabStatus.map.has(tabId)) {
|
||||||
debug("No TabStatus data yet for noscriptFrame", tabId);
|
debug("No TabStatus data yet for noscriptFrame", tabId);
|
||||||
|
|
|
@ -90,7 +90,7 @@ var Settings = {
|
||||||
|
|
||||||
if (typeof unrestrictedTab === "boolean") {
|
if (typeof unrestrictedTab === "boolean") {
|
||||||
ns.unrestrictedTabs[unrestrictedTab ? "add" : "delete"](tabId);
|
ns.unrestrictedTabs[unrestrictedTab ? "add" : "delete"](tabId);
|
||||||
ChildPolicies.storeTabInfo(tabId, unrestrictedTab && {unrestricted: true});
|
this.enforceTabRestrictions(tabId, unrestrictedTab);
|
||||||
}
|
}
|
||||||
if (reloadAffected) {
|
if (reloadAffected) {
|
||||||
browser.tabs.reload(tabId);
|
browser.tabs.reload(tabId);
|
||||||
|
@ -123,4 +123,8 @@ var Settings = {
|
||||||
}, null, 2);
|
}, null, 2);
|
||||||
},
|
},
|
||||||
|
|
||||||
|
async enforceTabRestrictions(tabId, unrestricted = ns.unrestrictedTabs.has(tabId)) {
|
||||||
|
await ChildPolicies.storeTabInfo(tabId, unrestricted && {unrestricted: true});
|
||||||
|
return unrestricted;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -38,33 +38,40 @@
|
||||||
if(!this.config.CURRENT) this.config.CURRENT = DEFAULT;
|
if(!this.config.CURRENT) this.config.CURRENT = DEFAULT;
|
||||||
|
|
||||||
// ugly hack: since now we use registerContentScript instead of the
|
// ugly hack: since now we use registerContentScript instead of the
|
||||||
// filterRequest dynamic script injection hack, we use top.name
|
// filterRequest dynamic script injection hack, we use window.name
|
||||||
// to store per-tab information. We don't want web content to
|
// to store per-tab information. We don't want web content to
|
||||||
// mess with it, though, so we wrap it around auto-hiding accessors
|
// mess with it, though, so we wrap it around auto-hiding accessors
|
||||||
this.config.MARKER = MARKER;
|
|
||||||
let eraseTabInfoRx = new RegExp(`[^]*${MARKER},?`);
|
|
||||||
if (eraseTabInfoRx.test(top.name)) {
|
|
||||||
let _name = top.name;
|
|
||||||
let tabInfoRx = new RegExp(`^${MARKER}\\[([^]*?)\\]${MARKER},`);
|
|
||||||
if (top === window) { // wrap to hide
|
|
||||||
Reflect.defineProperty(top.wrappedJSObject, "name", {
|
|
||||||
get: exportFunction(() => top.name.replace(eraseTabInfoRx, ""), top.wrappedJSObject),
|
|
||||||
set: exportFunction(value => {
|
|
||||||
let preamble = top.name.match(tabInfoRx);
|
|
||||||
top.name = `${preamble && preamble[0] || ""}${value}`;
|
|
||||||
return value;
|
|
||||||
}, top.wrappedJSObject)
|
|
||||||
});
|
|
||||||
}
|
|
||||||
let tabInfoMatch = _name.match(tabInfoRx);
|
|
||||||
if (tabInfoMatch) try {
|
|
||||||
this.config.tabInfo = JSON.parse(tabInfoMatch[1]);
|
|
||||||
} catch (e) {
|
|
||||||
error(e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
if (this.config.MARKER = MARKER) {
|
||||||
|
|
||||||
|
let tabInfoRx = new RegExp(`^${MARKER}\\[([^]*?)\\]${MARKER},`);
|
||||||
|
let name = window.name;
|
||||||
|
try {
|
||||||
|
name = top.name;
|
||||||
|
} catch(e) {
|
||||||
|
// won't work cross-origin
|
||||||
|
}
|
||||||
|
let tabInfoMatch = name.match(tabInfoRx);
|
||||||
|
if (tabInfoMatch) {
|
||||||
|
try {
|
||||||
|
this.config.tabInfo = JSON.parse(tabInfoMatch[1]);
|
||||||
|
} catch (e) {
|
||||||
|
error(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
let splitter = `${MARKER},`;
|
||||||
|
this.getWindowName = () => window.name.split(splitter).pop();
|
||||||
|
Reflect.defineProperty(window.wrappedJSObject, "name", {
|
||||||
|
get: exportFunction(() => this.getWindowName(), window.wrappedJSObject),
|
||||||
|
set: exportFunction(value => {
|
||||||
|
let tabInfoMatch = window.name.match(tabInfoRx);
|
||||||
|
window.name = tabInfoMatch ? `${tabInfoMatch[0]}${value}` : value;
|
||||||
|
return value;
|
||||||
|
}, window.wrappedJSObject)
|
||||||
|
});
|
||||||
|
}
|
||||||
if (!this.config.DEFAULT || this.config.tabInfo.unrestricted) {
|
if (!this.config.DEFAULT || this.config.tabInfo.unrestricted) {
|
||||||
|
debug("%s is loading unrestricted by user's choice (%o).", document.URL, this.config);
|
||||||
this.allows = () => true;
|
this.allows = () => true;
|
||||||
this.capabilities = Object.assign(
|
this.capabilities = Object.assign(
|
||||||
new Set(["script"]), { has() { return true; } });
|
new Set(["script"]), { has() { return true; } });
|
||||||
|
@ -84,10 +91,7 @@
|
||||||
},
|
},
|
||||||
|
|
||||||
getWindowName() {
|
getWindowName() {
|
||||||
let marker = this.config.MARKER;
|
return window.name;
|
||||||
return (top === window && marker) ?
|
|
||||||
window.name.split(`${marker},`).pop()
|
|
||||||
: window.name;
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue