| Index: lib/contentPolicy.js |
| =================================================================== |
| --- a/lib/contentPolicy.js |
| +++ b/lib/contentPolicy.js |
| @@ -139,90 +139,109 @@ let Policy = exports.Policy = |
| Utils.styleService.unregisterSheet(collapseStyle, Ci.nsIStyleSheetService.USER_SHEET); |
| }) |
| TimeLine.log("done registering stylesheet"); |
| TimeLine.leave("Done initializing content policy"); |
| }, |
| /** |
| + * Checks whether a window or its parent is whitelisted or has a valid site-key. |
| + * @param wnd {nsIDOMWindow} |
| + */ |
| + shouldNeverBlockWindow: 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; |
| + } |
| + } |
| + } |
| + |
| + 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.shouldNeverBlockWindow(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); |