| OLD | NEW | 
|    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-present eyeo GmbH |    3  * Copyright (C) 2006-present 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 | 
|   11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the |   11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the | 
|   12  * GNU General Public License for more details. |   12  * GNU General Public License for more details. | 
|   13  * |   13  * | 
|   14  * You should have received a copy of the GNU General Public License |   14  * You should have received a copy of the GNU General Public License | 
|   15  * along with Adblock Plus.  If not, see <http://www.gnu.org/licenses/>. |   15  * along with Adblock Plus.  If not, see <http://www.gnu.org/licenses/>. | 
|   16  */ |   16  */ | 
|   17  |   17  | 
|   18 "use strict"; |   18 "use strict"; | 
|   19  |   19  | 
|   20 const {createSandbox} = require("./_common"); |   20 const {createSandbox} = require("./_common"); | 
|   21  |   21  | 
|   22 let Filter = null; |   22 let Filter = null; | 
|   23 let InvalidFilter = null; |   23 let InvalidFilter = null; | 
|   24 let CommentFilter = null; |   24 let CommentFilter = null; | 
|   25 let ActiveFilter = null; |   25 let ActiveFilter = null; | 
|   26 let RegExpFilter = null; |   26 let RegExpFilter = null; | 
|   27 let BlockingFilter = null; |   27 let BlockingFilter = null; | 
 |   28 let ContentFilter = null; | 
|   28 let WhitelistFilter = null; |   29 let WhitelistFilter = null; | 
|   29 let ElemHideBase = null; |   30 let ElemHideBase = null; | 
|   30 let ElemHideFilter = null; |   31 let ElemHideFilter = null; | 
|   31 let ElemHideException = null; |   32 let ElemHideException = null; | 
|   32 let ElemHideEmulationFilter = null; |   33 let ElemHideEmulationFilter = null; | 
 |   34 let SnippetFilter = null; | 
