| Index: lib/contentPolicy.js |
| =================================================================== |
| --- a/lib/contentPolicy.js |
| +++ b/lib/contentPolicy.js |
| @@ -162,37 +162,18 @@ |
| let wndLocation = originWindow.location.href; |
| let docDomain = getHostname(wndLocation); |
| let match = null; |
| + let [sitekey, sitekeyWnd] = getSitekey(wnd); |
| if (!match && Prefs.enabled) |
| { |
| let testWnd = wnd; |
| + let testSitekey = sitekey; |
| + let testSitekeyWnd = sitekeyWnd; |
| 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; |
| - } |
| - } |
| - } |
| + match = Policy.isWhitelisted(testWndLocation, parentWndLocation, testSitekey); |
| if (match instanceof WhitelistFilter) |
| { |
| @@ -203,8 +184,10 @@ |
| if (testWnd.parent == testWnd) |
| break; |
| - else |
| - testWnd = testWnd.parent; |
| + |
| + if (testWnd == testSitekeyWnd) |
| + [testSitekey, testSitekeyWnd] = getSitekey(testWnd.parent); |
| + testWnd = testWnd.parent; |
| } |
| } |
| @@ -260,7 +243,7 @@ |
| if (!match && Prefs.enabled) |
| { |
| - match = defaultMatcher.matchesAny(locationText, Policy.typeDescr[contentType] || "", docDomain, thirdParty); |
| + match = defaultMatcher.matchesAny(locationText, Policy.typeDescr[contentType] || "", docDomain, thirdParty, sitekey); |
| if (match instanceof BlockingFilter && node.ownerDocument && !(contentType in Policy.nonVisual)) |
| { |
| let prefCollapse = (match.collapse != null ? match.collapse : !Prefs.fastcollapse); |
| @@ -298,9 +281,10 @@ |
| * Checks whether a page is whitelisted. |
| * @param {String} url |
| * @param {String} [parentUrl] location of the parent page |
| + * @param {String} [sitekey] public key provided on the page |
| * @return {Filter} filter that matched the URL or null if not whitelisted |
| */ |
| - isWhitelisted: function(url, parentUrl) |
| + isWhitelisted: function(url, parentUrl, sitekey) |
| { |
| if (!url) |
| return null; |
| @@ -318,12 +302,12 @@ |
| if (index >= 0) |
| url = url.substring(0, index); |
| - let result = defaultMatcher.matchesAny(url, "DOCUMENT", getHostname(parentUrl), false); |
| + let result = defaultMatcher.matchesAny(url, "DOCUMENT", getHostname(parentUrl), false, sitekey); |
| return (result instanceof WhitelistFilter ? result : null); |
| }, |
| /** |
| - * Checks whether the page loaded in a window is whitelisted. |
| + * Checks whether the page loaded in a window is whitelisted for indication in the UI. |
| * @param wnd {nsIDOMWindow} |
| * @return {Filter} matching exception rule or null if not whitelisted |
| */ |
| @@ -332,7 +316,6 @@ |
| return Policy.isWhitelisted(getWindowLocation(wnd)); |
| }, |
| - |
| /** |
| * Asynchronously re-checks filters for given nodes. |
| */ |
| @@ -691,6 +674,47 @@ |
| } |
| /** |
| + * Retrieves the sitekey of a window. |
| + */ |
| +function getSitekey(wnd) |
| +{ |
| + let sitekey = null; |
| + |
| + while (true) |
| + { |
| + if (wnd.document && wnd.document.documentElement) |
| + { |
| + let keydata = wnd.document.documentElement.getAttribute("data-adblockkey"); |
| + if (keydata && keydata.indexOf("_") >= 0) |
| + { |
| + let [key, signature] = keydata.split("_", 2); |
| + key = key.replace(/=/g, ""); |
| + |
| + // Website specifies a key but is the signature valid? |
| + let uri = Services.io.newURI(getWindowLocation(wnd), 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, wnd]; |
| + } |
| + } |
| + |
| + if (wnd === wnd.parent) |
| + break; |
| + |
| + wnd = wnd.parent; |
| + } |
| + |
| + return [sitekey, wnd]; |
| +} |
| + |
| +/** |
| * Retrieves the location of a window. |
| * @param wnd {nsIDOMWindow} |
| * @return {String} window location or null on failure |