| LEFT | RIGHT |
| 1 /* | 1 /* |
| 2 * This file is part of Adblock Plus <https://adblockplus.org/>, | 2 * This file is part of Adblock Plus <https://adblockplus.org/>, |
| 3 * Copyright (C) 2006-2015 Eyeo GmbH | 3 * Copyright (C) 2006-2015 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 15 matching lines...) Expand all Loading... |
| 26 | 26 |
| 27 let {Utils} = require("utils"); | 27 let {Utils} = require("utils"); |
| 28 let {Prefs} = require("prefs"); | 28 let {Prefs} = require("prefs"); |
| 29 let {FilterStorage} = require("filterStorage"); | 29 let {FilterStorage} = require("filterStorage"); |
| 30 let {BlockingFilter, WhitelistFilter, RegExpFilter} = require("filterClasses"); | 30 let {BlockingFilter, WhitelistFilter, RegExpFilter} = require("filterClasses"); |
| 31 let {defaultMatcher} = require("matcher"); | 31 let {defaultMatcher} = require("matcher"); |
| 32 let {objectMouseEventHander} = require("objectTabs"); | 32 let {objectMouseEventHander} = require("objectTabs"); |
| 33 let {ElemHide} = require("elemHide"); | 33 let {ElemHide} = require("elemHide"); |
| 34 | 34 |
| 35 /** | 35 /** |
| 36 * Randomly generated class name, to be applied to collapsed nodes. | |
| 37 */ | |
| 38 let collapsedClass = ""; | |
| 39 | |
| 40 /** | |
| 41 * Public policy checking functions and auxiliary objects | 36 * Public policy checking functions and auxiliary objects |
| 42 * @class | 37 * @class |
| 43 */ | 38 */ |
| 44 var Policy = exports.Policy = | 39 var Policy = exports.Policy = |
| 45 { | 40 { |
| 46 /** | 41 /** |
| 47 * Set of explicitly supported content types | 42 * Set of explicitly supported content types |
| 48 * @type Set | 43 * @type Set |
| 49 */ | 44 */ |
| 50 contentTypes: new Set([ | 45 contentTypes: new Set([ |
| (...skipping 22 matching lines...) Expand all Loading... |
| 73 */ | 68 */ |
| 74 init: function() | 69 init: function() |
| 75 { | 70 { |
| 76 // whitelisted URL schemes | 71 // whitelisted URL schemes |
| 77 for (let scheme of Prefs.whitelistschemes.toLowerCase().split(" ")) | 72 for (let scheme of Prefs.whitelistschemes.toLowerCase().split(" ")) |
| 78 this.whitelistSchemes.add(scheme); | 73 this.whitelistSchemes.add(scheme); |
| 79 | 74 |
| 80 let messageManager = Cc["@mozilla.org/parentprocessmessagemanager;1"] | 75 let messageManager = Cc["@mozilla.org/parentprocessmessagemanager;1"] |
| 81 .getService(Ci.nsIMessageListenerManager) | 76 .getService(Ci.nsIMessageListenerManager) |
| 82 .QueryInterface(Ci.nsIMessageBroadcaster); | 77 .QueryInterface(Ci.nsIMessageBroadcaster); |
| 83 let handler = (message => JSON.stringify(this.shouldAllow(message.data))); | 78 let handler = (message => this.shouldAllow(message.data)); |
| 84 messageManager.addMessageListener("AdblockPlus:ShouldAllow", handler); | 79 messageManager.addMessageListener("AdblockPlus:ShouldAllow", handler); |
| 85 onShutdown.add(() => messageManager.removeMessageListener("AdblockPlus:Shoul
dAllow", handler)); | 80 onShutdown.add(() => messageManager.removeMessageListener("AdblockPlus:Shoul
dAllow", handler)); |
| 81 |
| 82 // Generate class identifier used to collapse nodes and register |
| 83 // corresponding stylesheet. |
| 84 let collapsedClass = ""; |
| 85 let offset = "a".charCodeAt(0); |
| 86 for (let i = 0; i < 20; i++) |
| 87 collapsedClass += String.fromCharCode(offset + Math.random() * 26); |
| 86 | 88 |
| 87 let handler2 = () => collapsedClass; | 89 let handler2 = () => collapsedClass; |
| 88 messageManager.addMessageListener("AdblockPlus:GetCollapsedClass", handler2)
; | 90 messageManager.addMessageListener("AdblockPlus:GetCollapsedClass", handler2)
; |
| 89 onShutdown.add(() => messageManager.removeMessageListener("AdblockPlus:GetCo
llapsedClass", handler2)); | 91 onShutdown.add(() => messageManager.removeMessageListener("AdblockPlus:GetCo
llapsedClass", handler2)); |
| 90 | |
| 91 // Generate class identifier used to collapse node and register correspondin
g | |
| 92 // stylesheet. | |
| 93 let offset = "a".charCodeAt(0); | |
| 94 for (let i = 0; i < 20; i++) | |
| 95 collapsedClass += String.fromCharCode(offset + Math.random() * 26); | |
| 96 | 92 |
| 97 let collapseStyle = Services.io.newURI("data:text/css," + | 93 let collapseStyle = Services.io.newURI("data:text/css," + |
| 98 encodeURIComponent("." + collapsedClass + | 94 encodeURIComponent("." + collapsedClass + |
| 99 "{-moz-binding: url(chrome://global/content/bindings/general.xml#foobarb
azdummy) !important;}"), null, null); | 95 "{-moz-binding: url(chrome://global/content/bindings/general.xml#foobarb
azdummy) !important;}"), null, null); |
| 100 Utils.styleService.loadAndRegisterSheet(collapseStyle, Ci.nsIStyleSheetServi
ce.USER_SHEET); | 96 Utils.styleService.loadAndRegisterSheet(collapseStyle, Ci.nsIStyleSheetServi
ce.USER_SHEET); |
| 101 onShutdown.add(() => | 97 onShutdown.add(() => |
| 102 { | 98 { |
| 103 Utils.styleService.unregisterSheet(collapseStyle, Ci.nsIStyleSheetService.
USER_SHEET); | 99 Utils.styleService.unregisterSheet(collapseStyle, Ci.nsIStyleSheetService.
USER_SHEET); |
| 104 }); | 100 }); |
| 105 }, | 101 }, |
| 106 | 102 |
| 107 /** | 103 /** |
| 108 * Checks whether a node should be blocked, hides it if necessary | 104 * Checks whether a node should be blocked, hides it if necessary |
| 109 * @param contentType {String} | 105 * @param {Object} data request data |
| 110 * @param location {String} | 106 * @param {String} data.contentType |
| 111 * @param fremes {Object[]} | 107 * @param {String} data.location |
| 112 * @param isPrivate {Boolean} true if the request belongs to a private browsi
ng window | 108 * @param {Object[]} data.frames |
| 113 * @return {Object} An object containing properties block, collapse and hits | 109 * @param {Boolean} data.isPrivate true if the request belongs to a private b
rowsing window |
| 110 * @return {Object} An object containing properties allow, collapse and hits |
| 114 * indicating how this request should be handled. | 111 * indicating how this request should be handled. |
| 115 */ | 112 */ |
| 116 shouldAllow: function({contentType, location, frames, isPrivate}) | 113 shouldAllow: function({contentType, location, frames, isPrivate}) |
| 117 { | 114 { |
| 118 // Ignore whitelisted schemes | |
| 119 if (!this.isBlockableScheme(location)) | |
| 120 return true; | |
| 121 | |
| 122 // Interpret unknown types as "other" | |
| 123 if (!this.contentTypes.has(contentType)) | |
| 124 contentType = "OTHER"; | |
| 125 | |
| 126 let wndLocation = frames[0].location; | |
| 127 let docDomain = getHostname(wndLocation); | |
| 128 let match = null; | |
| 129 let [sitekey, sitekeyFrame] = getSitekey(frames); | |
| 130 let nogeneric = false; | |
| 131 let hits = []; | 115 let hits = []; |
| 132 | 116 |
| 133 function addHit(frameIndex, contentType, docDomain, thirdParty, location, fi
lter) | 117 function addHit(frameIndex, contentType, docDomain, thirdParty, location, fi
lter) |
| 134 { | 118 { |
| 135 if (filter && !isPrivate) | 119 if (filter && !isPrivate) |
| 136 FilterStorage.increaseHitCount(filter); | 120 FilterStorage.increaseHitCount(filter); |
| 137 hits.push({ | 121 hits.push({ |
| 138 frameIndex, contentType, docDomain, thirdParty, location, | 122 frameIndex, contentType, docDomain, thirdParty, location, |
| 139 filter: filter ? filter.text : null | 123 filter: filter ? filter.text : null |
| 140 }); | 124 }); |
| 141 } | 125 } |
| 142 | 126 |
| 143 function response(allow, collapse) | 127 function response(allow, collapse) |
| 144 { | 128 { |
| 145 return {allow, collapse, hits}; | 129 return {allow, collapse, hits}; |
| 146 } | 130 } |
| 147 | 131 |
| 132 // Ignore whitelisted schemes |
| 133 if (!this.isBlockableScheme(location)) |
| 134 return response(true, false); |
| 135 |
| 136 // Interpret unknown types as "other" |
| 137 if (!this.contentTypes.has(contentType)) |
| 138 contentType = "OTHER"; |
| 139 |
| 140 let wndLocation = frames[0].location; |
| 141 let docDomain = getHostname(wndLocation); |
| 142 let match = null; |
| 143 let [sitekey, sitekeyFrame] = getSitekey(frames); |
| 144 let nogeneric = false; |
| 148 if (!match && Prefs.enabled) | 145 if (!match && Prefs.enabled) |
| 149 { | 146 { |
| 150 let testSitekey = sitekey; | 147 let testSitekey = sitekey; |
| 151 let testSitekeyFrame = sitekeyFrame; | 148 let testSitekeyFrame = sitekeyFrame; |
| 152 for (let i = 0; i < frames.length; i++) | 149 for (let i = 0; i < frames.length; i++) |
| 153 { | 150 { |
| 154 let frame = frames[i]; | 151 let frame = frames[i]; |
| 155 let testWndLocation = frame.location; | 152 let testWndLocation = frame.location; |
| 156 let parentWndLocation = frames[Math.min(i + 1, frames.length - 1)].locat
ion; | 153 let parentWndLocation = frames[Math.min(i + 1, frames.length - 1)].locat
ion; |
| 157 let parentDocDomain = getHostname(parentWndLocation); | 154 let parentDocDomain = getHostname(parentWndLocation); |
| (...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 220 * Checks whether the location's scheme is blockable. | 217 * Checks whether the location's scheme is blockable. |
| 221 * @param location {nsIURI|String} | 218 * @param location {nsIURI|String} |
| 222 * @return {Boolean} | 219 * @return {Boolean} |
| 223 */ | 220 */ |
| 224 isBlockableScheme: function(location) | 221 isBlockableScheme: function(location) |
| 225 { | 222 { |
| 226 let scheme; | 223 let scheme; |
| 227 if (typeof location == "string") | 224 if (typeof location == "string") |
| 228 { | 225 { |
| 229 let match = /^([\w\-]+):/.exec(location); | 226 let match = /^([\w\-]+):/.exec(location); |
| 230 scheme = match ? match[0] : null; | 227 scheme = match ? match[1] : null; |
| 231 } | 228 } |
| 232 else | 229 else |
| 233 scheme = location.scheme; | 230 scheme = location.scheme; |
| 234 return !this.whitelistSchemes.has(scheme); | 231 return !this.whitelistSchemes.has(scheme); |
| 235 }, | 232 }, |
| 236 | 233 |
| 237 /** | 234 /** |
| 238 * Checks whether a page is whitelisted. | 235 * Checks whether a page is whitelisted. |
| 239 * @param {String} url | 236 * @param {String} url |
| 240 * @param {String} [parentUrl] location of the parent page | 237 * @param {String} [parentUrl] location of the parent page |
| (...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 310 function getSitekey(frames) | 307 function getSitekey(frames) |
| 311 { | 308 { |
| 312 for (let frame of frames) | 309 for (let frame of frames) |
| 313 { | 310 { |
| 314 if (frame.sitekey && frame.sitekey.indexOf("_") >= 0) | 311 if (frame.sitekey && frame.sitekey.indexOf("_") >= 0) |
| 315 { | 312 { |
| 316 let [key, signature] = frame.sitekey.split("_", 2); | 313 let [key, signature] = frame.sitekey.split("_", 2); |
| 317 key = key.replace(/=/g, ""); | 314 key = key.replace(/=/g, ""); |
| 318 | 315 |
| 319 // Website specifies a key but is the signature valid? | 316 // Website specifies a key but is the signature valid? |
| 320 let uri = Services.io.newURI(getWindowLocation(wnd), null, null); | 317 let uri = Services.io.newURI(frame.location, null, null); |
| 321 let host = uri.asciiHost; | 318 let host = uri.asciiHost; |
| 322 if (uri.port > 0) | 319 if (uri.port > 0) |
| 323 host += ":" + uri.port; | 320 host += ":" + uri.port; |
| 324 let params = [ | 321 let params = [ |
| 325 uri.path.replace(/#.*/, ""), // REQUEST_URI | 322 uri.path.replace(/#.*/, ""), // REQUEST_URI |
| 326 host, // HTTP_HOST | 323 host, // HTTP_HOST |
| 327 Utils.httpProtocol.userAgent // HTTP_USER_AGENT | 324 Utils.httpProtocol.userAgent // HTTP_USER_AGENT |
| 328 ]; | 325 ]; |
| 329 if (Utils.verifySignature(key, signature, params.join("\0"))) | 326 if (Utils.verifySignature(key, signature, params.join("\0"))) |
| 330 return [key, frame]; | 327 return [key, frame]; |
| (...skipping 79 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 410 if (!wnd || wnd.closed) | 407 if (!wnd || wnd.closed) |
| 411 return; | 408 return; |
| 412 | 409 |
| 413 if (entry.type == "OBJECT") | 410 if (entry.type == "OBJECT") |
| 414 { | 411 { |
| 415 node.removeEventListener("mouseover", objectMouseEventHander, true); | 412 node.removeEventListener("mouseover", objectMouseEventHander, true); |
| 416 node.removeEventListener("mouseout", objectMouseEventHander, true); | 413 node.removeEventListener("mouseout", objectMouseEventHander, true); |
| 417 } | 414 } |
| 418 Policy.processNode(wnd, node, entry.type, entry.location, true); | 415 Policy.processNode(wnd, node, entry.type, entry.location, true); |
| 419 } | 416 } |
| LEFT | RIGHT |