summaryrefslogtreecommitdiff
path: root/src/legacy/Legacy.js
diff options
context:
space:
mode:
authorhackademix2018-07-01 01:01:23 +0200
committerhackademix2018-07-01 01:01:23 +0200
commiteceae7187a6f0e9510bc1165f6977256b87f490f (patch)
treed943f1ec73c09efa70954dcedb55eac82a726148 /src/legacy/Legacy.js
downloadnoscript-eceae7187a6f0e9510bc1165f6977256b87f490f.tar.gz
noscript-eceae7187a6f0e9510bc1165f6977256b87f490f.tar.xz
noscript-eceae7187a6f0e9510bc1165f6977256b87f490f.zip
Initial commit starting at version 10.1.8.3rc4.
Diffstat (limited to 'src/legacy/Legacy.js')
-rw-r--r--src/legacy/Legacy.js147
1 files changed, 147 insertions, 0 deletions
diff --git a/src/legacy/Legacy.js b/src/legacy/Legacy.js
new file mode 100644
index 0000000..aeb0762
--- /dev/null
+++ b/src/legacy/Legacy.js
@@ -0,0 +1,147 @@
+'use strict';
+
+var Legacy = {
+
+ async init() {
+ let migrated = (await browser.storage.local.get("legacyBackup")).legacyBackup;
+ let real = await this.import(migrated);
+ this.init = async () => real;
+ return real;
+ },
+
+ async import(migrated) {
+ if (this.migrated) this.undo = this.migrated;
+ this.migrated = (migrated && migrated.prefs) ? migrated : {prefs: {}};
+ await include("/legacy/defaults.js");
+ return 'whitelist' in this.migrated; // "real" migration with custom policy
+ },
+
+ async persist() {
+ await browser.storage.local.set({legacyBackup: this.migrated});
+ },
+
+ getPref(name, def) {
+ return name in this.migrated.prefs ? this.migrated.prefs[name] : def;
+ },
+
+ getRxPref(name, parseRx = Legacy.RX.multi, flags, def) {
+ let source = this.getPref(name, def);
+ if (source instanceof RegExp) return source;
+ try {
+ return parseRx(source, flags);
+ } catch (e) {
+ error(e, "Parsing RegExp preference %s, falling back to %s", name, def);
+ if (def) {
+ if (def instanceof RegExp) {
+ return def;
+ }
+ try {
+ return parseRx(def, flags);
+ } catch(e) {
+ error(e);
+ }
+ }
+ }
+ return null;
+ },
+
+ async createOrMigratePolicy() {
+ try {
+ if (await this.init()) {
+ return this.migratePolicy();
+ }
+ } catch (e) {
+ error(e);
+ }
+ return new Policy();
+ },
+
+ extractLists(lists) {
+ return lists.map(listString => listString.split(/\s+/))
+ .map(sites => sites.filter(s => !(s.includes(":") &&
+ sites.includes(s.replace(/.*:\/*(?=\w)/g, ""))
+ )));
+ },
+
+ migratePolicy() {
+ // here we normalize both NS whitelist and blacklist, getting finally rid of
+ // the legacy of CAPS mandating protocols for top-level domains
+ let [trusted, untrusted] = this.extractLists(
+ [this.migrated.whitelist, this.getPref("untrusted", "")]);
+
+ // securify default whitelist domain items
+ if (this.getPref("httpsDefWhitelist")) {
+ this.getPref("default", "").
+ split(/\s+/).
+ filter(s => !s.includes(":")).
+ forEach(s => {
+ let idx = trusted.indexOf(s);
+ if (idx !== -1) {
+ trusted[idx] = Sites.secureDomainKey(s);
+ }
+ });
+ }
+
+ let DEFAULT = new Permissions(["other"]);
+ let {capabilities} = DEFAULT;
+ // let's semplify object permissions now that almost everything is
+ // either blacklisted or C2P by the browser
+ if (!["Java", "Flash", "Silverlight", "Plugins"]
+ .find(type => this.getPref(`forbid${type}`))) {
+ capabilities.add("object");
+ }
+
+ let prefMap = {
+ "Fonts": "font",
+ "Frames": "frame",
+ "IFrames": "frame",
+ "Media": "media",
+ "WebGL": "webgl",
+ };
+ for (let [legacy, current] of Object.entries(prefMap)) {
+ if (!this.getPref(`forbid${legacy}`, true)) capabilities.add(current);
+ }
+
+ let TRUSTED = new Permissions(new Set(this.getPref("contentBlocker") ? capabilities : Permissions.ALL));
+ TRUSTED.capabilities.add("script").add("fetch");
+
+ let UNTRUSTED = new Permissions();
+ if (this.getPref("global")) {
+ if (!this.getPref("alwaysBlockUntrustedContent")) {
+ UNTRUSTED.capabilities = new Set(capabilities);
+ }
+ DEFAULT = new Permissions(TRUSTED.capabilities);
+ }
+
+ return new Policy({
+ sites: {untrusted, trusted, custom: {}},
+ DEFAULT,
+ TRUSTED,
+ UNTRUSTED,
+ enforced: true,
+ // TODO: enforce these before ESR 59 gets released
+ cascadePermissions: this.getPref("cascadePermissions"),
+ restrictSubDocScripting: this.getPref("restrictSubDocScripting"),
+ onlySecure: this.getPref("allowHttpsOnly")
+ });
+
+ },
+
+ RX: {
+ simple: function(s, flags) {
+ var anchor = /\^/.test(flags);
+ return new RegExp(anchor ? rxParsers.anchor(s) : s,
+ anchor ? flags.replace(/\^/g, '') : flags);
+ },
+ anchor: function(s) {
+ return /^\^|\$$/.test(s) ? s : "^" + s + "$";
+ },
+ multi: function(s, flags) {
+ var anchor = /\^/.test(flags);
+ var lines = s.split(anchor ? /\s+/ : /[\n\r]+/).filter(l => /\S/.test(l));
+ return new RegExp((anchor ? lines.map(rxParsers.anchor) : lines).join('|'),
+ anchor ? flags.replace(/\^/g, '') : flags);
+ }
+ }
+}
+Legacy.init();