| Index: lib/contentPolicy.js |
| =================================================================== |
| --- a/lib/contentPolicy.js |
| +++ b/lib/contentPolicy.js |
| @@ -25,17 +25,16 @@ Cu.import("resource://gre/modules/Servic |
| let {TimeLine} = require("timeline"); |
| let {Utils} = require("utils"); |
| let {Prefs} = require("prefs"); |
| let {FilterStorage} = require("filterStorage"); |
| let {BlockingFilter, WhitelistFilter} = require("filterClasses"); |
| let {defaultMatcher} = require("matcher"); |
| let {objectMouseEventHander} = require("objectTabs"); |
| let {RequestNotifier} = require("requestNotifier"); |
| -let {ElemHide} = require("elemHide"); |
| /** |
| * List of explicitly supported content types |
| * @type Array of String |
| */ |
| let contentTypes = ["OTHER", "SCRIPT", "IMAGE", "STYLESHEET", "OBJECT", "SUBDOCUMENT", "DOCUMENT", "XMLHTTPREQUEST", "OBJECT_SUBREQUEST", "FONT", "MEDIA"]; |
| /** |
| @@ -138,91 +137,106 @@ let Policy = exports.Policy = |
| { |
| Utils.styleService.unregisterSheet(collapseStyle, Ci.nsIStyleSheetService.USER_SHEET); |
| }) |
| TimeLine.log("done registering stylesheet"); |
| TimeLine.leave("Done initializing content policy"); |
| }, |
| + processWindow: function(wnd) |
| + { |
| + let uri = wnd.document.documentURIObject; |
| + if (!uri) |
| + return true; |
| + |
| + if (!Policy.isBlockableScheme(uri.scheme)) |
| + return true; |
| + |
| + let topWnd = wnd.top; |
| + if (!topWnd || !topWnd.location || !topWnd.location.href) |
| + return true; |
| + |
| + let testWnd = wnd; |
| + let parentWndLocation = getWindowLocation(testWnd); |
| + while (true) |
| + { |
| + let testWndLocation = parentWndLocation; |
| + parentWndLocation = (testWnd == testWnd.parent ? testWndLocation : getWindowLocation(testWnd.parent)); |
| + |
| + let match = Policy.isWhitelisted(testWndLocation, parentWndLocation); |
| + |
| + if (match == null) |
| + { |
| + let keydata = (testWnd.document && testWnd.document.documentElement ? testWnd.document.documentElement.getAttribute("data-adblockkey") : null); |
| + if (keydata && keydata.indexOf("_") >= 0) |
| + { |
| + let [key, signature] = keydata.split("_", 2); |
| + let keyMatch = defaultMatcher.matchesByKey(testWndLocation, key.replace(/=/g, ""), docDomain); |
| + if (keyMatch && Utils.crypto) |
| + { |
| + // Website specifies a key that we know but is the signature valid? |
| + let uri = Services.io.newURI(testWndLocation, null, null); |
| + let params = [ |
| + uri.path.replace(/#.*/, ""), // REQUEST_URI |
| + uri.asciiHost, // HTTP_HOST |
| + Utils.httpProtocol.userAgent // HTTP_USER_AGENT |
| + ]; |
| + if (Utils.verifySignature(key, signature, params.join("\0"))) |
| + match = keyMatch; // XXX what is this? |
| + } |
| + } |
| + } |
| + |
| + if (match instanceof WhitelistFilter) |
| + { |
| + FilterStorage.increaseHitCount(match, wnd); |
| + RequestNotifier.addNodeData(testWnd.document, topWnd, Policy.type.DOCUMENT, getHostname(parentWndLocation), false, testWndLocation, match); |
| + return true; |
| + } |
| + |
| + if (testWnd.parent == testWnd) |
| + break; |
| + else |
| + testWnd = testWnd.parent; |
| + } |
| + |
| + return false; |
| + }, |
| + |
| /** |
| * Checks whether a node should be blocked, hides it if necessary |
| * @param wnd {nsIDOMWindow} |
| * @param node {nsIDOMElement} |
| * @param contentType {String} |
| * @param location {nsIURI} |
| * @param collapse {Boolean} true to force hiding of the node |
| * @return {Boolean} false if the node should be blocked |
| */ |
| processNode: function(wnd, node, contentType, location, collapse) |
| { |
| - let topWnd = wnd.top; |
| - if (!topWnd || !topWnd.location || !topWnd.location.href) |
| + if (Policy.processWindow(wnd)) |
| return true; |
| + let topWnd = wnd.top; |
| let originWindow = Utils.getOriginWindow(wnd); |
| let wndLocation = originWindow.location.href; |
| let docDomain = getHostname(wndLocation); |
| - let match = null; |
| - if (!match && Prefs.enabled) |
| - { |
| - let testWnd = wnd; |
| - let parentWndLocation = getWindowLocation(testWnd); |
| - while (true) |
| - { |
| - let testWndLocation = parentWndLocation; |
| - parentWndLocation = (testWnd == testWnd.parent ? testWndLocation : getWindowLocation(testWnd.parent)); |
| - match = Policy.isWhitelisted(testWndLocation, parentWndLocation); |
| - |
| - if (!(match instanceof WhitelistFilter)) |
| - { |
| - let keydata = (testWnd.document && testWnd.document.documentElement ? testWnd.document.documentElement.getAttribute("data-adblockkey") : null); |
| - if (keydata && keydata.indexOf("_") >= 0) |
| - { |
| - let [key, signature] = keydata.split("_", 2); |
| - let keyMatch = defaultMatcher.matchesByKey(testWndLocation, key.replace(/=/g, ""), docDomain); |
| - if (keyMatch && Utils.crypto) |
| - { |
| - // Website specifies a key that we know but is the signature valid? |
| - let uri = Services.io.newURI(testWndLocation, null, null); |
| - let params = [ |
| - uri.path.replace(/#.*/, ""), // REQUEST_URI |
| - uri.asciiHost, // HTTP_HOST |
| - Utils.httpProtocol.userAgent // HTTP_USER_AGENT |
| - ]; |
| - if (Utils.verifySignature(key, signature, params.join("\0"))) |
| - match = keyMatch; |
| - } |
| - } |
| - } |
| - |
| - if (match instanceof WhitelistFilter) |
| - { |
| - FilterStorage.increaseHitCount(match, wnd); |
| - RequestNotifier.addNodeData(testWnd.document, topWnd, Policy.type.DOCUMENT, getHostname(parentWndLocation), false, testWndLocation, match); |
| - return true; |
| - } |
| - |
| - if (testWnd.parent == testWnd) |
| - break; |
| - else |
| - testWnd = testWnd.parent; |
| - } |
| - } |
| // Data loaded by plugins should be attached to the document |
| if (contentType == Policy.type.OBJECT_SUBREQUEST && node instanceof Ci.nsIDOMElement) |
| node = node.ownerDocument; |
| // Fix type for objects misrepresented as frames or images |
| if (contentType != Policy.type.OBJECT && (node instanceof Ci.nsIDOMHTMLObjectElement || node instanceof Ci.nsIDOMHTMLEmbedElement)) |
| contentType = Policy.type.OBJECT; |
| let locationText = location.spec; |
| - if (!match && contentType == Policy.type.ELEMHIDE) |
| + let match = null; |
| + if (contentType == Policy.type.ELEMHIDE) |
| { |
| let testWnd = wnd; |
| let parentWndLocation = getWindowLocation(testWnd); |
| while (true) |
| { |
| let testWndLocation = parentWndLocation; |
| parentWndLocation = (testWnd == testWnd.parent ? testWndLocation : getWindowLocation(testWnd.parent)); |
| let parentDocDomain = getHostname(parentWndLocation); |
| @@ -242,16 +256,17 @@ let Policy = exports.Policy = |
| match = location; |
| locationText = match.text.replace(/^.*?#/, '#'); |
| location = locationText; |
| if (!match.isActiveOnDomain(docDomain)) |
| return true; |
| + let {ElemHide} = require("elemHide"); |
| let exception = ElemHide.getException(match, docDomain); |
| if (exception) |
| { |
| FilterStorage.increaseHitCount(exception, wnd); |
| RequestNotifier.addNodeData(node, topWnd, contentType, docDomain, thirdParty, locationText, exception); |
| return true; |
| } |
| } |