| OLD | NEW |
| 1 /* | 1 /* |
| 2 * This file is part of Adblock Plus <http://adblockplus.org/>, | 2 * This file is part of Adblock Plus <http://adblockplus.org/>, |
| 3 * Copyright (C) 2006-2014 Eyeo GmbH | 3 * Copyright (C) 2006-2014 Eyeo GmbH |
| 4 * | 4 * |
| 5 * Adblock Plus is free software: you can redistribute it and/or modify | 5 * Adblock Plus is free software: you can redistribute it and/or modify |
| 6 * it under the terms of the GNU General Public License version 3 as | 6 * it under the terms of the GNU General Public License version 3 as |
| 7 * published by the Free Software Foundation. | 7 * published by the Free Software Foundation. |
| 8 * | 8 * |
| 9 * Adblock Plus is distributed in the hope that it will be useful, | 9 * Adblock Plus is distributed in the hope that it will be useful, |
| 10 * but WITHOUT ANY WARRANTY; without even the implied warranty of | 10 * but WITHOUT ANY WARRANTY; without even the implied warranty of |
| (...skipping 144 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 155 processNode: function(wnd, node, contentType, location, collapse) | 155 processNode: function(wnd, node, contentType, location, collapse) |
| 156 { | 156 { |
| 157 let topWnd = wnd.top; | 157 let topWnd = wnd.top; |
| 158 if (!topWnd || !topWnd.location || !topWnd.location.href) | 158 if (!topWnd || !topWnd.location || !topWnd.location.href) |
| 159 return true; | 159 return true; |
| 160 | 160 |
| 161 let originWindow = Utils.getOriginWindow(wnd); | 161 let originWindow = Utils.getOriginWindow(wnd); |
| 162 let wndLocation = originWindow.location.href; | 162 let wndLocation = originWindow.location.href; |
| 163 let docDomain = getHostname(wndLocation); | 163 let docDomain = getHostname(wndLocation); |
| 164 let match = null; | 164 let match = null; |
| 165 let [sitekey, sitekeyWnd] = getSitekey(wnd); |
| 165 if (!match && Prefs.enabled) | 166 if (!match && Prefs.enabled) |
| 166 { | 167 { |
| 167 let testWnd = wnd; | 168 let testWnd = wnd; |
| 169 let testSitekey = sitekey; |
| 170 let testSitekeyWnd = sitekeyWnd; |
| 168 let parentWndLocation = getWindowLocation(testWnd); | 171 let parentWndLocation = getWindowLocation(testWnd); |
| 169 while (true) | 172 while (true) |
| 170 { | 173 { |
| 171 let testWndLocation = parentWndLocation; | 174 let testWndLocation = parentWndLocation; |
| 172 parentWndLocation = (testWnd == testWnd.parent ? testWndLocation : getWi
ndowLocation(testWnd.parent)); | 175 parentWndLocation = (testWnd == testWnd.parent ? testWndLocation : getWi
ndowLocation(testWnd.parent)); |
| 173 match = Policy.isWhitelisted(testWndLocation, parentWndLocation); | 176 match = Policy.isWhitelisted(testWndLocation, parentWndLocation, testSit
ekey); |
| 174 | |
| 175 if (!(match instanceof WhitelistFilter)) | |
| 176 { | |
| 177 let keydata = (testWnd.document && testWnd.document.documentElement ?
testWnd.document.documentElement.getAttribute("data-adblockkey") : null); | |
| 178 if (keydata && keydata.indexOf("_") >= 0) | |
| 179 { | |
| 180 let [key, signature] = keydata.split("_", 2); | |
| 181 let keyMatch = defaultMatcher.matchesByKey(testWndLocation, key.repl
ace(/=/g, ""), docDomain); | |
| 182 if (keyMatch && Utils.crypto) | |
| 183 { | |
| 184 // Website specifies a key that we know but is the signature valid
? | |
| 185 let uri = Services.io.newURI(testWndLocation, null, null); | |
| 186 let params = [ | |
| 187 uri.path.replace(/#.*/, ""), // REQUEST_URI | |
| 188 uri.asciiHost, // HTTP_HOST | |
| 189 Utils.httpProtocol.userAgent // HTTP_USER_AGENT | |
| 190 ]; | |
| 191 if (Utils.verifySignature(key, signature, params.join("\0"))) | |
| 192 match = keyMatch; | |
| 193 } | |
| 194 } | |
| 195 } | |
| 196 | 177 |
| 197 if (match instanceof WhitelistFilter) | 178 if (match instanceof WhitelistFilter) |
| 198 { | 179 { |
| 199 FilterStorage.increaseHitCount(match, wnd); | 180 FilterStorage.increaseHitCount(match, wnd); |
| 200 RequestNotifier.addNodeData(testWnd.document, topWnd, Policy.type.DOCU
MENT, getHostname(parentWndLocation), false, testWndLocation, match); | 181 RequestNotifier.addNodeData(testWnd.document, topWnd, Policy.type.DOCU
MENT, getHostname(parentWndLocation), false, testWndLocation, match); |
| 201 return true; | 182 return true; |
| 202 } | 183 } |
| 203 | 184 |
| 204 if (testWnd.parent == testWnd) | 185 if (testWnd.parent == testWnd) |
| 205 break; | 186 break; |
| 206 else | 187 |
| 207 testWnd = testWnd.parent; | 188 if (testWnd == testSitekeyWnd) |
| 189 [testSitekey, testSitekeyWnd] = getSitekey(testWnd.parent); |
| 190 testWnd = testWnd.parent; |
| 208 } | 191 } |
| 209 } | 192 } |
| 210 | 193 |
| 211 // Data loaded by plugins should be attached to the document | 194 // Data loaded by plugins should be attached to the document |
| 212 if (contentType == Policy.type.OBJECT_SUBREQUEST && node instanceof Ci.nsIDO
MElement) | 195 if (contentType == Policy.type.OBJECT_SUBREQUEST && node instanceof Ci.nsIDO
MElement) |
| 213 node = node.ownerDocument; | 196 node = node.ownerDocument; |
| 214 | 197 |
| 215 // Fix type for objects misrepresented as frames or images | 198 // Fix type for objects misrepresented as frames or images |
| 216 if (contentType != Policy.type.OBJECT && (node instanceof Ci.nsIDOMHTMLObjec
tElement || node instanceof Ci.nsIDOMHTMLEmbedElement)) | 199 if (contentType != Policy.type.OBJECT && (node instanceof Ci.nsIDOMHTMLObjec
tElement || node instanceof Ci.nsIDOMHTMLEmbedElement)) |
| 217 contentType = Policy.type.OBJECT; | 200 contentType = Policy.type.OBJECT; |
| (...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 253 FilterStorage.increaseHitCount(exception, wnd); | 236 FilterStorage.increaseHitCount(exception, wnd); |
| 254 RequestNotifier.addNodeData(node, topWnd, contentType, docDomain, thirdP
arty, locationText, exception); | 237 RequestNotifier.addNodeData(node, topWnd, contentType, docDomain, thirdP
arty, locationText, exception); |
| 255 return true; | 238 return true; |
| 256 } | 239 } |
| 257 } | 240 } |
| 258 | 241 |
| 259 let thirdParty = (contentType == Policy.type.ELEMHIDE ? false : isThirdParty
(location, docDomain)); | 242 let thirdParty = (contentType == Policy.type.ELEMHIDE ? false : isThirdParty
(location, docDomain)); |
| 260 | 243 |
| 261 if (!match && Prefs.enabled) | 244 if (!match && Prefs.enabled) |
| 262 { | 245 { |
| 263 match = defaultMatcher.matchesAny(locationText, Policy.typeDescr[contentTy
pe] || "", docDomain, thirdParty); | 246 match = defaultMatcher.matchesAny(locationText, Policy.typeDescr[contentTy
pe] || "", docDomain, thirdParty, sitekey); |
| 264 if (match instanceof BlockingFilter && node.ownerDocument && !(contentType
in Policy.nonVisual)) | 247 if (match instanceof BlockingFilter && node.ownerDocument && !(contentType
in Policy.nonVisual)) |
| 265 { | 248 { |
| 266 let prefCollapse = (match.collapse != null ? match.collapse : !Prefs.fas
tcollapse); | 249 let prefCollapse = (match.collapse != null ? match.collapse : !Prefs.fas
tcollapse); |
| 267 if (collapse || prefCollapse) | 250 if (collapse || prefCollapse) |
| 268 schedulePostProcess(node); | 251 schedulePostProcess(node); |
| 269 } | 252 } |
| 270 | 253 |
| 271 // Track mouse events for objects | 254 // Track mouse events for objects |
| 272 if (!match && contentType == Policy.type.OBJECT && node.nodeType == Ci.nsI
DOMNode.ELEMENT_NODE) | 255 if (!match && contentType == Policy.type.OBJECT && node.nodeType == Ci.nsI
DOMNode.ELEMENT_NODE) |
| 273 { | 256 { |
| (...skipping 17 matching lines...) Expand all Loading... |
| 291 */ | 274 */ |
| 292 isBlockableScheme: function(location) | 275 isBlockableScheme: function(location) |
| 293 { | 276 { |
| 294 return !(location.scheme in Policy.whitelistSchemes); | 277 return !(location.scheme in Policy.whitelistSchemes); |
| 295 }, | 278 }, |
| 296 | 279 |
| 297 /** | 280 /** |
| 298 * Checks whether a page is whitelisted. | 281 * Checks whether a page is whitelisted. |
| 299 * @param {String} url | 282 * @param {String} url |
| 300 * @param {String} [parentUrl] location of the parent page | 283 * @param {String} [parentUrl] location of the parent page |
| 284 * @param {String} [sitekey] public key provided on the page |
| 301 * @return {Filter} filter that matched the URL or null if not whitelisted | 285 * @return {Filter} filter that matched the URL or null if not whitelisted |
| 302 */ | 286 */ |
| 303 isWhitelisted: function(url, parentUrl) | 287 isWhitelisted: function(url, parentUrl, sitekey) |
| 304 { | 288 { |
| 305 if (!url) | 289 if (!url) |
| 306 return null; | 290 return null; |
| 307 | 291 |
| 308 // Do not apply exception rules to schemes on our whitelistschemes list. | 292 // Do not apply exception rules to schemes on our whitelistschemes list. |
| 309 let match = /^([\w\-]+):/.exec(url); | 293 let match = /^([\w\-]+):/.exec(url); |
| 310 if (match && match[1] in Policy.whitelistSchemes) | 294 if (match && match[1] in Policy.whitelistSchemes) |
| 311 return null; | 295 return null; |
| 312 | 296 |
| 313 if (!parentUrl) | 297 if (!parentUrl) |
| 314 parentUrl = url; | 298 parentUrl = url; |
| 315 | 299 |
| 316 // Ignore fragment identifier | 300 // Ignore fragment identifier |
| 317 let index = url.indexOf("#"); | 301 let index = url.indexOf("#"); |
| 318 if (index >= 0) | 302 if (index >= 0) |
| 319 url = url.substring(0, index); | 303 url = url.substring(0, index); |
| 320 | 304 |
| 321 let result = defaultMatcher.matchesAny(url, "DOCUMENT", getHostname(parentUr
l), false); | 305 let result = defaultMatcher.matchesAny(url, "DOCUMENT", getHostname(parentUr
l), false, sitekey); |
| 322 return (result instanceof WhitelistFilter ? result : null); | 306 return (result instanceof WhitelistFilter ? result : null); |
| 323 }, | 307 }, |
| 324 | 308 |
| 325 /** | 309 /** |
| 326 * Checks whether the page loaded in a window is whitelisted. | 310 * Checks whether the page loaded in a window is whitelisted for indication in
the UI. |
| 327 * @param wnd {nsIDOMWindow} | 311 * @param wnd {nsIDOMWindow} |
| 328 * @return {Filter} matching exception rule or null if not whitelisted | 312 * @return {Filter} matching exception rule or null if not whitelisted |
| 329 */ | 313 */ |
| 330 isWindowWhitelisted: function(wnd) | 314 isWindowWhitelisted: function(wnd) |
| 331 { | 315 { |
| 332 return Policy.isWhitelisted(getWindowLocation(wnd)); | 316 return Policy.isWhitelisted(getWindowLocation(wnd)); |
| 333 }, | 317 }, |
| 334 | 318 |
| 335 | |
| 336 /** | 319 /** |
| 337 * Asynchronously re-checks filters for given nodes. | 320 * Asynchronously re-checks filters for given nodes. |
| 338 */ | 321 */ |
| 339 refilterNodes: function(/**Node[]*/ nodes, /**RequestEntry*/ entry) | 322 refilterNodes: function(/**Node[]*/ nodes, /**RequestEntry*/ entry) |
| 340 { | 323 { |
| 341 // Ignore nodes that have been blocked already | 324 // Ignore nodes that have been blocked already |
| 342 if (entry.filter && !(entry.filter instanceof WhitelistFilter)) | 325 if (entry.filter && !(entry.filter instanceof WhitelistFilter)) |
| 343 return; | 326 return; |
| 344 | 327 |
| 345 for (let node of nodes) | 328 for (let node of nodes) |
| (...skipping 338 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 684 { | 667 { |
| 685 return Utils.unwrapURL(url).host; | 668 return Utils.unwrapURL(url).host; |
| 686 } | 669 } |
| 687 catch(e) | 670 catch(e) |
| 688 { | 671 { |
| 689 return null; | 672 return null; |
| 690 } | 673 } |
| 691 } | 674 } |
| 692 | 675 |
| 693 /** | 676 /** |
| 677 * Retrieves the sitekey of a window. |
| 678 */ |
| 679 function getSitekey(wnd) |
| 680 { |
| 681 let sitekey = null; |
| 682 |
| 683 while (true) |
| 684 { |
| 685 if (wnd.document && wnd.document.documentElement) |
| 686 { |
| 687 let keydata = wnd.document.documentElement.getAttribute("data-adblockkey")
; |
| 688 if (keydata && keydata.indexOf("_") >= 0) |
| 689 { |
| 690 let [key, signature] = keydata.split("_", 2); |
| 691 key = key.replace(/=/g, ""); |
| 692 |
| 693 // Website specifies a key but is the signature valid? |
| 694 let uri = Services.io.newURI(getWindowLocation(wnd), null, null); |
| 695 let host = uri.asciiHost; |
| 696 if (uri.port > 0) |
| 697 host += ":" + uri.port; |
| 698 let params = [ |
| 699 uri.path.replace(/#.*/, ""), // REQUEST_URI |
| 700 host, // HTTP_HOST |
| 701 Utils.httpProtocol.userAgent // HTTP_USER_AGENT |
| 702 ]; |
| 703 if (Utils.verifySignature(key, signature, params.join("\0"))) |
| 704 return [key, wnd]; |
| 705 } |
| 706 } |
| 707 |
| 708 if (wnd === wnd.parent) |
| 709 break; |
| 710 |
| 711 wnd = wnd.parent; |
| 712 } |
| 713 |
| 714 return [sitekey, wnd]; |
| 715 } |
| 716 |
| 717 /** |
| 694 * Retrieves the location of a window. | 718 * Retrieves the location of a window. |
| 695 * @param wnd {nsIDOMWindow} | 719 * @param wnd {nsIDOMWindow} |
| 696 * @return {String} window location or null on failure | 720 * @return {String} window location or null on failure |
| 697 */ | 721 */ |
| 698 function getWindowLocation(wnd) | 722 function getWindowLocation(wnd) |
| 699 { | 723 { |
| 700 if ("name" in wnd && wnd.name == "messagepane") | 724 if ("name" in wnd && wnd.name == "messagepane") |
| 701 { | 725 { |
| 702 // Thunderbird branch | 726 // Thunderbird branch |
| 703 try | 727 try |
| (...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 765 if (!wnd || wnd.closed) | 789 if (!wnd || wnd.closed) |
| 766 return; | 790 return; |
| 767 | 791 |
| 768 if (entry.type == Policy.type.OBJECT) | 792 if (entry.type == Policy.type.OBJECT) |
| 769 { | 793 { |
| 770 node.removeEventListener("mouseover", objectMouseEventHander, true); | 794 node.removeEventListener("mouseover", objectMouseEventHander, true); |
| 771 node.removeEventListener("mouseout", objectMouseEventHander, true); | 795 node.removeEventListener("mouseout", objectMouseEventHander, true); |
| 772 } | 796 } |
| 773 Policy.processNode(wnd, node, entry.type, Utils.makeURI(entry.location), true)
; | 797 Policy.processNode(wnd, node, entry.type, Utils.makeURI(entry.location), true)
; |
| 774 } | 798 } |
| OLD | NEW |