|   33  |   35  | 
|   34 let t = null; |   36 let t = null; | 
|   35 let defaultTypes = null; |   37 let defaultTypes = null; | 
|   36  |   38  | 
|   37 exports.setUp = function(callback) |   39 exports.setUp = function(callback) | 
|   38 { |   40 { | 
|   39   let sandboxedRequire = createSandbox(); |   41   let sandboxedRequire = createSandbox(); | 
|   40   ( |   42   ( | 
|   41     {Filter, InvalidFilter, CommentFilter, ActiveFilter, RegExpFilter, |   43     {Filter, InvalidFilter, CommentFilter, ActiveFilter, RegExpFilter, | 
|   42      BlockingFilter, WhitelistFilter, ElemHideBase, ElemHideFilter, |   44      BlockingFilter, WhitelistFilter, ContentFilter, ElemHideBase, | 
|   43      ElemHideException, |   45      ElemHideFilter, ElemHideException, ElemHideEmulationFilter, | 
|   44      ElemHideEmulationFilter} = sandboxedRequire("../lib/filterClasses") |   46      SnippetFilter} = sandboxedRequire("../lib/filterClasses") | 
|   45   ); |   47   ); | 
|   46   t = RegExpFilter.typeMap; |   48   t = RegExpFilter.typeMap; | 
|   47   defaultTypes = 0x7FFFFFFF & ~(t.CSP | t.ELEMHIDE | t.DOCUMENT | t.POPUP | |   49   defaultTypes = 0x7FFFFFFF & ~(t.CSP | t.ELEMHIDE | t.DOCUMENT | t.POPUP | | 
|   48                                 t.GENERICHIDE | t.GENERICBLOCK); |   50                                 t.GENERICHIDE | t.GENERICBLOCK); | 
|   49  |   51  | 
|   50   callback(); |   52   callback(); | 
|   51 }; |   53 }; | 
|   52  |   54  | 
|   53 function serializeFilter(filter) |   55 function serializeFilter(filter) | 
|   54 { |   56 { | 
| (...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
|  107         result.push("type=elemhideexception"); |  109         result.push("type=elemhideexception"); | 
|  108       else if (filter instanceof ElemHideEmulationFilter) |  110       else if (filter instanceof ElemHideEmulationFilter) | 
|  109         result.push("type=elemhideemulation"); |  111         result.push("type=elemhideemulation"); | 
|  110  |  112  | 
|  111       result.push("selectorDomains=" + |  113       result.push("selectorDomains=" + | 
|  112                   [...filter.domains || []] |  114                   [...filter.domains || []] | 
|  113                   .filter(([domain, isIncluded]) => isIncluded) |  115                   .filter(([domain, isIncluded]) => isIncluded) | 
|  114                   .map(([domain]) => domain.toLowerCase())); |  116                   .map(([domain]) => domain.toLowerCase())); | 
|  115       result.push("selector=" + filter.selector); |  117       result.push("selector=" + filter.selector); | 
|  116     } |  118     } | 
 |  119     else if (filter instanceof SnippetFilter) | 
 |  120     { | 
 |  121       result.push("type=snippet"); | 
 |  122       result.push("scriptDomains=" + | 
 |  123                   [...filter.domains || []] | 
 |  124                   .filter(([domain, isIncluded]) => isIncluded) | 
 |  125                   .map(([domain]) => domain.toLowerCase())); | 
 |  126       result.push("script=" + filter.script); | 
 |  127     } | 
|  117   } |  128   } | 
|  118   return result; |  129   return result; | 
|  119 } |  130 } | 
|  120  |  131  | 
|  121 function addDefaults(expected) |  132 function addDefaults(expected) | 
|  122 { |  133 { | 
|  123   let type = null; |  134   let type = null; | 
|  124   let hasProperty = {}; |  135   let hasProperty = {}; | 
|  125   for (let entry of expected) |  136   for (let entry of expected) | 
|  126   { |  137   { | 
|  127     if (/^type=(.*)/.test(entry)) |  138     if (/^type=(.*)/.test(entry)) | 
|  128       type = RegExp.$1; |  139       type = RegExp.$1; | 
|  129     else if (/^(\w+)/.test(entry)) |  140     else if (/^(\w+)/.test(entry)) | 
|  130       hasProperty[RegExp.$1] = true; |  141       hasProperty[RegExp.$1] = true; | 
|  131   } |  142   } | 
|  132  |  143  | 
|  133   function addProperty(prop, value) |  144   function addProperty(prop, value) | 
|  134   { |  145   { | 
|  135     if (!(prop in hasProperty)) |  146     if (!(prop in hasProperty)) | 
|  136       expected.push(prop + "=" + value); |  147       expected.push(prop + "=" + value); | 
|  137   } |  148   } | 
|  138  |  149  | 
|  139   if (type == "whitelist" || type == "filterlist" || type == "elemhide" || |  150   if (type == "whitelist" || type == "filterlist" || type == "elemhide" || | 
|  140       type == "elemhideexception" || type == "elemhideemulation") |  151       type == "elemhideexception" || type == "elemhideemulation" || | 
 |  152       type == "snippet") | 
|  141   { |  153   { | 
|  142     addProperty("disabled", "false"); |  154     addProperty("disabled", "false"); | 
|  143     addProperty("lastHit", "0"); |  155     addProperty("lastHit", "0"); | 
|  144     addProperty("hitCount", "0"); |  156     addProperty("hitCount", "0"); | 
|  145   } |  157   } | 
|  146   if (type == "whitelist" || type == "filterlist") |  158   if (type == "whitelist" || type == "filterlist") | 
|  147   { |  159   { | 
|  148     addProperty("contentType", 0x7FFFFFFF & ~( |  160     addProperty("contentType", 0x7FFFFFFF & ~( | 
|  149       t.CSP | t.DOCUMENT | t.ELEMHIDE | t.POPUP | t.GENERICHIDE | t.GENERICBLOCK |  161       t.CSP | t.DOCUMENT | t.ELEMHIDE | t.POPUP | t.GENERICHIDE | t.GENERICBLOCK | 
|  150     )); |  162     )); | 
|  151     addProperty("matchCase", "false"); |  163     addProperty("matchCase", "false"); | 
|  152     addProperty("thirdParty", "null"); |  164     addProperty("thirdParty", "null"); | 
|  153     addProperty("domains", ""); |  165     addProperty("domains", ""); | 
|  154     addProperty("sitekeys", ""); |  166     addProperty("sitekeys", ""); | 
|  155   } |  167   } | 
|  156   if (type == "filterlist") |  168   if (type == "filterlist") | 
|  157   { |  169   { | 
|  158     addProperty("collapse", "null"); |  170     addProperty("collapse", "null"); | 
|  159     addProperty("csp", "null"); |  171     addProperty("csp", "null"); | 
|  160     addProperty("rewrite", "null"); |  172     addProperty("rewrite", "null"); | 
|  161   } |  173   } | 
|  162   if (type == "elemhide" || type == "elemhideexception" || |  174   if (type == "elemhide" || type == "elemhideexception" || | 
|  163       type == "elemhideemulation") |  175       type == "elemhideemulation") | 
|  164   { |  176   { | 
|  165     addProperty("selectorDomains", ""); |  177     addProperty("selectorDomains", ""); | 
|  166     addProperty("domains", ""); |  178     addProperty("domains", ""); | 
|  167   } |  179   } | 
 |  180   if (type == "snippet") | 
 |  181   { | 
 |  182     addProperty("scriptDomains", ""); | 
 |  183     addProperty("domains", ""); | 
 |  184   } | 
|  168 } |  185 } | 
|  169  |  186  | 
|  170 function compareFilter(test, text, expected, postInit) |  187 function compareFilter(test, text, expected, postInit) | 
|  171 { |  188 { | 
|  172   addDefaults(expected); |  189   addDefaults(expected); | 
|  173  |  190  | 
|  174   let filter = Filter.fromText(text); |  191   let filter = Filter.fromText(text); | 
|  175   if (postInit) |  192   if (postInit) | 
|  176     postInit(filter); |  193     postInit(filter); | 
|  177   let result = serializeFilter(filter); |  194   let result = serializeFilter(filter); | 
| (...skipping 20 matching lines...) Expand all  Loading... | 
|  198 } |  215 } | 
|  199  |  216  | 
|  200 exports.testFilterClassDefinitions = function(test) |  217 exports.testFilterClassDefinitions = function(test) | 
|  201 { |  218 { | 
|  202   test.equal(typeof Filter, "function", "typeof Filter"); |  219   test.equal(typeof Filter, "function", "typeof Filter"); | 
|  203   test.equal(typeof InvalidFilter, "function", "typeof InvalidFilter"); |  220   test.equal(typeof InvalidFilter, "function", "typeof InvalidFilter"); | 
|  204   test.equal(typeof CommentFilter, "function", "typeof CommentFilter"); |  221   test.equal(typeof CommentFilter, "function", "typeof CommentFilter"); | 
|  205   test.equal(typeof ActiveFilter, "function", "typeof ActiveFilter"); |  222   test.equal(typeof ActiveFilter, "function", "typeof ActiveFilter"); | 
|  206   test.equal(typeof RegExpFilter, "function", "typeof RegExpFilter"); |  223   test.equal(typeof RegExpFilter, "function", "typeof RegExpFilter"); | 
|  207   test.equal(typeof BlockingFilter, "function", "typeof BlockingFilter"); |  224   test.equal(typeof BlockingFilter, "function", "typeof BlockingFilter"); | 
 |  225   test.equal(typeof ContentFilter, "function", "typeof ContentFilter"); | 
|  208   test.equal(typeof WhitelistFilter, "function", "typeof WhitelistFilter"); |  226   test.equal(typeof WhitelistFilter, "function", "typeof WhitelistFilter"); | 
|  209   test.equal(typeof ElemHideBase, "function", "typeof ElemHideBase"); |  227   test.equal(typeof ElemHideBase, "function", "typeof ElemHideBase"); | 
|  210   test.equal(typeof ElemHideFilter, "function", "typeof ElemHideFilter"); |  228   test.equal(typeof ElemHideFilter, "function", "typeof ElemHideFilter"); | 
|  211   test.equal(typeof ElemHideException, "function", "typeof ElemHideException"); |  229   test.equal(typeof ElemHideException, "function", "typeof ElemHideException"); | 
|  212   test.equal(typeof ElemHideEmulationFilter, "function", |  230   test.equal(typeof ElemHideEmulationFilter, "function", | 
|  213              "typeof ElemHideEmulationFilter"); |  231              "typeof ElemHideEmulationFilter"); | 
 |  232   test.equal(typeof SnippetFilter, "function", "typeof SnippetFilter"); | 
|  214  |  233  | 
|  215   test.done(); |  234   test.done(); | 
|  216 }; |  235 }; | 
|  217  |  236  | 
|  218 exports.testComments = function(test) |  237 exports.testComments = function(test) | 
|  219 { |  238 { | 
|  220   compareFilter(test, "!asdf", ["type=comment", "text=!asdf"]); |  239   compareFilter(test, "!asdf", ["type=comment", "text=!asdf"]); | 
|  221   compareFilter(test, "!foo#bar", ["type=comment", "text=!foo#bar"]); |  240   compareFilter(test, "!foo#bar", ["type=comment", "text=!foo#bar"]); | 
|  222   compareFilter(test, "!foo##bar", ["type=comment", "text=!foo##bar"]); |  241   compareFilter(test, "!foo##bar", ["type=comment", "text=!foo##bar"]); | 
|  223  |  242  | 
| (...skipping 192 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
|  416       "type=elemhideemulation", |  435       "type=elemhideemulation", | 
|  417       "text=foo.com#?#:-abp-properties(/margin: [3-4]{2}/)", |  436       "text=foo.com#?#:-abp-properties(/margin: [3-4]{2}/)", | 
|  418       "selectorDomains=foo.com", |  437       "selectorDomains=foo.com", | 
|  419       "selector=:-abp-properties(/margin: [3-4]\\7B 2\\7D /)", |  438       "selector=:-abp-properties(/margin: [3-4]\\7B 2\\7D /)", | 
|  420       "domains=foo.com" |  439       "domains=foo.com" | 
|  421     ] |  440     ] | 
|  422   ); |  441   ); | 
|  423   test.done(); |  442   test.done(); | 
|  424 }; |  443 }; | 
|  425  |  444  | 
 |  445 exports.testSnippetFilters = function(test) | 
 |  446 { | 
 |  447   compareFilter(test, "foo.com#$#abc", ["type=snippet", "text=foo.com#$#abc", "s
     criptDomains=foo.com", "script=abc", "domains=foo.com"]); | 
 |  448   compareFilter(test, "foo.com,~bar.com#$#abc", ["type=snippet", "text=foo.com,~
     bar.com#$#abc", "scriptDomains=foo.com", "script=abc", "domains=foo.com|~bar.com
     "]); | 
 |  449   compareFilter(test, "foo.com,~bar#$#abc", ["type=snippet", "text=foo.com,~bar#
     $#abc", "scriptDomains=foo.com", "script=abc", "domains=foo.com|~bar"]); | 
 |  450   compareFilter(test, "~foo.com,bar.com#$#abc", ["type=snippet", "text=~foo.com,
     bar.com#$#abc", "scriptDomains=bar.com", "script=abc", "domains=bar.com|~foo.com
     "]); | 
 |  451  | 
 |  452   test.done(); | 
 |  453 }; | 
 |  454  | 
|  426 exports.testFilterNormalization = function(test) |  455 exports.testFilterNormalization = function(test) | 
|  427 { |  456 { | 
|  428   // Line breaks etc |  457   // Line breaks etc | 
|  429   test.equal(Filter.normalize("\n\t\nad\ns"), |  458   test.equal(Filter.normalize("\n\t\nad\ns"), | 
|  430              "ads"); |  459              "ads"); | 
|  431  |  460  | 
|  432   // Comment filters |  461   // Comment filters | 
|  433   test.equal(Filter.normalize("   !  fo  o##  bar   "), |  462   test.equal(Filter.normalize("   !  fo  o##  bar   "), | 
|  434              "!  fo  o##  bar"); |  463              "!  fo  o##  bar"); | 
|  435  |  464  | 
| (...skipping 19 matching lines...) Expand all  Loading... | 
|  455   test.equal(Filter.normalize("   domain.c  om#@# # sele ctor   "), |  484   test.equal(Filter.normalize("   domain.c  om#@# # sele ctor   "), | 
|  456              "domain.com#@## sele ctor"); |  485              "domain.com#@## sele ctor"); | 
|  457  |  486  | 
|  458   // Incorrect syntax: the separator "#@#" cannot contain spaces; treated as a |  487   // Incorrect syntax: the separator "#@#" cannot contain spaces; treated as a | 
|  459   // regular filter instead (not an element hiding filter either!), because |  488   // regular filter instead (not an element hiding filter either!), because | 
|  460   // unlike the case with "# ?##" the "##" following the "@" is not considered |  489   // unlike the case with "# ?##" the "##" following the "@" is not considered | 
|  461   // to be a separator |  490   // to be a separator | 
|  462   test.equal(Filter.normalize("   domain.c  om# @## sele ctor   "), |  491   test.equal(Filter.normalize("   domain.c  om# @## sele ctor   "), | 
|  463              "domain.com#@##selector"); |  492              "domain.com#@##selector"); | 
|  464  |  493  | 
 |  494   // Snippet filters | 
 |  495   test.equal(Filter.normalize("   domain.c  om#$#  sni pp  et   "), | 
 |  496              "domain.com#$#sni pp  et"); | 
 |  497  | 
|  465   // Regular filters |  498   // Regular filters | 
|  466   let normalized = Filter.normalize( |  499   let normalized = Filter.normalize( | 
|  467     "    b$l     a$sitekey=  foo  ,domain= do main.com |foo   .com,c sp= c   s p
       " |  500     "    b$l     a$sitekey=  foo  ,domain= do main.com |foo   .com,c sp= c   s p
       " | 
|  468   ); |  501   ); | 
|  469   test.equal( |  502   test.equal( | 
|  470     normalized, |  503     normalized, | 
|  471     "b$la$sitekey=foo,domain=domain.com|foo.com,csp=c s p" |  504     "b$la$sitekey=foo,domain=domain.com|foo.com,csp=c s p" | 
|  472   ); |  505   ); | 
|  473   compareFilter( |  506   compareFilter( | 
|  474     test, normalized, [ |  507     test, normalized, [ | 
| (...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
|  551   let rewriteEvil = "/(^https?:\\/\\/[^/])/$script,rewrite=$1.evil.com"; |  584   let rewriteEvil = "/(^https?:\\/\\/[^/])/$script,rewrite=$1.evil.com"; | 
|  552   let filterEvil = Filter.fromText(rewriteEvil); |  585   let filterEvil = Filter.fromText(rewriteEvil); | 
|  553  |  586  | 
|  554   test.equal( |  587   test.equal( | 
|  555     filterEvil.rewriteUrl("https://www.adblockplus.org/script.js"), |  588     filterEvil.rewriteUrl("https://www.adblockplus.org/script.js"), | 
|  556     "https://www.adblockplus.org/script.js" |  589     "https://www.adblockplus.org/script.js" | 
|  557   ); |  590   ); | 
|  558  |  591  | 
|  559   test.done(); |  592   test.done(); | 
|  560 }; |  593 }; | 
| OLD | NEW |