summaryrefslogtreecommitdiff
path: root/data/extensions/spyblock@gnu.org/lib/contentPolicy.js
diff options
context:
space:
mode:
Diffstat (limited to 'data/extensions/spyblock@gnu.org/lib/contentPolicy.js')
-rw-r--r--data/extensions/spyblock@gnu.org/lib/contentPolicy.js415
1 files changed, 0 insertions, 415 deletions
diff --git a/data/extensions/spyblock@gnu.org/lib/contentPolicy.js b/data/extensions/spyblock@gnu.org/lib/contentPolicy.js
deleted file mode 100644
index ad36655..0000000
--- a/data/extensions/spyblock@gnu.org/lib/contentPolicy.js
+++ /dev/null
@@ -1,415 +0,0 @@
-/*
- * This file is part of Adblock Plus <https://adblockplus.org/>,
- * Copyright (C) 2006-2017 eyeo GmbH
- *
- * Adblock Plus is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 3 as
- * published by the Free Software Foundation.
- *
- * Adblock Plus is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with Adblock Plus. If not, see <http://www.gnu.org/licenses/>.
- */
-
-/**
- * @fileOverview Content policy implementation, responsible for blocking things.
- */
-
-"use strict";
-
-let {XPCOMUtils} = Cu.import("resource://gre/modules/XPCOMUtils.jsm", {});
-let {Services} = Cu.import("resource://gre/modules/Services.jsm", {});
-
-let {Utils} = require("utils");
-let {port} = require("messaging");
-let {Prefs} = require("prefs");
-let {FilterStorage} = require("filterStorage");
-let {BlockingFilter, WhitelistFilter, RegExpFilter} = require("filterClasses");
-let {defaultMatcher} = require("matcher");
-
-/**
- * Public policy checking functions and auxiliary objects
- * @class
- */
-var Policy = exports.Policy =
-{
- /**
- * Map of content types reported by Firefox to the respecitve content types
- * used by Adblock Plus. Other content types are simply mapped to OTHER.
- * @type Map.<string,string>
- */
- contentTypes: new Map(function* ()
- {
- // Treat navigator.sendBeacon() the same as <a ping>,
- // it's essentially the same concept - merely generalized.
- yield ["BEACON", "PING"];
-
- // Treat <img srcset> and <picture> the same as other images.
- yield ["IMAGESET", "IMAGE"];
-
- // Treat fetch() the same as XMLHttpRequest,
- // it's essentially the same - merely a more modern API.
- yield ["FETCH", "XMLHTTPREQUEST"];
-
- // Everything else is mapped to itself
- for (let contentType of ["OTHER", "SCRIPT", "IMAGE", "STYLESHEET", "OBJECT",
- "SUBDOCUMENT", "DOCUMENT", "XMLHTTPREQUEST",
- "OBJECT_SUBREQUEST", "FONT", "MEDIA", "PING",
- "WEBSOCKET", "ELEMHIDE", "POPUP", "GENERICHIDE",
- "GENERICBLOCK"])
- yield [contentType, contentType];
- }()),
-
- /**
- * Set of content types that aren't associated with a visual document area
- * @type Set.<string>
- */
- nonVisualTypes: new Set([
- "SCRIPT", "STYLESHEET", "XMLHTTPREQUEST", "OBJECT_SUBREQUEST", "FONT",
- "PING", "WEBSOCKET", "ELEMHIDE", "POPUP", "GENERICHIDE", "GENERICBLOCK"
- ]),
-
- /**
- * Map containing all schemes that should be ignored by content policy.
- * @type Set.<string>
- */
- whitelistSchemes: new Set(),
-
- /**
- * Called on module startup, initializes various exported properties.
- */
- init: function()
- {
- // whitelisted URL schemes
- for (let scheme of Prefs.whitelistschemes.toLowerCase().split(" "))
- this.whitelistSchemes.add(scheme);
-
- port.on("shouldAllow", (message, sender) => this.shouldAllow(message));
-
- // Generate class identifier used to collapse nodes and register
- // corresponding stylesheet.
- let collapsedClass = "";
- let offset = "a".charCodeAt(0);
- for (let i = 0; i < 20; i++)
- collapsedClass += String.fromCharCode(offset + Math.random() * 26);
- port.on("getCollapsedClass", (message, sender) => collapsedClass);
-
- let collapseStyle = Services.io.newURI("data:text/css," +
- encodeURIComponent("." + collapsedClass +
- "{-moz-binding: url(chrome://global/content/bindings/general.xml#foobarbazdummy) !important;}"), null, null);
- Utils.styleService.loadAndRegisterSheet(collapseStyle, Ci.nsIStyleSheetService.USER_SHEET);
- onShutdown.add(() =>
- {
- Utils.styleService.unregisterSheet(collapseStyle, Ci.nsIStyleSheetService.USER_SHEET);
- });
- },
-
- /**
- * Checks whether a node should be blocked, hides it if necessary
- * @param {Object} data request data
- * @param {String} data.contentType
- * @param {String} data.location location of the request
- * @param {Object[]} data.frames
- * @param {Boolean} data.isPrivate true if the request belongs to a private browsing window
- * @return {Object} An object containing properties allow, collapse and hits
- * indicating how this request should be handled.
- */
- shouldAllow: function({contentType, location, frames, isPrivate})
- {
- let hits = [];
-
- function addHit(frameIndex, contentType, docDomain, thirdParty, location, filter)
- {
- if (filter && !isPrivate)
- FilterStorage.increaseHitCount(filter);
- hits.push({
- frameIndex, contentType, docDomain, thirdParty, location,
- filter: filter ? filter.text : null,
- filterType: filter ? filter.type : null
- });
- }
-
- function response(allow, collapse)
- {
- return {allow, collapse, hits};
- }
-
- // Ignore whitelisted schemes
- if (contentType != "POPUP" && !this.isBlockableScheme(location))
- return response(true, false);
-
- // Interpret unknown types as "other"
- contentType = this.contentTypes.get(contentType) || "OTHER";
-
- let nogeneric = false;
- if (Prefs.enabled)
- {
- let whitelistHit =
- this.isFrameWhitelisted(frames, false);
- if (whitelistHit)
- {
- let [frameIndex, matchType, docDomain, thirdParty, location, filter] = whitelistHit;
- addHit(frameIndex, matchType, docDomain, thirdParty, location, filter);
- if (matchType == "DOCUMENT")
- return response(true, false);
- else
- nogeneric = true;
- }
- }
-
- let match = null;
- let wndLocation = frames[0].location;
- let docDomain = getHostname(wndLocation);
- let [sitekey, sitekeyFrame] = getSitekey(frames);
-
- let thirdParty = isThirdParty(location, docDomain);
- let collapse = false;
-
- if (!match && Prefs.enabled && RegExpFilter.typeMap.hasOwnProperty(contentType))
- {
- match = defaultMatcher.matchesAny(location, RegExpFilter.typeMap[contentType],
- docDomain, thirdParty, sitekey, nogeneric, isPrivate);
- if (match instanceof BlockingFilter && !this.nonVisualTypes.has(contentType))
- collapse = (match.collapse != null ? match.collapse : !Prefs.fastcollapse);
- }
- addHit(null, contentType, docDomain, thirdParty, location, match);
-
- return response(!match || match instanceof WhitelistFilter, collapse);
- },
-
- /**
- * Checks whether the location's scheme is blockable.
- * @param location {nsIURI|String}
- * @return {Boolean}
- */
- isBlockableScheme: function(location)
- {
- let scheme;
- if (typeof location == "string")
- {
- let match = /^([\w\-]+):/.exec(location);
- scheme = match ? match[1] : null;
- }
- else
- scheme = location.scheme;
- return !this.whitelistSchemes.has(scheme);
- },
-
- /**
- * Checks whether a top-level window is whitelisted.
- * @param {String} url
- * URL of the document loaded into the window
- * @return {?WhitelistFilter}
- * exception rule that matched the URL if any
- */
- isWhitelisted: function(url)
- {
- if (!url)
- return null;
-
- // Do not apply exception rules to schemes on our whitelistschemes list.
- if (!this.isBlockableScheme(url))
- return null;
-
- // Ignore fragment identifier
- let index = url.indexOf("#");
- if (index >= 0)
- url = url.substring(0, index);
-
- let result = defaultMatcher.matchesAny(url, RegExpFilter.typeMap.DOCUMENT,
- getHostname(url), false, null);
- return (result instanceof WhitelistFilter ? result : null);
- },
-
- /**
- * Checks whether a frame is whitelisted.
- * @param {Array} frames
- * frame structure as returned by getFrames() in child/utils module.
- * @param {boolean} isElemHide
- * true if element hiding whitelisting should be considered
- * @return {?Array}
- * An array with the hit parameters: frameIndex, contentType, docDomain,
- * thirdParty, location, filter. Note that the filter could be a
- * genericblock/generichide exception rule. If nothing matched null is
- * returned.
- */
- isFrameWhitelisted: function(frames, isElemHide)
- {
- let [sitekey, sitekeyFrame] = getSitekey(frames);
- let nogenericHit = null;
-
- let typeMap = RegExpFilter.typeMap.DOCUMENT;
- if (isElemHide)
- typeMap = typeMap | RegExpFilter.typeMap.ELEMHIDE;
- let genericType = (isElemHide ? "GENERICHIDE" : "GENERICBLOCK");
-
- for (let i = 0; i < frames.length; i++)
- {
- let frame = frames[i];
- let wndLocation = frame.location;
- let parentWndLocation = frames[Math.min(i + 1, frames.length - 1)].location;
- let parentDocDomain = getHostname(parentWndLocation);
-
- let match = defaultMatcher.matchesAny(wndLocation, typeMap, parentDocDomain, false, sitekey);
- if (match instanceof WhitelistFilter)
- {
- let whitelistType = (match.contentType & RegExpFilter.typeMap.DOCUMENT) ? "DOCUMENT" : "ELEMHIDE";
- return [i, whitelistType, parentDocDomain, false, wndLocation, match];
- }
-
- if (!nogenericHit)
- {
- match = defaultMatcher.matchesAny(wndLocation,
- RegExpFilter.typeMap[genericType], parentDocDomain, false, sitekey);
- if (match instanceof WhitelistFilter)
- nogenericHit = [i, genericType, parentDocDomain, false, wndLocation, match];
- }
-
- if (frame == sitekeyFrame)
- [sitekey, sitekeyFrame] = getSitekey(frames.slice(i + 1));
- }
-
- return nogenericHit;
- },
-
- /**
- * Deletes nodes that were previously stored with a
- * RequestNotifier.storeNodesForEntries() call or similar.
- * @param {string} id unique ID of the nodes
- */
- deleteNodes: function(id)
- {
- port.emit("deleteNodes", id);
- },
-
- /**
- * Asynchronously re-checks filters for nodes given by an ID previously
- * returned by a RequestNotifier.storeNodesForEntries() call or similar.
- * @param {string} id unique ID of the nodes
- * @param {RequestEntry} entry
- */
- refilterNodes: function(id, entry)
- {
- port.emit("refilterNodes", {
- nodesID: id,
- entry: entry
- });
- }
-};
-Policy.init();
-
-/**
- * Extracts the hostname from a URL (might return null).
- */
-function getHostname(/**String*/ url) /**String*/
-{
- try
- {
- return Utils.unwrapURL(url).host;
- }
- catch(e)
- {
- return null;
- }
-}
-
-/**
- * Retrieves and validates the sitekey for a frame structure.
- */
-function getSitekey(frames)
-{
- for (let frame of frames)
- {
- if (frame.sitekey && frame.sitekey.indexOf("_") >= 0)
- {
- let [key, signature] = frame.sitekey.split("_", 2);
- key = key.replace(/=/g, "");
-
- // Website specifies a key but is the signature valid?
- let uri = Services.io.newURI(frame.location, null, null);
- let host = uri.asciiHost;
- if (uri.port > 0)
- host += ":" + uri.port;
- let params = [
- uri.path.replace(/#.*/, ""), // REQUEST_URI
- host, // HTTP_HOST
- Utils.httpProtocol.userAgent // HTTP_USER_AGENT
- ];
- if (Utils.verifySignature(key, signature, params.join("\0")))
- return [key, frame];
- }
- }
-
- return [null, null];
-}
-
-/**
- * Retrieves the location of a window.
- * @param wnd {nsIDOMWindow}
- * @return {String} window location or null on failure
- */
-function getWindowLocation(wnd)
-{
- if ("name" in wnd && wnd.name == "messagepane")
- {
- // Thunderbird branch
- try
- {
- let mailWnd = wnd.QueryInterface(Ci.nsIInterfaceRequestor)
- .getInterface(Ci.nsIWebNavigation)
- .QueryInterface(Ci.nsIDocShellTreeItem)
- .rootTreeItem
- .QueryInterface(Ci.nsIInterfaceRequestor)
- .getInterface(Ci.nsIDOMWindow);
-
- // Typically we get a wrapped mail window here, need to unwrap
- try
- {
- mailWnd = mailWnd.wrappedJSObject;
- } catch(e) {}
-
- if ("currentHeaderData" in mailWnd && "content-base" in mailWnd.currentHeaderData)
- {
- return mailWnd.currentHeaderData["content-base"].headerValue;
- }
- else if ("currentHeaderData" in mailWnd && "from" in mailWnd.currentHeaderData)
- {
- let emailAddress = Utils.headerParser.extractHeaderAddressMailboxes(mailWnd.currentHeaderData.from.headerValue);
- if (emailAddress)
- return 'mailto:' + emailAddress.replace(/^[\s"]+/, "").replace(/[\s"]+$/, "").replace(/\s/g, '%20');
- }
- } catch(e) {}
- }
-
- // Firefox branch
- return wnd.location.href;
-}
-
-/**
- * Checks whether the location's origin is different from document's origin.
- */
-function isThirdParty(/**String*/location, /**String*/ docDomain) /**Boolean*/
-{
- if (!location || !docDomain)
- return true;
-
- let uri = Utils.makeURI(location);
- try
- {
- return Utils.effectiveTLD.getBaseDomain(uri) != Utils.effectiveTLD.getBaseDomainFromHost(docDomain);
- }
- catch (e)
- {
- // EffectiveTLDService throws on IP addresses, just compare the host name
- let host = "";
- try
- {
- host = uri.host;
- } catch (e) {}
- return host != docDomain;
- }
-}