| 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 198 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
|  209  |  209  | 
|  210 /** |  210 /** | 
|  211  * Combines a matcher for blocking and exception rules, automatically sorts |  211  * Combines a matcher for blocking and exception rules, automatically sorts | 
|  212  * rules into two Matcher instances. |  212  * rules into two Matcher instances. | 
|  213  * @constructor |  213  * @constructor | 
|  214  */ |  214  */ | 
|  215 function CombinedMatcher() |  215 function CombinedMatcher() | 
|  216 { |  216 { | 
|  217   this.blacklist = new Matcher(); |  217   this.blacklist = new Matcher(); | 
|  218   this.whitelist = new Matcher(); |  218   this.whitelist = new Matcher(); | 
 |  219   this.userBlacklist = new Matcher(); | 
 |  220   this.userWhitelist = new Matcher(); | 
|  219   this.resultCache = Object.create(null); |  221   this.resultCache = Object.create(null); | 
|  220 } |  222 } | 
|  221 exports.CombinedMatcher = CombinedMatcher; |  223 exports.CombinedMatcher = CombinedMatcher; | 
|  222  |  224  | 
|  223 /** |  225 /** | 
|  224  * Maximal number of matching cache entries to be kept |  226  * Maximal number of matching cache entries to be kept | 
|  225  * @type Number |  227  * @type Number | 
|  226  */ |  228  */ | 
|  227 CombinedMatcher.maxCacheEntries = 1000; |  229 CombinedMatcher.maxCacheEntries = 1000; | 
|  228  |  230  | 
|  229 CombinedMatcher.prototype = |  231 CombinedMatcher.prototype = | 
|  230 { |  232 { | 
|  231   /** |  233   /** | 
|  232    * Matcher for blocking rules. |  234    * Matcher for blocking rules. | 
|  233    * @type Matcher |  235    * @type Matcher | 
|  234    */ |  236    */ | 
|  235   blacklist: null, |  237   blacklist: null, | 
|  236  |  238  | 
|  237   /** |  239   /** | 
|  238    * Matcher for exception rules. |  240    * Matcher for exception rules. | 
|  239    * @type Matcher |  241    * @type Matcher | 
|  240    */ |  242    */ | 
|  241   whitelist: null, |  243   whitelist: null, | 
|  242  |  244  | 
|  243   /** |  245   /** | 
 |  246    * Matcher for user-defined blocking rules. | 
 |  247    * @type Matcher | 
 |  248    */ | 
 |  249   userBlacklist: null, | 
 |  250  | 
 |  251   /** | 
 |  252    * Matcher for user-defined exception rules. | 
 |  253    * @type Matcher | 
 |  254    */ | 
 |  255   userWhitelist: null, | 
 |  256  | 
 |  257   /** | 
|  244    * Lookup table of previous matchesAny results |  258    * Lookup table of previous matchesAny results | 
|  245    * @type Object |  259    * @type Object | 
|  246    */ |  260    */ | 
|  247   resultCache: null, |  261   resultCache: null, | 
|  248  |  262  | 
|  249   /** |  263   /** | 
|  250    * Number of entries in resultCache |  264    * Number of entries in resultCache | 
|  251    * @type Number |  265    * @type Number | 
|  252    */ |  266    */ | 
|  253   cacheEntries: 0, |  267   cacheEntries: 0, | 
|  254  |  268  | 
 |  269   _getMatcher: function(filter) | 
 |  270   { | 
 |  271     if (filter.isUserDefined) | 
 |  272     { | 
 |  273       if (filter instanceof WhitelistFilter) | 
 |  274         return this.userWhitelist; | 
 |  275       else | 
 |  276         return this.userBlacklist; | 
 |  277     } | 
 |  278     else | 
 |  279     { | 
 |  280       if (filter instanceof WhitelistFilter) | 
 |  281         return this.whitelist; | 
 |  282       else | 
 |  283         return this.blacklist; | 
 |  284     } | 
 |  285   }, | 
 |  286  | 
|  255   /** |  287   /** | 
|  256    * @see Matcher#clear |  288    * @see Matcher#clear | 
|  257    */ |  289    */ | 
|  258   clear: function() |  290   clear: function() | 
|  259   { |  291   { | 
|  260     this.blacklist.clear(); |  292     this.blacklist.clear(); | 
|  261     this.whitelist.clear(); |  293     this.whitelist.clear(); | 
 |  294     this.userBlacklist.clear(); | 
 |  295     this.userWhitelist.clear(); | 
|  262     this.resultCache = Object.create(null); |  296     this.resultCache = Object.create(null); | 
|  263     this.cacheEntries = 0; |  297     this.cacheEntries = 0; | 
|  264   }, |  298   }, | 
|  265  |  299  | 
|  266   /** |  300   /** | 
|  267    * @see Matcher#add |  301    * @see Matcher#add | 
|  268    */ |  302    */ | 
|  269   add: function(filter) |  303   add: function(filter) | 
|  270   { |  304   { | 
|  271     if (filter instanceof WhitelistFilter) |  305     this._getMatcher(filter).add(filter); | 
|  272       this.whitelist.add(filter); |  | 
|  273     else |  | 
|  274       this.blacklist.add(filter); |  | 
|  275  |  306  | 
|  276     if (this.cacheEntries > 0) |  307     if (this.cacheEntries > 0) | 
|  277     { |  308     { | 
|  278       this.resultCache = Object.create(null); |  309       this.resultCache = Object.create(null); | 
|  279       this.cacheEntries = 0; |  310       this.cacheEntries = 0; | 
|  280     } |  311     } | 
|  281   }, |  312   }, | 
|  282  |  313  | 
|  283   /** |  314   /** | 
|  284    * @see Matcher#remove |  315    * @see Matcher#remove | 
|  285    */ |  316    */ | 
|  286   remove: function(filter) |  317   remove: function(filter) | 
|  287   { |  318   { | 
|  288     if (filter instanceof WhitelistFilter) |  319     this._getMatcher(filter).remove(filter); | 
|  289       this.whitelist.remove(filter); |  | 
|  290     else |  | 
|  291       this.blacklist.remove(filter); |  | 
|  292  |  320  | 
|  293     if (this.cacheEntries > 0) |  321     if (this.cacheEntries > 0) | 
|  294     { |  322     { | 
|  295       this.resultCache = Object.create(null); |  323       this.resultCache = Object.create(null); | 
|  296       this.cacheEntries = 0; |  324       this.cacheEntries = 0; | 
|  297     } |  325     } | 
|  298   }, |  326   }, | 
|  299  |  327  | 
|  300   /** |  328   /** | 
|  301    * @see Matcher#findKeyword |  329    * @see Matcher#findKeyword | 
|  302    */ |  330    */ | 
|  303   findKeyword: function(filter) |  331   findKeyword: function(filter) | 
|  304   { |  332   { | 
|  305     if (filter instanceof WhitelistFilter) |  333     return this._getMatcher(filter).findKeyword(filter); | 
|  306       return this.whitelist.findKeyword(filter); |  | 
|  307     else |  | 
|  308       return this.blacklist.findKeyword(filter); |  | 
|  309   }, |  334   }, | 
|  310  |  335  | 
|  311   /** |  336   /** | 
|  312    * @see Matcher#hasFilter |  337    * @see Matcher#hasFilter | 
|  313    */ |  338    */ | 
|  314   hasFilter: function(filter) |  339   hasFilter: function(filter) | 
|  315   { |  340   { | 
|  316     if (filter instanceof WhitelistFilter) |  341     return this._getMatcher(filter).hasFilter(filter); | 
|  317       return this.whitelist.hasFilter(filter); |  | 
|  318     else |  | 
|  319       return this.blacklist.hasFilter(filter); |  | 
|  320   }, |  342   }, | 
|  321  |  343  | 
|  322   /** |  344   /** | 
|  323    * @see Matcher#getKeywordForFilter |  345    * @see Matcher#getKeywordForFilter | 
|  324    */ |  346    */ | 
|  325   getKeywordForFilter: function(filter) |  347   getKeywordForFilter: function(filter) | 
|  326   { |  348   { | 
|  327     if (filter instanceof WhitelistFilter) |  349     return this._getMatcher(filter).getKeywordForFilter(filter); | 
|  328       return this.whitelist.getKeywordForFilter(filter); |  | 
|  329     else |  | 
|  330       return this.blacklist.getKeywordForFilter(filter); |  | 
|  331   }, |  350   }, | 
|  332  |  351  | 
|  333   /** |  352   /** | 
|  334    * Checks whether a particular filter is slow |  353    * Checks whether a particular filter is slow | 
|  335    */ |  354    */ | 
|  336   isSlowFilter: function(/**RegExpFilter*/ filter) /**Boolean*/ |  355   isSlowFilter: function(/**RegExpFilter*/ filter) /**Boolean*/ | 
|  337   { |  356   { | 
|  338     let matcher = (filter instanceof WhitelistFilter ? this.whitelist : this.bla
     cklist); |  357     let matcher = this._getMatcher(filter); | 
|  339     if (matcher.hasFilter(filter)) |  358     if (matcher.hasFilter(filter)) | 
|  340       return !matcher.getKeywordForFilter(filter); |  359       return !matcher.getKeywordForFilter(filter); | 
|  341     else |  360     else | 
|  342       return !matcher.findKeyword(filter); |  361       return !matcher.findKeyword(filter); | 
|  343   }, |  362   }, | 
|  344  |  363  | 
|  345   /** |  364   /** | 
|  346    * Optimized filter matching testing both whitelist and blacklist matchers |  365    * Optimized filter matching testing both whitelist and blacklist matchers | 
|  347    * simultaneously. For parameters see Matcher.matchesAny(). |  366    * simultaneously. | 
|  348    * @see Matcher#matchesAny |  367    * @see Matcher#matchesAny | 
|  349    */ |  368    */ | 
|  350   matchesAnyInternal: function(location, contentType, docDomain, thirdParty, sit
     ekey) |  369   matchesAnyInternal: function(blacklist, whitelist, candidates, location, conte
     ntType, docDomain, thirdParty, sitekey) | 
|  351   { |  370   { | 
|  352     let candidates = location.toLowerCase().match(/[a-z0-9%]{3,}/g); |  | 
|  353     if (candidates === null) |  | 
|  354       candidates = []; |  | 
|  355     candidates.push(""); |  | 
|  356  |  | 
|  357     let blacklistHit = null; |  371     let blacklistHit = null; | 
|  358     for (let i = 0, l = candidates.length; i < l; i++) |  372     for (let i = 0, l = candidates.length; i < l; i++) | 
|  359     { |  373     { | 
|  360       let substr = candidates[i]; |  374       let substr = candidates[i]; | 
|  361       if (substr in this.whitelist.filterByKeyword) |  375       if (substr in whitelist.filterByKeyword) | 
|  362       { |  376       { | 
|  363         let result = this.whitelist._checkEntryMatch(substr, location, contentTy
     pe, docDomain, thirdParty, sitekey); |  377         let result = whitelist._checkEntryMatch(substr, location, contentType, d
     ocDomain, thirdParty, sitekey); | 
|  364         if (result) |  378         if (result) | 
|  365           return result; |  379           return result; | 
|  366       } |  380       } | 
|  367       if (substr in this.blacklist.filterByKeyword && blacklistHit === null) |  381       if (substr in blacklist.filterByKeyword && blacklistHit === null) | 
|  368         blacklistHit = this.blacklist._checkEntryMatch(substr, location, content
     Type, docDomain, thirdParty, sitekey); |  382         blacklistHit = blacklist._checkEntryMatch(substr, location, contentType,
      docDomain, thirdParty, sitekey); | 
|  369     } |  383     } | 
|  370     return blacklistHit; |  384     return blacklistHit; | 
|  371   }, |  385   }, | 
|  372  |  386  | 
|  373   /** |  387   /** | 
|  374    * @see Matcher#matchesAny |  388    * @see Matcher#matchesAny | 
|  375    */ |  389    */ | 
|  376   matchesAny: function(location, contentType, docDomain, thirdParty, sitekey) |  390   matchesAny: function(location, contentType, docDomain, thirdParty, sitekey) | 
|  377   { |  391   { | 
|  378     let key = location + " " + contentType + " " + docDomain + " " + thirdParty 
     + " " + sitekey; |  392     let key = location + " " + contentType + " " + docDomain + " " + thirdParty 
     + " " + sitekey; | 
|  379     if (key in this.resultCache) |  393     if (key in this.resultCache) | 
|  380       return this.resultCache[key]; |  394       return this.resultCache[key]; | 
|  381  |  395  | 
|  382     let result = this.matchesAnyInternal(location, contentType, docDomain, third
     Party, sitekey); |  396     let candidates = location.toLowerCase().match(/[a-z0-9%]{3,}/g); | 
 |  397     if (candidates === null) | 
 |  398       candidates = []; | 
 |  399     candidates.push(""); | 
 |  400  | 
 |  401     let result = (this.matchesAnyInternal(this.userBlacklist, this.userWhitelist
     , candidates, location, contentType, docDomain, thirdParty, sitekey) || | 
 |  402                   this.matchesAnyInternal(this.blacklist,     this.whitelist,   
       candidates, location, contentType, docDomain, thirdParty, sitekey)); | 
|  383  |  403  | 
|  384     if (this.cacheEntries >= CombinedMatcher.maxCacheEntries) |  404     if (this.cacheEntries >= CombinedMatcher.maxCacheEntries) | 
|  385     { |  405     { | 
|  386       this.resultCache = Object.create(null); |  406       this.resultCache = Object.create(null); | 
|  387       this.cacheEntries = 0; |  407       this.cacheEntries = 0; | 
|  388     } |  408     } | 
|  389  |  409  | 
|  390     this.resultCache[key] = result; |  410     this.resultCache[key] = result; | 
|  391     this.cacheEntries++; |  411     this.cacheEntries++; | 
|  392  |  412  | 
|  393     return result; |  413     return result; | 
|  394   } |  414   } | 
|  395 } |  415 } | 
|  396  |  416  | 
|  397 /** |  417 /** | 
|  398  * Shared CombinedMatcher instance that should usually be used. |  418  * Shared CombinedMatcher instance that should usually be used. | 
|  399  * @type CombinedMatcher |  419  * @type CombinedMatcher | 
|  400  */ |  420  */ | 
|  401 let defaultMatcher = exports.defaultMatcher = new CombinedMatcher(); |  421 let defaultMatcher = exports.defaultMatcher = new CombinedMatcher(); | 
| OLD | NEW |