Left: | ||
Right: |
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 12 matching lines...) Expand all Loading... | |
23 Cu.import("resource://gre/modules/Services.jsm"); | 23 Cu.import("resource://gre/modules/Services.jsm"); |
24 | 24 |
25 let {TimeLine} = require("timeline"); | 25 let {TimeLine} = require("timeline"); |
26 let {Utils} = require("utils"); | 26 let {Utils} = require("utils"); |
27 let {Prefs} = require("prefs"); | 27 let {Prefs} = require("prefs"); |
28 let {FilterStorage} = require("filterStorage"); | 28 let {FilterStorage} = require("filterStorage"); |
29 let {BlockingFilter, WhitelistFilter} = require("filterClasses"); | 29 let {BlockingFilter, WhitelistFilter} = require("filterClasses"); |
30 let {defaultMatcher} = require("matcher"); | 30 let {defaultMatcher} = require("matcher"); |
31 let {objectMouseEventHander} = require("objectTabs"); | 31 let {objectMouseEventHander} = require("objectTabs"); |
32 let {RequestNotifier} = require("requestNotifier"); | 32 let {RequestNotifier} = require("requestNotifier"); |
33 let {ElemHide} = require("elemHide"); | |
34 | 33 |
35 /** | 34 /** |
36 * List of explicitly supported content types | 35 * List of explicitly supported content types |
37 * @type Array of String | 36 * @type Array of String |
38 */ | 37 */ |
39 let contentTypes = ["OTHER", "SCRIPT", "IMAGE", "STYLESHEET", "OBJECT", "SUBDOCU MENT", "DOCUMENT", "XMLHTTPREQUEST", "OBJECT_SUBREQUEST", "FONT", "MEDIA"]; | 38 let contentTypes = ["OTHER", "SCRIPT", "IMAGE", "STYLESHEET", "OBJECT", "SUBDOCU MENT", "DOCUMENT", "XMLHTTPREQUEST", "OBJECT_SUBREQUEST", "FONT", "MEDIA"]; |
40 | 39 |
41 /** | 40 /** |
42 * List of content types that aren't associated with a visual document area | 41 * List of content types that aren't associated with a visual document area |
43 * @type Array of String | 42 * @type Array of String |
(...skipping 92 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
136 Utils.styleService.loadAndRegisterSheet(collapseStyle, Ci.nsIStyleSheetServi ce.USER_SHEET); | 135 Utils.styleService.loadAndRegisterSheet(collapseStyle, Ci.nsIStyleSheetServi ce.USER_SHEET); |
137 onShutdown.add(function() | 136 onShutdown.add(function() |
138 { | 137 { |
139 Utils.styleService.unregisterSheet(collapseStyle, Ci.nsIStyleSheetService. USER_SHEET); | 138 Utils.styleService.unregisterSheet(collapseStyle, Ci.nsIStyleSheetService. USER_SHEET); |
140 }) | 139 }) |
141 TimeLine.log("done registering stylesheet"); | 140 TimeLine.log("done registering stylesheet"); |
142 | 141 |
143 TimeLine.leave("Done initializing content policy"); | 142 TimeLine.leave("Done initializing content policy"); |
144 }, | 143 }, |
145 | 144 |
145 processWindow: function(wnd, contentType) | |
146 { | |
147 let uri = wnd.document.documentURIObject; | |
148 if (!uri) | |
149 return true; | |
150 | |
151 if (!Policy.isBlockableScheme(uri.scheme)) | |
152 return true; | |
153 | |
154 let topWnd = wnd.top; | |
155 if (!topWnd || !topWnd.location || !topWnd.location.href) | |
156 return true; | |
157 | |
158 let testWnd = wnd; | |
159 let parentWndLocation = getWindowLocation(testWnd); | |
160 while (true) | |
161 { | |
162 let testWndLocation = parentWndLocation; | |
163 parentWndLocation = (testWnd == testWnd.parent ? testWndLocation : getWind owLocation(testWnd.parent)); | |
164 | |
165 let match = Policy.isWhitelisted(testWndLocation, parentWndLocation); | |
166 | |
167 if (!(match instanceof WhitelistFilter)) | |
tschuster
2014/06/04 18:07:40
I think we should make this match === null, becaus
| |
168 { | |
169 let keydata = (testWnd.document && testWnd.document.documentElement ? te stWnd.document.documentElement.getAttribute("data-adblockkey") : null); | |
170 if (keydata && keydata.indexOf("_") >= 0) | |
171 { | |
172 let [key, signature] = keydata.split("_", 2); | |
173 let keyMatch = defaultMatcher.matchesByKey(testWndLocation, key.replac e(/=/g, ""), docDomain); | |
174 if (keyMatch && Utils.crypto) | |
175 { | |
176 // Website specifies a key that we know but is the signature valid? | |
177 let uri = Services.io.newURI(testWndLocation, null, null); | |
178 let params = [ | |
179 uri.path.replace(/#.*/, ""), // REQUEST_URI | |
180 uri.asciiHost, // HTTP_HOST | |
181 Utils.httpProtocol.userAgent // HTTP_USER_AGENT | |
182 ]; | |
183 if (Utils.verifySignature(key, signature, params.join("\0"))) | |
184 match = keyMatch; // XXX what is this? | |
tschuster
2014/06/04 18:07:40
Okay I am not sure about this case, is that |keyMa
| |
185 } | |
tschuster
2014/06/05 19:00:34
I have an other concern: This is never going to wo
| |
186 } | |
187 } | |
188 | |
189 if (match instanceof WhitelistFilter) | |
190 { | |
191 FilterStorage.increaseHitCount(match, wnd); | |
192 RequestNotifier.addNodeData(testWnd.document, topWnd, Policy.type.DOCUME NT, getHostname(parentWndLocation), false, testWndLocation, match); | |
193 return true; | |
194 } | |
195 | |
196 if (contentType == Policy.type.ELEMHIDE) | |
197 { | |
198 let parentDocDomain = getHostname(parentWndLocation); | |
199 match = defaultMatcher.matchesAny(testWndLocation, "ELEMHIDE", parentDoc Domain, false); | |
200 if (match instanceof WhitelistFilter) | |
201 { | |
202 FilterStorage.increaseHitCount(match, wnd); | |
203 RequestNotifier.addNodeData(testWnd.document, topWnd, contentType, par entDocDomain, false, testWndLocation, match); | |
204 return true; | |
205 } | |
206 } | |
207 | |
208 if (testWnd.parent == testWnd) | |
209 break; | |
210 else | |
211 testWnd = testWnd.parent; | |
212 } | |
213 | |
214 return false; | |
215 }, | |
216 | |
146 /** | 217 /** |
147 * Checks whether a node should be blocked, hides it if necessary | 218 * Checks whether a node should be blocked, hides it if necessary |
148 * @param wnd {nsIDOMWindow} | 219 * @param wnd {nsIDOMWindow} |
149 * @param node {nsIDOMElement} | 220 * @param node {nsIDOMElement} |
150 * @param contentType {String} | 221 * @param contentType {String} |
151 * @param location {nsIURI} | 222 * @param location {nsIURI} |
152 * @param collapse {Boolean} true to force hiding of the node | 223 * @param collapse {Boolean} true to force hiding of the node |
153 * @return {Boolean} false if the node should be blocked | 224 * @return {Boolean} false if the node should be blocked |
154 */ | 225 */ |
155 processNode: function(wnd, node, contentType, location, collapse) | 226 processNode: function(wnd, node, contentType, location, collapse) |
156 { | 227 { |
157 let topWnd = wnd.top; | 228 if (contentType == Policy.type.ELEMHIDE) |
158 if (!topWnd || !topWnd.location || !topWnd.location.href) | 229 throw new Error("unexpected!"); |
159 return true; | |
160 | |
161 let originWindow = Utils.getOriginWindow(wnd); | |
162 let wndLocation = originWindow.location.href; | |
163 let docDomain = getHostname(wndLocation); | |
164 let match = null; | |
165 if (!match && Prefs.enabled) | |
166 { | |
167 let testWnd = wnd; | |
168 let parentWndLocation = getWindowLocation(testWnd); | |
169 while (true) | |
170 { | |
171 let testWndLocation = parentWndLocation; | |
172 parentWndLocation = (testWnd == testWnd.parent ? testWndLocation : getWi ndowLocation(testWnd.parent)); | |
173 match = Policy.isWhitelisted(testWndLocation, parentWndLocation); | |
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 | |
197 if (match instanceof WhitelistFilter) | |
198 { | |
199 FilterStorage.increaseHitCount(match, wnd); | |
200 RequestNotifier.addNodeData(testWnd.document, topWnd, Policy.type.DOCU MENT, getHostname(parentWndLocation), false, testWndLocation, match); | |
201 return true; | |
202 } | |
203 | |
204 if (testWnd.parent == testWnd) | |
205 break; | |
206 else | |
207 testWnd = testWnd.parent; | |
208 } | |
209 } | |
210 | 230 |
211 // Data loaded by plugins should be attached to the document | 231 // Data loaded by plugins should be attached to the document |
212 if (contentType == Policy.type.OBJECT_SUBREQUEST && node instanceof Ci.nsIDO MElement) | 232 if (contentType == Policy.type.OBJECT_SUBREQUEST && node instanceof Ci.nsIDO MElement) |
213 node = node.ownerDocument; | 233 node = node.ownerDocument; |
214 | 234 |
215 // Fix type for objects misrepresented as frames or images | 235 // Fix type for objects misrepresented as frames or images |
216 if (contentType != Policy.type.OBJECT && (node instanceof Ci.nsIDOMHTMLObjec tElement || node instanceof Ci.nsIDOMHTMLEmbedElement)) | 236 if (contentType != Policy.type.OBJECT && (node instanceof Ci.nsIDOMHTMLObjec tElement || node instanceof Ci.nsIDOMHTMLEmbedElement)) |
217 contentType = Policy.type.OBJECT; | 237 contentType = Policy.type.OBJECT; |
218 | 238 |
239 if (Policy.processWindow(wnd, contentType)) | |
240 return true; | |
241 | |
242 let originWindow = Utils.getOriginWindow(wnd); | |
243 let wndLocation = originWindow.location.href; | |
244 let docDomain = getHostname(wndLocation); | |
245 let topWnd = wnd.top; | |
246 | |
219 let locationText = location.spec; | 247 let locationText = location.spec; |
220 if (!match && contentType == Policy.type.ELEMHIDE) | 248 let thirdParty = isThirdParty(location, docDomain); |
249 | |
250 let match = defaultMatcher.matchesAny(locationText, Policy.typeDescr[content Type] || "", docDomain, thirdParty); | |
251 if (match instanceof BlockingFilter && node.ownerDocument && !(contentType i n Policy.nonVisual)) | |
221 { | 252 { |
222 let testWnd = wnd; | 253 let prefCollapse = (match.collapse != null ? match.collapse : !Prefs.fastc ollapse); |
223 let parentWndLocation = getWindowLocation(testWnd); | 254 if (collapse || prefCollapse) |
224 while (true) | 255 schedulePostProcess(node); |
225 { | |
226 let testWndLocation = parentWndLocation; | |
227 parentWndLocation = (testWnd == testWnd.parent ? testWndLocation : getWi ndowLocation(testWnd.parent)); | |
228 let parentDocDomain = getHostname(parentWndLocation); | |
229 match = defaultMatcher.matchesAny(testWndLocation, "ELEMHIDE", parentDoc Domain, false); | |
230 if (match instanceof WhitelistFilter) | |
231 { | |
232 FilterStorage.increaseHitCount(match, wnd); | |
233 RequestNotifier.addNodeData(testWnd.document, topWnd, contentType, par entDocDomain, false, testWndLocation, match); | |
234 return true; | |
235 } | |
236 | |
237 if (testWnd.parent == testWnd) | |
238 break; | |
239 else | |
240 testWnd = testWnd.parent; | |
241 } | |
242 | |
243 match = location; | |
244 locationText = match.text.replace(/^.*?#/, '#'); | |
245 location = locationText; | |
246 | |
247 if (!match.isActiveOnDomain(docDomain)) | |
248 return true; | |
249 | |
250 let exception = ElemHide.getException(match, docDomain); | |
251 if (exception) | |
252 { | |
253 FilterStorage.increaseHitCount(exception, wnd); | |
254 RequestNotifier.addNodeData(node, topWnd, contentType, docDomain, thirdP arty, locationText, exception); | |
255 return true; | |
256 } | |
257 } | 256 } |
258 | 257 |
259 let thirdParty = (contentType == Policy.type.ELEMHIDE ? false : isThirdParty (location, docDomain)); | 258 // Track mouse events for objects |
260 | 259 if (!match && contentType == Policy.type.OBJECT && node.nodeType == Ci.nsIDO MNode.ELEMENT_NODE) |
261 if (!match && Prefs.enabled) | |
262 { | 260 { |
263 match = defaultMatcher.matchesAny(locationText, Policy.typeDescr[contentTy pe] || "", docDomain, thirdParty); | 261 node.addEventListener("mouseover", objectMouseEventHander, true); |
264 if (match instanceof BlockingFilter && node.ownerDocument && !(contentType in Policy.nonVisual)) | 262 node.addEventListener("mouseout", objectMouseEventHander, true); |
265 { | |
266 let prefCollapse = (match.collapse != null ? match.collapse : !Prefs.fas tcollapse); | |
267 if (collapse || prefCollapse) | |
268 schedulePostProcess(node); | |
269 } | |
270 | |
271 // Track mouse events for objects | |
272 if (!match && contentType == Policy.type.OBJECT && node.nodeType == Ci.nsI DOMNode.ELEMENT_NODE) | |
273 { | |
274 node.addEventListener("mouseover", objectMouseEventHander, true); | |
275 node.addEventListener("mouseout", objectMouseEventHander, true); | |
276 } | |
277 } | 263 } |
278 | 264 |
279 // Store node data | 265 // Store node data |
280 RequestNotifier.addNodeData(node, topWnd, contentType, docDomain, thirdParty , locationText, match); | 266 RequestNotifier.addNodeData(node, topWnd, contentType, docDomain, thirdParty , locationText, match); |
281 if (match) | 267 if (match) |
282 FilterStorage.increaseHitCount(match, wnd); | 268 FilterStorage.increaseHitCount(match, wnd); |
283 | 269 |
284 return !match || match instanceof WhitelistFilter; | 270 return !match || match instanceof WhitelistFilter; |
285 }, | 271 }, |
286 | 272 |
(...skipping 478 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
765 if (!wnd || wnd.closed) | 751 if (!wnd || wnd.closed) |
766 return; | 752 return; |
767 | 753 |
768 if (entry.type == Policy.type.OBJECT) | 754 if (entry.type == Policy.type.OBJECT) |
769 { | 755 { |
770 node.removeEventListener("mouseover", objectMouseEventHander, true); | 756 node.removeEventListener("mouseover", objectMouseEventHander, true); |
771 node.removeEventListener("mouseout", objectMouseEventHander, true); | 757 node.removeEventListener("mouseout", objectMouseEventHander, true); |
772 } | 758 } |
773 Policy.processNode(wnd, node, entry.type, Utils.makeURI(entry.location), true) ; | 759 Policy.processNode(wnd, node, entry.type, Utils.makeURI(entry.location), true) ; |
774 } | 760 } |
OLD | NEW |